Laravel validation for a numeric array of HTML Select input - php

In Laravel, its easy to validate numeric inputs-
$rules = array('numericInput' => 'numeric');
But not sure, how to validate a numeric array. What can be the rule for that. Or is it even possible by Laravel's Validator class?
For e.g-
This HTML form submits multiple Select item to a laravel service
<form .....>
<select multiple="multiple" name="objectIdArr[]" >
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</form>
What Laravel gets-
( [input] => Array ( [objectIdArr] => Array ( [0] => 1 [1] => 3 [2] => 5 ))
what can be the rule!
Please suggest

Laravel 3.x's validator doesn't handle arrays unfortunately as it expects each unique name to be a string.
You could however extend the validator class as a library (follow the docs for a decent example) and allow your extended class to recieve an array that then is broken out into strings and validated, if any of the strings fail validation the validator returns a failure with your custom message.

Related

How can I get only specific elements of an entity with Symfony formbuilder?

In my formbuilder I create a select box from an entity:
$options['choice_label'] = function ( $entity) use ($name) {
if( $entity->getCategory() == null) {
return $entity->getName();
}
};
In the case the Category is NULL, I want to get an option field and if not I do not want an option field.
But what happens is, that in the case the category is not NULL, I get empty option fields, where I am actually do not need an option field at all.
What I get:
<select>
<option>value with category 1</option>
<option>value with category 2</option>
<option>value with category 3</option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
What I need:
<select>
<option>value with category 1</option>
<option>value with category 2</option>
<option>value with category 3</option>
</select>
I see two ways, which will solve your problem.
Use a entity type with a query builder, that passes the right options to your select
https://symfony.com/doc/current/reference/forms/types/entity.html
Use a choice type but write the choices to an array and pass it to your form item
Symfony2 Form Builder - creating an array of choices from a DB query
In case that the query builder throws a error like „could not converted into string“ you will have to define a string-representation for the related entity. You need the string, to tell the typeField which attribute should be displayed in the select.
Here goes the way to solve it for the entity type:
Add a simple choice label
$builder->add('users', EntityType::class, [
// looks for choices from this entity
'class' => User::class,
// select the property which should be used to represent your option in select
'choice_label' => 'username',
]);
Add a more specific choice label
$builder->add('category', EntityType::class, [
'class' => Category::class,
'choice_label' => function ($category) {
return $category->getDisplayName();
}
])
Ofc refering to the docs
https://symfony.com/doc/current/reference/forms/types/entity.html

Laravel ignores select input validation if no option is selected

I have a form with some fields which I want to validate using Laravel's validate() method.
public function postSomething(Request $req) {
...
$this->validate($req, [
'text_input' => 'required',
'select_input' => 'required'
]);
...
}
The issue is that if the form is submitted without selecting an option from the select input it is ignored in the request and Laravel doesn't validate it despite the fact that it is added to the ruleset with the required validation rule. Empty text inputs are being validated correctly.
+request: ParameterBag {#42 ▼
#parameters: array:1 [▼
"text_input" => ""
"_token" => "TCDqEi2dHVQfmc9HdNf8ju1ofdUQS6MtDBpUMkl7"
]
}
As you can see, the select_input is missing from request parameters if it was left empty.
Here is the HTML code for my select input:
<select class="form-control" name="select_input">
<option disabled selected>Please select...</option>
<option value="val1">Value 1</option>
<option value="val2">Value 2</option>
</select>
Is there a way to make the validation work for all fields from the ruleset even if some of them are not present in the request?
From Laravel 5.1 validation documentation:
required
The field under validation must be present in the input data and not empty. A field is considered "empty" is one of the following conditions are true:
The value is null.
The value is an empty string.
The value is an empty array or empty Countable object.
The value is an uploaded file with no path.
P.S. I'm using Laravel 5.1, so present method is not available.
Your html should look like this
<select class="form-control" name="select_input">
<option value="" selected >Please select...</option>
<option value="val1">Value 1</option>
<option value="val2">Value 2</option>
</select>
$this->validate($req, [
'text_input' => 'required',
'select_input' => 'required',
]);
If your select box values are integer then
you can use required with integer like
$this->validate($req, [
'text_input' => 'required',
'select_input' => 'required|integer',
]);
Or if you have limited options for that select box then you can use
'select_input' => "required|in:val1,val2,val3",
You made it's option disabled, so it won't send anything through your form.
Change your select box to
<select class="form-control" name="select_input">
<option value="">Please select...</option>
<option value="val1">Value 1</option>
<option value="val2">Value 2</option>
</select>
There are few options I can recommend:
Manually validate the request without using the validation extended in the Controller, I.e:
//validator FACADE
$ validator = Validator::make ($request->all(), [
// rules here
]);
By this you can monitor which fields are passed and which one are not passed.
Secondly, set a default value for the select list and check that value when you are validating in the Controller, that is, if you have this default value then nothing is selected. You definitely will have only the fields submitted in your Controller.

How to get value from select value in Laravel

