0

I have a system which is using Entity Framework 6.1.1, jQuery UI (Combined Library) 1.11.1, jQuery Validation 1.13.0, and ASP.Net MVC 5.1.2 Database First. I'm new to javascript so I'm not exactly sure if I'm going about this the right way.

I have a view which has various various textboxes that need to be filled in on a stepped basis. I want these textboxes validated before the person clicks the "next" button. I have searched around the internet for solutions and I can't seem to find one that matches my requirements. I have everything encased in an Html.BeginForm tag, so I can't reference the id for the form, the textboxes are EditorFor's, and only the last button is the submit button. I have managed to get javascript that checks if all the textboxes are filled in when the page loads, which then disables the "next" button, but then I don't know how to get it to check the textboxes again to enable the "next" button once all of the textboxes have been filled in. Below is the code:

This is my view code:

@using (Html.BeginForm("Create", "Events"))

{ @Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>Event</h4>
    <hr />

    <div class="container">
        <div class="row form-group">
            <div class="col-xs-12">
                <ul class="nav nav-pills nav-justified thumbnail setup-panel">
                    <li class="active">
                        <a href="#step-1">
                            <h4 class="list-group-item-heading">Step 1</h4>
                            <p class="list-group-item-text">General Details</p>
                        </a>
                    </li>
                    <li class="disabled">
                        <a href="#step-2">
                            <h4 class="list-group-item-heading">Step 2</h4>
                            <p class="list-group-item-text">Time and Date Details</p>
                        </a>
                    </li>
                    <li class="disabled">
                        <a href="#step-3">
                            <h4 class="list-group-item-heading">Step 3</h4>
                            <p class="list-group-item-text">Questionnaire</p>
                        </a>
                    </li>
                </ul>
            </div>
        </div>


        <div class="row setup-content " id="step-1">
            <div class="col-xs-12">
                <div class="col-md-12">
                    <h1 class="text-center"> STEP 1</h1>

                    <div class="form-group" id="eventName" data-toggle="tooltip" data-placement="left" title="Enter an event name">
                        @Html.LabelFor(model => model.EventName, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventName, new { htmlAttributes = new { @class = "form-control step1" } })
                            @Html.ValidationMessageFor(model => model.EventName, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group" id="eventDesc" data-toggle="tooltip" data-placement="left" title="Enter a description for the event">
                        @Html.LabelFor(model => model.EventDescription, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.TextAreaFor(model => model.EventDescription, new { htmlAttributes = new { @class = "form-control step1" } })
                            @Html.ValidationMessageFor(model => model.EventDescription, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group" id="eventLocation" data-toggle="tooltip" data-placement="left" title="Enter the event location">
                        @Html.LabelFor(model => model.EventLocation, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventLocation, new { htmlAttributes = new { @class = "form-control step1" } })
                            @Html.ValidationMessageFor(model => model.EventLocation, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group  eventRating" id="eventRating" data-toggle="tooltip" data-placement="left" title="Rate the event between 1 and 10">
                        @Html.LabelFor(model => model.EventRating, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventRating, new { htmlAttributes = new { @class = "form-control step1" } })
                            @Html.ValidationMessageFor(model => model.EventRating, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group" id="NoOfEmp" data-toggle="tooltip" data-placement="left" title="Enter the number of employees that can attend this event">
                        @Html.LabelFor(model => model.NumberOfEmployees, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.NumberOfEmployees, new { htmlAttributes = new { @class = "form-control step1" } })
                            @Html.ValidationMessageFor(model => model.NumberOfEmployees, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group" id="eventSupplier" data-toggle="tooltip" data-placement="left" title="Enter the name of the event company">
                        @Html.LabelFor(model => model.EventSupplier, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventSupplier, new { htmlAttributes = new { @class = "form-control step1" } })
                            @Html.ValidationMessageFor(model => model.EventSupplier, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group" id="eventPic" data-toggle="tooltip" data-placement="left" title="Click the Choose Files button to select an event picture">
                        @Html.LabelFor(model => model.EventPicture, new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            <div class="btn btn-default btn-file">
                                <input id="fileInput" type="file" multiple>
                            </div>
                            <input type="button" class="btn btn-primary" value="Upload file" onclick="$('#uploader').submit()" />
                        </div>
                    </div>

                    <div class="text-center">
                        <button id="activate-step-2" class="btn btn-primary btn-lg ">Next Step</button>
                    </div>
                </div>
            </div>
        </div>
        <div class="row setup-content" id="step-2">
            <div class="col-xs-12">
                <div class="col-md-12  text-center">
                    <h1 class="text-center"> STEP 2</h1>

                    <div class="form-group" id="eventDays" data-toggle="tooltip" data-placement="left" title="Enter the days which teams can go on this event">
                        @Html.LabelFor(model => model.EventDays, htmlAttributes: new { @class = "control-label col-md-2" })

                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventDays, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EventDays, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EventStart, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventStart, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EventStart, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EventEnd, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventEnd, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EventEnd, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group" id="eventDuration" data-toggle="tooltip" data-placement="left" title="Enter the number of hours the event can be">
                        @Html.LabelFor(model => model.EventDuration, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventDuration, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EventDuration, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <button id="activate-step-3" class="btn btn-primary btn-lg">Final Step</button>
                </div>
            </div>
        </div>
        <div class="row setup-content" id="step-3">
            <div class="col-xs-12">
                <div class="col-md-12  text-center">
                    <h1 class="text-center"> STEP 3</h1>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EventTags, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EventTags, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EventTags, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EventDuration, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10 the-basics">
                            @Html.EditorFor(model => model.EventDuration, new { htmlAttributes = new { @class = "typeahead form-control", @type = "text", @placeholder = "WHY DOES THIS AND THE ABOVE NOT WORK??" } })
                            @Html.ValidationMessageFor(model => model.EventDuration, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EventDuration, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            <div id="the-basics">
                                <input class="typeahead form-control" type="text" placeholder="Tags">
                                <input class="typeahead form-control" type="text" placeholder="Tags" data-role="tagsinput">
                            </div>
                            @Html.ValidationMessageFor(model => model.EventDuration, "", new { @class = "text-danger" })
                        </div>
                    </div>



                    <button id="final" class="btn btn-primary btn-lg" type="submit" value="Create">Finish</button>
                </div>
            </div>
        </div>
    </div>
</div>

}

As can be seen above, the "next" button is just a button that takes the user to the next step, still in the same view. Also note that there is an "upload" button so I don't know how to validate that part either. The "Finish" button is the submit button that will post all the information.


This is my javascript code on the same view:

<script>
    var required_ele = document.getElementsByClassName('form-control step1');
    var allfilled = true;
    for (var i = 0; i < required_ele.length; ++i) {
        var item = required_ele[i];
        if (item.value.length == 0) {
            allfilled = false;
        }
    }

    if (allfilled) {
        document.getElementById("activate-step-2").disabled = false;
    }
    else {
        document.getElementById("activate-step-2").disabled = true;

    }

</script>

With this javascript code, it checks all the textboxes in step1 on page load and then disables the "Next" button because they're all empty, but it doesn't re-check the textboxes to see if they're filled in.


How do I go about doing this, i.e. checking the textboxes to see if they're filled in and disabling the "Next" button until all of them are filled in? Please note the "Upload" button as mentioned above as well. This is the link to an image of the view : MVC View with steps

Thanks

4
  • All your script is doing is check if something has been entered, not necessarily if its valid (it wont for instance validate if the field has say a StringLength attribute). You really should be calling $("form").validate().element(yourControl); for each group of elements. Have a look at this question/answer for a possible solution. It a slightly different approach in that the next button is not disabled, instead it just displays a message and prevents navigation if not valid. Commented Sep 8, 2014 at 4:36
  • Should I encase the code in your example, with the code you posted here? I tried your example code and when loading the page, it gets to the part '$('#button').click(function ()' and then jumps over the rest of the code in that function. Also, I'm using MVC validation, so it doesn't need to check whether the entry is valid, because MVC will do that, the jQuery just needs to check that the fields have been filled in before the user can click "next" Commented Sep 8, 2014 at 11:51
  • Not sure why you want to ignore client side validation, but the point of the linked code was that the next button is not actually disabled, it just does not do anything (except display an error message) if the associated controls are invalid (or empty in your case). The alternative is to handle the keyup event of every control, then test the validity of associated controls, and then if valid, enable the next button. This is a significant overhead compared to the first option. Commented Sep 8, 2014 at 12:03
  • I think you are correct. It would be better if I could just validate everything instead of each individual element. However, I tried your linked example and it's not working for some reason. When I click "next" it just goes to the next step. I assigned the first "next" button a type of button, I added '@using (Html.BeginForm("Create", "Events", FormMethod.Post, new { @class = "steps" }))' and referenced '.steps' as the form, '.step-1' to replace your '.section', and 'form-control step1' to replace your 'input'. I'm not sure what to put for '.error', but it's not running this javascript Commented Sep 8, 2014 at 13:25

1 Answer 1

2

Refer to this basic sample that I wrote : JSFiddle

<body>
    <input type="text" placeholder="First Name" id="fn" onkeyup="validateInputs();" />
    <input type="text" placeholder="Last Name" id="ln" onkeyup="validateInputs();" />
    <input type="submit" value="Submit" id="sb" />
</body>

<script>
$(document).ready(function () {
    validateInputs();
});

function validateInputs() {
    var firstName = $.trim($('#fn').val());
    var lastName = $.trim($('#ln').val());

    if (firstName && lastName) {
        $('#sb').attr("disabled", false);
    } else {
        $('#sb').attr("disabled", true);
    }
}
</script>
Sign up to request clarification or add additional context in comments.

8 Comments

Your JSFiddle doesn't work as is, you have to copy and paste the code you posted above. In terms of my solution, it disables the "next" button but it doesn't enable it again and I think it's because the javascript doesn't run again when the user enters information. I added your code and then in the parts that say "$.trim($('#fn').val());" I changed #fn to #eventName which is the ID of my first EditorFor, which I wanted to test. So somehow the javascript needs to run again after the user has entered something.
I just went through the code, when referencing "onkeyup="validateInputs();"", it doesn't pick up validateInputs();, so I don't know why that is, but it might work if onkeyup can pick up the validateInputs() function
@Dillon: Have you tried JSFiddle? what error do you get in the console?
It says "Uncaught ReferenceError: validateInputs is not defined" and then when I click on it, it says "onkeyup" and I'm not sure why this is happening in my application. In your JSFiddle it doesn't disable the submit button, and when i paste the code above into it, it works but if the user enters something into the first textbox then the submit button is enabled again instead of when both textboxes are filled in
I have updated the JSFiddle, check it out again make sure jquery is available also. Try again.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.