Livewire - Multiple root elements detected - laravel

I'm creating a table, whose rows are wrapped inside a livewire component
<div class="card">
<div class="card-body">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>Nombre del Riesgo</th>
<th>Información</th>
<th>Dueño del Riesgo</th>
<th>Costo Adicional</th>
<th>Prevención</th>
</tr>
</thead>
<tbody>
<div>
#foreach($risks as $risk)
<livewire:risk-row :risk="$risk"/>
#endforeach
</div>
</tbody>
</table>
</div>
</div>
But in the row component, whenever I change an input, or select something from a dropdown select, the component is not re rendering.
I was wondering why this could be happening. So I opened my console and saw:
Livewire: Multiple root elements detected. This is not supported. See docs for more information https://laravel-livewire.com/docs/2.x/troubleshooting#root-element-issues <div wire:id=​"6CNMP1hiBR3Qy7IbmfbQ">​ ​</div>​
value # index.js:85
Component # index.js:27
(anonymous) # index.js:88
value # index.js:87
(anonymous) # schedule:432
Here's the component blade file
<div>
<tr>
<td>{{ $risk['name'] }}</td>
<td>
<div><strong>Proceso: </strong>{{ $risk['process']['name'] }}</div>
<div><strong>Frecuencia: <span class="badge badge-secondary text-sm">{{ $risk['frequency_label'] }}</span></strong></div>
<div><strong>Impacto: </strong><span class="badge badge-info text-sm">{{ $risk['impact_label'] }}</span></div>
<div><strong>Riesgo: </strong><span class="badge badge-{{ $risk['risk_color'] }} text-sm">{{ $risk['risk_label'] }}</span></div>
</td>
<td>
<select name="owner" id="owner" class="form-control" wire:change="test">
#foreach(App\Models\Risk::OWNERS as $owner)
<option value="{{ $owner['id'] }}">{{ $owner['name'] }}</option>
#endforeach
</select>
{{ $owner_id }}
</td>
<td>
<select name="owner" id="owner" class="form-control">
#foreach(App\Models\Risk::COSTS as $cost)
<option value="{{ $cost['id'] }}">{{ $cost['name'] }}</option>
#endforeach
</select>
</td>
<td>
<select name="owner" id="owner" class="form-control">
#foreach(App\Models\Risk::PREVENTIONS as $prevention)
<option value="{{ $prevention['id'] }}">{{ $prevention['name'] }}</option>
#endforeach
</select>
</td>
</tr>
</div>
Is there any workaround for this?

When using livewire inside a foreach, you need to add a key.
<tbody>
#foreach ($risks as $risk)
<livewire:risk-row :risk="$risk" :wire:key="$loop->index">
#endforeach
</tbody>
Also, you could use the <tr> as the root element and avoid having <div> inside the <tbody>.
Finally, you're using a lot of id and name attributes that repeat over and over. You should not have duplicate ids. As for the name attributes, you can use the array notation.
<tr>
<td>{{ $risk['name'] }}</td>
<td>
<div><strong>Proceso: </strong>{{ $risk['process']['name'] }}</div>
<div><strong>Frecuencia: <span class="badge badge-secondary text-sm">{{ $risk['frequency_label'] }}</span></strong></div>
<div><strong>Impacto: </strong><span class="badge badge-info text-sm">{{ $risk['impact_label'] }}</span></div>
<div><strong>Riesgo: </strong><span class="badge badge-{{ $risk['risk_color'] }} text-sm">{{ $risk['risk_label'] }}</span></div>
</td>
<td>
<select name="owner[]" class="form-control" wire:change="test">
#foreach(App\Models\Risk::OWNERS as $owner)
<option value="{{ $owner['id'] }}">{{ $owner['name'] }}</option>
#endforeach
</select>
{{ $owner_id }}
</td>
<td>
<select name="cost[]" class="form-control">
#foreach(App\Models\Risk::COSTS as $cost)
<option value="{{ $cost['id'] }}">{{ $cost['name'] }}</option>
#endforeach
</select>
</td>
<td>
<select name="prevention[]" class="form-control">
#foreach(App\Models\Risk::PREVENTIONS as $prevention)
<option value="{{ $prevention['id'] }}">{{ $prevention['name'] }}</option>
#endforeach
</select>
</td>
</tr>

