JQuery Validation Plugin: Use Custom Ajax Method - jquery-plugins

Looking for some assistance with the Jquery form validation plugin if possible.
I am validating the email field of my form on blur by making an ajax call to my database, which checks if the text in the email field is currently in the database.
// Check email validity on Blur
$('#sEmail').blur(function(){
// Grab Email From Form
var itemValue = $('#sEmail').val();
// Serialise data for ajax processing
var emailData = {
sEmail: itemValue
}
// Do Ajax Call
$.getJSON('http://localhost:8501/ems/trunk/www/cfcs/admin_user_service.cfc?method=getAdminUserEmail&returnFormat=json&queryformat=column', emailData, function(data){
if (data != false) {
var errorMessage = 'This email address has already been registered';
}
else {
var errorMessage = 'Good'
}
})
});
What I would like to do, is encorporate this call into the rules of my JQuery Validation Plugin...e.g
$("#setAdminUser").validate({
rules:{
sEmail: {
required: function(){
// Replicate my on blur ajax email call here
}
},
messages:{
sEmail: {
required: "this email already exists"
}
});
Wondering if there is anyway of achieving this? Many thanks

You are doing an AJAX request, ergo: the validation is already finished working when your custom validator returns either true or false.
You will need to work with async. See also this post: How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?
Lets say we have a custom validation to check the Unique Mobile, So we will add a new method as follows to check the unqiue Mobile no :
jQuery.validator.addMethod("uniqueMobile", function(value, element) {
var response;
$.ajax({
type: "POST",
url: <YOUR SERVER SCRIPT/METHOD>,
data:"mobile="+value,
async:false,
success:function(data){
response = data;
}
});
if(response == 0)
{
return true;
}
else if(response == 1)
{
return false;
}
else if(response == 'logout')
{
return false;
}
}, "Mobile is Already Taken");

You can add a custom validation method like this
$.validator.addMethod('unique',
function(value) {
$.get('http://localhost:8501/ems/trunk/www/cfcs/admin_user_service.cfc','?method=getAdminUserEmail&returnFormat=json&queryformat=column&emailData='+ value,
function(return_data) {
return return_data;
})
}
, "this email already exists"
);
then add the unique class to your email field or you can use something like this
$.validator.addClassRules("unique-email", {
unique: true
});

Try this:
$.validator.addMethod('unique',
function(value) {
var result = $.ajax({
async:false,
url:"http://yoursamedomain.com/checkemail",
data:'email='+ value,
dataType:"text" });
if(result .responseText) return true; else return false;
} , "This email address has already been registered");

For serverside AJAX validation use remote rule. This is same as standard jQuery AJAX request object. Your server must returns string "true" for valid value or "false" for invalid, also it can passes some string "This email was already taken", and this will be perceived as invalid, and render as an error message:
$( "#myform" ).validate({
rules: {
email: {
required: true,
email: true,
remote: {
url: "check-email.php",
type: "post",
data: {
username: function() {
return $( "#username" ).val();
}
}
}
}
}
});
Read documentation here remote-method

Related

WordPress ajax call with add_filter

I have a WordPress function that works exactly how I want. The function below changes the email recipient in Contact Form 7 to abc#aol.com.
Now I need to use AJAX to update the email recipient to a dynamic value.
function wpcf7_dynamic_email_field($args) {
if(!empty($args['recipient'])) {
$args['recipient'] = str_replace('%admin%', 'abc#aol.com', $args['recipient']);
return $args;
}
return false;
}
add_filter('wpcf7_mail_components', 'wpcf7_dynamic_email_field');
Here's my AJAX call. I do not know how to tell the call to initiate the wpcf7_dynamic_email_field() function. Can that be done?
$.ajax({
url: ajaxurl, // or example_ajax_obj.ajaxurl if using on frontend
data: {
'action': 'update_team_page_contact_form',
'emailAddress' : emailAddress
},
success:function(data) {
// This outputs the result of the ajax request
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});

This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request.

I want to take both 'Blog Entry' and 'Blog Entry Photo' from controller with ajax. When taking only 'BlogEntry' there isnt any problem ,on the other hand, when taking both of them (BlogEntry and BlogEntryPhoto), there is a problem: "This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet."
I think the problem is in 'Blog Entry Photo' because it has photopath column like "/Content/img/blog/25052017_2334_400x400.jpg".
I used JsonResult but it doesnt work
return Json(new { Success = true, BlogEntries = blogEntries, BlogEntryPhotos = blogEntryPhotos}, JsonRequestBehavior.AllowGet);
what should i do?
Finally, i eventually solved this issue arising from PhotoPath data. First, at controller, data of both BlogEntry and BlogEntryPhotos are serailized together then at view this data is parsed as object.
CONTROLLER
List<BlogEntry> blogEntries = _blogEntryRepo.GetAll(x => x.IsActive.Value && x.PlaceMarkerID == placeMarker.Id, null, "BlogEntryPhotoes").ToList();
JsonSerializerSettings jss = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
return Json(new { Success = true, BlogEntries = JsonConvert.SerializeObject(blogEntries, Formatting.Indented, jss) }, JsonRequestBehavior.AllowGet);
VIEW
$.ajax({
url: "/Map/GetBlogEntries",
type: "post",
datatype: "json",
data: placeMarker,
success: function (response) {
if (response.Success) {
var BlogEntries = JSON.parse( response.BlogEntries );
//BlogEntries[i].Title can be used
//BlogEntries[i].BlogEntryPhotoes[0].PhotoPath can be used
}
else {
//do something
}
},
error: function (xhr, status) {
//do something
}
});

DropZonejs: Submit form without files

I've successfully integrated dropzone.js inside an existing form. This form posts the attachments and other inputs like checkboxes, etc.
When I submit the form with attachments, all the inputs post properly. However, I want to make it possible for the user to submit the form without any attachments. Dropzone doesn't allow the form submission unless there is an attachment.
Does anybody know how I can override this default behavior and submit the dropzone.js form without any attachments? Thank you!
$( document ).ready(function () {
Dropzone.options.fileUpload = { // The camelized version of the ID of the form element
// The configuration we've talked about above
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 50,
maxFiles: 50,
addRemoveLinks: true,
clickable: "#clickable",
previewsContainer: ".dropzone-previews",
acceptedFiles: "image/*,application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.openxmlformats-officedocument.spreadsheetml.template, application/vnd.openxmlformats-officedocument.presentationml.template, application/vnd.openxmlformats-officedocument.presentationml.slideshow, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.presentationml.slide, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.wordprocessingml.template, application/vnd.ms-excel.addin.macroEnabled.12, application/vnd.ms-excel.sheet.binary.macroEnabled.12,text/rtf,text/plain,audio/*,video/*,.csv,.doc,.xls,.ppt,application/vnd.ms-powerpoint,.pptx",
// The setting up of the dropzone
init: function() {
var myDropzone = this;
// First change the button to actually tell Dropzone to process the queue.
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
// of the sending event because uploadMultiple is set to true.
this.on("sendingmultiple", function() {
// Gets triggered when the form is actually being sent.
// Hide the success button or the complete form.
});
this.on("successmultiple", function(files, response) {
window.location.replace(response.redirect);
exit();
});
this.on("errormultiple", function(files, response) {
$("#notifications").before('<div class="alert alert-error" id="alert-error"><button type="button" class="close" data-dismiss="alert">×</button><i class="icon-exclamation-sign"></i> There is a problem with the files being uploaded. Please check the form below.</div>');
exit();
});
}
}
});
Use the following:
$('input[type="submit"]').on("click", function (e) {
e.preventDefault();
e.stopPropagation();
var form = $(this).closest('#dropzone-form');
if (form.valid() == true) {
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
myDropzone.uploadFiles([]); //send empty
}
}
});
Reference: https://github.com/enyo/dropzone/issues/418
You should check if there are files in the queue. If the queue is empty call directly dropzone.uploadFile(). This method requires you to pass in a file. As stated on [caniuse][1], the File constructor isn't supported on IE/Edge, so just use Blob API, as File API is based on that.
The formData.append() method used in dropzone.uploadFile() requires you to pass an object which implements the Blob interface. That's the reason why you cannot pass in a normal object.
dropzone version 5.2.0 requires the upload.chunked option
if (this.dropzone.getQueuedFiles().length === 0) {
var blob = new Blob();
blob.upload = { 'chunked': this.dropzone.defaultOptions.chunking };
this.dropzone.uploadFile(blob);
} else {
this.dropzone.processQueue();
}
Depending on your situation you could simply submit the form:
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
$("#my_form").submit();
}
The first approach is kind of too expensive for me, I would not like to dive into the source code and modify it,
If you happen to be like me , use this.
function submitMyFormWithData(url)
{
formData = new FormData();
//formData.append('nameOfInputField', $('input[name="nameOfInputField"]').val() );
$.ajax({
url: url,
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
alert(data);
}
});
}
And in your dropzone script
$("#submit").on("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
if (myDropzone.getQueuedFiles().length > 0)
{
myDropzone.processQueue();
} else {
submitMyFormWithData(ajaxURL);
}
});
I tried Matija Grcic's answer and I got the following error:
Uncaught TypeError: Cannot read property 'name' of undefined
And I didn't want to modify the dropzone source code, so I did the following:
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
myDropzone.uploadFiles([{name:'nofiles'}]); //send empty
}
Note: I'm passing an object inside the array to the uploadFiles function.
Then I check server-side, if name != 'nofiles' do upload stuff.
Pretty simple, you stop the propagation ONLY if you have files to be submitted via Dropzone:
// First change the button to actually tell Dropzone to process the queue.
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
// Stop the propagation ONLY if you have files to be submitted via Dropzone
if (myDropzone.getQueuedFiles().length > 0) {
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
}
});
I have successfully used :
submitButton.addEventListener("click", function () {
if(wrapperThis.files.length){
error = `Please select a file`;
} else {
wrapperThis.processQueue();
}
});
My answer is based on the fact that the other answers don't allow for an Ajax based solution where an actual HTML form isn't actually being used. Additionally you may want the full form contents submitted when sending the Files for upload as well.
As you'll see, my form occurs in a modal outside of any form tag. On completion, the modal is triggered to close.
(FYI getForm returns the form as an object and not directly related to the answer. Also assumes use of jQuery)
init: function() {
var dzClosure = this;
// When saving what are we doing?
$('.saveBtn').off('click').on('click',function(e){
e.preventDefault();
e.stopPropagation();
if (dzClosure.getQueuedFiles().length > 0) {
dzClosure.processQueue();
dzClosure.on('queuecomplete',function(){
$('.modal:visible').modal('hide');
})
} else {
var params = getForm();
$.post(dzClosure.options.url,params,function(){
$('.modal:visible').modal('hide');
})
}
});
dzClosure.on('sending', function (data, xhr, formData) {
var extra = getForm();
for (key in extra){
formData.append(key,extra[key]);
}
});

How to abort remote Jquery Validator method upon submit

My site is http://www.extrabux.com/users/login
When a user is logging in, Jquery Validate plugin uses a "remote" function to check whether the provided email address exists in our database as a user. If the connection and our server is fast, the user sees feedback before she even finishes typing her password.
email: {
required: true,
email: true,
remote: {//http://docs.jquery.com/Plugins/Validation/Methods/remote
url: 'check-signin-email-address',
type: "post",
data: {
emailAddress: function() {
return $("#email").val();
}
}
}
}
If the connection or our server is slow, however, this causes an undesirable delay before the form can be submitted (because the Jquery Validate plugin waits until the form is confirmed to be valid).
What I'd like is:
If the remote query finishes before the user submits the form, it should block the submission (in the case where it finds that the email address is not in the database).
If the user submits the form before the remote query finishes, the remote query validation rule should be ignored (so that there is no delay--the server-side validation will catch that the user doesn't exist).
Thoughts?
function checkEmail(){
$("#email").removeClass('email'); // this stops validation during ajax
//might want to add a loading image to let user know
$.ajax({
type: //type
url: //url to check email,
data: //email to check,
success: function (msg) {
$("#email").addClass('email'); //turns validation back on
//take away loading image
if (msg.GoodEmail != "GoodEmail" ) { //however you check for existing email
$("#email").addClass('error'); //forces failed validation
}
}
});
}
This is an example using jquery's ajax , with this you can handle events before ajax , on success , on error , a little more control this way
I think I figured this out. Instead of using the "remote" option, I used addMethod to create a rule that I call "isExtrabuxMember". I also created some global variables and used ajax bound to the change of the #email field to check whether the provided email address belonged to any existing Extrabux member.
Please comment if this helps you or if you have better ideas.
I now have this above the "validate" plugin call:
jQuery.validator.addMethod("isExtrabuxMember", function(value, element) {
var emailRemoteFuncResult = checkSigninEmailAddressResult === null ? true : checkSigninEmailAddressResult;
return emailRemoteFuncResult;
});
var checkSigninEmailAddressResult = null;
var emailXhrCheck;
$('#email').bind('change keyup', function(){
checkSigninEmailAddressResult = null;
if(emailXhrCheck){
emailXhrCheck.abort();
}
emailXhrCheck = $.ajax({
url: '/users/check-signin-email-address',
type: "post",
async: true,
data: {
emailAddress: function() {
return $("#email").val();
}
},
success: function(data){
checkSigninEmailAddressResult = data;
$("#email").valid();
}
});
});
$('#loginForm').submit(function(){
if(emailXhrCheck){
emailXhrCheck.abort();
}
});
Then within the "validate" plugin call:
rules: {
email: {
required: true,
email: true,
isExtrabuxMember: true
},
password: {
required: true,
minlength: 4
}
},
messages: {
email: {
isExtrabuxMember: function(){
var currentEmail = $('#email').val();
return $.validator.format('<b>{0}<\/b> does not yet have an Extrabux account. <a href="\/users\/register?emailAddress={0}">Sign up?<\/a>', currentEmail);
}
},
password: {
required: "Oops, you forgot to enter your password!"
}
}

Showing errors and messages on custom form in jqGrid

What I am trying to achieve it to show messages on a dialog form as asked and answered here. However, while the example above used the default editGridRow in the code, I have a custom dialog form loaded in via JSON. For example the JSON error/validation message returned could be:
{"CustomerName":{"isEmpty":"\u201cthis value is - not to be left empty.\u201d"}}
I need to be able to output them as "Customer Name - this value is not to be left empty" - at the top of the dialog form.
I have tried the solutions in A, B, C and D but I have not been able to customize them to work in my scenario yet.
I have a function call like so:
function LaunchEditForm(dialog)
{
$('form', dialog).submit(function ()
{
$.ajax({
url: '/customer/update-customer/',
type: this.method,
reloadAfterSubmit: true,
data: $(this).serialize(),
success: function (result)
{
if (result.success)
{
console.log(result);
//can I call a function here to prepend modal form
//with success message? how please?
}
else
{
console.log(result);
// can I prepend the dialog to show model errors here?
//var errorDetail = jQuery.parseJSON(result.responseText);
}
}
});
return false;
});
}
I have tried using afterSubmit like so:
afterSubmit: function (response, postdata)
{
if (response.responseText == "Success")
{
jQuery("#success").show();
jQuery("#success").html("Customer successfully updated");
jQuery("#success").fadeOut(6000);
return [true, response.responseText]
}
else
{
return [false, response.responseText]
}
}
This has not worked yet - perhaps I have placed it in a different scope
and also tried errorTextFormat like so:
errorTextFormat: function (data)
{
if (data.responseText.substr(0, 6) == "<html ")
{
return jQuery(data.responseText).html();
}
else
{
return "Status: '" + data.statusText + "'. Error code: " + data.status;
}
}
Please help with this. I know I need some function that parses the JSON successfully and hopefully presents the errors and messages Oleg described

Resources