On laravel 10 site using docs at https://dev.to/koossaayy/laravel-livewire-multiple-selection-with-virtual-select-1f87 I try to make multiselection.
I made it with some changes in the code. In component :
<?php
namespace AppLivewireAdmin;
use AppModelsPermission;
use IlluminateSupportStr;
use LivewireComponent;
class UsersPermissionsEditor extends Component
{
public $selectedPermissions= [];
public $permissionsListing= [];
public function render()
{
$this->permissionsListing = Permission::query()->get()/*->pluck('name', 'id')*/
->map(function ($selectedPermissionItem) {
return ['id' => $selectedPermissionItem->id, 'label' => Str::replace('_', ' ', Str::title($selectedPermissionItem->name))];
})
->toArray();
return view('livewire.admin.users-permissions-editor');
}
}
and in blade :
<div class="admin_page_container" id="users_permissions_editor_admin_page_container">
<div class="editor_listing_wrapper_bix_width" x-data="adminUsersPermissionsEditorComponent()"
x-init="[onAdminUsersPermissionsEditorComponentInit() ]" x-cloak>
$selectedPermissions::{{ print_r($selectedPermissions, true) }}
<input id="permissionsListing" name="permissionsListing" value="add permissionsListing TEST">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/virtual-select.min.js"
integrity="sha256-Gsn2XyJGdUeHy0r4gaP1mJy1JkLiIWY6g6hJhV5UrIw=" crossorigin="anonymous"></script>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/virtual-select.min.css"
integrity="sha256-KqTuc/vUgQsb5EMyyxWf62qYinMUXDpWELyNx+cCUr0=" crossorigin="anonymous">
<div>
AAAAA<div id="permissions"></div>BBB
<script>
function adminUsersPermissionsEditorComponent() {
console.log('adminUsersPermissionsEditorComponent::')
return {
fillUsersPermissions: function () {
var permissionsListing = @json($permissionsListing)
VirtualSelect.init({
ele: '#permissions',
multiple: true,
options: permissionsListing,
});
let selectedPermissions = document.querySelector('#permissions');
selectedPermissions.addEventListener('change', () => {
let data = selectedPermissions.value;
@this.set('selectedPermissions', data);
});
},
onAdminUsersPermissionsEditorComponentInit: function () {
},
}
}
</script>
</div>
</div>
I see available multiselection element, but when I click on one of elements the multiselection element is not visible at all,
What I see in browsers console :
How that can be fixed ?
"laravel/framework": "^10.48.4",
"livewire/livewire": "^3.4.9",
Thanks in advance!
2
Answers
The main problem is that every time @this.set(‘selectedPermissions’,…. is applied a call to the backend is done, so the DOM is redrawn and the changes and the event listeners applied by VirtualSelect are lost.
A simple fix is to add a wire:ignore to the <div> used by VirtualSelect, in this way Livewire will not alter the content of that <div>:
In this example I’ve applied some changes:
Here is a different version using Tailwind CSS, Livewire and Alpine I created to allow multiple roles to be selected for a user.
In your Livewire component:
To prefill the roles, for instance if you are editing, you would load the selected roles via mount():
Output:
If you’re using the Tall stcak there will be no need to import any additional JS libraries to run the code above.
Dropdown will show a checkmark next to the selected items and the number of selected items in the field.