i need to get the value from a select tag, but the problem is that i need to send the value to the route for example :
<select name="feeling">
<option value="0">Joyous</option>
<option value="1">Glad</option>
<option value="2">Ecstatic</option>
I neeed to send the value to a route like this:
retrieve_money/0/account
How can i get the value and send into another route
retrieve_money/{in this camp i need the value}/account
Thanks.
Try this:
You could accomplish this using JavaScript by making the following modifications
In View
<select onChange="newFunction(this)" name="feeling">
<option value="0">Joyous</option>
<option value="1">Glad</option>
<option value="2">Ecstatic</option>
In Script
function newFunction(newVal){
window.location.href = '/retrieve_money/'+newVal+'/account';
}
In Routes
Route::get('/retrieve_money/{selectVal}/account', ['uses' => 'DemoController#demoFunction');
Hope this would get you started.

Pre-selecting values in a multi-select drop-down list in laravel

I'm relatively new to Laravel (and using Laravel 4), but been around PHP and C# a long time. Seems like this should be easy, but I can't find anywhere that tells me how to do this.
In my Controller I get the data from the database and send it to the view like this:
$sections = DB::table('paperSections')->lists('section','id');
return View::make('layouts.publisher.step2', array('sections' => $sections));
in my View, I have the following:
{{ Form::select('sections[]', $sections, '', array('multiple')) }}
which generates a select list like this:
<select multiple="multiple" id="sections" name="sections">
<option value="1">News</option>
<option value="2">Sports</option>
<option value="3">Features</option>
<option value="4">Arts and Entertainment</option>
<option value="5">Technology and Science</option>
<option value="6">Op-Ed</option>
</select>
Lets assume I have a string (e.g. "1,3,5") which represents the multiple options selected previously. How can I re-select those three options using that string?
Pass array of selected options as 3rd param:
$selected = explode(',', $idsAsString);
Form::select('sections[]', $sections, $selected, ['multiple'])

Smarty: check if variable is in array

I'm using php with smarty. In php I have two arrays:
$code = Array
(
[n_id] => 1
[t_code] => ABC123
[t_description] => Test code
[b_enabled] => Yes
[n_type] => 3
[dt_start] =>
[dt_end] =>
[n_min_req_gbp] => 0
[n_min_req_usd] => 0
[n_amount_gbp] =>
[n_amount_usd] =>
[n_max_overall_gbp] =>
[n_max_overall_usd] =>
[n_extra] => 6
[b_reuse] => No
[n_applications] => Array
(
[0] => 2
)
)
and
$all_application = Array
(
[1] => New registration
[2] => Mid-subscription upgrade
[3] => Subscription renewal
[4] => Additional purchase
)
Note that the second array may - and will - grow, this is the reference data, from which n_applications array field in the first array is built. That is, the array in n_applications will contain a subset of keys from the $all_applications arrays.
Now, I'm assigning these two arrays into the template:
$template->assign('code', $code);
$template->assign('apps', $all_applications);
And in the template, I'm creating a form for editing the fields in the $code array. Everything is working fine except the 'applications' selection. I want to pre-select those apps that are already in the n_applications field. So, in my template I have this:
<select name="c_apps[]" size="3" class="multiselect" multiple="multiple">
{foreach from=$apps key=k item=a}
{assign var=v value=$k|#array_search:$code['n_applications']}
<option value="{$k}"{if $v!==FALSE} selected="selected"{/if}>{$a|escape}</option>
{/foreach}
</select>
However this doesn't work as expected - and ALL options end up being selected. I tried using in_array function - but with the same result. What's the best way to achieve what I'm after?
After a bit of struggling in all possible directions, I finally managed to pull it off like this (smarty code only)
<select name="c_apps[]" size="3" class="multiselect" multiple="multiple">
{foreach from=$apps key=k item=a}
{if #in_array($k, $code.n_applications)}
{assign var=v value=true}
{else}
{assign var=v value=false}
{/if}
<option value="{$k}"{if $v} selected="selected"{/if}>{$a|escape}</option>
{/foreach}
</select>
And this did the trick.
You can do it like this:
<select name="c_apps[]" size="3" class="multiselect" multiple="multiple">
{foreach from=$apps key=k item=a}
<option value="{$k}"{if in_array($k, $code.n_applications)} selected="selected"{/if}>{$a|escape}</option>
{/foreach}
</select>
I've done something similar a few years back, and stumbled over the same logical challenge.
My solution was to modify the base array (in your case, $all_applications) while adding another key there (maybe ['opt_selected']). I left the default value empty, and for the data I wanted to have selected, I've changed the value to, guess what, ... selected="selected".
This makes it rather easy for your Smarty template:
<option value="{$k}" {$a.opt_selected|default:''}>{$a|escape}</option>
It might not be the best solution, but it helps leaving alot of code out of the template where I usually don't want too much program logic.
Update
To counter having the HTML part in your php code, you might as well just flag the array:
$all_applications['opt_selected'] = 1
...and then arrange Smarty like this:
<option value="{$k}" {if $a.opt_selected eq '1'}selected="selected"{/if}>
{$a|escape}
</option>

Categories