Select input with 2 empty option values - laravel-5

In my laravel 5.7/mysql 5 app I have boolean is_quiz field in my vote Table and in model I define:
protected $casts = [
'is_quiz' => 'boolean',
];
...
And array with possible values/keys for using of this fields
private static $voteIsQuizLabelValueArray = Array(1 => 'Is Quiz', 0 => 'Is Not Quiz');
in control I add empty value for empty selector:
$viewParamsArray['voteIsQuizValueArray'] = $this->SetArrayHeader(['' => ' -Select Is Quiz- '], Vote::getVoteIsQuizValueArray(false));
and this array has values:
$viewParamsArray['voteIsQuizValueArray']::Array
(
[] => -Select Is Quiz-
[1] => Is Quiz
[0] => Is Not Quiz
)
In my form this array as :
{{ Form::select('is_quiz', $voteIsQuizValueArray, isset($vote->is_quiz) ? $vote->is_quiz : '', [ "id"=>"is_quiz", "class"=>"form-control editable_field select_input " ] ) }}
and in rendered html-source I see 2 options selected :
<select id="is_quiz" class="form-control editable_field select_input valid" name="is_quiz" aria-invalid="false" aria-describedby="is_quiz-error"><option value="" selected="selected"> -Select Is Quiz- </option><option value="1">Is Quiz</option><option value="0" selected="">Is Not Quiz</option></select>
and validator.w3.org raised error here.
I see what is the reson of the syntax error, but I do not know is there is easy way to fix it ?
Thanks!

Form builder is deprecated since Laravel 5
Why are Form and HTML helpers deprecated in Laravel 5.x?
As one of options you can try use Laravel Collective
https://packagist.org/packages/laravelcollective/html
But IMO the best decision is to build select via blade:
<select id="is_quiz"
class="form-control editable_field select_input valid"
name="is_quiz"
aria-invalid="false"
aria-describedby="is_quiz-error"
>
#foreach ($voteIsQuizValueArray as $k => $v)
<option
value="{{ $k }}"
#if( $k === old('is_quiz', '') ) selected="selected" #endif
>{{ $v }}</option>
#endforeach
</select>

Related

How do I create insert related field value from id [Laravel]

First of all sorry if my title question doesn't make sense, since I don't know how to word my problem and my English not that great. Okay, so
I have my controller
Buy::create([
'master_item_id' => $request->master_item_id,
'quantity_item' => $request->quantity_item,
'price' => $request->price
]);
I have my view
<select id="master_item_id" name="master_item_id"
class="form-control #error('master_item_id') is-invalid #enderror">
<option></option>
#foreach($item as $value)
<option {{ old('master_item_id') ? 'selected' : '' }} value="{{ $value->id }}">
{{ $value->name_item }} |
Rp {{ number_format($value->price, 0, ',', '.')}}
</option>
#endforeach
</select>
How do I create insert 'price' from one form select above? I'm guessing you use where() or maybe find()? I've been flipping through website searching and couldn't find anything. Thanks!
Using the model called MasterItem, this could work:
Buy::create([
'master_item_id' => $request->master_item_id,
'quantity_item' => $request->quantity_item,
'price' => MasterItem::find($request->master_item_id)->price
]);
This does assume that master_item_id in your request represents the id or primary key of the MasterItem model.
If not, and you cannot use find() then this would also work:
Buy::create([
'master_item_id' => $request->master_item_id,
'quantity_item' => $request->quantity_item,
'price' => MasterItem::firstWhere('whatever_the_column_is_called', $request->master_item_id)->price
]);

Laravel Trying to access array offset on value of type null

