jQuery Validate remote onblur only but allow onkeyup for rest [duplicate] - javascript

This question already has answers here:
JQuery.validate - one rule on blur only; the rest should be normal?
(2 answers)
Closed 8 years ago.
I am trying to do a jquery remote validation to see if a name is unique or not, but i do not want to do remote validation on every single onkekup event, however i would like to do this on blur event(when user leaves the textbox). but with current code i have below, it fires up after 2nd character is pressed. i would like to continue to have rest of the rules fire on onkeyup like required and minlength and rules for other elements.
is there not a property to control this behavior, just for single rule? i noticed a set default that does for entire form.
elem.validate({
ignore: "",
rules: {
name: {
required: true,
minlength: 2,
maxlength: 60,
remote: {
url: "/api/IsUniqueName",
onkeyup: false,
type: "get",
contentType: "application/json",
data: {
name: function () {
return elem.find('input[name^=Name]').val();
}
},
headers: {
RequestVerificationToken: Indexreqtoken
},
}
},
...

You cannot put the onkeyup option inside of the remote rule... that's not how the remote method works. The remote method can only accept the same options as jQuery .ajax() and nothing else.
However, you cannot restrict or control the triggering events on a "per rule" basis. These events are captured for the whole form or individually on each field, they can not be confined to a specific rule.
If you want to restrict the plugin's onkeyup function to certain fields, then you would use a conditional within the onkeyup option...
$('#myForm').validate({
onkeyup: function(element, event) {
if ($(element).attr('name') == "name") {
return false; // disable onkeyup for your element named as "name"
} else { // else use the default on everything else
if ( event.which === 9 && this.elementValue( element ) === "" ) {
return;
} else if ( element.name in this.submitted || element === this.lastElement ) {
this.element( element );
}
}
},
ignore: [], // <- note the proper format for the "ignore nothing" setting.
rules: {
name: {
required: true,
minlength: 2,
maxlength: 60,
remote: {
url: "/api/IsUniqueName",
....
EDIT:
Quote OP:
"is there not a property to control this behavior, just for single rule?"
No, the triggering events cannot be controlled on a "per rule" basis. They can only be controlled for the whole form OR for a specific field, as I've shown above.
https://stackoverflow.com/a/21313848/594235

Related

is there any way to disable angular multiselect(cuppa labs) dynamically

I am using multi select dropdown(cuppa labs) from this link https://www.npmjs.com/package/angular2-multiselect-dropdown But I am unable to disable the dropdown.
initially if i set In settings disabled:true is working fine but I want disabled:false initially then i need to change disabled:true after the success response from the api.
documentDropdownSettings = {
text: "Required Document",
badgeShowLimit: 3,
enableSearchFilter: true,
maxHeight: 150,
classes: "myclass custom-class",
showCheckbox: true,
enableFilterSelectAll: false,
disabled:false
}
this.taskService.getTaskDetails(this.taskId, (success) => {
this.documentDropdownSettings.disabled=true
}, (error) => {
enter code here
})
I want to make the dropdown disabled dynamically.
I believe the issue is that the the settings object is immutable.
you need to change the object reference not its properties for the binding to take effect.
doing your change, and changing the reference will probably work.
something like :
this.taskService.getTaskDetails(this.taskId, (success) => {
this.dropdownSettings['disabled'] = true;
this.dropdownSettings = Object.assign({}, this.dropdownSettings);
}, (error) => {
enter code here
})
P.S their official approach seems to be a bit awkward, they recreate the object for each settings change in their documentation..

Sequelize custom validation - unable to access all fields in entity

I attempted to create a model in sequelize (say has 3 attributes, attrA, B, and C) with some custom validation logic. This tutorial helped me get most of it set up:
const Model = Sequelize.define('model', {
attrA: { type: Sequelize.STRING },
attrB: { type: Sequelize.STRING },
attrC: { type: Sequelize.STRING },
}, {
validate: {
someValidationLogic() {
// Do something with attrA,B,C
// if (this.attrA ... this.attrB ... this.attrC) throw new Error..
}
}
})
In the application logic however, only say, 2 out of the 3 attributes (A and B) need to be updated:
Model.update(
{
attrA: 'foo',
attrB: 'bar'
}, {
where: {
id: 1,
},
returning: true,
})
This results in that when the custom validation logic being called, in the this object accessed in the function, only attrA and attrB are defined in this, and attrC remained undefined. This causes the validation logic to fail because attrC cannot be read. Is there any way I can get the object visible from someValidationLogic() to have all attributes populated? Or should this "validation" shouldn't have been validation logic at all and should've been done on the application level?
Your validation logic could take in account the possibility of attrC not being defined :
validate: {
someValidationLogic() {
if (this.attrA !== 'undefined' && this.attrA === 'forbidden value' ) {
// throw new Error
}
}
}
But if your validation includes checking the provided values against current database values, then you would better handle this in the application layer : first recover the current database record, manipulate it as needed, then save it to database.

JQuery validation only works on the first generated input

I'm trying to resolve this issue but no matter what I try (based on several suggestions solutions found here as well), I can never make it work.
I would like the Jquery validation plugin to validate automatically all the generated fields from a form. My problem is that it will only work on the first generated field; the validation of the subsequent ones will just be a duplicate of the first.
Here's the pertinent html code:
<form class="someFormClass" method="post">
<span>
<input class="calendarName" name="description" value="<?= value_from_php ?>">
<input class="calendarName" name="description" value="<?= value_from_php ?>">
</span>
</form>
And here's the jQuery validation code:
$(function () {
$('form').each(function () {
$(this).validate({
errorElement: "div",
rules: {
description: {
required: true,
remote: {
url: "calendar/calendar_available/",
type: "post",
data: {
name: function () {
return $(".calendarName").val();
}
}
}
}
},
messages: {
description: {
required: "Description field can't be blank !",
remote: "This calendar already exists."
}
}
});
});
So, as stated, the plug-in behaves properly for the first field. But if I check the values posted in Chrome's Network, the "name" key created in the jQuery validation will always send the value of the first input.
I tried many things (trying to implement on more level of ".each" method in the validation, trying to generate dynamically a specific id for each field to point on (instead of a class), trying to modify the plugin code as suggested here (How to validate array of inputs using validate plugin jquery), but it didn't work.
I think there's something I don't grasp about the logic here.
UPDATE :
So, one of the reasons of my problem is that jQuery validation absolutely requires input with different names. See : Jquery Validation with multiple textboxes with same name and corresponding checkboxes with same name
So, I made a script to generate a different name for each input with the intention to dynamically create validation rules based on those names, following this suggestion : https://stackoverflow.com/a/2700420/3504492
My validation script now look like this :
$(function() {
var rules = new Object();
var messages = new Object();
$('input[name*=description_]:text').each(function() {
var currentName = $("input[name="+this.name+"]").val();
rules[this.name] = {
description: {
required: true,
remote: {
url: "calendar/calendar_available/",
type: "post",
data: currentName
}
}
},
color: {required: true}
};
messages[this.name] = {
description: {
required: "Description field can't be blank !",
remote: "This calendar already exists."
},
color: {required: "Color field can't be blank !"}
};
});
$('form').each(function () {
$(this).validate({
errorElement: "div",
rules: rules,
messages: messages
});
}) });
This almost works. Almost because if I limit the rules et messages to the required keys, it will display the validation each field (if I add the specific name to the message string, it will display on the proper field). But with a most complex rule like mine (with a remote key containing various keys for instance), I get a " Cannot read property 'call' of undefined. Exception occurred when checking element , check the 'description' method." error in the Console.
My guess is that the "description" declaration in the "rules" definition should be dynamic too (the current "name" field being visited).
Any suggestion?

How to get jQuery validate to validate fields that are pre-populated by the browser

I have a form that collects some personal information from the end user and triggers some JS validation functions. For simplistic examples lets just say the form has first name, last name, and email address.
Now once the form is filled out and submitted, if I go back to it my browser pre-populates the form like you would expect. The problem is when I go to submit (without changing any fields or tabbing through them) the plugin does not go back and validate those fields (if they have been pre-populated.
I am not sure WHY it is not validating the pre-populated fields. And I am not sure how to get it to. Does anyone have any ideas? I am running the latest version of jQuery and the validate plugin (http://jqueryvalidation.org/).
Sample code:
$(document).ready(function() {
var rules = {
FirstName: 'required',
LastName: 'required',
EmailAddress: {
required: true,
customEmail: true,
checkAccountExists: true
}
};
//And field specific (and even validation type specific) error messages
var messages = {
FirstName: 'Your first name is required.',
LastName: 'Your last name is required.',
EmailAddress: {
required: 'Your email address is required.',
customEmail: 'You must enter a valid email address.',
checkAccountExists: 'We already have an account with that email address. Please login.'
}
};
$('#applicationForm').validate({
//debug: true,
rules: rules,
messages: messages,
errorElement: 'span'
});
});
jQuery.validator.addMethod('customEmail', function(value, element) {
return this.optional(element) || /[A-z0-9._%-+]{1,}#[A-z0-9._%-]{1,}\.[A-z0-9._%-]{1,}/.test(value);
}, 'Invalid email address entered.');
jQuery.validator.addMethod('checkAccountExists', function(value, element) {
if (this.optional(element)) {
return true;
}
var url = $(element).attr('checkEmailUrl');
$.ajax({
type: 'GET',
data: {EmailAddress: value, check: true},
dataType: 'json',
url: url,
success: function(response) {
var dataArray = jQuery.parseJSON(response);
//If it exists then trigger the popup
if (dataArray.result == 'EXISTS') {
kclHelpers.showEmailExistsModal(value);
}
}
});
return true; //If it exists the popup will handle it. We are just using this to trigger it
}, 'An account under the specified email address already exists. Please sign in.');
A simple solution that I employ is just to trigger the blur event already bound to elements you want to validate. You can check the value of each element to determine if they should be validated which prevents this operation from triggering them before the user has interacted.
$(window).load(function() {
//pre-highlight fields with values
$('input[type=text], input[type=email], input[type=url], input[type=password], select').filter(function() {
return $.trim($(this).val()) != '';
}).blur();
});

jQuery Form Validation - success + showErrors

I'm using the jQuery Validation Plugin and want to run my own code when the plugin detects a valid or invalid input.
I've figured out that the two .validate() options I need are success and showErrors and I can get them both to work on their own:
var validator = $('#form').validate({
rules: {
name: "required",
email: {
required: true,
email: true
}
},
success: function() {
console.log('success');
}
That logs success any time a valid input is made. And showErrors works correctly also:
var validator = $('#form').validate({
rules: {
name: "required",
email: {
required: true,
email: true
}
},
showErrors: function() {
console.log('error');
}
But when I try to combine the two, error is logged every time regardless of whether the input is valid:
var validator = $('#form').validate({
rules: {
name: "required",
email: {
required: true,
email: true
}
},
success: function() {
console.log('success');
},
showErrors: function() {
console.log('error');
}
The order of the options doesn't have any effect.
Does anyone know why the two options don't work together and how I can run my own functions on valid and invalid inputs?
"showErrors" is not called just when an error is detected, it's called everytime you change the input, regardless the value you typed.
"showErrors" receives two parameters: "errorMap" and "errorList". To verify if there really was an error you have to check one of those values:
showErrors: function(errorMap, errorList) {
if (errorsList.length > 0) {
console.log('error');
}
}
You can also handle the "success" event inside the showErrors function, since it's called in the current validator context.
showErrors: function(errorMap, errorList) {
if (errorsList.length == 0) {
this.currentElements.addClass("success");
}
}
Figured it out... sort of.
I replaced showErrors with highlight, which allows me to run a callback on either valid or invalid entries.
However, the plugin still displays the default error messages -- probably since I'm not doing anything with showErrors. So I had to hack that by setting an empty string for the message on each field:
var validator = $('#form').validate({
rules: {
name: "required",
email: {
required: true,
email: true
}
},
messages: {
name: '',
email: ''
},
success: function() {
console.log('success');
},
highlight: function() {
console.log('highlight');
}
}
Certainly not as clean as I would like, so if anyone has a better way that would be great.

Categories