Dynamically populated select menus in Laravel5 - laravel-5

In a view I have a couple of select menus that are populated by data from two separate tables.
Looking for a way to populate the second select menu depending on the value of the first.
<div class="form-group">
{{Form::label('company', 'Company')}}
<select selected="" class="form-control" id="company" name="company">
#foreach($company as $key)
<option value="">{{$key->name}}</option>
#endforeach
</select>
</div>
<div class="form-group">
{{Form::label('department', 'Department')}}
<select selected="" class="form-control" id="department" name="department">
#foreach($department as $key)
<option =value"">{{$key->name}}</option>
#endforeach
</select>
</div>
This feels like something that shouldn't be too hard, but have yet to find any good information about it.

A way to do this is using javascript. The main idea is to have a partial view with the second select and then call it when the user change something in the first select.
To do this, you need to have two views. The main view will have a call to the second view with a default collection of departments:
<div class="form-group">
{{Form::label('company', 'Company')}}
<select selected="" class="form-control" id="company" name="company">
#foreach($company as $key)
<option value="">{{$key->name}}</option>
#endforeach
</select>
</div>
<div id="second-select" class="form-group">
#include('contents.partial', ['department' => $department])
</div>
The second view (contents.partial) will print the form:
{{Form::label('department', 'Department')}}
<select selected="" class="form-control" id="department" name="department">
#foreach($department as $key)
<option =value"">{{$key->name}}</option>
#endforeach
</select>
Then you'll need a route to call a function to render the second view based on some value:
Route::get('/get/content/{value}', 'ContentController#getContent');
And the function to render the view in ContentController:
public function getContent(Request $request, $value)
{
$department = Department::where('value', $value)->get();
return view('contents.partial', [
'department' => $department
])->render();
}
And to call this, you need a javascript/jquery to identify the change in the select and fire the function in controller
<script>
$(document).ready(function(){
setListener();
});
function setListener() {
$('#company').change(function() {
var value = $(this).val();
$.get( "/get/content/"+value, function( data ) {
$('#second-select').empty();
$('#second-select').append(data);
});
});
}
</script>
This is the main idea, ok?

Related

How to get the old value in a select without unchecked with option formed with an foreach

I need a little help..
In case of validation errors, when the page is reloaded I lose the information entered previously.
This is my code:
Controller:
public function create()
{
$nationalities = array('Italian','Brazilian','Spanish','Romanian');
return view('guest.create', ['nationalities'=>$nationalities);
}
public function store(Request $request)
{
$request->validate([
'nationality' => 'required'
]);
Guest::create([
'nationality' => $request->nationality
]);
return redirect(route('guest.index'));
}
View:
<div class="mb-3">
<label for="nationality" class="form-label fw-bold">Select<span class="required">*</span></label>
<select class="form-select" id="nationality" name="nationality" aria-label="Floating label select example">
#foreach($nationalities as $nationality)
<option value="{{$nationality}}">{{$nationality}}</option>
#endforeach
</select>
</div>
How can I modify the code so that this doesn't happen?
How can you select back what failed if you did not even ask for the old value?
This may or not work depending on how you are validating, but you did not want to show that...
<div class="mb-3">
<label for="nationality" class="form-label fw-bold">Select<span class="required">*</span></label>
<select class="form-select" id="nationality" name="nationality" aria-label="Floating label select example">
#foreach($nationalities as $nationality)
<option value="{{$nationality}}" {{ old('nationality') === $nationality) ? 'selected="selected"' : '' }}>{{$nationality}}</option>
#endforeach
</select>
</div>
<option value="{{$nationality}}" #selected(old('nationality')==$nationality)>
{{$nationality}}
</option>
add the #selected directive in blade.

Multiple Selection field is blank in edit form, Select2 in edit form not triggering the selected values in edit form- Laravel Livewires