Trying to access array offset on the value of type null in the controller
foreach ($request->product_item_list as $xx)
echo $request->hidden_name_[$xx] . ' ' . $request->product_unit_price_[$xx] . ' ' . $request
->quantity_list_[$xx] . ' ' . $request->hidden_barcode_[$xx];
where The dd($request->product_item_list) like
array:1 [▼
0 => "13"
]
How can I fix the problem?
PHP version 7.4.6
dd($request->all()) looks like
array:14 [▼
"_token" => "JuFDWGzK10dV00cwMaqgX4I9R7tbVLErJ11vxjYv"
"category_salesCoffee" => "6"
"hidden_name_12" => "alto"
"quantity_list_12" => null
"hidden_barcode_12" => "11120"
"product_unit_price_12" => null
"hidden_cost_12" => "14"
"product_item_list" => array:1 [▼
0 => "13"
]
"hidden_name_13" => "black"
"quantity_list_13" => "1"
"hidden_barcode_13" => "11130"
"product_unit_price_13" => "33"
"hidden_cost_13" => "14"
"product_count" => "2"
]
blade.php
#foreach ($products as $item)
<tr>
<td scope="row">{{ $item->id }}</td>
<td>
<input type="checkbox" name="product_item_list[]" id="product_item_list[]" value="{{$item->id}}" {{$item->quantity == 0 ? 'disabled' : ''}}>
</td>
<td id="product_name">{{$item->name}}</td>
<input type="hidden" name="hidden_name_{{ $item->id }}" id="hidden_name_{{ $item->id }}" value="{{$item->name}}">
<td>
<input type="number" name="quantity_list_{{ $item->id }}" id="quantity_list_{{ $item->id }}" min="{{$item->quantity == 0 ? 0: 1}}" max="{{$item->quantity}}" onkeypress="return false" {{$item->quantity == 0 ? 'disabled' : ''}}>
</td>
<td>{{ $item->barcode }}
</td>
<input type="hidden" name="hidden_barcode_{{ $item->id }}" id="hidden_barcode_{{ $item->id }}" value="{{ $item->barcode }}">
<td>
<input type="text" name="product_unit_price_{{ $item->id }}" id="product_unit_price_{{ $item->id }}" {{$item->quantity == 0 ? 'disabled' : ''}}>
</td>
<td>
<input type="hidden" name="hidden_cost_{{ $item->id }}" id="hidden_cost_{{ $item->id }}" value="{{ $item->cost }}">
</td>
</tr>
#endforeach
Lets Understand the error first. It says that array offset has null value.
In the controller you are running a loop and adding value in the array and then you are passing the array to blade file and displaying its value via blade file.
You are getting this error because during the looping in controller atleast once No Value(or Null value) is getting stored in offset array and when that array is passed to blade file, Blade file is not able to find any value while displaying that given offset array and hence you are getting the given error.
Although error is shown by blade file but it is originating in the loop of that given offset array in the controller file.
For solution you need to find in which iteration null value is getting stored in offset array.
After that you need to check whether null value is possible at all or not(as per business logic of project) during the loop cycle.
If null value is not possible(as per business logic of project) then something is wrong with the logic of coding because of which null value is getting stored in array. and you need to fix that logic of loop in controller file to ensure that no null values are stored in array.
If business logic allows null value then you need to handle the array accordingly, first in controller file and then in blade file.
In blade file you can apply a 'IF' condition to check if offset array value is null or not and take preventive steps before displaying the value
You don't have arrays of inputs. You have individual inputs that just happen to have some type of identifier appended to their name. So there is no input named hidden_name_ which is what you are asking for from the Request.
You can try to just pull them by their actual name since they are not arrays:
$request->input('hidden_name_'. $xx)

BACKPACK Laravel manage extra columns in pivot table in a many-to-many relationship using Backpack CRUD

