Im interested in giving users the option to add articles to custom lists that they create. (like youtube's playlist feature).
I want to know how to show a 'checked' checkbox next to a list if the article already exists within it, so they don't add it twice.
My database tables:
list : | id | person_id | list_name | list_desc
list_ref : | id | list_id | article_id
My code for displaying lists.
$lists = Lists::where('person_id', Auth::user()->person_id)->get();
#foreach($lists as $list)
<input type="checkbox" id="available_list" value="{{ $list->id }}">
{{ $list->list_name }}
#endforeach
If anyone could help me understand the code to query the two tables to see if list already used || list is available.
You could use a raw expression in conjunction with a left join like this:
$lists = DB::table('list')->
leftJoin('list_ref', 'list_ref.list_id', '=', 'list.id')->
select(DB::raw('list.*, IF(list_ref.list_id = list.id, 1, 0) used'))->
where('person_id', Auth::user()->person_id)->
get();
The above uses a join to figure out which list rows has a corresponding key in the list_ref table. The result will contain a field called used that will tell if the entry has a reference in the list_ref table.
You should now be able to generate you form like this:
#foreach($lists as $list)
<input type="checkbox" id="available_list" value="{{ $list->id }}" {{ $list->used ? "CHECKED" : "" }}>
{{ $list->list_name }}
#endforeach
First crate class, here is example for facility
class HotelFacilities
{
public $facility_id;
public $facility;
public $status;
}
Get all data
$facilities = Facility::all();
Get user related data
$user_facilities = UserFacility::where('user_id', 3)->get();
//Here you add status
$array_hotel_facility = array();
for($i=0; $i<count($facilities); $i++)
{
$obj_hotel_facilities = new HotelFacilities;
$obj_hotel_facilities->facility_id = $facilities[$i]['id'];
$obj_hotel_facilities->facility = $facilities[$i]['facility'];
$obj_hotel_facilities->status = false;
for($j=0; $j<count($user_facilities); $j++)
{
if($user_facilities[$j]->facility_id == $facilities[$i]->id)
{
$obj_hotel_facilities->status = true;
}
}
//Pass this array to view
$array_hotel_facility[$i] = $obj_hotel_facilities;
}
//Pass to view
return view('extranet.view_facilities')->with('facilities', $array_hotel_facility);
//Generate UI like this
#foreach($facilities as $facility)
<div class="form-group col-md-3">
<div class="form-group">
<label>
<input type="checkbox" class="minimal" name="facilities[]" value="{{ $facility->facility_id }}" <?php if($facility->status){echo "checked";} ?>>
{{ $facility->facility }}
</label>
</div>
</div>
#endforeach
Related
Good morning, does livewire read the data-* attribute?
Note: I found this question, but I don't know how to do it in this case. livewire data-attributes
Ex:
<input value="{{ $v->id }}" data-price="{{ $v->price }}" >
As I need to save only the ids in the table and price is only to add and update a variable $product_price.
But as the livewire only reads the value attribute then the ids are being added.
The case:
I have some products that have options and when selecting an option, the price of the product is added to the option.
This magic function does the sum and updates the price:
public function updatedSelectedOption()
{
$price = 0.0;
for ($i = 0; $i < count($this->selectedOption); $i++) {
$price += $this->selectedOption[$i];
}
return $this->total = $price + ($this->product_price * $this->quantity);
}
View:
#foreach ($product->options as $index => $option)
<div wire:key="option.{{ $index }}">
<input type="checkbox" id="check.{{ $option->id }}" data-price="{{ $option->price }}" wire:model.lazy="selectedOption" value="{{ $option->id }}" class="sr-only peer">
<label for="check.{{ $option->id }}">
{{ $option->name }} - #money($option->price) - ID: {{ $option->id }}
</label>
</div>
#endforeach
I am trying to create a multiple select filter. When I use whereIn for the id I get this error
Invalid parameter number (SQL: select * from stations where id in (16128))
With 16128 being one of the two id's selected for that query. It works fine with a manual given array so I am not sure what the problem is. I also tried with array_values but I get the same result.
<label for="" class="col-md-3">Daypart</label>
<div class="container-checkbox">
#foreach($dayparts as $id => $daypart)
<div wire:key="{{ $daypart->id }}">
<input type="checkbox" id="{{ $daypart->daypart_name }}" name="{{ $daypart->daypart_name }}" wire:model="filters.dayparts.{{ $daypart->id }}" wire:click="filtru({{ $daypart->id }})" />
</div>
#endforeach
</div>
public function filtru($id){
$this->filters['dayparts'] = array_filter($this->filters['dayparts']);
$dayp = DaypartStation::whereIn('daypart_id', array_keys($this->filters['dayparts']))->get();
foreach($dayp as $day){
$this->arr[]=$day->station_id;
}
$toate = Station::whereIn('id', [$this->arr])->get();
//dd(Station::whereIn('id', $this->arr)->get());
//dd(Station::whereIn('id', [array_values($this->arr)])->get());
// dd(Station::whereIn('id', [16576, 16776, 16376])->get());
}
public function render()
{
return view('livewire.create-workbooks-table', [
'stations'=> Station::
when($this->filters['dayparts'], function($query){
$query->whereIn('id', [$this->arr]);
})
->search($this->search)
->orderBy($this->sortBy, $this->sortDirection)
->latest()
->Paginate($this->perPage),
]);
}
I believe you should change
$toate = Station::whereIn('id', [$this->arr])->get();
to
$toate = Station::whereIn('id', $this->arr)->get();
since $this->arr is already an array
I have three table and i'm in a many to many relationship.
Table "semaine"
id | name |
Table "bitheme"
id | namebitheme
Table "bitheme_semaine". In it i add a new "statut" columns
bitheme_id | semaine_id | statut
In my case I can have a status of 1 or 2 if the relationship exists (in database it"s 1 by defaut on this field).
In my edit form i have to checkbox :
<input type="checkbox" name="bithemes[]" value="{{ $id }}"> </input>
<input type="checkbox" name="statut[]" value="{{ $id }}"> </input>
I synchronize my table as well :
$semaine->update($request->all());
$semaine->bithemes()->sync($request->input('bithemes', []));
But i also want to synchronize the status if it is checked.
So I added in the relationship of my Semaine model :
public function bithemes()
{
return $this->belongsToMany(Bitheme::class)->withPivot('statut');
}
and i try to test synchronize with :
$semaine->bithemes()->sync($request->input('bithemes', []), ['statut' => 2]);
But the statut is never synchronized.
The sync method takes as first parameter an array of IDs as in your example. But when you want to sync the attributes of the pivot table, give it an array with the IDs as numeric index of that array and an array as value of each index for the pivot attributes.
$syncable = [];
foreach($request->input('bithemes', []) as $bithemeId) {
$syncable[$bithemeId] = ['status' => 2];
}
$semaine->bithemes()->sync($syncable);
For precision, the format you used is to sync only one ID
if (isset($request->input('bithemes')[0])) {
$semaine->bithemes()->sync($request->input('bithemes')[0], ['statut' => 2]);
}
Perfect.
I changed my form with :
<input type="checkbox" name="bithemes[]" value="{{ $id }}" {{ (in_array($id, old('bithemes', [])) || isset($semaine) && $semaine->bithemes->contains($id)) ? 'checked' : '' }}> </input>
<input type="checkbox" name="statut[]" value="{{ $id }}"> </input>
and my controller with :
$syncable = [];
foreach($request->input('bithemes', []) as $key => $value) {
if (!isset ($request->input('statut')[$key])) {$statut = 1;} else {$statut = 2;}
$syncable[$value] = ['statut' => $statut];
}
$semaine->bithemes()->sync($syncable);
and everything si fine now. Thanks
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.
In my page I can have multiple addresses, but the user can only select one address.
The problem I'm having is that both my radio buttons are being saved instead of just one.
So if the user has 2 addresses then only one should have selected = 1 and the other address should be selected = 0, but at the moment both address = 1.
I haven't been able to only have 1 address selected and saved as such in the database. I know that I'm passing the ID of the selected radio button through, but I was hoping to have this happen.
E.G: When the user saves their first address that is then saved as their selected address (selected = 1) and any other addresses they add after that will be (selected = 0).
If they change their mind and want their second address to be the one they use then the select it and that will then become like this, address 1 (selected = 0) and address 2 will become (selected = 1).
I hope this made sense. If it didn't please let me know.
My form
#foreach($addresses as $address)
<div class="col-lg-4">
<form id="address-radio" action="{{ route('account.post.addresses.radio', $address->id) }}" method="post">
#csrf
<div class="form-check">
<input type="radio" class="form-check-input" name="address_option" id="address_{{ $address->id }}" {!! $address->selected == '1' ? 'checked' : '' !!}>
<label for="address_{{ $address->id }}" class="form-check->label">
#if(!empty($address->complex))
{{ $address->complex }} <br>
#endif
{{ $address->address }} <br>
{{ $address->suburb }} <br>
{{ $address->city }} <br>
{{ $address->province }} <br>
{{ $address->postal_code }} <br>
</label>
</div>
</form>
</div>
#endforeach
<script>
$(document).ready(function(){
$('input[type="radio"]').on('change', function(){
$(this).closest("form").submit();
})
})
</script>
and this is my function
public function postAddressesRadio(Request $request, $id)
{
$selected = Address::findOrFail($id);
$user_id = Auth::user()->id;
$not_selected = $selected->where('id', '!=', $id)
->where('user_id', $user_id)->get();
foreach($not_selected as $selected)
{
$selected->selected = "0";
}
if($request->address_option == 'on'){
$selected->selected = '1';
}
$selected->save();
return redirect()->back()->with('success', 'Address was updated');
}
So I've managed to do it. I'm not sure if there is a better way but this works.
In my function I did
public function postAddressesRadio(Request $request, $id)
{
$address = Address::findOrFail($id);
$user_id = Auth::user()->id;
$addresses = Address::where('user_id', $user_id)->get();
foreach($addresses as $address)
{
if($address->id == $id)
{
$address->selected = "1";
}else{
$address->selected = "0";
}
$address->save();
}