backbone validate pairs of fields - javascript

I am currently using Backbone.validate to do form validations.
I need to be able to validate pairs of fields, meaning if you start filling in 'field1' then you have to fill in 'field2' as well, and the other way around. If you leave them blank then the validation passes.
I have backbone.validate setup and working for single fields.
is there anything that i can use that is already part of validation to declare this? i cannot seem to be able to find anything related.
Thanks!

So here is how i solved it using Backbone.validation
https://github.com/thedersen/backbone.validation
validateFlickr: function (value, attr, computedState) {
return this.validatePairs(value, attr, computedState, "flickr");
},
validatePairs: function (value, attr, computedState, name) {
var totalNotBlank =
(computedState["app_id_" + name] != "" ? 1 : 0)
+ (computedState["app_secret_" + name] != "" ? 1 : 0);
if (totalNotBlank == 1) {
return "Need to enter " + name + " App ID and App Secret";
}
},
And the validation hash:
validation: {
app_id_flickr: "validateFlickr",
app_secret_flickr: "validateFlickr"
}

There is nothing built-in to manage this. But you can use the validator API to add your custom methods:
JS
$.validator.addMethod( "custom-rule", function( value ) {
return true; // put your logic here
}, function() {
return "error message";
});
HTML:
<input type="text" name="foo" class="custom-rule">

Related

Validating React-Bootstrap-Typeahead input

I am using a validation function in my form, that checks whether a field is empty or not. This works for normal text input boxes, but not for the Typeahead box.
I want to check if the Typeahead box is empty, and if it is, display an error message i.e. this.state.industryError
This is my state:
state = {
name: "",
industry: [],
nameError: "",
industryError: "",
}
And this is my Typeahead form element:
<Form>
<Label>Industry</Label>
<Typeahead
id="industryMultiSelect"
multiple
options={industries}
placeholder="Select industry..."
onChange={this.handleTypeaheadChangeIndustry} />
<div>
{this.state.industryError} // Where the error message appears
</div>
</Form>
My validate function is as follows:
validate = () => {
let nameError = "";
let industryError = "";
if(!this.state.name) { // Checks if field is empty
nameError = "Please enter a name";
}
if(this.state.industry === []) { // I think this is the problem
industryError = "Please enter an industry";
}
if (nameError || industryError) {
this.setState({nameError, industryError});
return false;
}
return true;
};
This is handleChange function I call for the typeahead:
handleTypeaheadChangeIndustry = selected => {
const industry = selected.map(option => option.value);
this.setState({industry})
};
It works fine with the name field because it equals an empty string. But with the Typeahead, it's not a string, and so I'm unsure what to set this.state.industry to.
Any help or advice is much appreciated, and I can quickly update my answer if you need more detail.
It's a little hard to pinpoint why your code isn't working without seeing everything. That said, I created a sandbox which I believe does what you're after using the code you posted above:
https://codesandbox.io/s/react-bootstrap-typeahead-form-validation-686qe
As #ravibagul91 notes, you should be using one of
if (this.state.industry.length === 0) { ... }
if (!this.state.industry.length) { ... }
rather than
if (this.state.industry === []) { ... }
Using the latter in the sandbox I posted causes the code not to work, while things work fine when using either of the first two.

Angularjs - Validate initial url value with custom directive

