Yup validation check if not empty - yup

const validationSchema = Yup.object().shape({
newPassword: Yup.string().min(8, 'Password must be at least 8 characters');
});
I want to validation check only if newPassword field is not empty.
How could I do?

There are different approach on solving this problem.
Using test
const validationSchema = Yup.object().shape({
newPassword: Yup.string().test(
'empty-check',
'Password must be at least 8 characters',
password => password.length == 0
});
Using when
const validationSchema = Yup.object().shape({
newPassword: Yup.string().when('newPassword',{
is:(password) => password.length > 0
then: Yup.string().min(8, 'Password must be at least 8 characters');
});

Alternative using test:
const validationSchema = Yup.object().shape({
newPassword: Yup.string().test(
'empty-or-8-characters-check',
'Password must be at least 8 characters',
password => !password || password.length >= 8,
),
});

Alternative using trim()
const validationSchema = Yup.object().shape({
newPassword: Yup.string().trim().required("Password must be at least 8 characters"),
});

There is a way of using .when() and not generating a cyclic dependency like the accepted answer, .shape() accepts an exhaustive list of dependencies as last argument, that resolves the cyclic conflict, the secret is using the same key twice https://github.com/jquense/yup/issues/176#issuecomment-369925782
const validationSchema = Yup.object().shape({
newPassword: Yup.string().test(
'empty-or-8-characters-check',
'Password must be at least 8 characters',
password => !password || password.length >= 8,
),
}, [["newPassword","newPassword"]]);

The way I solved this for myself was to first add .nullable() and then .transform() empty string into a null.
const validationSchema = Yup.object().shape({
newPassword: Yup
.string()
.nullable()
.transform((v, o) => (o === '' ? null : v))
.min(8, 'Password must be at least 8 characters')
});

The simplest way is:
const validationSchema = Yup.object().shape({
newPassword: Yup
.string()
.matches(/^\w{8}/, "Password must be at least 8 characters")
});

Alternative that won't allow 8 empty characters.
const notEmpty = Yup.string()
.ensure() // Transforms undefined and null values to an empty string.
.test('Only Empty?', 'Cannot be only empty characters', (value) => {
const isValid = value.split(' ').join('').length !== 0;
return isValid;
});
const validationSchema = Yup.object({
newPassword: notEmpty.min(8, 'Password must be at least 8 characters');
});

I used the Yup function nullable() so it is only validated with the next functions if it not null:
kmBegin: Yup.number().nullable().positive().integer(),
parcelTotal: Yup.number().positive().integer(),
timeBegin: Yup.date(),
timeEnd: Yup.date().nullable(),

Related

how to modify a String from a Textfield before validated using validator?

I am using form field validator, I think it will be the same if using normal TextField, and I have form field like this
TextFormField(
onChanged: (val) => selectedEmail = val,
validator: EmailValidator(errorText: "Email is not valid"),
)
unfortunately, my user sometimes unintentionally will put an empty string at the end of email string like this :
"john#gmail.com "
as you can see, I have email validator here, but the email validator will consider the string with empty space like that as an invalid email.
I want to remove or trim the email string first before it is validated by the EmailValidator, how to do that?
TextFormField(
onChanged: (val) => selectedEmail = val,
validator: EmailValidator(errorText: "Email is not valid"),
inputFormatters: [FilteringTextInputFormatter.deny(RegExp(r'\s'))]
)
FilteringTextInputFormatter.deny(RegExp(r'\s')) it's deny white space in the TextFormField
It could be helpful.
TextFormField(
onChanged: (val) => selectedEmail.trim() = val.trim(),
validator: EmailValidator(errorText: "Email is not valid"),
)

I m trying to fetch order details from website and getting error "A non-null String must be provided to a Text widget'

1.getting error on this line as null
enter code here
return OrderItem(
order: model.myOrders[index],
onRefresh: refreshMyOrders,
);
}),
),
)
You have to check if the indexed order is null and set a default value to protect your code from these types of errors like this:
return OrderItem(
order: model.myOrders[index] ?? 'Default Value',
onRefresh: refreshMyOrders,
);
}),
),
)

