Trying to get my head around unobtrusive validation. I created a simple page like this:
#using (Html.BeginForm())
{
<text>Validation for name should fail unless this box contains the word christmas</text>
#Html.TextBoxFor(c => c.IsChristmas, new { id = "IsChristmas" }) <br />
#Html.TextBoxFor(c => c.Name)
#Html.ValidationMessageFor(c => c.Name)
<br />
<input type="submit" value="Submit" />
}
The model just has two strings, [Required] Name and IsChristmas.
This works fine, if you press submit when the text box is empty, you get the Name is required validation error appearing.
What I want to do now is make a validation error appear when they try to submit, if the first textbox doesn't contain the word 'Christmas'. This is just to learn how I can create my own custom validation types. I don't want to use data attributes, I want to do it entirely in javascript. I'd like to hook into the existing unobtrusive stuff if possible.
Any ideas?
I figured I could write a function first:
function isChristmas()
{
return $('#isChristmas').val() == 'christmas';
}
Then perhaps I can register it somehow so it is called on submit? Either directly into the validation code, by registering some kind of handler, or write my own handler (a submit button click event) that calls isChristmas() and if it's false, calls a method to display the validation error.
I am not sure how flexible the unobtrusive stuff is. I guess another desirable thing would be that if the page is submitted with the validation being bypassed, I can check server-side as well and have it go back to the view and somehow display the error that way too.
Related
Whenever i create a boolean property in my ASP.NET MVC model and try to create a checkbox using #Html.CheckBoxFor i get a hidden form field autogenerated. I know it is happening for a good reason but whenever i submit my form and get that value using form collection it returns 2 values when it is in checked state. It submits value like this - 'true,false'. Now when i get the values using form collection and do bool.Parse() it throws an error because it cannot parse 'true,false' together. Is there any way around to get rid of hidden form field or should i try something while processing the request ??
In Model
[Display(Name ="Is Enabled")]
public bool IsEnabled { get; set; }
In Controller
public ActionResult Request(FormCollection collection)
{
bool valueIsEnabled=bool.Parse(collection["IsEnabled"])
}
In View
#Html.CheckBoxFor(m => m.IsEnabled, new {
#class = "custom-input"
})
When I click Checked
Expected Result - true
Actual Result - true,false
When I don't click checked
Expected Result - false
Actual Result - false
Ok I did some research and found that the CheckBox helper generates an additional hidden field with the same name as the checkbox (you can see it by browsing the generated source code):
<input checked="checked" id="Visible" name="Visible" type="checkbox" value="true" />
<input name="Visible" type="hidden" value="false" />
So both values are sent to the controller action when you submit the form. Here's a comment directly from the ASP.NET MVC source code explaining the reasoning behind this additional hidden field:
if (inputType == InputType.CheckBox) {
// Render an additional <input type="hidden".../> for checkboxes. This
// addresses scenarios where unchecked checkboxes are not sent in the request.
// Sending a hidden input makes it possible to know that the checkbox was present
// on the page when the request was submitted.
...
I'm using ASP.NET MVC and I have jQuery, jQuery validate, jQuery validate.config, jQuery validate unobtrusive, unobtrusive ajax and other libraries in my bundle. I have a form in my page and has some fields inside of it. It has a button of type button and when the user clicks the button I'm trying to do some stuff and then do a $(form).submit(), which I want it to be intercepted by the submithandler in the jQuery validate method and instead of submitting the form it will do a ajax post to my server. The reason I want to use the jQuery.validate method is that I have a lot of conditional required fields and other validations inside the form. But for some reason the jQuery validate is not executing/firing at all and the form is getting submitted instead of being intercepted by the submit handler. I have no idea why its not working if I setup everything correctly. Here is my call of the jQuery validate method. I never see the alert saying is good.
$('form[name="submitCheckoutForm"]').validate({
debug: true,
rules: {
"Password": {
required: true
}
},
submitHandler: function (form) {
//actions.SubmitCheckout();
alert('is good');
return false;
}
});
If you're using the Unobtrusive Validation plugin, then you cannot also call jQuery Validate's .validate() method.
Why?
The Unobtrusive Validation plugin automatically constructs the .validate() method based on the various data attributes in your form.
The jQuery Validate plugin does not allow the .validate() method to be called more than once on the same form. So since you're already using Unobtrusive Validation to construct .validate(), your other call to .validate() will be totally ignored.
Please use the required attribute instead
<input type="password" required>
I am writing a recipe manager for my wife in C#/.NET MVC 5. I'm getting to the page for creating a recipe, and I'm a little stumped. A recipe consists of a Name and a list of ingredients.
When I create a view, I have my form:
#using(Html.BeginForm()){
//Form elements
#Html.DisplayNameFor(x => Model.Name)
//button for adding a new ingredient to the recipe
<input type="submit" text="Submit New Recipe!" />
}
When the button for adding an ingredient is clicked, it should render a block of html inside the form just above the button itself, that way the user can add any number of ingredients and then submit the recipe back when the form is posted back to the controller.
For this functionality, should I make the button call a controller that sends back a partial view or something? I'm not sure how to accomplish this outside of JavaScript, but I'm wanting to use a .NET MVC solution if I can.
I try to minimize my reliance on javascript whenever I can, however I agree with #br4d that knockout is your best option here. If you want to avoid it at all cost, it will be more complex, slower and not as user friendly but here is how I would do it.
Enclose the form in a div. Have a place holder div inside the form to hold your ingredients list. Make the "Add new ingredient" call into a controller that will return a partial view with the required fields. In the target attribute indicate the place holder div as the update target and append the response to the html of the place holder div by specifying InsertionMode.InsertAfter.
<div id="parentDiv">
#Html.BeginForm........
#Ajax.ActionLink("Add New Ingredient","ActionName","ControllerName",routeValues,
new AjaxOptions
{
UpdateTargetId = "ChildDiv",
InsertionMode = InsertionMode.InsertAfter
}
<div id=ChildDiv>
</div>
</div>
This code is by no means comprehensive or production ready (I prefer to have a way of handling failed ajax calls and you might want to block off interactions until the call comes back just to mention two of the enhancements). Once again KnockOut would be the preferred way to do this.
NOTE: I referred these questions Qn1 , Qn2 before asking this . But honestly the answers are not working. Please suggest a solution..
I am doing validation to my input fields using jquery validation plugin. My code works fine when all the tags are kept inside a form tag and accessing it in jquery like, $("#formID").validate() --> this is working fine... But I want to achieve the same for a div instead of a form.
I tried it like this: $("#divID").validate() but it's not working...
Below is my code. please take a look and tell me how to achieve it for a div.
<script type="text/javascript">
$(document).ready(function () {
$("#content").validate({
onfocusout: true,
rules: {
fullname:
{
lettersonly: true,
required: true
},
age:
{
required: true,
number: true,
min: 20,
max:98,
nowhitespace:true
}
},
messages: {
fullname: "Please specify your name.",
age:"Please enter your correct age."
}
});
});
</script>
<div id="content">
<p>
<label for="fullname">Full name:</label>
<input type="text" name="fullname" id="fullname" /><br />
<label for="age">Age</label>
<input type="text" name="age" />
</p>
<p>
<button id="submit" value="">Search User</button>
</p>
</div>
Quote OP: "NOTE: I referred these questions Qn1 , Qn2 before asking this . But honestly the answers are not working."
Incorrect, the the accepted answer on Qn2 is working perfectly:
The validation plugin is (currently) designed to work on a <form>,
and only on a <form>. You can also note that all of the plugin
documentation references a form, not any other generic container.
You must use a form element with the jQuery Validate plugin. There is no workaround for this.
However, if you just want to validate some inputs without actually submitting a form, there are lots of working solutions. Example: http://jsfiddle.net/GmQ5d/
Full Documentation
Unfortunately, not the answer you want to hear, but using the JQuery Validate plugin you can't perform the validation on anything other than a form tag. You may note that all of the plugin documentation references a form and not any other generic container, e.g Div.
This website shows you how to implement JQuery Validate with webforms, not as easy as the normal examples that you get from JQuery, but still good.
jQuery's own validation only works for forms. This plugin, however, looks like it should work without forms. According to their documentation that is, I haven't tested it myself.
Very outdated, but seems like it still requires one possible solution to be added. If you cannot use form (in .NET it simply cannot be more than 1 form per page), you can still validate directly each field.
So instead of
$("#divID").validate();
you can use:
var isValid = $("#fullname").validate();
isValid = $("#age").validate();
if(isValid){
// do submit form
}
say for instance I have the following button in a form in asp.net mvc 3 app:
<input type="submit" name="command" value="Click me" data-custom="D" />
I know how to get the value from the button.. however do I get the data-custom attr value in an action method? Thank you very much!!
Edit:
I should note that I'm not allowed to use javascript at all since this is a mobile version of the site for devices that do not support javascript..
however do I get the data-custom attr value in an action method?
No you don't. There is nothing in the HTML specification that indicates that data-* attributes should be sent to the server when submitting a form. So if you want to get that value you will need to use javascript. One technique consists in subscribing to the submit event of the form and then automatically injecting a hidden field into that form which will be populated from the data-* attribute of the submit button. This way the value will be sent to the server.
But since I suspect that what you are trying to achieve here is that you have multiple submit buttons and you want to know which button was clicked in your controller action. In this case you could use the following:
<button type="submit" name="btn" value="S">Save</button>
<button type="submit" name="btn" value="D">Delete</button>
...
and then have your controller action take an argument called btn.
But personally I prefer to use separate actions otherwise it makes the controller action very ugly since it will contain lots of if statements. Here's a nice blog post I would invite you to checkout.
A custom attribute is not passed through get or post; only values do.
You can grab the custom attribute value from client side (for example using jQuery .attr() function) and add it to your form data before submitting it.
as far as I know you can't get data directly from data-... . you can write javascript to get this value.
Only the value and the name of the form element are posted within a form and any data-* cannot be passed.
You can consider a workaround using JavaScript. The idea is to so somehow merge the data-custom value to your value attribute.
$("input[type=textbox][data-custom]").each(function(index, value) {
$(value).attr("value", $(value).attr("value") + "$$$" + $(value).attr("data-custom"));
});
And from your action method, use data.split("$$$")[1] to get data-custom.
Hope this helps