Laravel input array why do I get null in $request->quantity - php

After searching similar questions I still didn't get the error
The thing is that I have a form that usually works, but the 10% of the users have this error
array_sum() expects parameter 1 to be array, null given
Form
<select name="quantity[]" class="form-control option-quantity" data-price="100">
<option data-price="100" value="0">0</option>
<option data-price="101" value="1" selected="selected">1</option>
<option data-price="102" value="2">2</option>
</select>
Controller
$validator = Validator::make($request->all(), [
'quantity.*' => 'required|integer',
]);
if ($validator->fails()) {
abort(500);
}
if(count($request->quantity) == 0 || array_sum($request->quantity) < 1)){
//message to select at least a quatity
}
They always put an amount because I did't restrictions, js to avoid nulls or 0 and from the server side not to allow 0
So, as it happens just sometimes, I'm wondering if some explorers do something weird changing the quantity[] to quantity or null or something, I'm driving a bit crazy here and I can't reproduce the error myself and it wouldn't be a good idea to wait the error to happen to a user (:
BTW of course I can add if($request->quantity) to avoid the error, but that not solves the question of why I get a null just sometimes, rest is fine.
As per suggestion after doing dd($request->quantity); I get:
array:1 [
0 => "1"
]
But again, for me its working good, not for the 10%.

You can simply avoid this error by checking quantity.It
if($request->quantity){
if(count($request->quantity) == 0 || array_sum($request->quantity) < 1)){
//message to select at least a quatity
}
}
It is throwing this error because $request->quantity is null;
Hope this helps

Since you have not tagged the version of Laravel, I'll make an assumption that you are using latest version.
why I get a null
Check your validation rule..
When a user submits the data with empty strings, Laravel makes it nullable. Checkout the middleware ConvertEmptyStringsToNull which is located inside Illuminate\Foundation\Http\Middleware folder.
So, if you want it to be always present at the time of submitting the user data, make it required like so.
return [
'quantity' => 'required',
// .. other validation rules..
];

Try removing "[]" from the name on the select, so you will have this:
<select name="quantity" class="form-control option-quantity" data-price="100">
<option data-price="100" value="0">0</option>
<option data-price="101" value="1" selected="selected">1</option>
<option data-price="102" value="2">2</option>
</select>

Related

laravelcollective: add extra attribute to each options(Form::Select)

<select class="form-control" id="user" name="car">
<option value="0" selected="selected">Select Cars</option>
<option dta-img='1.jpg' value="134">Volvo</option>
<option dta-img='2.jpg' value="135">Noah</option>
<option dta-img='3.jpg' value="136">Marcidis</option>
<option dta-img='4.jpg' value="143">London Express</option>
</select>
My array for options :
public function guardianList()
{
$list = ["Select Cars"];
foreach ($carss->all() as $car) {
$list[$car->id] = $car->name;
}
return $list;
}
Form::select('car',$list, null, null);
How can i add extra dynamic html attribute to all options?
I want to show image infront of every option in jquery select2. For that i need to send image from Form::Select(). I there any easy way to do that without using marcos?
Solved the issue:
Pass array in the 4th param.
$opt_attributes = collect($guardians->all())
->mapWithKeys(function ($item) {
return [$item->id => ['data-img' => $item->photos->last()->name]];
})->all();
make a array linke this and pass it as 4th parameter.
I don't know exactly since which version, but laravelcollective/html 5.8 version takes optionParameters as fifth parameter, not 4th

How to make Request default in Laravel 5.1 when none is given

I am using Laravel 5.1 and I need to make a default value when in field is none given.
So the view looks like:
<form name="search" method="POST" action="/s">
Country<input name="country" type="text">
Field<input name="field" type="text">
<button type="submit" type="button">Search</button>
<input name="_token" value="{{ csrf_token() }}" type="hidden">
</form>
The controller looks like:
public function extendedPost(Request $request){
$data = $request->all();
$request->input('field', 'Random');
dd($data);
}
In Laravel 5.1 Documentation we have:
You may pass a default value as the second argument to the input
method. This value will be returned if the requested input value is
not present on the request:
$name = $request->input('name', 'Sally');
So when I have something in "Field" I have:
array:21 [▼
"country" => ""
"field" => "dddd"
"_token" => "XeMi"
]
But when the "Field" is empty I have
array:21 [▼
"country" => ""
"field" => ""
"_token" => "XeMi"
]
Instead of
array:21 [▼
"country" => ""
"field" => "Random"
"_token" => "XeMi"
Thanks for helping me
Very late answer here, but hopefully still useful clarification.
You may pass a default value as the second argument to the input
method. This value will be returned if the requested input value is
not present on the request:
This means the second argument will be used if the input isn't present. But if this comes from an optional field in a form, then the input IS present - with the value of an empty string.
That means that
$name = $request->input('name', 'Sally');
Will return "Sally" when there is no name field submitted by the form, but will return "" if the user leaves the name field blank.
If we want the value of 'Sally' when the field was blank, we can do as Zakaria suggests and use:
if( $request->has('field')) {
$request->field = 'Random';
}
... but that will very quickly become messy if you have a lot of fields that all need to be checked.
Another option is to use the ternary operator. Something like:
$yourValue = $request->has('field') ? $request->input('field') : 'Random';
$yourValue2 = $request->has('country') ? $request->input('country') : 'Australia';
It's a mouthful, but allows you to write each value out on its own line.
Your $request variable still won't show these fields. If you are planning to check for the field multiple times, then you can either assign a value to $request like in Zakaria's answer, or you can set it in a variable that you will check.
In many cases, you want to assign the input to something, in which case you can use the ternary operator directly when you're assigning it.
For example, if we're setting the country field for the current user, we might use:
$user->country = $request->has('country') ? $request->input('country') : 'Unspecified';
Often, it's easier to bypass the problem. Some other options might be:
When using an optional select dropdown, you can set the "empty" default value to have a value when it's submitted. For example, in a country dropdown you might start with:
<select name="country">
<option value="unspecified" selected="selected></option>
<option>Australia</option>
<option>Brazil</option>
<option>Canada</option>
</select>
Set fields as required in the form. And verify that a value was submitted using request validation.
$this->validate(request(), [
'field' => 'required',
'country' => 'required:min:3',
]);
That will return to the form with an $errors collection that can be used to display a message to the user. Put this first, and by the time you need to use the input, the validation has already checked that they submitted something.
The function input not updating the $request it will just check if the given attribute is not present in Request if so it will return default value passed in second argument, try to use has() to check if the attribute is present in request and then update the request manually :
if( $request->has('field')) {
$request->field = 'Random';
}
Note : The has method returns true if the value is present and is not an empty string.
Hope this helps.
In my case, request()->country = 'default' or $request->country = 'default'; does not work as validation rule still throws out error for the missing field. But $request['country'] = 'default' does the trick.

Input validation exclusive or

I have a model called Answer.
This model has two possible relations. A Question or a Product.
But, Answer should only ever have one relation. Either Question or Product.
There is a form to create answers.
This form has three inputs. two of them are <select> inputs. The other is a text input, called name.
I want my validation to only allow one to be filled out.
My current validation:
$validator = Validator::make(
Input::all(),
array('name' => array('required'))
);
$validator->sometimes('product', array('required', 'numeric'), function ($input) {
return !is_numeric($input->question);
});
$validator->sometimes('question', array('required', 'numeric'), function ($input) {
return !is_numeric($input->product);
});
Requires at least one of the selected to be filled out, but will also allow two.
So, my question is: How can I change my validation to only allow one of the selects to be filled out.
But one of them must always be filled out.
Select 1:
<select name="question" class="form-control">
<option>None</option>
<option value="1" selected="selected">Question 1</option>
<option value="2">Question 2</option>
</select>
Select 2:
<select name="product" class="form-control">
<option>None</option>
<option value="2" selected="selected">Product 1</option>
<option value="3">Product 2</option>
</select>
#Razor's custom XOR validation rule is pretty nice, but there's another route if you don't want to create a custom rule. You can add values to Input representing your constraints, using Input::merge, then use those for validation:
Input::merge(array(
'hasBoth' => Input::has('product') && Input::has('question'),
'hasNeither' => !Input::has('product') && !Input::has('question')
));
$validator = Validator::make(
Input::all(), array(
'name' => 'required',
'hasNeither' => 'size:0',
'hasBoth' => 'size:0',
), array(
'hasNeither.size' => 'A question or a product is required.',
'hasBoth.size' => 'You cannot choose both a question and a product.'
)
);
You should still change the empty value in your form to <option value=''>None</option>.
Unlike using an XOR comparison, this method allows you to return separate error messages for no values vs. two values without any further error checking.
First off. You must specify an empty value in "None" option:
<option value=''>None</option>
You are looking for XOR operator, you need to create a custom validation rule in this case:
Validator::extendImplicit('xor', function($attribute, $value, $parameters)
{
if( $value XOR app('request')->get($parameters[0]))
return true;
return false;
});
Validator::replacer('xor', function($message, $attribute, $rule, $parameters)
{
// add indefinite articles
$IAattribute = (stristr('aeiou', $attribute[0]) ? 'an ' : 'a ') . $attribute;
$parameters[0] = (stristr('aeiou', $parameters[0][0]) ? 'an ' : 'a ') . $parameters[0];
if(app('request')->get($attribute))
return 'You cannot choose both '.$IAattribute.' and '.$parameters[0].'.';
return $IAattribute.' or '.$parameters[0].' is required.';
});
$validator = Validator::make(
app('request')->all(),
array('name' => array('required')
,'product' => array('xor:question')
));
The required_without validation rule might be what you want:
The field under validation must be present only when any of the other
specified fields are not present.
Set the question field to required_without:product and the product field to required_without:question.
Answers are a little old now. Today laravel brings some prohibition-rules which will resolve your problems without any hacks.
For your validation that means:
return [
'question' => 'nullable|required_without:product',
'product' => ['nullable',
Rule::prohibitedIf(fn() => $this->question != '')]
Both selects need an item with empty-value, with a text/label you like. Like this:
<select>
<option value="">Foo</option>
</select>
Like this one of the both always need to be set. But its not possible that both are set.
See here: https://laravel.com/docs/9.x/validation#rule-prohibited

CakePhp: Dropdowns repeating options

I'm using CakePHP 2.1.1, and upgraded to 2.2.0 and the issue exists in both. I am using the FormHelper to generate a Select dropdown with the options defined in an array. When it generates the options, it repeats some of them. Which ones and how many repeat changes depending on which record I am editing.
Using the following code in my view:
debug($advisors);
echo $this->Form->input('advisor',array('options'=>$advisors));
I see:
/app/View/Students/edit.ctp (line 38)
array(
'K-1' => 'K-1',
'K-2' => 'K-2',
'2-3' => '2-3',
'3-5n' => '3-5n',
'3-5s' => '3-5s',
'4-5' => '4-5',
'6-8' => '6-8'
)
and then a dropdown with the following options:
<option selected="selected" value="K-1">K-1</option>
<option value="K-2">K-2</option>
<option value="2-3">2-3</option>
<option value="3-5n">3-5n</option>
<option value="3-5s">3-5s</option>
<option value="4-5">4-5</option>
<option value="6-8">6-8</option>
<option value="K-1">K-1</option>
<option value="K-2">K-2</option>
<option value="2-3">2-3</option>
What else should I be checking?
Ok, never mind. It was a javascript function I wrote a while back that was messing with the generated options.

How to set any attribute of Select lke disabled='disabled' by using ViewHelper in Zend Framework

I am using Zend Frameworks ViewHelpers.
I am trying to pass something to set disabled attribute in SELECT. For example if
$countries = array(1=>'Select Option', 2=>'us', 3=>'uk')
and
formSelect('country','us',null,$this->countries)
I need to diable first option i.e. 'Select Option'
Do you have any idea ?
Thanks in addvance
I don't think you can disable one element? If you disable it then why have it at all?
You can only disable the whole <select> input.
Suggest you write validation to not accept the first element.
Edit after OP's comment about being able to do this
Here is another answer
// Get the countries element (do this after adding your options), then set the
// attribute disable for option '1'
$form->getElement("countries")->setAttrib("disable", array(1));
This is suggested here
There IS a way of doing it through Zend_Form (at least on my current ve 1.11):
$this->addElement
(
"select","selectName",
array("multiOptions"=>array("one","two","three"), "disable"=>array(0,1))
);
That one will disable first two options.
Credit goes to jakenoble.
Just reformatted the code to use the formSelect-viewhelper instead of a form-element.
<?php
$countries = array(1 => 'Select Option', 2 => 'us', 3 =>'uk');
echo $this->formSelect('country', 2, array('disable' => array(1)), $countries)
This will result in:
<select name="country" id="country">
<option value="1" label="Select Option" disabled="disabled">Select Option</option>
<option value="2" label="us" selected="selected">us</option>
<option value="3" label="uk">uk</option>
</select>

Categories