How to clear jquery validate errors - jquery-validate

I'm hijaxing an existing form and POSTing to the server. jQuery validate does most of the validation but if validation fails on the server we return the errors to the client as JSON.
Below is the code that does that:
<script type="text/javascript">
$(function () {
$("form").submit(function (e) {
var $form = $(this);
var validator = $form.data("validator");
if (!validator || !$form.valid())
return;
e.preventDefault();
$.ajax({
url: "#Url.Action("index")",
type: "POST",
data: $form.serialize(),
statusCode: {
400: function(xhr, status, err) {
var errors = $.parseJSON(err);
validator.showErrors(errors);
}
},
success: function() {
// clear errors
// validator.resetForm();
// just reload the page for now
location.reload(true);
}
});
});
});
</script>
The problem is I can't seem to clear the validation errors if the POST is successful. I've tried calling validator.resetForm() but this makes no difference, the error messages added by the showError() call, are still displayed.
Note I'm also using the jQuery.validate.unobtrusive plugin.

You posted this a while ago, I don't know if you managed to solve it? I had the same problem with jQuery validate and the jQuery.validate.unobtrusive plugin.
After examining the source code and some debugging, I came to the conclusion that the problem comes from the way the unobtrusive plugin handles error messages. It removes the errorClass that the jQuery.validate plugin sets, and so when the form is reset, jQuery validate cannot find the error labels to remove.
I did not want to modify the code of the plugins, so I was able to overcome this in the following way:
// get the form inside we are working - change selector to your form as needed
var $form = $("form");
// get validator object
var $validator = $form.validate();
// get errors that were created using jQuery.validate.unobtrusive
var $errors = $form.find(".field-validation-error span");
// trick unobtrusive to think the elements were succesfully validated
// this removes the validation messages
$errors.each(function(){ $validator.settings.success($(this)); })
// clear errors from validation
$validator.resetForm();
note: I use the $ prefix for variables to denote variables that contain jQuery objects.

$("#form").find('.field-validation-error span').html('')

In .NET Core I have the form inside a builtin Bootstrap modal.
For now I'm manually removing the error message spans from their containers, once the modal is starting to show, by using the additional .text-danger class of the error message container like so:
$('#my-form').find('.text-danger').empty();
so that I don't rely on container .field-validation-error that might have been already toggled to .field-validation-valid.
The min.js versions of the libraries jquery.validate and jquery.validate.unobtrusive are loaded via the partial view _ValidateScriptsPartial.cshtml, so I played with them to see what resetForm() / valid() and native html form reset() do.
So in my case $('#my-form').data("validator").resetForm() only resets some validator internals, not the form and it doesn't trigger the onReset() function in the unobtrusive library. The $('#my-form').valid() indeed removes the errors in the modal, but only if the modal is fully shown and valid. The native html form reset() is the only one that triggers both onReset() of unobtrusive library, and then the resetForm() of the validator. So it seems like we need to trigger the native html form document.querySelector('#my-form').reset() to activate the reset functions of both libraries/plugins.
The interesting thing is that the unobtrusive library runs the simple jQuery empty() on the .field-validation-error class (the container of the error span message) only in its onSuccess() function, and not onReset(). This is probably why valid() is able to remove error messages. The unobtrusive onReset() looks like it's responsible only for toggling .field-validation-error class to .field-validation-valid. Hense we are left with a <span id="___-error">The error message</span> inside the container <span class="text-danger field-validation-error">...</span>.

May be I am wrong to clear the errors like this:
function clearError(form) {
$(form + ' .validation-summary-errors').each(function () {
$(this).html("<ul><li style='display:none'></li></ul>");
})
$(form + ' .validation-summary-errors').addClass('validation-summary-valid');
$(form + ' .validation-summary-errors').removeClass('validation-summary-errors');
$(form).removeData("validator");
$(form).removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse($(form));
};
I tried answer given in the comment by AaronLS but not got the solution so I just do it like this.
Maybe helpful to someone.

Here's the code I ended up using to clear/reset all errors. It's possible there's some redundancy in there, but it's working for me.
function removeValidationErrors(frmId) {
var myform = $('#' + frmId);
myform.get(0).reset();
var myValidator = myform.validate();
$(myform).removeData('validator');
$(myform).removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse(myform);
myValidator.resetForm();
$('#' + frmId + ' input, select').removeClass('input-validation-error');
}

