Multiple forms with field name arrays fail vaildation - validation

I have multiple forms in a tabbed layout and post to the same resource controller. These fields have the same field names with a few as arrays. Use case is password storage where depending on the type of password depends on the fields needed.
Input field
<?= Form::text('name', Input::old('name'), array('class' => ($errors->has('name')) ? 'invalid' : '', 'placeholder' => 'Application Name')) ?>
<?= Form::text("data['username']", Input::old('data["username"]'), array('class' => ($errors->has('data.username')) ? 'invalid' : '', 'placeholder' => 'Username')) ?>
<?= Form::text("data['password']", Input::old('data["password"]'), array('class' => ($errors->has('data.password')) ? 'invalid' : '', 'placeholder' => 'Password')) ?>
Validation rules
protected $rules = array(
'name' => 'required',
'data.username' => 'required',
'data.password' => 'required'
);
I have more data fields but this illustrates the use case.
I get errors properly with posting with empty fields and the old input is populated but I also get errors for filled fields. My post data shows populated fields.

Tested with just one form (could have done that the first time) and still had the error. My issue here was with the how the data['username'] was used.
Should be data[username] without the quotes. While post data and everything works with the quotes, the validator was not liking it.

Related

Laravel required_with throwing error even when its supposed to be ignored

Basic user profile update page with an optional password change. Only if theyre trying to change their password, does it request the current password.
Controller:
$this->validate($request, [
'name' => 'required',
'email' => 'required|email',
'new_password' => 'confirmed',
'current_password' => 'required_with:new_password|current_password'
]);
$user->name = $request->get('name');
$user->surname = $request->get('surname');
$user->email = $request->get('email');
if($request->get('password') !== ''){
$user->password = Hash::make($request->get('new_password'));
}
$user->save();
But validation keeps tripping up and giving me the error "validation.current_password"
View (scaled back for readability):
#if($errors)
#foreach ($errors->all() as $error)
<div>{{ $error }}</div>
#endforeach
#endif
{!! Form::model($user, ['method'=>'PATCH', 'action'=>['UserController#update', $user->id], 'class'=>'kt-form kt-form--state', 'id'=>'form-user-profile', 'files' => true]) !!}
{!! Form::text('name', null, ['class'=>'form-control']) !!}
{!! Form::password('current_password', ['class'=>'form-control','placeholder'=>__('Current Password')]) !!}
{!! Form::password('new_password', ['class'=>'form-control','placeholder'=>__('New Password')]) !!}
{!! Form::password('new_password_confirmation', ['class'=>'form-control','placeholder'=>__('Verify New Password')]) !!}
{{ Form::button(__('Submit'), ['type' => 'submit', 'class' => 'btn btn-success']) }}
{{ Form::button(__('Reset'), ['type' => 'reset', 'class' => 'btn btn-secondary']) }}
{!! Form::close() !!}
As per https://laravel.com/docs/9.x/validation#rule-required-with
required_with only needs to be present if new_password is present. So why am I getting a "validation.current_password" error when I only update my "name" field (for example).
From the error you're getting, it is somehow clear that the required_with is not the rule behind the error, it actually is the current_password rule.
According to the docs, the current_password rule does the following check
The field under validation must match the authenticated user's password
So with that being said, it seems you're not typing the correct password of the currently logged in user which trigger the validation error of the current_password rule.
A quick fix could be:
starting by adding the nullable validation rule on both new_password and current_password fields so the validation can pass when the fields are empty.
use required_unless rule instead of required_with which allows you to verify whether new_password field is empty (null) or not.
required_unless: The field under validation must be present and not empty unless the anotherfield field is equal to any value. This also means anotherfield must be present in the request data unless value is null. If value is null (required_unless:name,null), the field under validation will be required unless the comparison field is null or the comparison field is missing from the request data.
Here's a code sample illustrating what's being said:
$this->validate($request, [
'name' => 'required',
'email' => ['required', 'email'],
'new_password' => ['nullable', 'confirmed'],
'current_password' => ['nullable', 'required_unless:new_password,null', 'current_password']
]);
In the above code sample i used arrays instead of strings to specify the rules. This doesn't have anything to do with the solution, it is used to make the changes clearer and the code more readable
Bonus Tip: you're getting validation.current_password as the error message is due to the lang files that contain the validation message being deleted. TheEN version of those files should be under resources/lang/en/validation.php. You may simply download that file from GitHub and place it there or you may use your own custom error messages.
Learn more about Validation Rules on Laravel docs.

Default value for laravel collective select

I have a Laravel collective select as follows:
{!! Form::select('phone', $numbers, $title, ['class' => 'phone-select2 col4', 'id' => 'phone']) !!}
I want to pass default value for dropdown as separate variable from $numbers. So, have passed it as $title but it is didn't work due to it is not in the $numbers. So, how can I pass default value for it?
What you're looking for is a placeholder.
https://laravelcollective.com/docs/6.x/html#drop-down-lists
According to the documentation, you can set the default value to null and provide placeholder attribute as part of the fourth argument:
['class' => 'phone-select2 col4', 'id' => 'phone', 'placeholder' => 'Pick an option']

Validate Select2 in Yii2 via AJAX

