i am new to Yii2. I want to validate mobile number by custom validation function. How can i validate mobile no in Yii2 and how can i use user-defined rule to yii2 and How can we add error message to any attribute in yii2 after form post? Thanks in advance
you need to edit your model. Lets say you have the following model:
class User extends ActiveRecord implements IdentityInterface
{
...
/**
* #inheritdoc
*/
public function rules()
{
return [
[['email', 'password', 'id'], 'required'],
[['email', 'username'], 'unique'],
['mobile', 'customValidation'] //<----this will be your custom validation
}
public function customValidation(){
//perform your validation here
if(/*has error*/){
$this->addError("mobile","Your mobile number is not valid.");
}
}
}
the addError method's first parameter is the atribute you want to add the error to and the second parameter is the message you want to show.
Hope this helps ;)
Maybe this could help anyone.
Use pattern match in Yii2 and validate your input field.
It's going to check and return alert message if number has less/more than 10 digits.
['mobile', 'match', 'pattern'=>"/^[0-9]{3}[0-9]{3}[0-9]{2}[0-9]{2}$/",'message'=> 'Not Correct Format - mobile number should have 10 digits.'],
Related
In my update form, the passport field receives the value of its record, but when I confirm the form the unique validation points out that this value is already repeated, and is only valid when I change the value, I don't want to do that I want this validation to be ignored if the value remains unchanged.
I use the same JudokaRequest.php class in the store() and update() methods.
JodokaRequest.php
public function rules()
{
return [
'passaport' => ['required','size:8','unique:judokas,passaport', new PassportNumberRule],
];
}
public function messages()
{
return [
'passaport.unique' => 'The passport number is already registered, repeated passport values are not accepted.',
];
}
You can use the Illuminate\Validation\Rule so that you can add a condition on whether to ignore the validation rule for the given model.
Usage
return [
'passaport' => [
'required',
'size:8',
Rule::unique('judokas','passaport')->ignore(the instance of model you are editing), // if you are using the Route-Model Binding you can just refer the model using `$this->yourModel`
new PassportNumberRule,
],
];
Laravel has a 'unique' rule with an 'except' clause. From the validation documentation, it takes this form:
unique:table,column,except,idColumn
My application has a 'shop' entity. When the user updates the shop's profile, I have a Form Request, with a validation rule configured as follows:
public function rules()
{
return [
'shop.name' => 'required|string|max:100|unique:shops,name,except,id',
];
}
(The primary key on my shops table is id).
The problem is that Laravel does not take any notice of the 'except' clause. This makes sense (sort of) since the shop ID is not being injected into the Form Request. I can inject id as just another form value, but that doesn't seem to work.
How can I get this rule working in a Form Request?
To use the except clause of the unique rule, we need to provide the value of the field on the record that we want the rule to ignore directly in the rule itself.
So, if we want a unique name field for every record except for on the record that the request updates, we need to add the value of the ID field to ignore:
class UpdateShopRequest extends FormRequest
{
...
public function rules()
{
return [
'shop.name' => 'unique:shops,name,' . $this->shop['id'],
];
}
}
As shown, this rule will cause validation to fail if any row contains the same shop name unless the row's id matches $this->shop['id']. This example assumes that our form contains a nested input field for the record's ID attribute because this particular question is performing validation on an array input:
<input type="hidden" name="shop[id]" value="{{ $shop->id }}">
...which lets us fetch the value within the request like we can with any other request.
However, most forms do not contain arrays, so—in other cases—the validation rule will likely refer to the input field directly (without nested identifiers):
'name' => 'unique:shops,name,' . $this->id,
More typically, we pass the record ID as a route parameter, which we can retrieve using the request's route() method:
'name' => 'unique:shops,name,' . $this->route('id'),
...which works if we have a route defined similarly to:
Route::post('shops/{id}', ...);
The fourth parameter to the unique validation rule lets us specify which column the except clause applies to, and defaults to id, so we can leave it off if we're just comparing the record's ID.
The rule looks a bit clumsy when we just concatenate the column value, especially for a field with a lot of other rules. Since version 5.3, Laravel provides a more elegant syntax to create a unique rule with an except clause:
use Illuminate\Validation\Rule;
...
return [
'name' => [
'required',
'string',
'max:100',
Rule::unique('shops', 'name')->ignore($this->id, 'optional_column'),
],
];
This example assumes that our form contains an array input field for the record's ID attribute because the question is performing validation on an array input:
<input type="hidden" name="shop[id]" value="{{ $shop->id }}">
Laravel 5.8: I've tried you solution right now, without adding the input, it's working well. Because Laravel pass the Shop object into request (shown with dd() into rules() )
Just:
`public function rules()
{
return [
'name' => 'unique:shops,name,'.$this->shop->id
];
}`
I use this solution in laravel 9, assuming that you use route model binding and resource controller, and do not have to add hidden input for the model id.
public function rules()
{
return [
'buy' => 'required|numeric|gt:0',
'sell' => 'required|numeric|gt:0',
'date' => 'required|' . Rule::unique('prices')->ignore($this->price),
];
}
for laravel 8 use $this->get('id') to exclude current record to taste
use Illuminate\Foundation\Http\FormRequest;
class Update extends FormRequest
{
public function rules()
{
return [
'name' => ['required', 'string', 'unique:shops,slug,'. $this->get('id')],
];
}
}
I have two models: Cities and Schools. As you already understand Cities can have many schools and taking this into account I have defined my model as follows:
class School extends Model
{
public $fillable = ['city_id' ,'name'];
public function city()
{
return $this->belongsTo('App\City','city_id','id');
}
}
class City extends Model
{
public $fillable = ['name'];
Public function schools()
{
return $this->hasMany('App\School', 'id','city_id');
}
}
But I have faced a pproblem when trying to validate update of a school model. I have to validate whether name of the school is unique for selected city or not. I have defined the rule like this:
$rules = array(
'name' => ['required', Rule::unique('schools')->ignore($id)],
);
$validator=Validator::make(Input::all(),$rules);
But it is not allowing to save a school with existing name in other city than selected. How should I change the rule to ensure that school names can be same if the city is different.
Thank you.
Custom rule
The best solution would be to create a custom rule for this, that accepts the field with the corresponding city name/id as a parameter.
Something like
//Calling the custom rule like this
['name' => 'required|validateSchool:yourFieldNameOfCityHere'];
Declaring the custom validation function in your service provider like this
Validator::extend('validateSchool', function ($attribute, $value, $parameters, $validator) {
$cityName = ($validator->data, $parameters[0]);
//Now check if the $value is already set for the specific city by using normal database queries and comparison
return count(City::whereName($cityName)->schools()->whereName($value)->get()) == 0
});
What does it
The custom validation rule receives the data of the field you give with the function (in the code above it's yourFieldNameOfCityHere), so it knows which city the user chose. With this information, you now can check if there is already a school with the name for the entered city.
At the DB level, it sounds like what you want is a compound uniqueness constraint across name and city_id. Eloquent seems to support passing an array of column names in model definitions. It seems like this requires custom validation, though. See Laravel 4: making a combination of values/columns unique and the custom validator at https://github.com/felixkiss/uniquewith-validator
I'm want to ensure that a multi-select field (belongsToMany) has at least one item checked/selected. I have two entities:
Listings and PaymentTypes - belongsToMany.
My field is created with the helper:
echo $this->Form->input('payment_types._ids', ['options' => $paymentTypes, 'multiple' => 'checkbox']);
In my ListingsModel.php file I have my validator setup as follows:
public function validationDefault(Validator $validator) {
$validator = new Validator();
$validator->requirePresence('payment_types._ids');
return $validator;
}
This prevent the save from happening but I don't see any validation error message. Why doesn't the HTML5 form validation work as it does on other fields which are of type text?
I managed it with this custom rule:
->add('delivery_types', [
'multiple'=>[
'rule'=>['multiple', ['min'=>1]],
'message'=>'Select at least one method of delivery method'
]
])
This isn't especially well documented in the book so hopefully it iwll be of some help to others starting with Cake v.3
You should be able to accomplish this with nested validators - http://book.cakephp.org/3.0/en/core-libraries/validation.html#nesting-validators.
As an example:
public function validationDefault(Validator $validator) {
$paymentTypesValidator = new Validator();
$paymentTypesValidator->requirePresence('_ids');
$validator-> addNested('payment_types', $paymentTypesValidator);
return $validator;
}
You could then decorate the $paymentTypesValidator object with any other rules you require.
Suppose I have a field name id and I want the user to enter some integer in the id field but at the same time I want to check that id against the database whether it exists or not. If it exists then it should show some error.
Is there a function to achieve this in Yii 2.0?
If this is from a model, you can have a unique rule to it in the validation rules.
In your model, you have a rules() function:
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
return array(
array('name', 'required'),
array('some_id', 'unique'),
);
}