The reason this is still an issue (even 6 years on) is that jQuery Validation doesn't have an event handler for when your form is valid; only for when it's invalid.
Unobtrusive Validation taps into the Invalid handler to add your errors to your Validation Summary elements. (Specifically, any element with data-valmsg-summary=true.) But because there's no Valid handler, there's no way for Unobtrusive Validation to know when they can be cleared.
However, jQuery Validation does allow you to supply your own showErrors method, which is called after every validation check, whether the result is valid or invalid. Thus, you can write a custom function that will clear those validation summary boxes if your form is valid.
Here's a sample that will apply it globally. (You could apply it to specific instances of your validators by using settings, but since I always want this functionality, I just put it in the defaults object.)
$.validator.defaults.showErrors = function () {
if (!this.errorList.length) {
var container = $(this.currentForm).find("[data-valmsg-summary=true]");
container.find("ul").empty();
container.addClass("validation-summary-valid").removeClass("validation-summary-errors");
}
// Call jQuery Validation's default showErrors method.
this.defaultShowErrors();
};
This also has the benefit of clearing the validation summary box the moment your form is valid, instead of having to wait for the user to request a form submission.

I couldn't find this documented anywhere, but you should be able to reset the form by triggering a specific event, reset.unobtrusiveValidation, to which unobtrusive listens.
Example here:
.validation-summary-valid, .field-validation-valid { display: none; }
.field-validation-error { display: block; color: #dc3545 }
.input-validation-error { border: 1px solid #dc3545 }
.validation-summary-errors { background-color: #dc3545; color: #fff; margin-bottom: .5rem; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.5/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/4.0.0/jquery.validate.unobtrusive.js"></script>
<form id="testForm">
<div class="validation-summary-valid" data-valmsg-summary="true">
Validation Summary:
<ul><li style="display:none"></li></ul>
</div>
<div>
<label for="first_name">first name:</label>
<input data-val="true" data-val-required="the 'first name' field is required" name="first_name" id="first_name" />
<span class="field-validation-valid" data-valmsg-for="first_name" data-valmsg-replace="true"></span>
</div>
<div>
<label for="last_name">last name:</label>
<input data-val="true" data-val-required="the 'last name' field is required" name="last_name" id="last_name" />
<span class="field-validation-valid" data-valmsg-for="last_name" data-valmsg-replace="true"></span>
</div>
<button type="submit">Submit form (click first)</button>
<button type="button" onclick="$('#testForm').trigger('reset.unobtrusiveValidation')">Reset form (click second)</button>
</form>

Related

how to clear validation errors for Angular Material mat-error

I'm trying to reset a form after I've added a value.
Form Code Snippet
<form [formGroup]="addAttributeForm" fxLayout="column">
<mat-form-field>
<input matInput formControlName="title" placeholder="Title" required>
<mat-error>This field is required</mat-error>
</mat-form-field>
</form>
In the component
onSubmit(form: FormGroup) {
// do work
form.reset();
}
What I'm observing:
The form values are set to empty.
But the validation messages are still displayed from mat-error.
I've tried form.markAsPristine(), form.markAsUntouched() and combining all three.
How can I reset the form so the mat-error is not displayed?
The form group has no "knowledge" about whether the actual HTML form has been submitted or not. It only keeps track of the form values/validity/enabled state. So resetting the form group does reset the values but not any state regarding whether the form has been submitted.
To do this, you need to get a hold of the FormGroupDirective and call resetForm() on it.
Form Code Snippet
<form [formGroup]="addAttributeForm" fxLayout="column">
<!-- ... -->
</form>
In the component
#ViewChild(FormGroupDirective) formDirective: FormGroupDirective;
onSubmit(form: FormGroup) {
// do work
this.formDirective.resetForm();
}
This solution works with me.
You need to do next:
formReset(form: FormGroup) {
form.reset();
Object.keys(form.controls).forEach(key => {
form.get(key).setErrors(null) ;
});
}
This reset the form and clear all error.
The only way I've been able to successfully do this is by setting a flag to hide the form when you want to reset it and then using a timeout to set that flag back to true. As far as I know, there is no built-in way to do this yet.
showForm = true;
reset(): void {
this.showForm = false;
setTimeout(() => this.showForm = true);
}
And then in the HTML on the form element use *ngIf="showForm".

Ajax POST issue with comment system

I downloaded a php/ajax comment script almost 2 years ago and been having this small issue since day one. I tried to contact the author, but he's no where to be found.
Sometimes when I click the "Send" button, the button stays disabled and nothing happens at all. It just continues to show the animated busy picture. I do not receive any error messages at all.
I'm wondering if any of you pros can help me with this?
Here is the relevant code :
<div class="comment_heading">Leave a Comment</div>
<div class="post_comment">
<textarea name="txtpostcomment" id="txtpostcomment-'.$postid.'" class="txtpostcomment"></textarea>
<button class="btnpostcomment" id="btnpostcomment-'.$postid.'" onclick="comment('.$postid.');" type="button">Send</button>
<input type="hidden" name="token" id="token" value="'.$_SESSION['token'].'">
<script>document.getElementById("txtpostcomment-'.$postid.'").focus();</script>
</div>
comment = function(postid1)
{
var txt = $('#txtpostcomment-'+postid1);
var btn = $('#btnpostcomment-'+postid1);
var comment1 = $(txt).val();
var token = $("#token").val();
$(btn).css('background-image', 'url(/comments/submit-busy.gif)');
$(btn).attr('disabled', true);
$.post("/comments/submit.php",{commenting:1, postid:postid1, comment: comment1, name: name, token: token},
function(msg)
{
if(msg.status)
{
$('.post_comment .error_msg').remove();
$('.comment-list-'+postid1).prepend(msg.html);
$(txt).val('');
$('.comChars').empty();
}
else
{
$('.post_comment .error_msg').remove();
$('.error_msg').clone().appendTo('.post_comment');
$('.error_msg:last').append(msg.error);
}
$(btn).css('background-image', 'none');
$(btn).attr('disabled', false);
$(txt).attr('disabled', false);
},'json');
}
It appears that your code is not checking for error conditions just in case the Ajax request fails (due to network disconnection, server error etc). Check your javascript console for any js errors. Since it is using $.post you might want to extend the code to add error handling if the jQuery version that you are using supports it. Or, alternatively, use $.ajax. For more info see http://api.jquery.com/jquery.post or http://api.jquery.com/jquery.ajax

Ajax html response to div

Hi I am printing the ajax html response to div element and giving radio input option to select the file. after selecting the specific file the another div should show the message. but the ajax html response is not working
Jquery script:
$(document).ready(function()
{
$('#upload').ajaxForm({
beforeSubmit: function() {
$('#Analysis').show();
$('#Content_column').hide();
$('#file_list').show();
$('#trait').show();
$('#trait').html('Submitting...');
},
success: function(data) {
var $out = $('#file_list');
$out.html('&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspFile list:');
$out.append('<div id="list">');
$('#list').html(data);
$out.append('</div>');
}
});
});
The output of this script is
<ul class="php-file-tree"><li class="pft-directory">Genotypic<ul><input id="Penotypic" type="radio" name="uploads/Genotypic/" value="uploads/Genotypic/jquery.txt" />jquery.txt<br><input id="Penotypic" type="radio" name="uploads/Genotypic/" value="uploads/Genotypic/marker.csv" />marker.csv<br></ul></li><li class="pft-directory">Other</li><li class="pft-directory">Penotypic<ul><input id="Penotypic" type="radio" name="uploads/Penotypic/" value="uploads/Penotypic/namPheno.csv" />namPheno.csv<br><input id="Penotypic" type="radio" name="uploads/Penotypic/" value="uploads/Penotypic/perl.pl" />perl.pl<br></ul></li></ul>
Jquery script:
$('#Penotypic').click(function() {
var $out1 = $('#trait');
$('#trait').show();
$out1.append('Submitted...');
});
this is not showing anything in the div trait. may be the html response is loading as a tesxt so the #Penotypic is not recognised. please help me to fix this.
Thanku
You have many inputs of id="Penotypic". Make every id unique or use classes as function trigger.
I wouldn't use "/" in the name attribute. See: http://www.w3.org/TR/html401/types.html#type-name
Then try if your ajax script does work. If it doesn't work, try if it works from static page (don't use your first jQuery script, but it's output as a static form). You probably need to bind your event trigger. Use jQuery's on().

jQuery.validate stops my form from being submitted

jQuery.validate stops my form from being submitted. I would like it to just show the user what is wrong but allow them to submit anyway.
I am using the jquery.validate.unobtrusive library that comes with ASP MVC.
I use jquery.tmpl to dynamically create the form and then I use jquery.datalink to link the input fields to a json object on the page. So my document ready call looks something like this.
jQuery(function ($) {
// this allows be to rebind validation after the dynamic form has been created
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse($("form"));
// submit the answers
$("form").submit(function(e) {
$("input[name=jsonResponse]").val(JSON.stringify(answerArray));
return true;
});
}
I note that there is an option
$("form").validate({ onsubmit: false });
but that seems to kill all validation.
So just to recap when my form is rendered I want to show all errors immediately but I don't want to prevent the submit from working.
So after some research (reading the source code) I found I needed to do 2 things
add the class cancel to my submit button
<input id="submitButton" type="submit" class="cancel" value="OK" />
This stops the validation running on submit.
To validate the form on load I just had to add this to my document ready function
$("form").valid();
Hope this helps someone else

how to create an function using jquery live?

I am writing a function that well keep the user in lightbox images while he adds to cart.
When you click any image it well enlarge using lightbox v2, so when the user clicks the Add image, it will refresh the page. When I asked about it at jcart support they told me to use jquery live, but I dont know how to do that. T tried this code but still nothing is happening:
jQuery(function($) {
$('#button')
.livequery(eventType, function(event) {
alert('clicked'); // to check if it works or not
return false;
});
});
I also used
jQuery(function($) {
$('input=[name=addto')
.livequery(eventType, function(event) {
alert('clicked'); // to check if it works or not
return false;
});
});
yet nothing worked.
for code to create those images http://pasite.org/code/572
I also tried:
function adding(form){
$( "form.jcart" ).livequery('submit', function() {var b=$(this).find('input[name=<?php echo $jcart['item_id']?>]').val();var c=$(this).find('input[name=<?php echo $jcart['item_price']?>]').val();var d=$(this).find('input[name=<?php echo $jcart['item_name']?>]').val();var e=$(this).find('input[name=<?php echo $jcart['item_qty']?>]').val();var f=$(this).find('input[name=<?php echo $jcart['item_add']?>]').val();$.post('<?php echo $jcart['path'];?>jcart-relay.php',{"<?php echo $jcart['item_id']?>":b,"<?php echo $jcart['item_price']?>":c,"<?php echo $jcart['item_name']?>":d,"<?php echo $jcart['item_qty']?>":e,"<?php echo $jcart['item_add']?>":f}
});
return false;
}
and it seems to add to jcart but yet it still refreshes
.live() is to assign handlers to future creating elements. On your site, however, you are re-loading the page so .live would have no bearing. (you are submitting a form)
It sounds like you want to make an ajax request to add the item to the cart and update that display on the site? That would be in the submit of the form and if jcart is dynamically created then yes, live is the answer.
$('.jcart').live('submit', function() {
// aggregate form elements into object and send via ajax
// update the cart on the page, since we haven't reloaded the page the light box is still displayed
});
Regarding comment:
When you send an ajax request, jquery takes an object as an argument. Such as $.post('urlToPostTo.php', { title: 'title of whatever', id: 5 } );
The server sees this the same as:
<form id="myForm" action="uroToPostTo.php" method="POST" >
<input type="text" name="title" value="title of whatever" />
<input type="hidden" name="id" value="5" />
<input type="submit" name="submit" value="submit" />
</form>
So if you were to aggregate the form inputs into an object, there's a few ways (even some jquery plugins to help you out). The primitive way would be:
var $form = $('#myForm'); // instead of finding myForm over and over, cache it as a variable to use
var objToSend = {};
objToSend.title = $form.find('input[name=title]').val();
objTosend.id = $form.find('input[name=id]').val();
$.post( 'urlToPostTo.php', objToSend );
A more Elegant solution is to have something loop through all form elements and put them into an object for you. Plugins like http://docs.jquery.com/Plugins:Forms make that a bit easier.
The end result is the form elements are stuffed into an object to send to your script.

Resources