Related

separate each value with comma from multiple select in laravel

I make task manager there is a form where to assign task I want to do that if user select multiple option then it is seperated by comma
This is my form
<form method="post" action="{{route('assignments.store')}}">
#csrf
<table>
<tr>
<td>Task Title : </td>
<td>
<select name="task_id" id="task_id">
#foreach ($tasks as $task)
<option value="{{ $task->id }}">{{ $task->title }}</option>
#endforeach
</select>
</td>
</tr>
<tr>
<td>Staff Name : </td>
<td>
<select name="staff_id" multiple>
<option value=null>Select One</option>
#foreach ($staffs as $staff)
<option value="{{ $staff->id }}">{{ $staff->name }}</option>
#endforeach
</select>
</td>
</tr>
<tr>
<td>Done At :</td>
<td><input type="time" name="done_at" class="form-control"></td>
</tr>
<td><button class="btn btn-primary" name="submit" type="submit" value="submit">Submit</button></td>
</table>
</form>
And this is my store function from where I storing the data recieved from form
$request->validate([
'staff_id' => 'required',
'task_id' => 'required',
'done_at' => 'sometimes',
]);
$assignment = new Assignment();
$assignment->staff_id = $request->staff_id;
$assignment->task_id = $request->task_id;
$assignment->done_at = $request->done_at;
$assignment->save();
return redirect()->route('assignments.index', compact('assignment'))->withSuccess('Done');
try this,
change the name=staff_id[]
<select id="staff" name="staff_id[]" multiple="multiple">
---
</select>
you can check the by
dd(implode(',', $request->staff_id));
$assignment = new Assignment();
$assignment->staff_id = implode(',', $request->staff_id);
And ya one more thing I forgot to tell you in your database I think staff_id is f.k so it will allow one id at the item to store so what you have to do CHANGE staff_id with type varchar then it will allow to store value with comma separate.
And below is the image form implode we are converting an array to string
Please set select name = staff_id[] then only you will get multiple data

How to use old() helper in input fields of Laravel blade

In my Laravel-5.8 project I am working on a leave application that will iterate with employee_type. The fields in the view blade are array elements. The code is as shown below:
#foreach ($employeetypes as $key=> $employeetype)
<tr>
<td width="5%">
{{$key+1}}
</td>
<td width="30%">
<span>{{$employeetype->employee_type_name}}</span>
</td>
<td width="20%"><input type="number" name="no_of_days[]" placeholder="Enter leave days here" class="form-control no_of_days" max="120">
</td>
<td width="15%">
<select class="form-control select2bs4" data-placeholder="Select Applicable Gender" tabindex="1" name="leave_applicable_gender[]">
<option value="0" selected="true" disabled="true">Select Applicable Gender</option>
#foreach(AppHelper::LEAVE_APPLICABLE_GENDER as $key1 => $value)
<option value="{{ $key1 }}" {{ (($applicableGender == $key1) || (is_null($applicableGender) && $key1 == 1)) ? 'selected' : '' }}>
{{ $value }}
</option>
#endforeach
</select>
</td>
<td width="10%"><input type="checkbox" name="weekend_inclusive{{$key}}" class="form-control" unchecked data-bootstrap-switch data-off-color="danger" data-on-color="success" data-off-text="NO" data-on-text="YES">
</td>
#endforeach
Everything submits to the database successfully.
Since all are array fields, how do I add old() helper to each of the input fields (number, dropdown and checkbox)?
Thank you

How to get Laravel Blade value as an Array data using Post Method?