Is there any way to pass the validation of NOT REQUIRED v-text-field rules?

I tried to validate v-text-field for entering number only but it is not required but the rules deny to pass the validation.
I used v-form, v-text-field and rules of v-text-field.
<template>
<v-form ref="form">
<v-text-field
v-model="name"
:label="label"
:rules="rules"
#blur="changeValue"
clearable
></v-text-field>
<v-btn #click="send">submit</v-btn>
</v-form>
</template>
<script>
export default {
data() {
return {
name: "",
rules: [
v =>
v.length <= 50 || "maximum 50 characters",
v =>
(v.length > 0 && /^[0-9]+$/.test(v)) || "numbers only"
]
};
},
methods: {
changeValue(event) {
this.$emit("changeValue", event.target.value);
},
send() {
const valid = this.$refs["form"].validate(); // doesn't pass
if (valid) {
this.$store.dispatch("xxx", {
...
});
}
}
}
};
</script>
When the submit button was clicked, error message of v-text-field is shown and valid is false.
Clicked X(the clear icon), The error message is also shown on console:
"TypeError: Cannot read property 'length' of null"
A bit late, but i have solved it with this function:
rules: [
v => {
if (v) return v.length <= 50 || 'maximum 50 characters';
else return true;
},
],
i use this way one for email and one for name
nameRules: [
v => v.length <= 10 || 'Name must be less than 10 characters',
],
emailRules: [
v =>( v.length ===0 || /.+#.+/.test(v) ) || 'E-mail must be valid',
],

Validate default values

I have a form which consists of selects/dropdowns. I have set their default values to be -1. When the form is submitted, I want to validate that the submitted value is not equal to the default value. I tried setRequired(true), but as far as I know, that is just a convenient way of adding a notEmpty validator, which is not really what I want.
Here is a part of my form:
$select = new Zend_Form_Element_Select('myselect');
$select->setMultiOptions(array(
'-1' => 'Gender',
'0' => 'Female',
'1' => 'Male'
))
->addValidator(new Zend_Validate_Int(), false);
$this->setDefaults(array('myselect' => -1));
And here is my controller:
if ($this->getRequest()->isPost()) {
$form = new My_Form_Contact();
if ($form->isValidPartial(array('myselect' => $this->getRequest()->getPost('myselect')))) {
// "myselect" is valid
}
I need to use the isValidPartial method because I need to use different logic depending on which elements have a value that is different from their default value. I guess what I need is a notEqual validator, but I couldn't find one. I know that it is possible to make my own validators, but I wanted to ask if there is an easier way first. I also looked at Zend_Validate_Identical, but I don't think I can make use of it in this case.
To sum up: I only want my select to be validated successfully if the submitted value is not equal to the default value.
The simplest solution is to use an empty string as the default:
$select->setMultiOptions(array(
'' => 'Gender',
'0' => 'Female',
'1' => 'Male'
))
->addValidator(new Zend_Validate_Int(), false)
->addValidator(new Zend_Validate_NotEmpty(), false);
$this->setDefaults(array('myselect' => ''));
but I'm guessing you already thought of that, and discounted it from some reason.
So, the next easiest is to use GreaterThan():
$select->setMultiOptions(array(
'-1' => 'Gender',
'0' => 'Female',
'1' => 'Male'
))
->addValidator(new Zend_Validate_Int(), false)
->addValidator(new Zend_Validate_GreaterThan(-1), false);
$this->setDefaults(array('myselect' => '-1'));
I hope that is what you are looking for.

How can I setup custom error messages for each form field in Codeigniter?

i'm trying to setup a codeigniter form with different error messages.
set_message(rule, msg) is setting up a message for the whole form.
I need:
$this->form_validation->set_rules('name', 'First Name', 'required');
$this->form_validation->set_message('name', 'required', 'Enter your Name');
$this->form_validation->set_rules('second', 'Variables', 'required');
$this->form_validation->set_message('second', 'required',
'The Variables are required');
Adding the %s into the message string is no help in this case, since the messages have to be completely different.
Possibly I could do something like:
controller
$this->form_validation->set_rules('name', 'Name',
'required|min_length[6]|max_length[12]');
$this->form_validation->set_rules('second', 'Variables',
'required|min_length[3]|max_length[5]');
$this->form_validation->set_message('required', 'required');
$this->form_validation->set_message('min_length', 'short');
$this->form_validation->set_message('max_length', 'long');
view
switch(form_error('name')) {
case '<p>required</p>':
echo 'Enter your Name';
break;
case '<p>short</p>':
echo 'min length 6';
break;
case '<p>long</p>':
echo 'min length 12';
break;
}
switch(form_error('second')) {
case '<p>required</p>':
echo 'The Variables are required';
break;
case '<p>short</p>':
echo 'min length 3';
break;
case '<p>long</p>':
echo 'min length 5';
break;
}
But isn't there a smarter way to do it?
I think a smarter way would be to use Codeigniter's callback feature (something similar to below). The following works but it may be possible to streamline it even more. If nothing else, it's a starting point.
Create two callback functions (I've named these custom_required and custom_check_length) and place them at the bottom of your controller (or wherever you feel necessary).
private function _custom_required($str, $func) {
switch($func) {
case 'name':
$this->form_validation->set_message('custom_required', 'Enter your name');
return (trim($str) == '') ? FALSE : TRUE;
break;
case 'second':
$this->form_validation->set_message('custom_required', 'The variables are required');
return (trim($str) == '') ? FALSE : TRUE;
break;
}
}
and...
private function _custom_check_length($str, $params) {
$val = explode(',', $params);
$min = $val[0];
$max = $val[1];
if(strlen($str) <= $max && strlen($str) >= $min) {
return TRUE;
} elseif(strlen($str) < $min) {
$this->form_validation->set_message('custom_check_length', 'Min length ' . $min);
return FALSE;
} elseif(strlen($str) > $max) {
$this->form_validation->set_message('custom_check_length', 'Max length ' . $max);
return FALSE;
}
}
These two functions take care of the set_message aspect of your form validation. To set the rules, you simply need to call these two functions by prefixing the function name with callback_.
So...
$this->form_validation->set_rules('name', 'Name', 'callback__custom_required[name]|callback__custom_check_length[6,12]');
$this->form_validation->set_rules('second', 'Second', 'callback__custom_required[second]|callback__custom_check_length[3,5]');
I hope the above helps in some way!!
you can set custom error like I mentioned below, no need to create custom function for this error message content change.
$validation = array(
array(
'field' => 'name',
'label' => 'NAME',
'rules' => 'trim|required',
"errors" => array('required' => " Enter your %s. ")
),
);
$this->form_validation->set_rules($validation);
if ($this->form_validation->run()) {}
You were almost there with your initial thought. All you needed was to execute validation after each group of set_message() changes. I find this approach much easier and faster than callback functions, unless you are going to use this exact customisation in many places.
$this->form_validation->set_rules('name', 'First Name', 'required|alpha')
$this->form_validation->set_message('name', 'required', 'Enter your Name');
$this->form_validation->set_message('name', 'alpha', 'Numbers in %s?');
$this->form_validation->run();
$this->form_validation->set_rules('second', 'Variables', 'required');
$this->form_validation->set_message('second', 'required', 'Variables required');
if ($this->form_validation->run()) {
...
}
This validation approach works on all versions of Codeigniter.
$this->form_validation->set_rules('name', 'Name', 'callback__custom_required[name]|callback__custom_check_length[6,12]');
$this->form_validation->set_rules('second', 'Second', 'callback__custom_required[second]|callback__custom_check_length[3,5]');**