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.
Related
I am currently working on jQuery validation; the current code I have was working fine, I am getting the number of error count. But I am not getting when the user enter the value in the corresponding field the error count has to detect one by one.
For example if I have 5 fields are not entered by the user it should say You have missed 5 fields. Please fill before submitted when all fields are entered the error field has to disable. And I need to highlight the label of the radio input when nothing is selected. Moreover I am trying to change my mandatory star from black to red. That is also not happening.
Here is my jQuery code.
$(document).ready(function () {
$("#basicForm").validate({
invalidHandler: function(event, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
var message = errors == 1
? 'You missed 1 field. It has been highlighted'
: 'You have missed ' + errors + ' fields. Please fill before submitted.';
$("#error_message").html(message);
$(".error_msge").show();
$("div.error").show();
$("#error_message").addClass("error_msge");
} else {
$("div.error").hide();
$("#error_message").removeClass("error_msge");
}
},
errorPlacement: function(error, element) {
},
onkeyup: false,
highlight: function(element) {
$(element).addClass('errRed');
$(element).addClass('text-error-red');
},
unhighlight: function(element) {
$(element).removeClass('errRed');
$(element).removeClass('text-error-red');
},
rules: {
txt_Fname: "required",
txt_lname: "required",
txt_Mfname: "required",
txt_Mlname: "required",
txt_Pptnum: "required",
txt_Pi: "required",
txt_dob: "required",
txt_Idt:"required",
txt_Epdt:"required",
sel_ms:"required",
ipt_nation:"required",
ipt_countryres:"required",
sel_rg:"required",
sel_sem:"required",
ipt_acdem:"required",
gender:"required"
}
});
});
Here is the Fiddle link.
You have lots of issues and I strongly recommend that you review the documentation.
But I am not getting when the user enter the value in the corresponding field the error count has to detect one by one for example If I have 5 fields are not entered by the user it should say You have missed 5 fields.
You have used the wrong option. The invalidHandler only fires on an invalid form, so when there are zero errors your function will never be called and it will be stuck on show "1 error". Use the showErrors option instead.
showErrors: function (errorMap, errorList) {
var errors = this.numberOfInvalids();
if (errors) {
var message = errors == 1 ? 'You missed 1 field. It has been highlighted' : 'You have missed ' + errors + ' fields. Please fill before submitted.';
$("#error_message").html(message);
$(".error_msge").show();
//$("div.error").show(); // superfluous
//$("#error_message").addClass("error_msge"); // superfluous
} else {
$(".error_msge").hide();
//$("div.error").hide(); // superfluous
//$("#error_message").removeClass("error_msge"); // superfluous
}
// ensures that highlight/unhighlight will function
this.defaultShowErrors();
},
Please fill before submitted. when all fields are entered the error field has to disable.
You forgot to hide the error message box when there are no errors: $(".error_msge").hide() was missing
And I need to highlight the label of the radio input when nothing is selected.
You need a conditional inside the highlight and unhighlight functions that will take care of this when the element is a radio.
highlight: function (element) {
if ($(element).is(':radio')) {
$(element).siblings('label').addClass('errRed');
} else {
$(element).addClass('errRed');
}
$(element).prev('span.required-star').addClass('text-error-red').removeClass('text-error-black');
},
unhighlight: function (element) {
if ($(element).is(':radio')) {
$(element).siblings('label').removeClass('errRed');
} else {
$(element).removeClass('errRed');
}
$(element).prev('span.required-star').addClass('text-error-black').removeClass('text-error-red');
}
I also moved the code for the asterisks in here since you want them to toggle color individually.
More over I am trying to change my mandatory star from black to red.
Your CSS technique is flawed. You are trying to select everything with the "black" class and simply add a "red" class, leaving you with two classes each with a different color. Instead, you need to replace one class with the other class. Something like this...
$(".required-star").removeClass("text-error-red").addClass("text-error-black");
You need to programmatically trigger validation using the .valid() method when you use the date-picker...
$('.ipt_Field').on('change', function() {
$("#basicForm").valid();
});
You do not need the messages option. Since you are suppressing all of the messages, it's pointless.
Also do not leave the errorPlacement function empty. Put a return false inside.
errorPlacement: function() {
return false; // suppress error messages.
}
DEMO: http://jsfiddle.net/k5wxtmpL/
I have custom ErrorPlacement function in my validator, which displays error in tooltip:
errorPlacement: function (error, element) {
var lastError = $(element).data('lastError'),
newError = $(error).text();
$(element).data('lastError', newError);
if (newError !== '' && newError !== lastError) {
$(element).tooltipster('content', newError);
$(element).tooltipster('show');
}
},
This works fine, but I would also need to display "Please, fill in all required fields" message on top of the form.
How can I do that with jQuery Validate?
Sorry for bad english, You can use bootstrap tooltip for this like that
`
rules: {
first_name:"required",
},
highlight: function (element) {
$(element).addClass('is-invalid');
},
unhighlight: function (element) {
$(element).removeClass('is-invalid');
$(element).attr('data-original-title','');
},
errorPlacement: function (error, element) {
element.attr("data-toggle", "tooltip");
element.attr("data-original-title", error[0].innerHTML);
error.css({
'color': '#FF0000',
});
$('.is-invalid').tooltip();
return false;
},
messages:{
first_name:"Please provide first Name."
}`
In error placement you define and initialize tooltip then in unhighlight you reset tooltip title.
The option you are looking for is described in the documentation, under errorContainer:
errorContainer
Hide and show this container when
validating. Example: Uses an additonal container for error messages.
The elements given as the errorContainer are all shown and hidden when
errors occur. However, the error labels themselves are added to the
element(s) given as errorLabelContainer, here an unordered list.
Therefore the error labels are also wrapped into li elements (wrapper
option).
Code would look like this:
$('form').validate({
errorContainer:'#myErrorDiv'
});
Working example: http://jsfiddle.net/ryleyb/3cDY4/
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.
I'm using jQuery Validator on a form on my site. It is functioning properly, but every keystroke results in an error:
Uncaught TypeError: Object #<error> has no method 'call'
I am implementing validation through classes on each field and all that is working properly - required fields, email fields, numbers, etc.. Here is my validate code:
if(jQuery().validate) {
//assign to global var for manual validation
validator = $(".validated").validate({
errorClass: "help-inline text-error",
errorElement: "span",
invalidHandler: function(e, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
var message = errors == 1
? 'Please fix the indicated field before saving this form.'
: 'Please fix the errors on the indicated fields before saving this form.';
$(".validation-message").text(message);
$(".validation-message").addClass('alert alert-error');
} else {
$(".validation-message").removeClass('alert alert-error').text("");
}
},
onkeyup: true,
submitHandler: function(form) {
$(".validation-message").removeClass('alert alert-error').text("");
form.submit();
},
errorPlacement: function(error, element) {
if(element.parent().hasClass('input-append')){
error.insertAfter( element.parent() );
}else{
error.insertAfter(element);
}
}
});
}
Can anyone see what would trigger that error without impacting functionality?
Cheers!
There is no true value for onkeyup option.
By default the field validation is enabled during keyup event. You need to use this option only in two scenarios
To disable validation during keyup event, in that case set onkeyup: false
To customize field validation during keyup
In your case you can just remove the option onkeyup.
I am using the jquery validation plugin and want to use the errorPlacement function to add error messages to the fields title attribute and display just a ✘ next to the field.
This works great when the form is submitted with the submit button but when any of the following events are triggered:
- onfocusout
- click
- onkeyup
The validation checks are run but it skips the errorPlacement function and adds the full error message after the field, like the default behaviour.
I am using the following code:
$("#send-mail").validate({
debug: true,
// set this class to error-labels to indicate valid fields
success: function(label) {
// set text as tick
label.html("✔").addClass("valid");
},
// the errorPlacement has to take the table layout into account
errorPlacement: function(error, element) {
console.log("errorPlacement called for "+element.attr("name")+" field");
// check for blank/success error
if(error.text() == "")
{
// remove field title/error message from element
element.attr("title", "");
console.log("error check passed");
}
else
{
// get error message
var message = error.text();
// set as element title
element.attr("title", message);
// clear error html and add cross glyph
error.html("✘");
console.log("error check failed: "+message);
}
// add error label after form element
error.insertAfter(element);
},
ignoreTitle: true,
errorClass: "invalid"
});
Your problem is that the plugin only calls the errorPlacement function once for each element which is validated. Namly when the error label for the element is first created. Afterwards the plugin just reuses the already present label and just replaces the html inside (or hides the error label if the element is now valid). That's why your cross gets removed and the actual error message is shown.
Just to make sure the flow of the plugin is clear.
element (no errorlabel yet)
element gets validated at some point
plugin creates error label and calls errorPlacement function
element "cross" (error message in title)
Element gets focus and you change something
plugin revalidates element
Sees that error label was already created (and placed)
plugin just calls label.html(message) instead of removing old label and readding it
So you see your problem is a kind of optimization the plugin does to save some unnecessary inserts/removes of error labels. Which makes sense too.
You can check what I said by looking at the validation-plugin-sourcecode
jquery.validate.js v1.6 check in function showLabel lines 617-625 for the relevant pieces.
A possible solution could be to additional provide a custom showErrors callback which solves the problem with brute force.
Something along the lines of
$("#send-mail").validate({
...
showErrors: function(errorMap, errorList) {
for (var i = 0; errorList[i]; i++) {
var element = this.errorList[i].element;
//solves the problem with brute force
//remove existing error label and thus force plugin to recreate it
//recreation == call to errorplacement function
this.errorsFor(element).remove();
}
this.defaultShowErrors();
}
...
});
Maybe there is a cleaner solution to this but this should do it and give you time to investigate a better solution.
Thanks jitter,
I done some digging around and found the same problem.
I managed to get it working by "hacking" the showLabel function in the jquery.validation.js. It's not pretty but works.
Overriding the showErrors function option would prevent me from having to change the plugin code so I will take a look.
Here is the code I used for the showLabel method:
showLabel: function(element, message) {
// look for existing error message
var label = this.errorsFor( element );
// existing error exist?
if (label.length) {
// refresh error/success class
label.removeClass().addClass( this.settings.errorClass );
// check if we have a generated label, replace the message then
label.attr("generated");
// is message empty?
if(!message)
{
// add tick glyph
label.html("✔");
// wipe element title
$(element).attr('title', message)
}
else
{
// clear error html and add cross glyph
label.html("✘");
// update element title
$(element).attr('title', message)
}
// && label.html(message);
}
else {
// create label
label = $("<" + this.settings.errorElement + "/>")
.attr({"for": this.idOrName(element), generated: true})
.addClass(this.settings.errorClass)
.html(message || "");
if ( this.settings.wrapper ) {
// make sure the element is visible, even in IE
// actually showing the wrapped element is handled elsewhere
label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
}
if ( !this.labelContainer.append(label).length )
this.settings.errorPlacement
? this.settings.errorPlacement(label, $(element) )
: label.insertAfter(element);
}
if ( !message && this.settings.success ) {
label.text("");
typeof this.settings.success == "string"
? label.addClass( this.settings.success )
: this.settings.success( label );
}
this.toShow = this.toShow.add(label);
}