I'm using backpack for laravel and I'm trying to add/update some extra columns in a pivot table used in a many-to-many relationship.
Summarizing the context: I have a model Task, another model Machine and this intermediate pivot table machine_task containing the many-to-many relation between Task and Machine
In this machine_task there are machine_id, task_id and then boolean columns m (for 'monthly'), q (for 'quarterly'), b (for 'biannual') and y (for 'yearly').
This is what I have
In my Models/Task.php I've defined the m-2-m relationship
public function machines()
{
return $this->belongsToMany('App\Machine')->withPivot('m','q','b','y');
}
In /app/Http/Controllers/Admin/TaskCrudController.php I have the fields, the most relevant one being this
$this->crud->addField([ // n-n relationship
'label' => "Machines", // Table column heading
'type' => "select2_from_ajax_multiple_custom", // a customized field type modifying the standard select2_from_ajax_multiple type
'name' => 'machines', // the column that contains the ID of that connected entity
'entity' => 'machines', // the method that defines the relationship in your Model
'attribute' => "name", // foreign key attribute that is shown to user
'model' => "App\Models\Machine", // foreign key model
'data_source' => url("api/machines"), // url to controller search function (with /{id} should return model)
'placeholder' => "Select machine(s)",
'minimum_input_length' => 0,
'pivot' => true,
'dependencies' => ['building_id'], // this "Machines" field depends on another previous field value
]);
This works perfectly: When I create or update a Task, the AJAX call is made returning the right results, values are correctly added into the select2 input, and the pivot table machine_task is correctly filled and updated with task_id and machine_id when I click on the Save and back button.
But how to insert into the pivot table the extra values m,q,b,y alongside task_id and machine_id?
At the end of TaskCrudController.php I have
public function store(StoreRequest $request)
{
// your additional operations before save here
// What I should do here to get the pivot values into the request??????????????
$redirect_location = parent::storeCrud($request);
// your additional operations after save here
// use $this->data['entry'] or $this->crud->entry
return $redirect_location;
}
public function update(UpdateRequest $request)
{
// your additional operations before save here
// What I should do here to get the pivot values into the request??????????????
$redirect_location = parent::updateCrud($request);
// your additional operations after save here
// use $this->data['entry'] or $this->crud->entry
return $redirect_location;
}
In my modified version of select2_from_ajax_multiple I have added some rows with checkboxes for each of the options selected. Let's see in a screenshot for better understanding
select2_from_ajax_multiple_custom
In /vendor/backpack/crud/src/resources/views/fields/select2_from_ajax_multiple_custom.blade.php I initialize the values like this, and then I use jquery to update the rows synced with the select2 control, but I don't know how to associate the m,q,b,y checkboxes with each of the select2 selected options and to pass them to the request.
#if ($old_value)
#foreach ($old_value as $item)
#if (!is_object($item))
#php
$item = $connected_entity->find($item);
#endphp
#endif
<div id="div{{ $item->getKey() }}">
<span> {{ $item->getKey() }} {{ $item->{$field['attribute']} }} -- </span>
Monthly <input type="checkbox" id="m{{ $item->getKey() }}" name="m{{ $item->getKey() }}" value="1" #php if ($item->pivot['m'] == "1") echo "checked"; #endphp >
Quarterly <input type="checkbox" id="q{{ $item->getKey() }}" name="q{{ $item->getKey() }}" value="1" #php if ($item->pivot['q'] == "1") echo "checked"; #endphp>
Biannual <input type="checkbox" id="b{{ $item->getKey() }}" name="b{{ $item->getKey() }}" value="1" #php if ($item->pivot['b'] == "1") echo "checked"; #endphp>
Yearly <input type="checkbox" id="y{{ $item->getKey() }}" name="y{{ $item->getKey() }}"value="1" #php if ($item->pivot['y'] == "1") echo "checked"; #endphp> <br/>
#php
#endphp
</div>
#endforeach
#endif
Thank you very much in advance for your time and I hope you can help me! Kinda stuck with this!
I've been able to solve it, so I'll post the solution as it may be useful for others.
What I did,
In my TaskCrudController.php I added the underlying Task model
// add this to the use statements
use App\Models\Task;
then, also in TaskCrudController.php I made this
// Notice: You need to add this to "create" function as well, I'm just writing here the update function to keep it short.
public function update(UpdateRequest $request)
{
$redirect_location = parent::updateCrud($request);
foreach ($request->machines as $machine) {
$set= array('m'=>'0','t'=> '0', 's' => '0', 'a' => '0');
if (isset($request['m'])) in_array ($machine, $request['m']) ? $set['m'] = '1' : $set['m'] = '0';
if (isset($request['t'])) in_array ($machine, $request['t']) ? $set['q'] = '1' : $set['q'] = '0';
if (isset($request['s'])) in_array ($machine, $request['s']) ? $set['b'] = '1' : $set['b'] = '0';
if (isset($request['a'])) in_array ($machine, $request['a']) ? $set['y'] = '1' : $set['y'] = '0';
Task::find($request->id)->machines()->syncWithoutDetaching([$machine => $set]);
return $redirect_location;
}
// Code explanation:
// what we are doing basically here is to grab the $request data
// For example: In the $request we receive m[3] b[1,3] y[1] arrays
// meaning that for our task:
// Machine 1 has no monthly, no quarterly but biannual and yearly checkboxes checked
// Machine 3 has monthly, no quarterly, biannual and no yearly checkboxes checked
// with the loop above, we cast that incoming data into this structure
// $set would contain after the loop:
// '1' => ['m' => '0', 'q'=> '0', 'b' => '1', 'y' => '1']
// '3' => ['m' => '1', 'q'=> '0', 'b' => '1', 'y' => '0']
// with that, we updated the intermediate table using syncWithoutDetaching
Now let's see select2_from_ajax_multiple_custom.blade.php although I'm not posting all code (the rest is the same as select2_from_ajax_multiple standard field)
<div #include('crud::inc.field_wrapper_attributes') >
<label>{!! $field['label'] !!}</label>
#include('crud::inc.field_translatable_icon')
<select
name="{{ $field['name'] }}[]"
style="width: 100%"
id="select2_ajax_multiple_custom_{{ $field['name'] }}"
#include('crud::inc.field_attributes', ['default_class' => 'form-control'])
multiple>
#if ($old_value)
#foreach ($old_value as $item)
#if (!is_object($item))
#php
$item = $connected_entity->find($item);
#endphp
#endif
<option value="{{ $item->getKey() }}" selected>
{{ $item->{$field['attribute']} }}
</option>
#endforeach
#endif
</select>
// What I added is:
<div id="freq">
#if ($old_value)
#foreach ($old_value as $item)
#if (!is_object($item))
#php
$item = $connected_entity->find($item);
#endphp
#endif
<div id="div{{ $item->getKey() }}">
<span>{{ $item->{$field['attribute']} }} -- </span>
Monthly <input type="checkbox" id="m{{ $item->getKey() }}" name="m[]" value="{{ $item->getKey() }}" #php if ($item->pivot['m'] == "1") echo "checked"; #endphp >
Quarterly <input type="checkbox" id="q{{ $item->getKey() }}" name="q[]" value="{{ $item->getKey() }}" #php if ($item->pivot['q'] == "1") echo "checked"; #endphp>
Biannual <input type="checkbox" id="b{{ $item->getKey() }}" name="b[]" value="{{ $item->getKey() }}" #php if ($item->pivot['b'] == "1") echo "checked"; #endphp>
Yearly <input type="checkbox" id="y{{ $item->getKey() }}" name="y[]"value="{{ $item->getKey() }}" #php if ($item->pivot['y'] == "1") echo "checked"; #endphp> <br/>
</div>
#endforeach
#endif
</div>
// js code to add or remove rows containing the checkboxes (This needs to be put inside <script> tags obviously) $("#select2_ajax_multiple_custom_machines").on("select2:select", function(e) {
// add checkbox row
htmlRow = "<div id=\"div"+e.params.data.id+"\">"+"<span> "+e.params.data.text+"-- </span>"+" Monthly <input type=\"checkbox\" id=\"m"+e.params.data.id+"\" name=\"m[]\" value=\""+e.params.data.id+"\">";
htmlRow += " Quarterly <input type=\"checkbox\" id=\"q"+e.params.data.id+"\" name=\"q[]\" value=\""+e.params.data.id+"\">";
htmlRow += " Biannual <input type=\"checkbox\" id=\"b"+e.params.data.id+"\" name=\"b[]\" value=\""+e.params.data.id+"\">";
htmlRow += " Yearly <input type=\"checkbox\" id=\"y"+e.params.data.id+"\" name=\"y[]\" value=\""+e.params.data.id+"\"><br/>";
htmlRow += "</div>";
$("#freq").append(htmlRow);
});
$("#select2_ajax_multiple_custom_machines").on("select2:unselect", function(e) {
// remove checkbox row
$("#div"+e.params.data.id).remove();
});
And that's all, folks.
Hope it helps.

