Adding validation to dynamic forms - javascript

I pull what to display on a particular form from my database, so the form elements are dynamic.
I display radio buttons, or checkboxes or textboxes/textareas depending on how I want the form to display.
Before someone submits the form, I have to validate that each form entry (radio, checkbox, textbox etc) has been selected.
How can I insert validation to these dynamic form elements?
Example:
<input type="checkbox" id="#formInputId" name="#formInputName" value="#element.Id" />

to get started, you can also inject JSON/Javascript into the view. Though this is not preffered because then you wont be able to make a separate js file out of it. But in case of validation of dynamic forms i did this earlier.
since your form ids are coming from the database you know Id of each control therefore you can identify each element separately using jquery.
jquery validation plugins makes it very easy to add validation rules. So you just make the validation rules server side with something like this.
forEach(FormElement element in Model.FormElements){
dynamic rules = new ExpandoObject();
//set all the rule here.
ViewBag.ElementId = rules;
}
basic rules structure is given here.
Then inside the view when you are rendering the controls. check for
#if(ViewData.ContainsKey("[ElementId]")){
//if it exists
//inject json using newtonsoft json
<script>
$('##Html.raw([ElementId])').rules("Add", JsonConvert.SerializeObject(ViewData["ElementId"]))
</script>
}

Have you looked at the jquery validation plugin? Why try to reinvent the wheel. It's pretty simple to use.
Check this Demo
Here is the link to the official docs. http://jqueryvalidation.org/documentation/

Html
<form id="myform">
<input name="product[0][name]" id="form_product[0][name]" data-rule-required="true" />
<input name="product[1][name]" id="form_product[1][name]" data-rule-required="true" />
<input name="product[2][name]" id="form_product[2][name]" data-rule-required="true" />
<br/>
<br/>
<br/>
<input type="submit" />
add one field
Validation Documentation
css
#docs {
display: block;
position: fixed;
bottom: 0;
right: 0;
}
js
$(document).ready(function () {
$('#myform').validate({ // initialize the plugin
submitHandler: function (form) { // for demo
alert('valid form submitted'); // for demo
return false; // for demo
}
});
$('button').one('click', function () {
$('#myform').append('<input name="product[3][name]" id="form_product[3][name]" data-rule-required="true">');
});});
DEMO jsfiddle HERE

You should be able to parse the elements dynamically with the unobtrusive validation, however you'll need to add the appropriate attributes to trigger the appropriate validation first. Fundamentally it's very similar to what's happening in this question where they are adding elements dynamically by javascript.

If you can output a json blob of validations you can use this: https://github.com/parris/iz#json
It will let you specify a JSON blob of rules as such:
var rules = {
'cost': [
{
'rule': 'between',
'args': [17, 1000],
'error': 'The cost must be between 17, 1000'
},
{
'rule': 'required',
'error': 'You must specify a cost'
},
],
'producer.id': [
{
'rule': 'int',
'error': 'Producer ID must be an int'
}
],
'producer.name.first': [
{
'rule': 'alphaNumeric',
'error': 'Must be names and numbers'
}
]
};
Then collect your values and validate like this:
are(rules).validFor({
cost: 20,
producer: {
id: 1,
name: {
first: 'bob'
}
}
});
It has some built in validations that should pretty closely match what you need. If not, you can shim in some custom validations.
Note: Iz, is a library I wrote, and yes I am totally pitching it to you right now.