I have a select2 in a livewire component. Everything works fine but in my edit view, the selected options don't show in the box is selected. When I open the dropdown they show as highlighted, so data is coming from the backend. Please check below codes and output screenshots, Thanks in advance for your kind help.
Livewire Component
public $home_categories = [];
public $no_of_products;
public function mount()
{
$category = HomeCategory::all()->first();
$this->home_categories = explode(',', $category->home_categories);
$this->no_of_products = $category->no_of_products;
}
Blade Component:
<div class="form-group">
<label for="home_categories" class="col-md-4 control-label">Choose Category</label>
<div class="col-md-6" wire:ignore>
<select class="select2 form-control" name="home_categories[]" multiple="multiple" wire:model="home_categories">
#foreach ($categories as $category)
<option value="{{$category->id}}">{{$category->name}}</option>
#endforeach
</select>
</div>
The script inside the livewire:
#push('scripts')
<script>
$(document).ready(function() {
$('.select2').select2();
$('.select2').on('change', function (e) {
var data = $('.select2').select2("val");
#this.set('home_categories', data);
});
});
</script> #endpush
Use this code inside the blade components:
#if (in_array($category->id, $home_categories)) {{'selected'}} #endif
The script, component properties everything As-It-Is only changes in select option tag: like below code:
<select class="select2 form-control" name="home_categories[]" multiple="multiple" wire:model="home_categories">
#foreach ($categories as $category)
<option value="{{$category->id}}" #if (in_array($category->id, $home_categories)){{'selected'}}
#endif>{{$category->name}}</option>
#endforeach
In you component
public function hydrate(){$this->emit('data');}

How to use select2 multiselect with livewire

