select2 not showing options within livewire component - laravel

I am working with laravel livewire.There is a component to update brands and categories of a product. category and brand select option is a select2 option. dropdown showing as a select2, but does not show the options.
This is my component
<?php
namespace App\Http\Livewire\Components\MemberArea\Product;
use App\Models\ProductBrand;
use App\Models\ProductCategory;
use App\Models\Product;
use Illuminate\Support\Facades\Session;
use Livewire\Component;
class UpdateProductBrand extends Component
{
public $product_id;
public $product_category_id;
public $product_brand_id, $categories, $brands, $product;
public function render()
{
return view('pages.products.components.update-product-brand');
}
public function mount()
{
$this->product = Product::get($this->product_id);
$this->categories = ProductCategory::all();
$this->brands = ProductBrand::all();
$this->product_category_id = $this->product->product_category_id;
}
public function submit()
{
$data = $this->validate();
$product = Product::get($this->product_id);
Product::update($product, $data);
session()->flash('message', 'Brand Details Updated Successfully.');
}
}
This is My Blade
<div class="card-body">
<form wire:submit.prevent="submit">
<div class="row">
<div class="form-group col-lg-6">
<label class="h5">Product Category <sup class="text-danger">*</sup>|<button type="button"
id="new-category" class="btn btn-light ">+</button></label>
<select required class="form-control" wire:model="product_category_id" id="categories_edit">
<option value=""></option>
#foreach ($categories as $category)
<option {{ $product->product_category_id === $category->id ? 'selected' :'' }}
value="{{ $category->id }}">{{
$category->title }}</option>
#endforeach
</select>
</div>
#error('product_brand_id')
<span class="text-danger error">{{ $message }}</span>
#enderror
<div class="form-group col-lg-6">
<label class="h5">Product Brand <sup class="text-danger">*</sup>| <button type="button" id="new-brand"
class="btn btn-light">+</button></label>
<select class="form-control" wire:model="product_brand_id" id="brands_edit">
#foreach ($brands as $brand)
<option {{ $product->product_brand_id === $brand->id ? 'selected' :'' }} value="{{ $brand->id }}">
{{ $brand->title }}
</option>
#endforeach
</select>
</div>
#error('product_category_id')
<span class="text-danger error">{{ $message }}</span>
#enderror
<div class="form-group col-lg-12 text-center">
<button class="btn btn-primary" type="submit">Submit</button>
</div>
</div>
</form>
</div>
#push('js')
<script>
document.addEventListener("livewire:load", function (event) {
window.livewire.hook('afterDomUpdate', () => {
$('#categories_edit, #brands_edit').select2({
placeholder: 'Select an option',
});
});
});
$(document).ready(function () {
$('#categories_edit').select2();
$('#brands_edit').select2();
});
//set category on select
$('#categories_edit').on('change', function (e) {
var category_select = $('#categories_edit').select2("val");
console.log("category when select= " + category_select);
#this.product_category_id = category_select;
});
//set brand on select
$('#brands_edit').on('change', function (e) {
var brand_select = $('#brands_edit').select2("val");
console.log("brand when select= " + brand_select);
#this.product_brand_id = brand_select;
});
</script>
#endpush
this is how show it
when use wire:ignore it also not working. show only dropdown as select2 , but it does not show the options

Related

Laravel Livewire Select Search Dropdown not working

I have a form in the Laravel Livewire project and try to search and select users from the database. When I search User then search results in users, but nothing to select. Also, no error showing just page refresh. my code is below:
I'm trying this
livewire component view
<div class="col-md-4">
<div class="form-group row">
<label class="control-label col-md-2 col-sm-2">Select User</label>
<div class="col-md-10 col-sm-10 ">
<div>
<select wire:model="user_id" class="form-control" name="user_id" required>
<option></option>
#foreach($users as $user)
<option value="{{$user->id}}">{{$user->username}} : {{ $user->fullname }}</option>
#endforeach
</select>
</div>
<div style="position:relative">
<input wire:model.debounce.500ms="inputsearchuser" class="form-control relative" type="text"
placeholder="search..."/>
</div>
<div style="position:absolute; z-index:100">
#if(strlen($inputsearchuser)>2)
#if(count($searchusers)>0)
<ul class="list-group">
#foreach($searchusers as $searchuser)
<li class="list-group-item list-group-item-action">
<spanwire:click
="selectuser({{$searchuser->id}},{{$searchuser->terms}})">{{$searchuser->username}}
: {{$searchuser->fullname}}</span>
</li>
</ul>
#endforeach
#else
<li class="list-group-item">User Not Found...</li>
#endif
#endif
</div>
</div>
</div>
</div>
livewire component
class MyLiveWireComponent extends Component
{
public $j = 1;
public $users = [];
public $inputsearchuser = '';
public $user_id;
public function selectuser($user_id,$terms)
{
$this->user_id = $user_id;
$this->terms = $terms;
$this->inputsearchuser = '';
}
public function render()
{
$searchusers = [];
if (strlen($this->inputsearchuser) >= 2) {
$searchusers = User::Where('username', 'LIKE', '%' . $this->inputsearchuser . '%')
->get();
}
return view('livewire.admin.orders.add-order', ['searchusers' => $searchusers])->layout('components.layouts.admin');
}
}
Change this:
<spanwire:click="selectuser({{$searchuser->id}},{{$searchuser->terms}})">
{{$searchuser->username}} : {{$searchuser->fullname}}
</span>
To:
<span wire:click.prevent="selectuser({{$searchuser->id}},{{$searchuser->terms}})">
{{$searchuser->username}} : {{$searchuser->fullname}}
</span>
Your component should have a single-level root element only. Also, add wire:key in your element inside of the loop.
<ul class="list-group">
#foreach($searchusers as $key => $searchuser)
<li wire:key="{{'users'.$key}}" class="list-group-item list-group-item-action">
<span wire:click="selectuser({{$searchuser->id}},
{{$searchuser->terms}})">{{$searchuser->username}}
: {{$searchuser->fullname}}</span>
</li>
#endforeach
</ul>
Did you change it to wire:click.prevent as suggested above? Otherwise, it does not prevent the default action from occurring, and can cause that exact behavior.