The JQuery Validate plugin should work (see http://jqueryvalidation.org).
It sounds like all you need is to mark all fields required, so you can add a required rule to them by using a class, which would avoid having to coordinate ids/names of your dynamic elements between the model and the javascript.
Change your input line to:
<input type="checkbox" id="#formInputId" name="#formInputName"
value="#element.Id" class="requiredField" />
Then in your javascript:
$(document).ready(function() {
var form = $( "#MyForm" );
form.validate();
jQuery.validator.addClassRules('requiredField', {
required: true
});
form.on('submit', function () {
if (form.valid()) {
form.submit();
}
});
});
You can also check validity of individual elements by using (selector).valid(). You can add other validation rules (besides required) by adding to the list of class rules.

You could also use Jquery Validate engine .
In which, you just have to manage class attribute of the dynamic element.
I suggest you, you could use Hook of Jquery Validate Engine.
It will be easy for you.

I have recently answered a question where we do no of things with jQuery, if you want to user custom jQuery, take reference as follows:
On form element you can use recursive code for ex: in case of a checkbox
$(document).ready(function () {
$('#new_user_form *').filter(':checkbox').each(function(){
if(this.id=='row1' && this.value=='3') {
} else {
$(this).attr("checked",false);
}
});
});
Will work same for other type of element i.e input, radio etc.
On selecting a checkbox disable spefic checkboxes
Review above for more, comment for more info or a small demo form.

i have achieved the same requirement using jQuery Validation Plugin
Place the following code in script section of your page.
you need to add the form-data class to your form and add required_field while adding the elements to page.
var validator = null;
$(document).ready(function () {
try {
var validatedForm = $(".form-data");
validator = validatedForm.validate && validatedForm.validate({
rules: {
required_field: {
required: true
}
},
messages: {
required_field: {
required: " "
}
},
errorElement: "span",
showErrors: function (errorMap, errorList) {
this.defaultShowErrors();
},
highlight: function (element) {
// do something like
$(element).closest('...').removeClass('success').addClass('error');
},
unhighlight: function (element) {
// do something like
$(element).closest('...').removeClass('error');
},
submitHandler: function(form) {
// submit form
form.submit();
}
success: function (element) {
// do something like
$(element).closest('...').removeClass('error').end().remove();
},
onfocusout: function (element) {
$(element).valid();
},
});
$.each($(".required_field"), function (index, value){
$(value).rules( "add", {
required: true,
messages: {
required: " "
}
});
});
} catch(err) {
console.log("javascript error", err);
}
});
While submitting you can check if the form is valid or not:
if($('#formId').valid()) {
...

i guess the best way is make your client-side validation using $.validate plugin and in your POST action create methods to validate your data. I always suggest to not mix javascript with csharp, or others places, to maintains things organized.

Related

how to add custom error replacment messages in jquery validaiton plugin?

I would like to add custom error replacement using jquery validation plugin (http://jqueryvalidation.org/documentation/) I would like to do custom error replacement like click here
$(function() {
//simple example 1
//click event for first button
$("#form1").validate({
errorPlacement: function(error, element) {
if (element.attr("name") == "business_email" ) {
$("#bus_email").css('color',"#f42156");
$("#busp_email").removeClass("field_validation_error hidden");
$("#busp_email").addClass("field_validation_error");
}
},
rules: {
business_email: "required"
},
messages: {
business_email: "Please enter your firstname"
}
});
});
https://jsfiddle.net/fr0dc2es/7/
With this code you can get custom replacement message and act on #bus_email:
$(function() {
//simple example 1
//click event for first button
$("#form1").validate({
rules: {
business_email: "required"
},
messages: {
business_email: "Please enter your firstname"
},
errorPlacement: function(error, element) {
if (element.attr("name") == "business_email") {
$("#bus_email").css('color',"#f42156");
$("#busp_email").removeClass("hidden");
$("#busp_email").html(error);
} else {
$("#busp_email").addClass("hidden");
$("#busp_email").html();
error.insertAfter(element);
}
}
});
});
JQueryValidation Documentation
In your JSFiddle, errorPlacement function is being called and jQueryVal is working properly.
However,
Your #busp_email is shown but empty.
Your script logic is incorrect. Why do you remove a class, and add this class right after it? Why don't you hide it?
You don't need to check for every value in errorPlacement. It is not how it works. You shouldn't define a error placement for every input in a predefined error box - you should define a common placement logics by creating dynamic error messages after an input or in a specified place; or by appending an error to the specified alert; but definitely not by checking for every item.
Why default validation error placement is not suitable for you? What do you want to change? Describe it and I will try to help you - now you just provide an invalid code without any explanations.

jQuery validate not working for two fields

I need to validate that both the domain field is correct and that the placeholder field has a value. Once both are true, the Submit button will show. Using jQuery validate, I can check that the domain is correct, but its not validating the placeholder field. The playerClass rule is not being applied:
$(function() {
$("#form").validate({
rules: {
playerClass: {
required: true
}
},
submitHandler: function() {
$("body").append("<p>Validation Complete!</p>");
}
});
});
jQuery.validator.addMethod("domainChk", function(value, element, params) {
$(".submit").show();
if (this.optional(element)) return true;
var regExp = new RegExp("^(?!www\\.|http:\/\/www\.)(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$");
return regExp.test(value);
},
function errmess(params, element) {
$(".submit").hide();
return "Valid hostname required for player code";
});
jQuery.validator.addClassRules({
domainChk: {
domainChk: true
}
});
jsFiddle: Link
The playerClass rule is not being applied
Your second field, with name="playerClass" is not being validated because you've applied no validation rules to it. There is no such rule called playerClass in your jsFiddle or in your OP, and you've applied no rules to the playerClass field in your jsFiddle.
Even if playerClass was a custom rule, the form is considered valid because the playerClass field is optional in your jsFiddle. Without the required rule, when the field is left blank, it's valid.
You've also failed to close your <form> element in the jsFiddle. There is no </form> tag.
EDIT:
As per documentation, any ajax() should go inside the submitHandler function within the .validate() method.
In other words, you are breaking the validation plugin with your click handler.
I need to validate that both the domain field is correct and that the placeholder field has a value. Once both are true, the Submit button will show.
Then why are you showing the submit button from within the domainChk rule? Once this rule is passed, you're showing the button with $(".submit").show().
You would typically use the .valid() method to test the form and show/hide the button.
$('input[type="text"]').on('click keyup blur', function() {
if ($('#form').valid()) {
$(".submit").show();
} else {
$(".submit").hide();
}
});
This is much closer to how it should be: http://jsfiddle.net/e04rca0t/2/

$.validator.addMethod()

I have a dropdownlist
$.validator.addMethod("ddlNames", function (value) {
if ($("#NameList.val()=="-1")
{
return false;
}
else
{
return true;
}
}, "Please select a valid Name");
This validation is going fine. But when i change the dropdown value (valid selection ) the error message occured previously its stil displayed. Please can any one help me out?
thanks
You need to call the validation programmatically when changing the drop down.
Eg. If you have: YOUR_FORM validation. Assign a variable to the validate method.
And then call that with .form() on the change event of your dropdown.
Documentation: http://jqueryvalidation.org/Validator.form/
Sample code:
$('#ddlNames').change(function() {
form_validator.form();
});
var form_validator = $("#YOUR_FORM").validate({
ignore: "",
rules: {
firstname: {
required: true,
minlength: 2
},
...
In document.ready you need to add another line that says (replace: # < targetform> with your form):
$('#<targetform>').validate({
rules : {
names : { ddlNames: true }
}
});
Make sure you have a class="required" on your <select>
You should not need to clear them yourself, but there are ways...:
$("#NameList").removeClass("error").addClass("valid");
or
$.validator.resetForm();
That will make sure you start off valid each time.

Custom form validation using jquery plugin, based on attributes

I am using Jquery valdiation plugin for validating the form at client side. But I want to do the validation like.
<input type="text" id="txtInf" regex="/some regular expression/" error="Inf is mandatory"></inf>
here regex and error are custom attributes. Field will be validated against the given regular expression in regex and if the regular expression text fails then error meessage should be shown.
I tried to add a method to validator like this.
$("*[regex]").each(function () {
$.validator.addMethod($(this).attr('id'), function () {
return this.optional($(this)) || $(this).attr('regex').test($(this).text());
}, $(this).attr('error'));
});
But there is some issue, with the approach. Please let me know, if I am thinking it right.
If there is some other approach in your mind, please let me know. Any thought process is welcomed.
I haven't used that plugin, but it looks like you'll get an error from the use of test().
$(this).attr('regex').test($(this).text());
should be
var regEx = new RegExp($(this).attr('regex'));
regEx.test($(this).text());
custom form validation in bootstrap is possible using few lines of code
// Add below code in html
<form id="addForm" action=" " method="post" class="needs-validation" novalidate> </form>
// add this in script tag
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
document.getElementById("btn_inject").addEventListener("click", function(event) {
//form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})
();
//you will also need this to make the text boxes back to dismiss the validation
$("#Modalidname").on('hide.bs.modal', function() {
$("#Formidname").removeClass('was-validated');
});

How can I add, remove, or swap jQuery validation rules from a page?

Note:
This question refers to a very old version of jQuery.validate() (version 1.5). This plugin now provides a built-in solution for doing this: the .rules() method that should be used instead. I'm leaving this question and answer in its original form for historical purposes for anyone who needs to maintain a legacy site that is unable to upgrade to the latest versions of jQuery and jQuery.validate().
I have a form that toggles what input elements are visible. I want to validate only the visible elements on the form.
I'm having a hard time getting this to function correctly. I want to disable validators for non-visible elements and I can't seem to figure out the best way to do this. Any insight to what may be wrong with my code, or my approach would be appreciated.
When visibility is toggled, I've tried a few things:
Calling $("form").rules("remove") to clear all existing validation rules. This throws an "undefined" JavaScript exception.
Calling $("form").validation(...options...) for the visible elements, hoping this would overwrite the rules. This only allows the first group that is validated to work. The second panel can not be validated.
Unbinding the submit handler before calling the new validation() method. This didn't do what I would have thought. It removes all validation (seemingly) permanently and the form submits without validation.
Clearing out the validation object with $.removeData($('form'), 'validator') before trying to call the validator again. This also doesn't work.
This is in an ASP.NET site, so using multiple <form /> tags is out of the question since that would break the page.
I'm sort of stumped on how I can make this work. You can see a complete working demo of what I have at http://jsbin.com/ucibe3, or edit it at http://jsbin.com/ucibe3/edit. I've tried to strip it down to just the code that causes the bug.
Here are the key pieces of my code (use above links for complete working page)
HTML:
<td id="leftform">
Left Form<br />
Input 1: <input type="text" name="leftform_input1" /><br />
Input 2: <input type="text" name="leftform_input2" /><br />
<input type="submit" name="leftform_submit" value="Submit Left" />
</td>
<td id="rightform" style="visibility:hidden">
Right Form<br />
Input 1: <input type="text" name="rightform_input1" /><br />
Input 2: <input type="text" name="rightform_input2" /><br />
<input type="submit" name="rightform_submit" value="Submit Right" />
</td>
JavaScript:
$('#toggleSwitch').click(function() {
if ($('#leftform').css("visibility") !== "hidden") {
$('#leftform').css("visibility", "hidden");
$('#rightform').css("visibility", "visible");
$('form').validate({
rules: {
rightform_input1: { required: true },
rightform_input2: { required: true }
},
messages: {
rightform_input1: "Field is required",
rightform_input2: "Field is required"
}
});
} else {
$('#rightform').css("visibility", "hidden");
$('#leftform').css("visibility", "visible");
$('form').validate({
rules: {
leftform_input1: { required: true },
leftform_input2: { required: true }
},
messages: {
leftform_input1: "Field is required",
leftform_input2: "Field is required"
}
});
}
});
Obsolete notice:
This answer refers to an extremely old version of the jQuery.validate() plugin (version 1.5) and is now obsolete as the plugin provides an official API for solving this problem. See the .rules() documentation for the current approach to solving this. I'm leaving this answer as-is to help anyone who must maintain a legacy site that is unable to upgrade to the latest versions of jQuery and jQuery.validate().
This uses a feature of the validator that is not well documented in the API (and by this I mean it isn't documented at all), however since it is a fundamental part of how the validator works, it is not likely to be removed even if it is undocumented.
Once you've initialized the jQuery validator, you can get access to the validator object again by calling the validate() method on the form object you applied the validator to. This validator object has a settings property, which stores the default settings, combined with the settings you applied to it in initialization.
Assuming I initialize the validator like this:
$('form').validate({
rules: {
leftform_input1: { required: true },
leftform_input2: { required: true }
},
messages: {
leftform_input1: "Field is required",
leftform_input2: "Field is required"
}
});
I can then get those exact settings out of the validator by doing the following:
var settings = $('form').validate().settings;
I can then easily work with this settings object to add or remove validators for the form.
This is how you would remove validation rules:
var settings = $('form').validate().settings;
delete settings.rules.rightform_input1;
delete settings.messages.rightform_input1;
And this is how you would add validation rules:
var settings = $('form').validate().settings;
settings.rules.leftform_input1 = {required: true};
settings.messages.leftform_input1 = "Field is required";
Here is a working solution for the scenario in my question. I use jQuery's extend() method to overwrite the rules and messages properties of the validate object, which is how I toggle between the two panels.
$('#toggleSwitch').click(function() {
var settings = $('form').validate().settings;
var leftForm = $('#leftform');
var rightForm = $('#rightform');
if (leftForm.css("visibility") !== "hidden") {
leftForm.css("visibility", "hidden");
rightForm.css("visibility", "visible");
$.extend(settings, {
rules: {
rightform_input1: { required: true },
rightform_input2: { required: true }
},
messages: {
rightform_input1: "Field is required",
rightform_input2: "Field is required"
}
});
} else {
rightForm.css("visibility", "hidden");
leftForm.css("visibility", "visible");
$.extend(settings, {
rules: {
leftform_input1: { required: true },
leftform_input2: { required: true }
},
messages: {
leftform_input1: "Field is required",
leftform_input2: "Field is required"
}
});
}
});
If you want to call validate again with new settings (rules,messages ... etc.)
call
$('#formid').removeData('validator')
This will remove validation for the form then initialize it again with the new settings
The "required" declarations inside of the validate.rules hash do not have to be statically declared as "true". You can actually supply an anonymous function instead which can check for the visibility of something and return true or false depending on the answer.
$('form').validate({
rules: {
rightform_input1: {
required: function(){
return $('#leftform').css("visibility") !== "hidden"
} },
rightform_input2: {
required: function(){
return $('#leftform').css("visibility") !== "hidden"
} }
}
});
$('#form_id').validate();//empty rules
//add rules/message to form element
$('#form_id #inputId').rules("add", {
required : true,
messages : {
required : 'Add your required message'
}
});
I wrote small function for editting rules (only required).
$.editRules = function($array, $type) {
var settings = $('#signupForm').validate().settings;
$.each($array, function($k, $v) {
settings.rules[$v] = {required: ($type == 'add' ? true : false)};
});
};
While there are other ways to do this ASP.net does allow you to use multiple form tags so long as they are not all rendered - so if you use a multi view to only display the relevant content you can use multiple forms.
It tends to clean up validation and submit handling quite a bit.
Alternatively jquery does allow :visible to be added to your selector, so you could potentially only run the selector on visible elements and sidestep the issue that way depending on how they are hidden.
How :visible is calculated was changed in jQuery 1.3.2. Element assumed as visible if it and its parents consumes space in document. CSS visibility isn't taken into account. The release notes outline the changes in more detail.
Here is a better / simpler solution from another post on stack overflow-
Apparently the validation plug-in allows you to specify :visible in your rules. Here is the post-
Advanced JQuery Validation: Avoiding Validations on Certain Conditions

Categories

Resources