What I am trying to achieve is, there are two models A and B with a relationship of One to many, where A has many B. So if the records for A and B have already been created, A can be assigned to many B. So I started this current project with livewire, and now I am at a loss. Normal select with multiple works just fine and populates the array in the backend of livewire. But when I use select2 nothing is stored in the array, and when I dd it, it shows an empty array.
Even though livewire provides wonderful set of tools, I am starting to realize that there is a lot of gray areas where things are missing or lacks external support, like select2 here.
Here is what I have done so far:
<div>
<div class="tab-pane fade show active" id="card1" role="tabpanel" aria-labelledby="card1-tab">
<div class="pt-3"></div>
<div class="row" >
<div class="form-group col">
<label for="cards">Enter Cards</label>
<select class="form-control select2" id="cards" multiple="multiple" onchange="this.dispatchEvent(new InputEvent('input'))>
<option disabled="">Select Cards</option>
#foreach($cardsUnassigned as $card)
<option value="{{ $card->id }}">{{ $card->imei_number }}</option>
#endforeach
</select>
</div>
<div class="form-group col">
<label for="technicians" class="">Technicians</label>
<select class="form-control select2" id="technicians" wire:model='techies.'>
<option disabled="">Select Technicians</option>
#foreach($technicians as $tech)
<option value="{{ $tech->id }}">{{ $tech->first_name }}</option>
#endforeach
</select>
</div>
</div>
#foreach($cardSelect as $key => $value)
{{$value}}
#endforeach
<button wire:click="assignCardToTech()" class="btn btn-primary">Submit</button>
</div>
</div>
#push('scripts')
<script>
$('#cards').select2({
placeholder: 'Select Cards to assign'
});
//send data to livewire
$('#technicians').select2({
placeholder: 'Select Technicians'
});
</script>
#endpush
And the backend:
<?php
namespace App\Http\Livewire\Stock\Assigns;
use App\Models\Card;
use App\Models\Sim;
use App\Models\Technician;
use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Support\Facades\Auth;
class Assigns extends Component
{
public $sortBy_card = 'imei_number';
public $sortBy_sim = 'ip';
public $sortDirection = 'asc';
public $search = '';
public $perPage = 10;
public $cardSelect = [];
public $techies;
public function render()
{
$simsUnassigned = Sim::query()
->whereNull('technician_id')
->searchUnassigned($this->search)
->get();
$cardsUnassigned = Card::query()
->whereNull('technician_id')
->searchUnassignedCard($this->search)
->get();
// dd($cardsUnassigned);
$simsAssigned = Sim::query()
->searchAssigned($this->search)
->orderBy($this->sortBy_sim, $this->sortDirection)
->paginate($this->perPage);
$cardsAssigned = Card::query()
->searchAssignedCard($this->search)
->orderBy($this->sortBy_card, $this->sortDirection)
->paginate($this->perPage);
$technicians = Technician::query()->get();
return view('livewire.stock.assigns.assigns',compact('simsUnassigned','cardsUnassigned','simsAssigned','cardsAssigned','technicians'))
->extends('layouts.base')
->section('content');
}
public function assignCardToTech(){
dd($this->cardSelect);
if($this->cards){
foreach($this->cards as $card){
}
}
}
}
Hopefully this helps.
######## INSIDE LIVEWIRE COMPONENT
public array $locationUsers = [];
protected $listeners = ['locationUsersSelected'];
public function locationUsersSelected($locationUsersValues)
{
$this->locationUsers = $locationUsersValues;
}
######## INSIDE LIVEWIRE BLADE
<div class="col-md-12 mb-3" wire:ignore>
<label for="locationUsers">Select Users</label>
<select id="locationUsers" class="form-control select2" multiple="multiple">
<option value="">--select--</option>
#foreach($this->users as $id => $name)
<option value="{{ $id }}">{{ $name }}</option>
#endforeach
</select>
</div>
######## INSIDE LIVEWIRE SCRIPTS
document.addEventListener('livewire:load', function () {
$('#locationUsers').on('select2:close', (e) => {
#this.emit('locationUsersSelected', $('#locationUsers').select2('val'));
});
$('#locationUsers').val(#this.get('locationUsers')).trigger('change');
});
Your could try adding this to your html
<div class="form-group col-md-6" wire:ignore>
<label for="manager" class="mb-0 h5">Assign Managers:</label>
<select wire:model="reporting_managers" id="manager" class="select-2 multiple='multiple' data-placeholder="Assign Managers">
#foreach ($managers as $manager)
<option value="{{ $manager->id }}" data-name="{{ $manager->name }}">{{ $manager->name }}</option>
#endforeach
</select>
</div>
and then in your javaScript section
$('#manager').on('select2:select', function (e) {
#this.set('reporting_managers', $('#manager').select2('val'));
});
$('#manager').on('select2:unselect', function (e) {
#this.set('reporting_managers', $('#manager').select2('val'));
});
This will directly store your selection in variable in livewire and won't get deselected on render.

Laravel 5.4 passing form select option value to a Route::get

I am trying to do the following within my Laravel 5.4 project.
In a users.index blade page I am listing all users from a database in a table.
All the users belong to a district. Some districts have more users then the other.
At the top of this table view I created a form with a select field. The options hold the id's for the 10 districts:
<form class="form-horizontal" method="GET" action="/users/district">
<div class="form-group col-md-5">
<select name="district" class="form-control">
<option value="1">Amsterdam</option>
<option value="2">Arnhem</option>
<option value="3">Assen</option>
<option value="4">Groningen</option>
<option value="5">Leeuwarden</option>
<option value="6">Rotterdam</option>
<option value="7">Sittard</option>
<option value="8">Tilburg</option>
<option value="9">Utrecht</option>
<option value="10">Antillen</option>
</select>
</div>
<div class="form-group col-md-4 col-md-offset-1">
<button class="btn btn-md btn-primary">Haal gegevens op</button>
</div>
</form>
When I put the URL "http://localhost/users/district/5" in manually in the browser it shows me a table view with only users from the district with the ID of 5.
This is my UsersController:
public function perDistrict($district)
{
$users = User::where('district_id', $district)
->paginate(12);
$totalusers = User::count();
return view('users.index', compact('users', 'totalusers'));
}
I would like to use the form to get me the results but when I submit the form it show me this URL: "http://localhost/users/district?district=5" and it gives me no result of course.
How can I convert that to the URL "http://localhost/users/district/5" ?
This my route:
Route::get('users/district/{district}', 'UsersController#perDistrict');
Hope someone can help me.
https://www.codecourse.com/lessons/laravel-fundamentals/729 did the trick for me with some own customization.

Laravel save dropdown value

I've made a dropdown in laravel but when I save the request it won't save the value that was selected. How do can I achieve this?
This is my code in my view:
<div class="form-group">
<label for="content" class="col-lg-2 control-label">Karakterrit</label>
<div class="col-lg-10">
<select class="form-control input-sm" name="karakterrit_id">
#foreach($karakterrit as $krit)
<option value="{!! $krit->id !!}">{!! $krit->rit !!}</option>
#endforeach
</select>
</div>
</div>
And this is my controller where I save the request:
public function store(Request $request)
{
$rit = new Rittenregistratie($request->all());
Auth::user()->Rittenregistratie()->save($rit);
return redirect('/create')->with('message','Rit '.$rit->id.' is aangemaakt.');
}
It saves everything right except the value from the dropdown which must be a number.

Resources