I have this custom validation directive:
/**
* Overwrites default url validation using Django's URL validator
* Original source: http://stackoverflow.com/questions/21138574/overwriting-the-angularjs-url-validator
*/
angular.module('dmn.vcInputUrl', [])
.directive('vcUrl', function() {
// Match Django's URL validator, which allows schemeless urls.
var URL_REGEXP = /^((?:http|ftp)s?:\/\/)(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::\d+)?(?:\/?|[\/?]\S+)$/i;
var validator = function(value) {
if (!URL_REGEXP.test(value) && URL_REGEXP.test('http://' + value)) {
return 'http://' + value;
} else {
return value;
}
}
return {
require: '?ngModel',
link: function link(scope, element, attrs, ngModel) {
function allowSchemelessUrls() {
// Silently prefixes schemeless URLs with 'http://' when converting a view value to model value.
ngModel.$parsers.unshift(validator);
ngModel.$validators.url = function(value) {
return ngModel.$isEmpty(value) || URL_REGEXP.test(value);
};
}
if (ngModel && attrs.type === 'url') {
allowSchemelessUrls();
}
}
};
});
It works fine when you 'dirty' the input by typing or pasting, but I need it to run this validation, overwriting the default type="url" validation when the value is initially set in the ngModel.
I've tried adding ngModel.$formatters.unshift(validator); but it results in the 'http://' being added to input, which I need to avoid as user's changes are manually approved and it would be a waste of time to approve the addition of 'http://'.
Any help would be appreciated!
Set ng-model-options on the input type field, for example:
<input type="text"
ng-model-options="{ updateOn: 'default', debounce: {'default': 0} }"</input>
This will ensure your validator gets fired "when the value is initially set in the ngModel", as you have stated in the question.
See detailed AngularJs documentaion on ngModelOptions:enter link description here
validation of Url :
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form name="form">
URL: <input type="url" ng-model="url.text" placeholder="Enter Link" name="fb_link"></input>
<span class="error" ng-show="form.fb_link.$error.url"></span>
</form>

Angular JS Email Validation with unicode characters

