Skip to content

Instantly share code, notes, and snippets.

@drfraker
Last active April 3, 2020 21:50
Show Gist options
  • Save drfraker/31e76616713f6744256b8747ea82acfb to your computer and use it in GitHub Desktop.
Save drfraker/31e76616713f6744256b8747ea82acfb to your computer and use it in GitHub Desktop.
LiveWire realtime search bug.
<div class="bg-white shadow overflow-hidden sm:rounded-md mt-10">
<div class="flex justify-between items-center px-4 py-5 border-b border-gray-200 sm:px-6">
<div>
<h3 class="text-lg leading-6 font-medium text-gray-900">
Users & Staff
</h3>
<p class="mt-1 text-sm leading-5 text-gray-500">
Search across staff members and users to assign permissions & roles.
</p>
</div>
<div class="flex-1 flex items-center justify-center lg:ml-6 lg:justify-end">
<div class="max-w-lg w-full lg:max-w-xs">
<label for="search" class="sr-only">Search</label>
<div class="relative z-0">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<svg class="h-5 w-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
</svg>
</div>
<!-- Search model-->
<input wire:model.debounce.500ms="search" id="search" class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:border-blue-300 focus:shadow-outline-blue sm:text-sm transition duration-150 ease-in-out" placeholder="Search users..." />
</div>
</div>
</div>
</div>
<ul>
@if($staff->count() || $users->count())
@foreach($staff as $staffMember)
<li>
<div class="flex items-center px-4 py-4 sm:px-6">
<div class="min-w-0 flex-1 flex items-center">
<div class="flex-shrink-0 capitalize">
<!-- If I remove this it works!-->
@component('components.avatar', ['initials' => $staffMember->initials])
@endcomponent
</div>
<div class="min-w-0 flex-1 px-4 md:grid md:grid-cols-2 md:gap-4">
<div>
<div class="text-sm leading-5 font-medium text-blue-600 truncate">{{$staffMember->full_name}}</div>
@if($staffMember->email)
<div class="mt-2 flex items-center text-sm leading-5 text-gray-500">
<svg class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884zM18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" clip-rule="evenodd"/>
</svg>
<span class="truncate">{{$staffMember->email}}</span>
</div>
@endif
</div>
<div>
@livewire('role-selector', ['person' => $staffMember], key(\Str::slug($staffMember->last_name.'-'.$staffMember->id)))
</div>
</div>
</div>
</div>
</li>
@endforeach
@foreach($users as $user)
<li>
<div class="flex items-center px-4 py-4 sm:px-6">
<div class="min-w-0 flex-1 flex items-center">
<div class="flex-shrink-0 capitalize">
@component('components.avatar', ['initials' => $user->initials])
@endcomponent
</div>
<div class="min-w-0 flex-1 px-4 md:grid md:grid-cols-2 md:gap-4">
<div>
<div class="text-sm leading-5 font-medium text-blue-600 truncate">{{$user->full_name}}</div>
@if($user->email)
<div class="mt-2 flex items-center text-sm leading-5 text-gray-500">
<svg class="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884zM18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" clip-rule="evenodd"/>
</svg>
<span class="truncate">{{$user->email}}</span>
</div>
@endif
</div>
<div
<!-- If I remove this it works!-->
@livewire('role-selector', ['person' => $user], key(\Str::slug($user->last_name.'-'.$user->id)))
</div>
</div>
</div>
</div>
</li>
@endforeach
@else
<li class="p-6 text-gray-500">
No staff or users in your organization match that search.
</li>
@endif
</ul>
</div>
<?php
namespace App\Http\Livewire;
use App\Staff;
use App\User;
use Livewire\Component;
class RolesAssign extends Component
{
public $search = '';
public $allStaff;
public $allUsers;
public $staff;
public $users;
public function mount()
{
$this->allStaff = Staff::get(['id', 'first_name', 'last_name']);
$this->allUsers = User::get(['id', 'first_name', 'last_name']);
}
public function render()
{
if (strlen($this->search) >= 2) {
$this->staff = Staff::byName($this->search)->get(['id', 'first_name', 'last_name']);
$this->users = User::byName($this->search)->get(['id', 'first_name', 'last_name']);
} else {
$this->staff = $this->allStaff;
$this->users = $this->allUsers;
}
return view('livewire.roles-assign', [
'staff' => $this->staff,
'users' => $this->users,
]);
}
}
id: "KPPiM4iddgxca9BEAgwr"
name: "roles-assign"
dom: "<div wire:id="KPPiM4iddgxca9BEAgwr" class="bg-white shadow overflow-hidden sm:rounded-md mt-10">↵ <div class="flex justify-between items-center px-4 py-5 border-b border-gray-200 sm:px-6">↵ <div>↵ <h3 class="text-lg leading-6 font-medium text-gray-900">↵ Users & Staff↵ </h3>↵ <p class="mt-1 text-sm leading-5 text-gray-500">↵ Search across staff members and users to assign permissions & roles.↵ </p>↵ </div>↵ <div class="flex-1 flex items-center justify-center lg:ml-6 lg:justify-end">↵ <div class="max-w-lg w-full lg:max-w-xs">↵ <label for="search" class="sr-only">Search</label>↵ <div class="relative z-0">↵ <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">↵ <svg class="h-5 w-5 text-gray-400" fill="currentColor" viewBox="0 0 20 20">↵ <path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />↵ </svg>↵ </div>↵ <input wire:model.debounce.500ms="search" id="search" class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:border-blue-300 focus:shadow-outline-blue sm:text-sm transition duration-150 ease-in-out" placeholder="Search users..." />↵ </div>↵ </div>↵ </div>↵ </div>↵↵ <ul>↵ <li>↵ <div class="flex items-center px-4 py-4 sm:px-6">↵ <div class="min-w-0 flex-1 flex items-center">↵ <div class="flex-shrink-0 capitalize">↵ <div>↵ <span class="inline-flex items-center justify-center h-10 w-10 rounded-full bg-brand-light">↵ <span class="text-md font-medium leading-none text-white">DJ</span>↵ </span>↵ </div>↵ </div>↵ <div class="min-w-0 flex-1 px-4 md:grid md:grid-cols-2 md:gap-4">↵ <div>↵ <div class="text-sm leading-5 font-medium text-blue-600 truncate">Dr. John Jekyl, MD</div>↵ </div>↵ <div>↵ <div wire:initial-data="{&quot;id&quot;:&quot;pU9yjtyU1A3mVgo3iFCU&quot;,&quot;name&quot;:&quot;role-selector&quot;,&quot;redirectTo&quot;:false,&quot;events&quot;:[],&quot;eventQueue&quot;:[],&quot;dispatchQueue&quot;:[],&quot;data&quot;:{&quot;person&quot;:{&quot;class&quot;:&quot;App\\Staff&quot;,&quot;id&quot;:&quot;1:100000001&quot;,&quot;relations&quot;:[&quot;roles&quot;],&quot;connection&quot;:&quot;tenant&quot;},&quot;guard&quot;:&quot;staff&quot;},&quot;children&quot;:[],&quot;checksum&quot;:&quot;99ef3c6f5817590080b60fa00c7d122ee7643f46438550f43a71b8e1506736bb&quot;}" wire:id="pU9yjtyU1A3mVgo3iFCU">↵ <div x-data="{editing: false}">↵ ↵ <div class="inline">↵ <span class="mr-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-blue-100 text-blue-800">↵ Staff↵ </span>↵ </div>↵↵ ↵ <button x-show="!editing" class="mr-2 text-sm underline text-gray-500 hover:text-gray-700" @click="editing = true">add/remove roles</button>↵↵ <div x-show="editing" @click.away="editing=false" class="mt-3 flex justify-start">↵ <span class="text-gray-800 mr-4">Click to add/remove roles: </span>↵ <button wire:click="assignRole('Staff')" class="underline mr-2 text-brand-dark sm:text-sm sm:leading-5">↵ Staff↵ </button>↵ </div>↵ </div>↵</div>↵ </div>↵ </div>↵ </div>↵ </div>↵ </li>↵ <li>↵ <div class="flex items-center px-4 py-4 sm:px-6">↵ <div class="min-w-0 flex-1 flex items-center">↵ <div class="flex-shrink-0 capitalize">↵ <div>↵ <span class="inline-flex items-center justify-center h-10 w-10 rounded-full bg-brand-light">↵ <span class="text-md font-medium leading-none text-white">JD</span>↵ </span>↵ </div>↵ </div>↵ <div class="min-w-0 flex-1 px-4 md:grid md:grid-cols-2 md:gap-4">↵ <div>↵ <div class="text-sm leading-5 font-medium text-blue-600 truncate">John Doe</div>↵ </div>↵ <div>↵ <div wire:id="gEt0cfVCvr2Z7c1RWPze"></div> </div>↵ </div>↵ </div>↵ </div>↵ </li>↵ </ul>↵</div>↵"
fromPrefetch: false
redirectTo: false
children: {jekyl-md-1100000001: {id: "pU9yjtyU1A3mVgo3iFCU", tag: "div"},…}
dirtyInputs: ["staff.class", "staff.id", "staff.relations", "staff.connection"]
data: {search: "john ", allStaff: {class: "App\Staff",…},…}
search: "john "
allStaff: {class: "App\Staff",…}
allUsers: {class: "App\User", id: [1], relations: [], connection: "tenant"}
staff: {class: "App\Staff", id: ["1:100000001"], relations: ["roles"], connection: "tenant"}
users: {class: "App\User", id: [1], relations: [], connection: "tenant"}
eventQueue: []
dispatchQueue: []
events: []
checksum: "c8428958b339f2d9620a37a359c24929477b3c023c9cdbcd2a584f5b9f66910c"
{"id":"KPPiM4iddgxca9BEAgwr","name":"roles-assign","dom":"<div wire:id=\"KPPiM4iddgxca9BEAgwr\" class=\"bg-white shadow overflow-hidden sm:rounded-md mt-10\">\n <div class=\"flex justify-between items-center px-4 py-5 border-b border-gray-200 sm:px-6\">\n <div>\n <h3 class=\"text-lg leading-6 font-medium text-gray-900\">\n Users & Staff\n <\/h3>\n <p class=\"mt-1 text-sm leading-5 text-gray-500\">\n Search across staff members and users to assign permissions & roles.\n <\/p>\n <\/div>\n <div class=\"flex-1 flex items-center justify-center lg:ml-6 lg:justify-end\">\n <div class=\"max-w-lg w-full lg:max-w-xs\">\n <label for=\"search\" class=\"sr-only\">Search<\/label>\n <div class=\"relative z-0\">\n <div class=\"absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none\">\n <svg class=\"h-5 w-5 text-gray-400\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path fill-rule=\"evenodd\" d=\"M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z\" clip-rule=\"evenodd\" \/>\n <\/svg>\n <\/div>\n <input wire:model.debounce.500ms=\"search\" id=\"search\" class=\"block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:border-blue-300 focus:shadow-outline-blue sm:text-sm transition duration-150 ease-in-out\" placeholder=\"Search users...\" \/>\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n\n <ul>\n <li>\n <div class=\"flex items-center px-4 py-4 sm:px-6\">\n <div class=\"min-w-0 flex-1 flex items-center\">\n <div class=\"flex-shrink-0 capitalize\">\n <div>\n <span class=\"inline-flex items-center justify-center h-10 w-10 rounded-full bg-brand-light\">\n <span class=\"text-md font-medium leading-none text-white\">DJ<\/span>\n <\/span>\n <\/div>\n <\/div>\n <div class=\"min-w-0 flex-1 px-4 md:grid md:grid-cols-2 md:gap-4\">\n <div>\n <div class=\"text-sm leading-5 font-medium text-blue-600 truncate\">Dr. John Jekyl, MD<\/div>\n <\/div>\n <div>\n <div wire:initial-data=\"{&quot;id&quot;:&quot;pU9yjtyU1A3mVgo3iFCU&quot;,&quot;name&quot;:&quot;role-selector&quot;,&quot;redirectTo&quot;:false,&quot;events&quot;:[],&quot;eventQueue&quot;:[],&quot;dispatchQueue&quot;:[],&quot;data&quot;:{&quot;person&quot;:{&quot;class&quot;:&quot;App\\\\Staff&quot;,&quot;id&quot;:&quot;1:100000001&quot;,&quot;relations&quot;:[&quot;roles&quot;],&quot;connection&quot;:&quot;tenant&quot;},&quot;guard&quot;:&quot;staff&quot;},&quot;children&quot;:[],&quot;checksum&quot;:&quot;99ef3c6f5817590080b60fa00c7d122ee7643f46438550f43a71b8e1506736bb&quot;}\" wire:id=\"pU9yjtyU1A3mVgo3iFCU\">\n <div x-data=\"{editing: false}\">\n \n <div class=\"inline\">\n <span class=\"mr-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium leading-4 bg-blue-100 text-blue-800\">\n Staff\n <\/span>\n <\/div>\n\n \n <button x-show=\"!editing\" class=\"mr-2 text-sm underline text-gray-500 hover:text-gray-700\" @click=\"editing = true\">add\/remove roles<\/button>\n\n <div x-show=\"editing\" @click.away=\"editing=false\" class=\"mt-3 flex justify-start\">\n <span class=\"text-gray-800 mr-4\">Click to add\/remove roles: <\/span>\n <button wire:click=\"assignRole('Staff')\" class=\"underline mr-2 text-brand-dark sm:text-sm sm:leading-5\">\n Staff\n <\/button>\n <\/div>\n <\/div>\n<\/div>\n <\/div>\n <\/div>\n <\/div>\n <\/div>\n <\/li>\n <li>\n <div class=\"flex items-center px-4 py-4 sm:px-6\">\n <div class=\"min-w-0 flex-1 flex items-center\">\n <div class=\"flex-shrink-0 capitalize\">\n <div>\n <span class=\"inline-flex items-center justify-center h-10 w-10 rounded-full bg-brand-light\">\n <span class=\"text-md font-medium leading-none text-white\">JD<\/span>\n <\/span>\n <\/div>\n <\/div>\n <div class=\"min-w-0 flex-1 px-4 md:grid md:grid-cols-2 md:gap-4\">\n <div>\n <div class=\"text-sm leading-5 font-medium text-blue-600 truncate\">John Doe<\/div>\n <\/div>\n <div>\n <div wire:id=\"gEt0cfVCvr2Z7c1RWPze\"><\/div> <\/div>\n <\/div>\n <\/div>\n <\/div>\n <\/li>\n <\/ul>\n<\/div>\n","fromPrefetch":false,"redirectTo":false,"children":{"jekyl-md-1100000001":{"id":"pU9yjtyU1A3mVgo3iFCU","tag":"div"},"doe-1":{"id":"gEt0cfVCvr2Z7c1RWPze","tag":"div"}},"dirtyInputs":["staff.class","staff.id","staff.relations","staff.connection"],"data":{"search":"john ","allStaff":{"class":"App\\Staff","id":["1:100000001","1:100000002","1:100000003","1:100000005","1:100000006","1:100000007","1:2","2:100000001","2:100000002"],"relations":[],"connection":"tenant"},"allUsers":{"class":"App\\User","id":[1],"relations":[],"connection":"tenant"},"staff":{"class":"App\\Staff","id":["1:100000001"],"relations":["roles"],"connection":"tenant"},"users":{"class":"App\\User","id":[1],"relations":[],"connection":"tenant"}},"eventQueue":[],"dispatchQueue":[],"events":[],"checksum":"c8428958b339f2d9620a37a359c24929477b3c023c9cdbcd2a584f5b9f66910c"}
@drfraker
Copy link
Author

drfraker commented Apr 3, 2020

Update #2:
I believe the problem is the same nested component within 2 separate foreach loops. I merged the two collections and looped over the single collection and things appear to be working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment