Search code examples
jqueryhtmlasp.net-mvc-5jquery-validation-engine

Jquery validate an Html.BeginForm with steps before submit


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


Solution

  • 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>