I have a sign up form for an application, and angular js is responsible for its validation.
I ran into an issue when Angular js wasn't accepting an email address which has apostrophe in it. "Pear'lpeerh.shin#xyz.com" .
I found out that angularJs doesnt like unicode characters in email address.
Has anyone else came across an issue like this, I am interested in knowing my options to get away with this bug in angularJs.
Any inputs are appreciated. Thanks !
If having html5 <input type=email /> is not critical, you can use <input type=text /> and pattern validation
<input type="text" ng-model="field" ng-pattern="EMAIL_REGEXP" />
and you can use regex that #Andy Joslin posted in his answer
$scope.EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+#[a-z0-9-]+(\.[a-z0-9-]+)*$/i;
AngularJS uses this regular expression to test email: https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js#L4
What you could do is write a directive that checks it yourself. Just copy the one from AngularJS and use your own regexp: https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js#L606-L614
myApp.directive('nanuEmail', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, model) {
//change this:
var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/;
var emailValidator = function(value) {
if (!value || EMAIL_REGEXP.test(value)) {
model.$setValidity('email', true);
return value;
} else {
model.$setValidity('email', false);
return undefined;
}
model.$parsers.push(emailValidator);
model.$formatters.push(emailValidator);
}
};
});
Then you can just do:
<input nanu-email ng-model="userEmail">
I just updated the regex in the angular.js file (added " ' " in the expression) and it worked, without making any other changes.
EMAIL_REGEXP = /^[A-Za-z0-9._%+-']+#[A-Za-z0-9.-]+.[A-Za-z]{2,4}$/ . Thanks Vittore, for giving me the idea to update REGEX. :)
why do you return undefined?
Refactoring of the function:
var verificationEmail = function (viewValue) {
if ((typeof viewValue != "undefined") && viewValue != "") {
return regex.test(viewValue);
}
};
Angular do not support the apostrophe(') in email Id. If you need to validate the apostrophe in Angular, you need to change the regular expression from:
(/^[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
To:
/^[A-Za-z0-9._%+'-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/.
It will work perfectly.

Remove literals from input value before validation and submit

I have a form with a required phone number field that looks like this with the maskedinput plugin
(999) 999-9999
I want the jquery validation to ignore the literals in order to validate this. Also, i want the literals to be removed before the form is submitted. But if there is a validation error i still want the maskedinput plugin activated so the format looks correct for the user still.
I figure i could edit the regex for the validation but then when the form is submitted the literals will still be on there.
Let me know i need to explain this better.
Any Ideas? I'm pretty new to jquery and all so detailed solution would be great.
My javascript code is this
$(document).ready(function(){
jQuery.validator.addMethod("phoneUS", function(phone_number, element) {
phone_number = phone_number.replace(/\s+/g, "");
return this.optional(element) || phone_number.length > 9 &&
phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
}, "US Phone Number Required");
$("#valform").validate({
invalidHandler: function(form, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
$("#error-message").show().text("Please correct the required field(s)");
} else {
$("#error-message").hide();
}
},
messages: {
phone: {
required: ""
}
},
rules: {
phone: {
required: true,
phoneUS: true
},
},
});
$("#phone").mask("(999) 999-9999",{placeholder:" "});
});
You could remove the other characters before submitting the form using js
This code will remove the forbidden character from the input as soon as its entered.
The input field has the class "numbers". This binds the "keyup" event to that input field and calls a function called "handleInputKeyUp"
$(".numbers").bind("keyup", handleInputKeyUp);
The function:
function handleInputKeyUp(e){
var temp = e.currentTarget.value;
temp = temp.replace(/[^\d-]/g, "");
e.currentTarget.value = temp;
}
This code removes all but digits and - from the input field.

How to display messages in invalidHandler in JQuery validator

I'm trying to use the JQuery validator on a form and am trying to figure out to get the messages of the errors in the invalidHandler option (or if there's somewhere else, do tell).
When a user clicks the submit button, whatever the first error is, I want to display an alert box with the message of the error. I don't want the error to be written on the document. I can't seem to figure out how to get the error messages to use in an alert after validation. I only found how to get the elements, and that doesn't really help me.
Pulling out from the example, here's some code I'm testing with
$(document).ready(function() {
$('#commentForm').validate({
invalidHandler: function(f, v) {
var errors = v.numberOfInvalids();
if (errors) {
var invalidElements = v.invalidElements();
alert(invalidElements[0]);
}
}
});
});
and
<form class="cmxform" id="commentForm" method="get" action="">
<fieldset>
<legend>A simple comment form with submit validation and default messages</legend>
<p>
<label for="cname">Name</label>
<em>*</em><input id="cname" name="name" size="25" class="required" minlength="2" />
</p>
<p>
<input class="submit" type="submit" value="Submit"/>
</p>
</fieldset>
</form>
This works for me...
invalidHandler: function(form, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
var message = errors == 1
? 'Please correct the following error:\n'
: 'Please correct the following ' + errors + ' errors.\n';
var errors = "";
if (validator.errorList.length > 0) {
for (x=0;x<validator.errorList.length;x++) {
errors += "\n\u25CF " + validator.errorList[x].message;
}
}
alert(message + errors);
}
validator.focusInvalid();
}
I know the question is quite old, but to help other people to get a better answer I would advise you guys not using invalidHandler, but showErrors.
Thats because invalidHandler will be called only when you submit your form while
showErrors is called every time a field is updated.
So, do this:
Script in the end of the page
$("form").validate({
rules: {
name: {
required: true
}
},
messages: {
name: {
required: "required"
}
},
highlight: function (element) {
$(element).closest('.form-group').removeClass('has-success').addClass('has-error')
$(element).parent().find('.form-control-feedback').removeClass('glyphicon-ok').addClass('glyphicon-remove');
},
unhighlight: function (element) {
$(element).closest('.form-group').removeClass('has-error').addClass('has-success');
$(element).parent().find('.form-control-feedback').removeClass('glyphicon-remove').addClass('glyphicon-ok');
},
errorElement: 'span',
errorClass: 'help-block',
errorPlacement: function (error, element) {
if (element.parent('.input-group').length) {
error.insertAfter(element.parent());
} else {
error.insertAfter(element);
}
},
showErrors: function (errorMap, errorList) {
var errors = this.numberOfInvalids();
if (errors) {
var message = errors == 1
? 'Your form has 1 error'
: 'Your form has ' + errors + ' errors.';
message = message + ' Please, fix then.'
$("#error span").empty().html(message);
$("#error").show();
} else {
$("#error").hide();
}
this.defaultShowErrors();
},
});
Don't forget your html tag
<div id="error"><span></span></div>
Overloading showErrors worked as expected. I just needed to get the first error message.
showErrors: function(errorMap, errorList) {
alert(errorList[0].message);
}
Also remember to take a look at the onfocusout and onkeyup options, else you'll get continuous messages.
MUST check errorList.length
if (errorList.length > 0) alert(errorList[0].message);
You should not use alert,
But if you really want to use that. Solution depend of how plugin add dom elements but you can remove those dom elements in invalidHandler. So let those dom element added but remove it.
Other option is, you should patch plugin you use for validation and instead of adding dom show alert.

Categories