Laravel blade form select statement has index for value

Having searched and tried to resolve this I can't seem to work it out.
I have a simple static method in a class that returns a list of options. I am using this to populate a select element in a form. This works fine but I'm using the Laravel blade shortcut language and the value of each option is coming out as the index of the array, which is sent to the database when persisting the results of the form:
{!! Form::select('type', \App\Http\Utilities\Airporttype::all(), null, ['class' => 'form-control'] ) !!}
HTML produced:
<select class="form-control" id="type" name="type">
<option value="0">Commercial</option>
<option value="1" selected="selected">Military</option>
<option value="2">Galactic</option><option value="3">Private</option>
</select>
Static method called:
class Airporttype
{
protected static $types = [
"Commercial",
"Military",
"Galactic",
"Private",
];
public static function all()
{
return static::$types;
}
}
By using the 'null' option, it will give me the option = selected if the database matches what is already saved for that record.
I can achieve it buy doing the following, but wanted to use the blade shortcode style as it's clean (below is what I have tested elsewhere in te form and works):
<select id="country" name="country" class="form-control">
#foreach (\App\Http\Utilities\Country::all() as $country => $code)
<option value="{{ $country }}" #if ($country == $airport->country) selected = 'selected' #endif>{{ $country }}</option>
#endforeach
</select>
Array dump of Aiporttype::all();
array (size=4)
0 => string 'Commercial' (length=10)
1 => string 'Military' (length=8)
2 => string 'Galactic' (length=8)
3 => string 'Private' (length=7)
Thanks
If I've understood you correctly, you need something like this:
{!! Form::select('type', \App\Http\Utilities\Airporttype::all(), $airport->country, ['class' => 'form-control'] ) !!}
UPDATE:
If you have types in strings, you can try to change your array to:
protected static $types = [
'commercial => 'Commercial',
'military' => 'Military',
'galactic' => 'Galactic',
'private' => 'Private',
];
To get an array indexed by its values you can try something like this
$types = \App\Http\Utilities\Airporttype::all();
$types = array_combine($types, $types);
-- view --
{!! Form::select('type', $types, null, ['class' => 'form-control'] ) !!}
Working Fine for me...
In controller
View::share('types',\App\Http\Utilities\Airporttype::all());
In View
{!! Form::select('types',array(''=>'- Select types -')+$types,Input::get('types',null),array('class'=>'form-control')) !!}
You can use array_flip function in php:
{!! Form::select('type', array_flip(\App\Http\Utilities\Airporttype::all()), $airport->country, ['class' => 'form-control'] ) !!}
Simple elegant function!

How to disable an option from select laravel blade template

I'm passing this array to a blade view:
$data['publish'] = [
null => '- Select Ad Type -',
1 => 'Featured Ad',
2 => 'Normal Ad'
];
Within the view I'm creating a select input like this:
{{ Form::select('publish', $publish, null, array('class'=>'span10 m-wrap')) }}
How can I disable one option, for example Featured Ad?
You can't using the Form::select helper because the options use the 'value' => 'name' format for each array item, so there's no way to specify the additional disabled attribute. You just have to build the select manually using a #foreach loop and add the disabled attribute using a condition:
<select name="publish" class="span10 m-wrap">
#foreach ($publish as $value => $name)
<option value="{{ $value }}"
#if ($name == 'Featured Ad')
disabled
#endif
>
{{ $name }}
</option>
#endforeach
</select>
As an alternative you could create your custom Form::macro that uses some other parameters that allows disabling individual options, but it seem too much of a hassle unless you need to use this in a lot of places.

Resources