Using Select in an Edit Form Laravel

Im trying to implement a Edit function to update permissions from an Laravel User, (I already installed Spatie), it parcially works, it save the changes but I cant see the permissions of the role on the Select Form. Any help please
<--CONTROLLER-->
public function edit($id)
{
$role = Role::findById($id);
$permissions = Permission::all();
return view('admin_roles_edit', compact('role','permissions', 'permissions1'));
}
public function update(Request $request, $id)
{
$request->validate([
'name'=>'required|max:30',
]);
$role = Role::findById($id);
$role->update($request->all());
$role->permissions()->sync($request->permissions);
return redirect()->route('admin.roles.index')->with('message', 'El rol se ha actualizado correctamente');
}
<--HTML-->
<form action="{{route('admin.roles.update', $role->id)}}" method="post"
class="form">
#csrf
<div class="form-group has-feedback">
<label class="control-label col-lg-3">Nombre<span
class="text-danger">*</span></label>
<input type="text" class="form-control" name="name"
value="{{$role->name}}" required="required">
#error('name')
<label class="validation-error-label" for="basic">{{$message}}</label>
#enderror
</div>
<div class="form-group has-feedback">
<label class="control-label col-lg-3">Permisos<span
class="text-danger">*</span></label>
<div class="multi-select-full">
<select class="multiselect" multiple="multiple" name="roles">
#foreach($permissions as $permission)
<option value="{{$permission->id}} #if($permission->id == $role->permission) selected #endif">{{$permission->name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group pull-right">
<a href="{{route('admin.roles.index')}}" type="button" class="btn btn-default"><i
class="icon-cross2 position-left"></i>Cancelar
</a>
<button type="submit" class="submit-btn btn btn-success"><i
class="icon-add position-left"></i>Editar
</button>
</div>
</form>
<--RESULT-->
in your controller add this line:
public function edit($id)
{
$role = Role::findById($id);
$permissions = Permission::all();
$rolePermissions = $role->permissions()->pluck('name','id')->toArray();
return view('admin_roles_edit', compact('role','permissions', 'rolePermissions'));
}
update your blade:
<option value="{{$permission->id}}" {{in_array($permission->id, array_keys($rolePermissions)) ? 'selected' : '')}}>{{$permission->name}}</option>
Fixed finally
RoleController.php
public function edit($id)
{
$role = Role::findById($id);
$permissions = Permission::all();
return view('admin_roles_edit', compact('role','permissions'));
}
RoleView.blade.php
<select class="multiselect" multiple="multiple" name="roles">
#foreach($permissions as $permission)
<option value="{{$permission->id}}"
#if($role->hasPermissionTo($permission->id))
selected="selected"
#endif/>{{$permission->name}}</option>
#endforeach
</select>
Fixed Result

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 - How to display child goal type name on select dropdown on edit form

In my Laravel-5.8 project, I am trying to child name (text) on select list in edit form.
I have this table:
CREATE TABLE `goal_types` (
`id` int(11) NOT NULL,
`name` varchar(200) NOT NULL,
`parent_id` int(11) DEFAULT NULL,
`max_score` int(11) DEFAULT 0,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Model
class GoalType extends Model
{
public $timestamps = false;
protected $table = 'goal_types';
protected $primaryKey = 'id';
protected $fillable = [
'name',
'parent_id',
'max_score',
];
protected $casts = [];
public function children()
{
return $this->hasMany('App\Models\GoalType', 'parent_id');
}
public function parent()
{
return $this->hasOne(App\Models\GoalType::class, 'id', 'parent_id');
}
}
Controller
public function index()
{
$categories = GoalType::with('children')->whereNull('parent_id')->get();
return view('goal_types.index')->with('categories', $categories);
}
public function create()
{
return view('goal_types.create');
}
public function store(StoreGoalTypeRequest $request)
{
$data = GoalType::create([
'name' => $request->name,
'parent_id' => $request->parent_id,
'max_score' => $request->max_score,
]);
Session::flash('success', 'Goal Type is created successfully');
return redirect()->route('goal_types.index');
}
I have a modal form for the edit
view
<div class="row">
<div class="col-md-8">
<div class="card card-secondary">
<div class="card-header">
<h3 class="card-title">Goal Type(s)</h3>
</div>
<div class="card-body">
<ul class="list-group">
#foreach ($categories as $category)
<li class="list-group-item">
#if ($category->children)
<ul class="list-group mt-2">
#foreach ($category->children as $child)
<li class="list-group-item">
<div class="d-flex justify-content-between">
{{ $child->name }}
<div class="button-group d-flex">
#can('goal_type_edit')
<button type="button" class="btn btn-sm btn-primary mr-1 edit-category" data-toggle="modal" data-target="#editCategoryModal" data-id="{{ $child->id }}" data-name="{{ $child->name }}">Edit</button>
#endcan
</div>
</div>
</li>
#endforeach
</ul>
#endif
</li>
#endforeach
</ul>
</div>
</div>
</div>
<div class="modal fade" id="editCategoryModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit Goal Type</h4>
<form action="" method="POST">
#csrf
#method('PUT')
<div class="modal-body">
<div class="form-group">
<label class="control-label"> Parent Goal Type:</label>
<select class="form-control select2bs4" data-placeholder="Choose Parent Goal Type" tabindex="1" name="parent_id" style="width: 100%;">
<option value="">Select Goal Type</option>
#foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
#endforeach
</select>
</div>
<div class="form-group">
<label class="control-label"> Name:<span style="color:red;">*</span></label>
<input type="text" name="name" class="form-control" value="" placeholder="Category Name" required>
</div>
<div class="form-group">
<label class="control-label"> Max. Weight (%):</label>
<input type="number" name="max_score" class="form-control" value="" step="0.01" placeholder="Enter maximum weight here: 15, 50, 75 etc" style="width: 100%;">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Update</button>
</div>
</div>
</form>
</div>
</div>
</div>
When I click on edit from the index a modal form should popup to display the child name where the parent_id equals the id of the parent as it is in the database. But the select dropdown value/text is not displaying anything until when I click on the select dropdown.
How do I modify
#foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
#endforeach
in the edit to achieve that (displaying the name of the select child on the dropdown)?
Thanks
In your edit view you must pass your category id in your form action like this action="{{ route('admin.categories.update' , $category->id) }}" and then compare it with parent_id and in your category model you have to pass children.
category model:
public function children()
{
return $this->hasMany(GoalType::class, 'parent_id' , 'id')->with('children');
}
edit.blade.php view
<div class="col-md-12">
<label for="parent_id" class="form-control-label">parents category name</label>
<select class="form-control" data-toggle="select" data-live-search="true" name="parent_id" id="parent_id">
<option value="0" {{ $category->parent_id === 0 ? 'disabled' : '' }} selected> - Default</option>
#foreach(\App\Models\Category::latest()->get() as $cate)
<option value="{{ $cate->id }}" {{ $cate->id === $category->parent_id ? 'selected' : '' }} {{ $cate->id === $category->id ? 'disabled' : '' }} {{ $cate->id === $category->parent_id ? 'disabled' : '' }}>{{ $cate->name }}</option>
#endforeach
</select>
</div>

Laravel Dropdown Selected item send to edit view

This is my view index page
<div class="form-group">
{!! Form::label('cname','Clients: ') !!}
{!! Form::select('cname',[''=>'Select Category']+$client,null,['class'=>'form-control selectpicker']) !!}
<span class="input-group-btn">
<a class="btn btn-primary" href="">Edit</a>
</span>
</div>
Controller:
public function index() {
$client = Client::pluck('cname','clientid')->all();
return view('client.index', compact('client'));
}
How can i get select item from dropdown and from button click send the selected details to edit view?
You can do something like this
// Controller
public function index()
{
$roles = Roles::all();
$selectedRole = User::first()->role_id;
return view('my_view', compact('roles', 'selectedRole');
}
And then in your view
<select class="form-control m-bot15" name="role_id">
#if ($roles->count())
#foreach($roles as $role)
<option value="{{ $role->id }}" {{ $selectedRole == $role->id ? 'selected="selected"' : '' }}>{{ $role->name }}</option>
#endif
</select>

Resources