Custom jQuery Validation Method - javascript

I've got two input fields, email and email_confirm. The email field has the value of the users email from the database. I want to make sure if the user updates their email (both inputs have to have the same value) that they match, however, I can't use the defaul equalTo because email input always has a value. So I need to check if email_confirm is equalTo email IF the email value is different to the default value.
Here's the code I have, value seems to be empty always also.
$.validator.addMethod('myEqual', function (value, element, param){
return value == $(param).val();
}, 'Message');

Just add the below rule for email_confirm field,
equalTo : "#email" //Replace #email with the id the of the email field.
No need to add custom method for that.

if ($("#email").val() != theDefaultValue) {
if ($("#email").val() == $("#email_confirm")) {
// It's all good
} else {
// It's all bad
}
} else {
// It doesn't matter
}

Related

Update input value after validation

Iā€™m new to Vue.
I would like to know if it is possible to update the input value after running a custom validation in Vuelidate. I have an input field for postcode. I want to return the postcode with the correct format in case the user forgets to put a whitespace, and update the input field with the correct value, e.g.
user input = XXXXXX
returned output = XXX XXX
Sample code
export default {
...
validations: {
postcode: {
required,
maxLength: maxLength(10),
validatePostcode: (value) => {
const result = customValidators.validatePostcode(value);
if (result !== false) {
if (result !== value) {
// UPDATE THE INPUT VALUE HERE WITH THE CORRECT POSTCODE FORMAT
}
return true;
}
return false;
}
}
}
...
}
I changed the arrow function declaration to a function shorthand declaration. I'm now able to access the component object and change the input field value via the Vuelidate model. Thanks to this: https://github.com/vuelidate/vuelidate/issues/237 šŸ™‚

Refactoring validation handling and messaging

I am working on a react project that uses redux forms. I've looped through the fields to check their validation requirements if need be. This stack works well - but I know I should re-visit this to place parts inside a function
if(field.validate.includes("email")) {
//email
if (!/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values[fieldName])) {
errors[fieldName] = 'Invalid email address'
}
}
if(field.validate.includes("minLength")) {
//minLength
if (values[fieldName] !== undefined && values[fieldName].length < 3) {
errors[fieldName] = 'Must be 3 characters or more'
}
}
if(field.validate.includes("required")) {
//required
if (!values[fieldName] && typeof values[fieldName] !== "number") {
errors[fieldName] = 'Required'
}
}
I've tried to write a function that looks like this - but I don't want to break the stack.
messageHandler(field, validation, rule, message){
if(field.validate.includes(validation)) {
if (rule) {
return message;
}
}
}
From what I can see, you're trying to validate a field's content against a set of defined rules.
To me, rules are just functions that can either be successful or not. For the sake of simplicity, let's say that if they return null it means that they are successful and otherwise, we'll return an error message (just a string).
const rules = {
email: value => !/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
? 'Invalid email address'
: null,
minLength: value => value !== undefined && value.length < 3
? 'Must be 3 characters or more'
: null,
required: value => !value && typeof value !== "number"
? 'Required'
: null,
};
Now, for each rule that we find in field.validate, we'll apply the corresponding rule and collect the result :
const matchingRules = field.validate
.map(formValidate => rules[formValidate])
.filter(x => x); // filter nullish values (rules that are not found)
const errors = matchingRules
.map(fn => fn(values[fieldName]))
.filter(x => x); // filter nullish values (successful rules)
Now, errors contains a list of strings describing how the field failed the different rules, and of course, if errors.length === 0, the test is successful.
You can add as many rules as you want without repeating all the ifs.
Is it acceptable in this project to bring in another lib? I like to use joi for validation. Of course, it is important to understand how validation works under the hood, but it seems like you have a pretty good grasp on that.
Here's an example of how you'd implement this with your current code:
First you would define a schema, which essentially represents your ideal end-state for your filled-in form. Below, I am saying that the form values will include an email, which will be a required string that is at least 3 characters long.
const Joi = require('joi');
const schema = Joi.object({
email: Joi.string().email().required().min(3)
})
Then, when you are ready to validate the form data:
const validation = schema.validate({ email: 'foo#bar.com' });
validation will contain values & errors (if there are any).
You can throw that schema.validate function in a useEffect that fires off whenever the user updates an input, or you can wait until the user is trying to submit the form, whatever your UI requires.
I like it because it is easy to read and write and it's quite flexible.

Express-validator how to make a field required only when another field is present

express-validator, how do I make a field required only when another field exists?
const validateUpdateStore = () => {
return [
body('logo').optional().isURL().withMessage('invalid url'),
body('email')
.optional()
.isEmail()
.withMessage('email is invalid')
.trim()
.escape(),
body('phone').optional().isInt().withMessage('integers only!'),
body('account_number').optional().isInt().withMessage('integers only!'),
body('bank_code').optional().isInt().withMessage('integers only!'),
];
};
I'd like to make the field bank_code required only when account_number is provided and vise-versa
Version 6.1.0 of express-validator added support for conditional validators. I do not currently see it in the documentation but there is a pull request with more information. It looks like you should be able to define your validation as follows:
const validateUpdateStore = () => {
return [
body('logo').optional().isURL().withMessage('invalid url'),
body('email')
.optional()
.isEmail()
.withMessage('email is invalid')
.trim()
.escape(),
body('phone').optional().isInt().withMessage('integers only!'),
body('account_number')
.if(body('bank_code').exists()) // if bank code provided
.not().empty() // then account number is also required
.isInt() // along with the rest of the validation
.withMessage('integers only!')
,
body('bank_code')
.if(body('account_number').exists()) // if account number provided
.not().empty() // then bank code is also required
.isInt() // along with the rest of the validation
.withMessage('integers only!')
,
];
};
To add to #Jason's answer here's how you can conditionally validate one field based on the value of another when the objects are in an array and you're using wildcard syntax:
// only validate `target` if `requiresTarget` is true
body('people[*].weight')
.if((value, { req, location, path }) => {
/*
Gets numeric, index value of "*". Adjust your regex as needed
if nested data uses more than one wildcard
*/
const wildcardIndex = parseInt(path.match(/([0-9]+)/)[1])
// return a true value if you want the validation chain to proceed.
// return false value if you want the remainder of the validation chain to be ignored
return req.body.people[wildcardIndex].requiresWeight
})
.isFloat() // only applies this if `requiresWeight` is true
.withMessage('weight must be float'),

