How to validate in CakePHP 3 multiple select field (belongsToMany Association)? All I need is validation rule.
Multiple select field:
<!--select multiple-->
<div class="form-group ">
<label class="control-label">Group:<em>*</em></label>
<select name="newsletter_groups[_ids][]" class="form-control" multiple>
<option></option>
<option value="1" selected>Group 1</option>
<option value="2" >Group 2</option>
<option value="3" selected>Group 3</option>
<option value="4" selected>Group 4</option>
</select>
<label class="error"></label>
</div>
Add in NewsletterTable.ctp
$validator
->add('groups', 'custom', [
'rule' => function($value, $context) {
return (!empty($value['_ids']) && is_array($value['_ids']));
},
'message' => 'Please choose at least one Group'
]);
Related
I need for filtering data based on getting requests,
Current Route
Route::get('datasearch', [Mycontroller::class, 'MyFunction'])->name('this.is.route.name');
Current Forntend form
<form method="get" enctype="multipart/form-data" action="{{ route('this.is.route.name') }}">
#csrf
<select class="form-control" name="searchAdmin">
<option class="hidden" selected disabled>Admin List </option>
<option value="1">Value 1</option>
<option value="2">Value 2</option>
</select>
<<select class="form-control" name="searchAgent">
<option class="hidden" selected disabled>Agent List </option>
<option value="1">Value 1</option>
<option value="2">Value 2</option>
</select>
<input type="submit" value="Search Data" />
</form>
I need to create below type of URL
http://127.0.0.1:8000/datasearch?filter[dbfieldname1]=searchAdmin&filter[dbfieldname2]=searchAgent
To make request like your requirement, just set form with this content, example in resources\views\home.blade.php:
<form method="get" enctype="multipart/form-data" action="{{ route('search.data') }}">
<select class="form-control" name="filter[dbfieldname1]">
<option class="hidden" disabled selected>Admin List </option>
<option value="1">Value 1</option>
<option value="2">Value 2</option>
</select>
<select class="form-control" name="filter[dbfieldname2]">
<option class="hidden" disabled selected>Agent List </option>
<option value="1">Value 1</option>
<option value="2">Value 2</option>
</select>
#csrf
<input type="submit" value="Search Data" />
</form>
Configure the route routes\web.php:
Route::get('/search/data', [App\Http\Controllers\HomeController::class, 'search'])->name('search.data');
Then set search function as app\Http\Controllers\HomeController.php:
// Get search data
public function search(Request $request)
{
logger('Function search is working.');
$filter = $request->filter;
if($filter) {
if(isset($filter['dbfieldname1'])){
logger('Value of dbfieldname1:');
logger($filter['dbfieldname1']);
} else {
logger('Admin list is not choosen.');
}
if(isset($filter['dbfieldname2'])){
logger('Value of dbfieldname2:');
logger($filter['dbfieldname2']);
} else {
logger('Agent list is not choosen.');
}
} else {
logger('Not any lists choosen!');
}
}
Clear storage\logs\laravel.log, then you will get successful result!
[2022-03-05 05:53:54] local.DEBUG: Function search is working.
[2022-03-05 05:53:54] local.DEBUG: Admin list is not choosen.
[2022-03-05 05:53:54] local.DEBUG: Value of dbfieldname2:
[2022-03-05 05:53:54] local.DEBUG: 2
[2022-03-05 05:54:24] local.DEBUG: Function search is working.
[2022-03-05 05:54:24] local.DEBUG: Value of dbfieldname1:
[2022-03-05 05:54:24] local.DEBUG: 1
[2022-03-05 05:54:24] local.DEBUG: Agent list is not choosen.
Simply provide an array with key values to the route parameters. For example:
route('products.index', ['manufacturer' => 'Samsung','price' => '10000']);
If you're not uploading any files, you probably want to use enctype="application/x-www-form-urlencoded" with your forms. The multipart/form-data is to be used with (special) POST requests for which you need file uploads (I'm not sure what happens when you use it with a GET, it might just get ignored).
Then, you have to keep in mind that every name="..." attribute on your inputs/selects/textareas will determine the key of the data in the URL, i.e.
<input type="text" name="username" value="foobar" />
// example.com?username=foobar
// Laravel will interpret it as ['username' => 'foobar']
You can also change this name to username[] to automatically have the inputs parsed as an array (I believe this all works out of the box with PHP, in the end it depends on your server), i.e.
<input type="text" name="username[]" value="foo" />
<input type="text" name="username[]" value="bar" />
// example.com?username[]=foo&username[]=bar
// Laravel will interpret it as ['username' => ['foo', 'bar']]
Lastly, when you put stuff inside the brackets, it will be interpreted as keys inside of that value like so:
<input type="text" name="username[a]" value="foo" />
<input type="text" name="username[b]" value="bar" />
// example.com?username[a]=foo&username[b]=bar
// Laravel will interpret it as ['username' => ['a' => 'foo', 'b' => 'bar']]
<div class="form-group">
<label for="category-id">Category</label>
<select id="category-id" class="form-control {{$errors->get('category_id') ? 'is-invalid' : ''}}" name="category_id">
<option value="177">Select a category</option>
#foreach ($categories as $category)
<option value="{{$category['id']}}">{{$category['title']}}</option>
#endforeach
</select>
#if ($errors->has('category_id'))
<div class="invalid-feedback"><strong>{{$errors->first('category_id')}}</strong></div>
#endif
</div>
The category_id is defined as the required field in my Request php file ('category_id' => 'required')
But when I submit the form without any input to any field, all fields generate error messages by highlighting the field, except this SELECT field.
It passes the validation because your are sending a value in that field.
Change this
<option value="177">Select a category</option>
to
<option selected disabled>Select a category</option>
then it should not pass the validation.
In my form the user can add (or remove) licence items which
are generated as input nested arrays:
<div>
<select name="licences[0][type]">
<option value="">- Select -</option>
<option value="car">Car</option>
<option value="motorbike">Motorbike</option>
</select>
<input type="text" name="licences[0][car_spec]" value="">
<input type="text" name="licences[0][motorbike_spec]" value="">
</div>
<div>
<select name="licences[1][type]">
<option value="">- Select -</option>
<option value="car">Car</option>
<option value="motorbike">Motorbike</option>
</select>
<input type="text" name="licences[1][car_spec]" value="">
<input type="text" name="licences[1][motorbike_spec]" value="">
</div>
...
and here are my rules:
$rules = [
'licences.*.type' => 'required',
'licences.*.car_spec' => 'required_if:licences.*.type|car',
'licences.*.motorbike_spec' => 'required_if:licences.*.type|motorbike',
];
Now how can I ensure that the validations match the same index (*) of the licences array ?
For instance, the licences[1][car_spec] input is checked against the licences[1][type] input and not against the licences[0][type].
try like this one:
public function validation(){
$rules = [
'licences.*.type' => 'required',
'licences.*.car_spec' => 'required_if:licences.*.type|car',
'licences.*.motorbike_spec' => 'required_if:licences.*.type|motorbike',
];
foreach($this->request->get('licences') as $key => $value){
$rules['licences.'.$key.'.type'] = 'required';
$rules['licences.'.$key.'.car_spec'] = 'required_if:licences.*.type|car';
$rules['licences.'.$key.'.motorbike_spec'] = 'required_if:licences.*.type|motorbike';
}
return $rules;
}
I hope this works for you.
I have simple select for gender option :
<select class="form-control show-tick" name="kelamin" required="true">
<option value="">-- Please select --</option>
<option value="L" >Laki-Laki</option>
<option value="P">Perempuan</option>
</select>
How to set_value on select option like
<input type="text" name="nama" class="form-control" value="<?= set_value('nama'); ?>" required="true">
Use the set_select function.
<select class="form-control show-tick" name="kelamin" required="true">
<option value="" <?= set_select('kelamin', '', TRUE); ?> >-- Please select --</option>
<option value="L" <?= set_select('kelamin', 'L'); ?> >Laki-Laki</option>
<option value="P" <?= set_select('kelamin', 'P'); ?> >Perempuan</option>
</select>
I have come to writing my controller code after doing the view:
A few questions regarding the Select Menus:
How do I validate the select menu - I do not want them to be able to select “Please Select”
Can I still use $this->form_validation->set_rules('','','required');
How do I send the correct answer into the controller?
<label for="hostingRequired">Hosting Required:</label>
<select name="hostingRequired">
<option value="pleaseSelect"> Please Select</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
<label for="domainRequired">Domain Registration: </label>
<select name="domainRequired">
<option value="pleaseSelect">Please Select</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
<div id="domainToBeReged">
<label for="domainToBeReged">Domain:</label><input name="domainToBeReged" type="text" placeholder="http://www." />
<label for="domainToBeReged0">Domain:</label><input name="domainToBeReged0" type="text" placeholder="http://www." />
</div>
You could do the following
then use the following validation rule
$this->form_validation->set_rules('','','required|callback_is_default');
function is_default($array)
{
foreach($array as $element)
{
if($element == 'pleaseSelect')
{
return FALSE;
}
}
return TRUE;
}
If you didnt find validation rule that you want, extend Validation library and write your own rule. Look example how to do this.
In your validation rules add:
$this->form_validation->set_rules('hostingRequired','Hosting Required','required|callback__check_select_yes_or_no');
$this->form_validation->set_rules('domainRequired','Domain registration','required|callback__check_select_yes_or_no');
Also, add this additional method to your controller as a validation rule callback:
function _check_select_yes_or_no($str)
{
if ($str != 'yes' && $str != 'no')
{
$this->form_validation->set_message('_check_select_yes_or_no', 'Please select yes or no for the %s field');
return FALSE;
}
else
{
return TRUE;
}
}
This will work for 'Yes' or 'No' options - if you would like to add more adjust the callback, or invert the check to fail if the user selects 'Please select'.
Alternatively, a better way to do this may be to use radio buttons for 'Yes' and 'No' and not have one 'checked' when the form loads.
<fieldset><legend> Hosting required:</legend>
<label><input type="radio" name="hostingRequired" value="yes">Yes</label><br />
<label><input type="radio" name="hostingRequired" value="no">No</label>
</fieldset>
The correct way of doin this is as follows:
first you set the value of the default option to empty
second you use a simple validation rule
So here goes the code
<label for="hostingRequired">Hosting Required:</label>
<select name="hostingRequired">
<option value=""> Please Select</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
<label for="domainRequired">Domain Registration: </label>
<select name="domainRequired">
<option value="">Please Select</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
<div id="domainToBeReged">
<label for="domainToBeReged">Domain:</label><input name="domainToBeReged" type="text" placeholder="http://www." />
<label for="domainToBeReged0">Domain:</label><input name="domainToBeReged0" type="text" placeholder="http://www." />
</div>
.
$this->form_validation->set_rules('hostingRequired','HostingRequired','required');
$this->form_validation->set_rules('domainRequired','DomainRequired','required');