I'm using MVC3 with unobtrusive validation. I have a field that the user is expected to fill with some data and then press a "search" button. If search has never been pressed or the user has changed the input field after pressing search, the form should not be possible to submit.
I've added a hidden field that is set to true by the click() event of the button and emptied by the keyup() event of the input box. Now I would like to add a validation rule that requires the hidden field to be true to allow submit.
Preferably I would like to use unobtrusive validation, but if that doesn't work it is ok with something that requires some javascript, as long as it doesn't spoil the unobtrusive validation for the rest of the form.
The following code snippet does exactly what I want, until I add type="hidden".
<input class="required" id="client-searched" data-val="true"
name="ClientSearched" data-val-required="Press search!"/>
<span class="field-validation-valid" data-valmsg-replace="true"
data-valmsg-for="ClientSearched"/>
try
var validator = $("#myFormId").data('validator');
validator.settings.ignore = "";
Here is an informative blog post
EDIT
#RAM suggested a better solution please FOLLOW
I had a similar problem, and I used this code to change defaults, in MVC 4:
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$.validator.setDefaults({
ignore: ""
})
</script>
Source:
JQuery validate
In some cases you want just ignore validation on one or several
hidden fields (not all hidden field) in client side and also you want validate them and other hidden fields in server side.
In these cases you have validation attributes for all hidden fields in your ViewModel and they will be used to validate the form when you post it (server side).
Now you need a trick to just validate some of the hidden fields in client side (not all of them). In these cases i recommend you to use my mechanism!
Set data-force-val as true in the target hidden input tags. It's our custom attribute that we use to detect target hidden inputs witch we want validate them in client side.
// This hidden input will validate both server side & client side
<input type="hidden" value="" name="Id" id="Id"
data-val-required="The Id field is required."
data-val="true"
data-force-val="true">
// This hidden input will validate both server side & client side
<input type="hidden" value="" name="Email" id="Email"
data-val-required="The Email field is required."
data-val="true"
data-force-val="true">
// This hidden input just will validate server side
<input type="hidden" value="" name="Name" id="Name"
data-val-required="The Neme field is required."
data-val="true">
Also you can set data_force-val for your hidden inputs by jQuery:
$("#Id").attr("data-force-val", true); // We want validate Id in client side
$("#Email").attr("data-force-val", true); // We want validate Email in client side
$("#Name").attr("data-force-val", false); // We wont validate Name in client side (This line is not necessary, event we can remove it)
Now, active data-force-val="true" functionality by some simple codes like these:
var validator = $("#TheFormId").data('validator');
validator.settings.ignore = ":hidden:not([data-force-val='true'])";
Note: validator.settings.ignore default value is :hidden
Related
I`m a beginner in Foundation. I just got a task to fix issues in a form created with Foundation. And its validation is done with Foundation Abide. The issue is, in the HTML i can see "required" is added, and when we add only spaces in input field, validation accepts it as normal string. When the input field is left empty, validation working fine, it showing error message "This field is required".
I want the validation to return error "This field is required", when user enter only spaces in input field. Any idea how this is done?
<input required type="text" name="first_name" placeholder="First name">
You could just create a custom pattern matcher for the field.
Find in your code base where you're keeping your abide patterns, add something like
abide : {
patterns: {
characters_only: /[A-Za-z]+/, // this will match only letters
}
}
then add the pattern to your input element
<input required type="text" name="first_name" placeholder="First name" pattern='characters_only'>
You might have to add the error message yourself, as in -
<small class='error'>First name must only contain characters/</small>
Check here for more details -
https://foundation.zurb.com/sites/docs/v/5.5.3/components/abide.html#custom-named-patterns
I have a form with the autocomplete attribute set to off.
Inside this form, there is a hidden input element (generated using ASP.NET MVC's Html.HiddenFor() method, but, that should be irrelevant):
<input type="hidden" value="0" name="Status" id="Status" data-val-required="The Status field is required." data-val-number="The field Status must be a number." data-val="true">
When the form is submitted, this value is incremented by one and the model is returned to the view. If I write the status value to the page, I can see that the value was correctly incremented.
However, this hidden input field is always cached. It's never getting the correct value. I tried setting the autocomplete attribute directly on the input element, but without success.
How can I get this hidden field to get the correct value? I'd prefer not to use any Javascript.
Edit: Supplying more code...
Controller
//This code is being executed, and the status is being incremented.
shippingOrder.Status = (shippingOrder.Status != (int)OrderStatus.Closed) ? shippingOrder.Status + 1 : shippingOrder.Status;
View
#using (Html.BeginForm("Number", "Order", FormMethod.Post, new { id = "orderSummary", autocomplete = "off" })) {
...
#Html.HiddenFor(m => m.Status)
}
According to this post here html helpers such as HiddenFor will always first use the posted value and after that the value in the model.
As you said, when writing the value to the page you can see it incremented, yet the helper is using the previously posted value, which is the intended behaviour.
The link does suggest the use of ModelState.Remove("Status") or ModelState.Clear() before assigning the new value.
It also suggest that another option could be not using a HiddenFor helper but instead to build the hidden field yourself. Similar to this:
<input type="hidden" name="Status" value="#Model.Status" />
Either way it looks like your problem is based on similar circumstances.
I have got a hidden field with a validation for it as below
#Html.HiddenFor(m => m.Rating)
#Html.ValidationMessageFor(m => m.Rating)
The Rating property has Range validator attribute applied with range being 1-5. This is put inside a form with a submit button.
I have then got following jquery that sets the value in hidden field on some user event (Basically user clicks on some stars to rate)
$(".star").click(function(){
$("#Rating").val(2);
});
Now if I submit the form without the user event that sets the hidden field, the validation works. The error messages is displayed properly and it works all client side.
Now, in this situation, if I click on stars, that invokes the above javascript a sets the hidden field, the validation error message would not go away. I can submit the form after the hidden variable has some valid value. But I'm expecting that the client side validation should work. (When the hidden variable has been set with some valid value, the validation error should go away)
Initially I thought, the jquery validation would be invoked on some special events so I tried raising click, change, keyup, blur and focusout events myself as below
$(".star").click(function(){
$("#Rating").val(2);
$("#Rating").change();
});
But this is still not working. The error messages once appeared, does not go away at all.
You can wrap your hidden field with a div put somewhere but still inside the <form>. Add css to kick it to outer space.
<div style="position:absolute; top:-9999px; left:-9999px">
<input id="Rating" type="hidden" name="rating" >
</div>
Then add the following label to where you want to show the error:
<label for="rating" class="error" style="display:none">I am an an error message, please modify me.</label>
Client-side validation ignores hidden fields. You can set the "ignore" option dynamically but just to get it to work I did the following directlyl in the .js file.
For now this should do the trick.
In my aspx...
<%: Html.HiddenFor(model => model.age, new { #class="formValidator" }) %>
In jquery.validate.js
ignore: ":hidden:not('.formValidator')",
This turned out to be a very interesting issue. the default "ignore" setting is ignores hidden fields. The field was hidden in a jQuery ui plug-in. I simply added a class called "includeCheckBox" to the rendered input I wanted to validate and put the following line of code in...
var validator = $('#formMyPita').validate();
validator.settings.ignore = ':hidden:not(".includeCheckBox")';
if ($('#formMyPita').valid()) {....
In the code which sets the hidden field's value, manually invoke validation for the form, like so:
$("form").validate().form();
I think it is because hidden inputs don't fire any of these events.
What you could do instead would be to use a <input type="text" style="display:none" /> instead of the hidden field;
#html.TextBoxFor(m => m.Rating, new {display = "display:none"})
Using Asp.Net MVC3 with unobtrusive validation. I have a form that has a few input fields. One of the fields is pretty simple:
<input id="Name" class="valid" type="text" value="" name="Name" data-val-required="Enter your name." data-val-length-min="5" data-val-length-max="50" data-val-length="Enter a valid name." data-val="true">
I then have some js that validates the form and submits it only if client-side validation passes as in:
var $form = $('#contact_form');
var formAction = $form.attr('action');
var serialized = $form.serialize();
if ($form.validate().valid()) {...
Now the last line always returns true (yes I have unobtrusive enabled). However if I change the last line to:
if ($form.validate().element('#Name')) { ...
It works great and returns false. I have many fields and don't want to iterate over each one and am confused as to why when validating the whole form it says true but validating each individual element returns false correctly.
Things I tried:
- reparsing the the form via unobtrusive's $.validator.parse(... to no avail. It's not a dynamic form and gets rendered when the page loads.
Note: I also checked that jquery (v1.6.2) jquery.validate.min.js (v1.8.1) and jquery.validate.unobtrusive.min.js are loaded in the browser.
You don't have to call .validate() but directly .valid():
if ($form.valid()) {
...
}
I'm using MVC 3 with razor as the view engine and the unobtrusive client validation enabled.
I'm trying to create a form where the user has a radio button group to select their preferred contact method - either phone or email. Depending on the option selected, I want to show the appropriate textbox, but then also enable/disable the required validator for the appropriate textbox.
My markup looks something like this at the moment (Just starting out with MVC so please point out any obvious mistakes):
<div id="prefferedContact">
<p>Preferred Contact Method *</p>
<input type="radio" id="contactMethodEmail" name="PreferredContactMethod" value="email" #if (Model.PreferredContactMethod != "phone"){<text>checked="checked"</text>} /> <label for="contactMethodEmail">by email</label>
<input type="radio" id="contactMethodPhone" name="PreferredContactMethod" value="phone" #if (Model.PreferredContactMethod == "phone"){<text>checked="checked"</text>} /> <label for="contactMethodPhone">by phone</label>
</div>
<div id="contactMethodDetails" class="formItem">
<div id="emailAddressBox">
#Html.LabelFor(x => x.Email, "Email address")
#Html.TextBoxFor(x => x.Email, new { #class = "textbox" })
</div>
<div id="phoneNumberBox">
#Html.LabelFor(x => x.PhoneNumber, "Phone number")
#Html.TextBoxFor(x => x.PhoneNumber, new { #class = "textbox" })
</div>
</div>
</div>
</div>
There's some jquery function that adds an onclick event to the radio buttons to toggle between the two boxes depending on the selected value.
The Model - for these specific fields - doesn't have any required validation on it at the moment but is binding fine. Also, validation is working on other fields as expected
I really just need to get an idea of:
(a) is it possible to toggle validation on and off
(b) does this impact the ModelState validation in anyway (or do I need to customise it)
I had also thought of having the one textbox for the contact data, but I wanted to have regular expression validation for the email and for the phone number separately. If I was to have a single textbox, could I switch the validation rules on the textbox depending on the selected option???
Hope that's clear enough with enough information.
Thanks
Joel
You can perform class-level validation if you need to enforce rules based on multiple properties:
http://weblogs.asp.net/scottgu/archive/2010/12/10/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3.aspx
Unfortunately, this seems to only work server-side, so you'd have to implement custom client-side validation.
Another option would be to have two different models, one for each scenario (with common properties in a base class), but this might be a little more complicated.