user869375
user869375

Reputation: 2419

MVC4 validation does not work

I have simple 1 page application to send email out to users. I have 3 fields for name, email and phone number. The code seems to work with input button, with validations firing and throwing proper error message. But I am more inclined towards using anchor tag (ActionLink) for my UI. The data still posts when I click on anchor tag (using jQuery) but the validations don't fire. Is there anything that I am missing or there's a better way of doing it?

I have used this post as reference.

Model

public class Contact
{
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }

    [Required(ErrorMessage = "Email is required")]
    public string Email { get; set; }

    [Required(ErrorMessage = "Phone is required")]
    public string PhoneNumber { get; set; }
}

View

            <div>
                @Html.TextBoxFor(model => model.Name, new { @class = "form-control", placeholder="Name" })
                @Html.ValidationMessageFor(model=>model.Name)
            </div>
            <div>
                @Html.TextBoxFor(model => model.Email, new { @class = "form-control", placeholder="Email" })
                @Html.ValidationMessageFor(model=>model.Email)
            </div>
            <div>
                @Html.TextBoxFor(model => model.PhoneNumber, new { @class = "form-control", placeholder="Phone" })
                @Html.ValidationMessageFor(model=>model.PhoneNumber)
            </div>
            <div>
                <input type="submit" value="Give me Free Advice" />
                <div class="btn">
                    @Html.ActionLink("I want free advice", "designerhome")
                </div>
            </div>
  <script>
    $(function () {
        $('.btn').click(function (e) {

            $.post("/campaign/designerhome", { Name: $("#Name").val(), Email: $("#Email").val(), PhoneNumber: $("#Phone").val() }, function (result) {
                //do whatever with the response
                if (result.status == true) {
                    alert('Email submitted successfully');
               }
            });//end of post
        });//end of click
    });
</script>

Controller

[HttpPost]
    public ActionResult designerhome(Contact contact)
    {
        if (ModelState.IsValid)
        {
        }
        return View("Advert1");
    }

Upvotes: 2

Views: 941

Answers (4)

Chander .k
Chander .k

Reputation: 541

We have some reasons why validation not working

1. Check appsettings in web config

    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />

Both Should be true if you want to run client side validation.

2. Seems in your code you are not using Form tag as it is posted in the question

Form tag is must for validation

3. Jquery is not properly refrenced on layout page

please check following jquery refrence on your layout page

jquery.unobtrusive*.js
jquery.validate*.js

Hope it will help you.

Upvotes: 2

hutchonoid
hutchonoid

Reputation: 33326

Simply style your input button to look like a link with the following CSS:

input[type=submit] {
    background:none!important;
     border:none; 
     padding:0!important;
     color:#069;
     text-decoration:underline;
     cursor:pointer;
}
<input type="submit" value="Give me Free Advice" />

This will allow all the built in validation to work as is, with no difference to the user other than the appearance.

If your requirement is to use ajax to post you must manually call the validate method within the JavaScript with jquery unobtrusive.

This can be done with the following:

    // replace the `formId` with the one defined in your view
    var $form = $('#formId');
    $.validator.unobtrusive.parse($form);
    $form.validate();
    if ($form.valid()) {
      // Do post
   }

In order to manually pull out the error messages you can use this:

$.each($form.validate().errorList, function (key, value) {
            $errorSpan = $("span[data-valmsg-for='" + value.element.id + "']");
            $errorSpan.html("<span style='color:red'>" + value.message + "</span>");
            $errorSpan.show();
        });

Which replaces the ValidationMessageFor markup with the failure messages.

Upvotes: 0

Tushar Gupta
Tushar Gupta

Reputation: 15933

As your making an Ajax request to the Action, your validations will not be reflected as the view is not rendered again. To stay on the same track you can return the JSON like

return Json(new {Valid = validState,
                Errors = Get Errors FromModel State, 
            });

and then repopulate using the JavaScript.

Another Way could be around making custom Helpers which will |make a POST request to the desired Action.Code Reference for the same is here.

And at last what you can do is create a HTML button and make a POST request.

Upvotes: 0

Efran Cobisi
Efran Cobisi

Reputation: 6484

I would force the validation in your click handler, as jQuery seems to do that only for the automatic submit of the form (and not for the manual post() you are doing):

$('.btn').click(function (e) {
   if ($('#YourFormIdHere').valid()) { // Will force validation
      $.post(...);
   }
});

Upvotes: 0

Related Questions