I Have a Blade Form that will execute Post Method, this is my blade
#foreach ($dataku as $row => $order)
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-12 text-center">
<b>{{ $order->delivery_order_no }}</b>
<input type="hidden" name="order[{{ $row }}][do_id]" value="{{ $order->id }}">
<input type="hidden" name="order[{{ $row }}][so_id]" value="{{ $order->sales_order->id }}">
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="table-responsive m-t-40" style="clear:both;">
<table class="table table-hover" style="font-size: 9pt;">
<thead>
<tr><th class="text-center">No</th>
<th class="text-center">SKUID</th>
<th class="text-center">Item Name</th>
<th class="text-center">UOM</th>
<th class="text-center">Qty So</th>
<th class="text-center">Qty Do</th>
<th class="text-center">Qty Confirm</th>
<th class="text-center">Qty Minus</th>
<th class="text-center">Remark Confirm</th>
</tr>
</thead>
<tbody>
#foreach ($order->delivery_order_details as $do =>$detOrder )
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $detOrder->skuid }}</td>
<td>{{ $detOrder->sales_order_detail->item_name }}</td>
<td>{{ $detOrder->uom->name }}</td>
<td>{{ $detOrder->sales_order_detail->qty }}</td>
<td>{{ $detOrder->qty_do }}</td>
<td>
<input type="hidden" class="form-control" name="order[{{ $row }}][detail[][{{ $do }}][skuid]]" value="{{ $detOrder->skuid}}">
<input type="number" class="form-control" name="order[{{ $row }}][detail[][{{ $do }}][qty_do]]" value="{{ $detOrder->qty_do }}">
</td>
<td>
<input type="number" min="0" class="form-control" name="order[{{ $row }}][detail[][{{ $do }}][qty_minus]]" value="0">
</td>
<td>
<input type="text" placeholder="Remark Confirm" class="form-control" name="order[{{ $row }}][detail[][{{ $do }}][remarks]]">
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
#endforeach
I Just want to get the data from the blade as an array ,... and then this is my controller
public function update(Request $request)
{
return $request->all();
}
I Get The Data Like This
is the return value from my blade $request->all(); correct? looks like something wrong ???
#sta provided an answer but I would make it more detailed:
When you build more complex structure (nested) in a html form input, every next key or list has to be surrounded by [].
So if you do just a nested keys it will be something[key1][key2][key3].
And if you do an array and a nested keys it will be something[key1][key2][][key3], where [] means that [key2] will be an array (and every array element will have a key3 key with provided value in input value attribute.
That's why this input name can't work:
order[0][detail[][0][skuid]]
but this one will work:
name="order[0][detail][0][qty_minus]

How to insert multiple dropdown value in database?

I have many dropdown list in my html and I want to send each value from some dropdown in database (which dropdown I open and select any value that should go into database with the dropdown name as well).
Database will show like this that this user selected value 1 from "ABC Dropdown" and value 3 from "XYZ" dropdown and etc etc and those dropdown whose value I don't select should not go into database.
<pre>
<tr class="evenrow">
<td align="center"><input type="hidden" name="report_id[]" id="report_id" value="1">1</td>
<td>Customer Balances</td>
<td>
<select name="printer[]" id="printer" class="form-control" title="">
<option value="">Browser support</option>
<option value="1">QL500 - Label printer</option>
<option value="2">Samsung - Main network printer</option>
<option value="3">Local - Local print server at user IP</option>
</select>
</td>
</tr>
<tr class="evenrow">
<td align="center"><input type="hidden" name="report_id[]" id="report_id" value="2">2</td>
<td>Customer Balances</td>
<td>
<select name="printer[]" id="printer" class="form-control" title="">
<option value="">Browser support</option>
<option value="1">QL500 - Label printer</option>
<option value="2">Samsung - Main network printer</option>
<option value="3">Local - Local print server at user IP</option>
</select>
</td>
</tr>
<tr class="evenrow">
<td align="center"><input type="hidden" name="report_id[]" id="report_id" value="3">3</td>
<td>Customer Balances</td>
<td>
<select name="printer[]" id="printer" class="form-control" title="">
<option value="">Browser support</option>
<option value="1">QL500 - Label printer</option>
<option value="2">Samsung - Main network printer</option>
<option value="3">Local - Local print server at user IP</option>
</select>
</td>
</tr>
<tr class="evenrow">
<td align="center"><input type="hidden" name="report_id[]" id="report_id" value="4">4</td>
<td>Customer Balances</td>
<td>
<select name="printer[]" id="printer" class="form-control" title="">
<option value="">Browser support</option>
<option value="1">QL500 - Label printer</option>
<option value="2">Samsung - Main network printer</option>
<option value="3">Local - Local print server at user IP</option>
</select>
</td>
</tr>
</table>
</div>
<!-- /.box-body -->
</div>
<center>
<div class="input-group">
<input type="submit" name="submit" id="submit" value="Add New" class="btn btn-info pull-right">
</div>
</center>
</pre>
Why not using the different name instead of same at all.
Report1, Printer1
Report2, Printer2
Report3, Printer3
and in controller you can catch them by the name...
<table>
<tr class="evenrow">
<td align="center"><input type="hidden" name="report_id1" id="report_id" value="1">1</td>
<td>Customer Balances</td>
<td>
<select name="printer1" id="printer" class="form-control" title="">
<option value="">Browser Support</option>
<option value="1">Text</option>
<option value="2">Text</option>
<option value="3">Text</option>
</select>
</td>
</tr>
<tr class="evenrow">
<td align="center"><input type="hidden" name="report_id2" id="report_id" value="2">2</td>
<td>Customer Balances</td>
<td>
<select name="printer2" id="printer" class="form-control" title="">
<option value="">Browser Support</option>
<option value="1">Text</option>
<option value="2">Text</option>
<option value="3">Text</option>
</select>
</td>
</tr>
</table>
And then in controller :
$report1 = $this->input->post('report1');
$report2 = $this->input->post('report2');
$printer1= $this->input->post('printer1');
$printer2= $this->input->post('printer2');
you used array for select box name and all three select box have same name so if you want to store all different section values differ change select box name so you get the 2 different array in controller or you can easily identifier from which section its got and make a customer json
$selected_option= array("section1"=>$this->input->post('printer1',"section2"=>$this->input->post('printer2');
$selected_option_json= json_encode($selected_option);
store $selected_option_json(its a json string) in db
Hope its helpful for you.

How to fix this error message: Undefined variable: data

ErrorException in 1e886a45102a3e4898f23b52cd7ca771 line 354: Undefined variable: data (View: C:\xampp\htdocs\soulfy_repo\framework\resources\views\soulfy\setting.blade.php)
Where should I put my code to define data?
setting.blade.php
<form action="{{ action('HomeController#getBackgroundTheme')}}" method="post">
<span class="setting-name">THEME</span>
<!-- <form method="POST" action="/posts"> -->
{{ csrf_field() }}
<span class="setting-value center">
<select name="menu">
<option value="Landscape">Landscape</option>
<option value="Lifestyle">Lifestyle</option>
<option value="Music">Music</option>
<option value="Office">Office</option>
<option value="Hobby">Hobby</option>
<option value="Politic">Politic</option>
<option value="Building">Building</option>
</select>
<!-- <div style="width: 150px; height: 30px;"><input type="image" src="http://localhost/framework_freshway/public_html/images/submit.png" value="SUBMIT" width="10"> -->
List User
#foreach($data as $d)
<tr>
<td>
<img width="200px" height="200px" src="{{url('/')}}/uploads/{{$d->background}}"/>
</td>
</tr>
#endforeach
<input type="submit" value="Submit">
</span>
<br><br><br>
</form>
HomeController.php
public function getBackgroundTheme()
{
$data = user::all();
return view('setting', ['data' => $data]);
}
You should either pass an empty array $data, or check if $data is set before using it. I personally prefer the second method.
#if(isset($data))
#foreach($data as $d)
<tr>
<td>
<img width="200px" height="200px" src="{{url('/')}}/uploads/{{$d->background}}"/>
</td>
</tr>
#endforeach
#endif
public function getBackgroundTheme()
{
$data = user::all();
return view('setting')->with('data',$data);
}
You are not passing variables to views. either you can with method or you can compose
To solve the problem:
check if $data defined before excute a loops
#if (isset($data))
#foreach($data as $d)
<tr>
<td>
<img width="200px" height="200px" src="{{url('/')}}/uploads/{{$d->background}}"/>
</td>
</tr>
#endforeach
#endif
Recommendation: create form view and post form in two controller actions.

Resources