Getting Sitecore Field with Web API

I have a question regarding the Sitecore Item Web API.
I have this JSON extract result when I call my Sitecore Web API:
{"statusCode":200,
[...]
"Version":1,
"Fields":{
"{0DE95AE4-41AB-4D01-9EB0-67441B7C2450}":{
"Name":"Phone number",
"Type":"Single-Line Text",
"Value":"XXXX"},
"{FA170F50-43FA-49B7-9AB1-9B4047DDBC2C}":{
"Name":"Fax",
"Type":"Number",
"Value":"YYYYYY"}
What I would like to do is to get the phone number Value field, or the Fax value field, directly, without looping through each GUID testing if the Name == "Phone Number" and then getting the Value etc...
I already have this JavaScript code but it is with this foreach loop, and it's not really fast.
function extractPhoneNumber(siteCoreFieldsList) {
var phoneNumberFieldValue;
$jq.each(siteCoreFieldsList, function (index, value) {
if (value.Name == "Phone number") {
phoneNumberFieldValue = value.Value;
}
});
return phoneNumberFieldValue;
}
Anyone has a work around or something more clean ?
Thanks a lot for your help. Regards.
In terms of a "best practice", you should be storing the field IDs somewhere any using them to get to the value.
However, given you're already creating function with the specific purpose of getting a value you could place the IDs there.
function extractFax(sitecoreFieldList){
return sitecoreFieldList['{FA170F50-43FA-49B7-9AB1-9B4047DDBC2C}'] || '';
}
function extractPhoneNumber(sitecoreFieldList){
return sitecoreFieldList['{0DE95AE4-41AB-4D01-9EB0-67441B7C2450}'] || '';
}

Javascript populate form after validation

I am doing a form for my javascript class, and I am getting stuck on a certain portion of it. I have a separate validator javascript file and call the function on the html file. All the validation works if the form areas are not filled in. What I want to do is if the fields are left blank they will fail the validation and will insert a value into that field. Below are an example of the form field, javascript function in the html page, and the external validator js file.
call function in html head:
function formvalidation(thisform) {
with (thisform) {
if (textbox_validation(first_name,"Please enter your first name.")==false)
{first_name.blur(); return false;};
if (textbox_validation(business_name,"Please enter your business. Please enter N/A if
you do not have one.")==false) { business_name.focus(); return false;
business_name.value=="N/A";};
The external js validator:
function textbox_validation(entered, alertbox) {
with (entered) {
if (value==null || value=="") {
alert(alertbox);
return false;
}
else {
return true;
}
}
}
So the validator works and focuses on the empty fields, but for some of my fields I want them to fill themselves with a certain value if validation fails or if it isnt filled int. The business_name line of code is when I tried to make it work. Any help is much appreciated!
Ordinarilly, you wouldn't use alert, but would instead put error messages in a span or div either near the input or at the top (or bottom) of the form. Additionally (as mentioned by #Frits van Campen) it is generally bad practice to use with
Try something like this instead:
function textbox_validation(entered, errormsg) {
var errbox = document.getElementById(entered.id + '-errors'); // just to prevent writing it twice
// Note this requires the input to have an id, and the errer box's id to be the same with an '-errors' suffix.
// Instead of using with, just acces properties normally
if (!entered.value) { // The `!` "neggation" operater makes "falsy" values `true`
// "falsy" values include `false`, the empty string, `0`, `null`, `undefined`, `NaN` and a few others
// Put the error message in the DOM instead of alerting it
errbox.innerHTML = errormsg;
return false;
}
else {
// Wipe any previous error messages
errbox.innerHTML = '';
return true;
}
}
And for the form validator, again; let's not use with. But also, when attempting to assing "N/A" to the value, you've used the comparison operator instead of the assignment operator, and you've done it after returning:
function formvalidation(thisform) {
// just use the `!` "negation" operator
if (!textbox_validation(thisform.first_name,
"Please enter your first name."))
{
thisform.first_name.blur();
return false;
}
if (!textbox_validation(business_name,
"Please enter your business. Please enter N/A if you do not have one."))
{
thisform.business_name.focus();
thisform.business_name.value = "N/A"; // for assignment, use `=`. `==` and `===` are used for comparison
return false; // a return statement ends the function, make sure it's after anything you want to execute!
}
}
Use the DOM to set the placeholder for the fields. Like this.
var myInput = document.getElementById('input1');
myInput.placeholder = 'This validation has failed.';

Categories

Resources