I have Yii2 application which uses the Kartik plugin to initialize Select2 dropdowns in forms.
I have one particular Select2 which uses AJAX call to get the data for the drop down options.
<?=
$form->field($model, 'court_house_id', ['enableAjaxValidation' => true, 'selectors' => ['input' => '#' . $id . "-court-house"],'template' => FormHelper::GenerateFieldTemplate([6])])
->widget(Select2::classname(), [
'options' => ['id' => $id . "-court-house", 'placeholder' => Yii::t('app', 'Search court house...')],
'hashVarLoadPosition' => \yii\web\View::POS_READY,
'pluginOptions' => [
'dropdownParent' => new JsExpression("$('#$modalWindowId')"),
'allowClear' => true,
'minimumInputLength' => 2,
'language' => [
'errorLoading' => new JsExpression("function () { return '" . Yii::t('app', 'Search...') . "'; }"),
],
'ajax' => [
'url' => app\components\UrlMaker::link('data/court-house-list'),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(courthouse) { return courthouse.text; }'),
'templateSelection' => new JsExpression('function (courthouse) { return courthouse.text;}'),
]])
->label(Yii::t('app', 'Court House'), ['class' => FormHelper::GenerateLabelClassTemplate([3])]);
?>
Intentionally pasting all of the code, although most of it is irrelevant I would assume.
I have this loaded in multiple dynamically created forms thus all the strange ids and selectors. However, the form has different dropdown which controls whether some of the fields are shown (and required) or not. This particular field above is only shown in one of the scenarios which all the other variations of the form do not have it. So the model has the following validation:
[['court_house_id', 'staff'], 'required', 'on' => self::SCENARIO_ONE],
By the way staff is just a regular text field and everything works for it.
In order to change the scenario, I have the following line in the view with the form:
<?php $model->scenario = \app\models\MyModel::SCENARIO_ONE; ?>
The problem is that when I submit the form empty, the staff field gets marked in red as invalid but the court house is marked in green as valid although it is empty.
If I go into the model and remove the 'on' => self::SCENARIO_ONE part then everything works as expected - on empty submit the court house field also lights up in red but that would be a problem for the rest of my scenarios where this field is not needed.
Any ideas what might be causing the problem and how to resolve it?
Try to set the scenario in controller before calling save() method, for example
$model = new MyModel(['scenario' => MyModel::SCENARIO_ONE])

Laravel custom validation messages

I'm trying to validate a UK postcode using Laravel. Here's what I've got:
//routes.php
$rules = array(
'pcode' => array('required:|Regex:/^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][‌​0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$/')
);
$messages = array(
'required' => 'The :attribute field is required.',
'pcode' => array('regex', 'Poscode should be a valid UK based entry'),
);
$validator = Validator::make(Input::all(), $rules, $messages);
In my blade:
<input id="postcode" name="pcode" value="{{Input::old('pcode')}}" type="text" placeholder="Postcode" class="form-control" xequired="" />
#if( $errors->has('pcode') ) <span class="error" style='background-color: pink;'>{{ $errors->first('pcode') }}</span> #endif
If I submit the form with an empty pcode field, it warns me for a required field. If I enter an invalid postcode, '74rht' say, my validator does nothing or fails to display my custom message as defined above?
The Laravel manual states:
Note: When using the regex pattern, it may be necessary to specify rules in an array instead of using pipe delimiters, especially if the regular expression contains a pipe character.
Change the $rules to this structure:
$rules = array(
'pcode' => array(
'required',
'Regex:/^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][‌​0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$/'
)
);
If that doesn't work, then maybe your regex isn't valid, try to use a easier regex to check if the validator works.
Fist, you will want to register a custom validation rule with the validator.
Validator::extend('pcode_rule_name', function($attribute, $value)
{
return preg_match('/^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][‌​0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$/', $value);
});
src: http://laravel.com/docs/validation#custom-validation-rules
Then you will want to specify custom messages in app/lang/en/validation.php
You will find a place to add your custom message for your your rule
'custom' => array(
'attribute-name' => array(
'rule-name' => 'custom-message',
),
),
You can add a rule like so:
'custom' => array(
'pcode' => array(
'pcode_rule_name' => 'Post Code should be a valid UK based entry',
),
),
There will also be an array to name your "pcode" field so it will be more eloquently named for rules like "required".
'attributes' => array(),
just add the name like so
'attributes' => array(
'pcode' => 'Postal Code",
),

how to give value of dropdown in controller in codeigniter

i have this code in codeigniter (section of form in codeigniter controller) :
$this->data['SalaryType'] = array(
'name' => 'SalaryType',
'id' => 'SalaryType',
'type' => 'text',
'value' => $this->form_validation->set_value('SalaryType'),
);
$this->data['DefaultSalary'] = array(
'name' => 'DefaultSalary',
'id' => 'DefaultSalary',
'type' => 'text',
'value' => $this->form_validation->set_value('DefaultSalary'),
);
$this->data['Salary_options'] = array(
'language' => 'monthly',
'world' => 'world'
);
(section of form in codeigniter view) :
<p>
Salary Type: <br />
<?php echo form_dropdown($SalaryType,$Salary_options,'monthly');?>
</p>
<p>
Default Salary: <br />
<?php echo form_input($DefaultSalary);?>
</p>
and i want use dropdown value but form send input value alone , and i can't access to dropdown value.
i check with print_r($_POST); but in post array observation 'DefaultSalary'.
You have initialized dropdown in wrong way
<?php echo form_dropdown($SalaryType,$Salary_options,'monthly');?>
use instead
<?php echo form_dropdown('DefaultSalary',$Salary_options,'language');?>
1st parameter is the name of the control
2nd parameter is the options array ->which is correct
3rd parameter is the selected index from the options array not value that can be in your case 'language' instead of 'monthly'
read form_helper
And you will be able to access it using $this->input->post('DefaultSalary'); and it will return the value of the option selected
May be your name attr of the drop down is not setting...
For adding id to form_drop down you can try this..
form_dropdown('country', $options_array, '1','id="select_id"')
Note : this is not tested.

Resources