Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Jdubstep1357's avatar

Difficulty with using wire:key and wire:click

I made a group of radio buttons that when clicked show a table on a different part of my page. What's strange is that every time I click on the radio button, the entire top table disappears. The bottom table is changed. I read up on using wire:key, but wire:key does not listen for a click event.

Here is my top table, which after clicking on the radio button, the entire table except for the header dissapears:

					<tbody>
                           <div wire:model="product" name="product">
                               @foreach ($products as $product)
                               <tr>
                                   <td>
                                       <input type="radio" name="displayBtn" wire:click="display({{ $product->id }})" />
                                   </td>
                                   <td class="p-2 border-b border-l text-left" value="{{ $product->id }}">{{ $product->Date }}</td>
                                   <td class="p-2 border-b border-l text-left" value="{{ $product->id }}">{{ $product->FLA }}</td>
                                   <td class="p-2 border-b border-l text-left" value="{{ $product->id }}">{{ $product->Location_Name }}</td>
                                   <td class="p-2 border-b border-l text-left" value="{{ $product->id }}">{{ $product->Max_Students }}</td>

                               </tr>
                                   @endforeach
                           </div>
                       </tbody>```



Here is my bottom table, which changes successfully after clicking on the radio button:

           
```<div>
               <div x-show="show">
            
                   <!-- SECOND TABLE -->
           
                       <h1>Table 2</h1>
                       <table>
                           <thead>
                               <tr>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Name</th>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Company</th>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Sign-Up-date</th>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Fee</th>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Status</th>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Inv #</th>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Email</th>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Phone</th>
                                       <th class="font-bold py-2 px-4 border-b border-l text-left">Test?</th>
                               </tr>
                           </thead>
                           <tbody>
                               <div>
                                   @foreach ($sizes as $size)
                                   <tr>
                                       <td class="p-2 border-b border-l text-left" value="{{ $size->id }}">{{ $size->Student_First_Name }} {{ $size->Student_Last_Name }}</td>
                                       <td class="p-2 border-b border-l text-left"></td>
                                       <td class="p-2 border-b border-l text-left"></td>
                                       <td class="p-2 border-b border-l text-left"></td>
                                       <td class="p-2 border-b border-l text-left"></td>
                                       <td class="p-2 border-b border-l text-left"></td>
                                       <td class="p-2 border-b border-l text-left"></td>
                                       <td class="p-2 border-b border-l text-left">{{ $size->Phone }}</td>
                                       <td class="p-2 border-b border-l text-left">{{ $size->Email }}</td>
                                       <td class="p-2 border-b border-l text-left"></td>
                                   </tr>
                                       @endforeach
                               </div>
                           </tbody>
                       </table>
                   </div>
                   <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full">Print Cities</button>

               </div>```
0 likes
42 replies
Jdubstep1357's avatar

@vincent15000 I tried putting wire:ignore at the top of the . Upon clicking it still causes the first table to go dissapear.

1 like
Jdubstep1357's avatar

@vincent15000

     <tbody wire:ignore>
                        <div wire:model="product" name="product">
                            @foreach ($products as $product)
                                <tr>
                                    <td>
                                        <input type="radio" name="displayBtn" wire:click="display({{ $product->id }})" />
                                    </td>
                                    <td class="p-2 border-b border-l text-left" value="{{ $product->id }}">{{ $product->Date }}</td>
                                    <td class="p-2 border-b border-l text-left" value="{{ $product->id }}">{{ $product->FLA }}</td>
                                    <td class="p-2 border-b border-l text-left" value="{{ $product->id }}">{{ $product->Location_Name }}</td>
                                    <td class="p-2 border-b border-l text-left" value="{{ $product->id }}">{{ $product->Max_Students }}</td>
                                </tr>
                          
                                @endforeach
                        </div>
                    </tbody>

The first part of my code that has a dropdown selection box.

<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<div x-data="{ show: false }" class="grid grid-col-12 h-screen flex items-center justify-center">
    <div class="col-sm-6">
        <!-- FIRST DROPDOWN -->
            <label class="block text-sm font-medium text-gray-700" for="category"> Regions </label>
            <select wire:model="category" name="category"    
                class="rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" required>
                <option value="">-- Pick a class --</option>
                @foreach ($categories as $category)
                    <option value="{{ $category->id }}">{{ $category->FLA }}</option>
                @endforeach
            </select>

I also added a at the first line and last line of my file.

1 like
vincent15000's avatar

@Jdubstep1357 I don't really understand what you really need to do with the radio buttons and the table.

Are you french ? I am ... I see the Eiffel tower behind you on your image. Don't hesitate to explain in french if you want.

Jdubstep1357's avatar

@vincent15000 I am not French lol

Going back to my main problem: I have a table with radio buttons. On click it is supposed to trigger a query that displays a second table based on the top table's id.

When clicked, the bottom table's data is shown, but for whatever reason, everything inside of the gets deleted, or hidden. If I inspect the element after clicking on the radio button, it appears to not be shown at all.

1 like
vincent15000's avatar

@Jdubstep1357 Each time you do an action that modifies any content of the view, the component will be automatically reloaded. If a part of this component had loaded any JS script, I think that this JS script isn't reloaded once again, this could cause some strange behavior when you try to use for example Livewire and JQuery (what is perhaps not your case, but it's only an example).

If I summarize, when you click on the radio button, the first table disappears and the second one appears. But you don't want that the first one disappears.

Rather than doing this with Livewire, you should perhaps try to use only AlpineJS to handle the radio buttons and the show / hide of the tables.

1 like
Jdubstep1357's avatar

@vincent15000 I only used javascript to show the table on click. If I get rid of the javascript the same result happens

1 like
vincent15000's avatar

@Jdubstep1357 Ok thank you for the screenshots.

I assume that the display({{ $product->id }}) method retrieves datas in the database to display the second table.

I see that you don't use any wire:key. I would add this.

<input type="radio" name="displayBtn" wire:click="display({{ $product->id }})" wire:key="'radio-'.$product->id" />
1 like
Jdubstep1357's avatar

@vincent15000 Hmm. Unfortunately, that doesn't seem to work. I even got rid of all my javascript. I think this has to be a controller-query issue. I posted my controller below, and also added the first dropdown button.

1 like
vincent15000's avatar

@Jdubstep1357 Sorry there was an error.

<input type="radio" name="displayBtn" wire:click="display({{ $product->id }})" wire:key="radio-{{ $product->id }}" />
Jdubstep1357's avatar

Here is my controller:

    public $category = null; 
    public $product = null; 
    public $size = null;


    public Collection $categories;
    public Collection $products;
    public Collection $sizes;
 
    // DROPDOWN SELECTION BOX
    public function mount(): void
    {
        $this->categories = CourseModel::all();
        $this->products = collect();
        $this->sizes = collect();    
    }

    // FIRST TABLE WITH DROPDOWN BOX    
    public function updatedCategory($value): void 
    {
        $this->sizes = collect();
        $this->reset('size', 'product');

        $this->products = CourseModel::select('class_date.id', 'Date', 'Course_Name', 'FLA', 'Location_Name', 'Max_Students', 'Is_Primary')
        ->join('class_date','class_date.Course_ID','=','course.id')
        ->join('class_location','class_date.Location_ID','=','class_location.id')
        ->where('Course_ID', $value)
        ->get();
    } 

    // SECOND TABLE WITH RADIO BUTTON
    public function display(int $id): void
     {
        if(! is_null($id)) {
            $this->sizes = Class_DateModel::select(
                'Student_First_Name', 'Student_Last_Name', 'Phone', 'Email',
                'class_date.id', 'Date', 'Course_Name', 'FLA', 'Location_Name', 'Max_Students', 'Is_Primary'
                )
            ->join('course','Course_ID','=','course.id')
            ->join('class_location','class_location.id','=','Location_ID')
            ->join('address','Address_ID_FK','=','address.id')
            ->join('student','Student_Address_ID','=','address.id')
            ->where('Location_ID', $id)
            ->get();

            $this->size = $this->sizes->first()->id ?? null;        
        }
    }
    

    public function render(): View
    {
        return view('livewire.review_roster_final');
    }```
1 like
Jdubstep1357's avatar

@vincent15000 Ahhh. Interesting! I got this error:

Illuminate\Database\Eloquent\Collection {#498 ▼ // app\Http\Livewire\Review_Roster_Final.php:61

#items: []

#escapeWhenCastingToString: false

}

1 like
Jdubstep1357's avatar

@vincent15000 Sure thing!

    public function display(int $id): void
     {
        if(! is_null($id)) {
            $this->sizes = Class_DateModel::select(
                'Student_First_Name', 'Student_Last_Name', 'Phone', 'Email',
                'class_date.id', 'Date', 'Course_Name', 'FLA', 'Location_Name', 'Max_Students', 'Is_Primary'
                )
            ->join('course','Course_ID','=','course.id')
            ->join('class_location','class_location.id','=','Location_ID')
            ->join('address','Address_ID_FK','=','address.id')
            ->join('student','Student_Address_ID','=','address.id')
            ->where('Location_ID', $id)
            ->get();

            dd($this->products);

            $this->size = $this->sizes->first()->id ?? null;        
        }
    }```
1 like
vincent15000's avatar

@Jdubstep1357 Now the idea is to understand why the $products variable is empty after having clicked on a radio button.

Sorry I have to go, I come back soon.

Jdubstep1357's avatar

@vincent15000 That's fine Vincent. Ill be here most of the day. Thank you again for your help. You have been very helpful and I am most grateful

1 like
Jdubstep1357's avatar

I think the question that needs to be asked is:

how to change escapeWhenCastingToString to true.

I believe the query is not accepting any values after the button is clicked due to some values not being able to be cast as String... which is bizzare, since they were originally shown when clicked upon the dropdown.

1 like
vincent15000's avatar

@Jdubstep1357 Which category ... ? see this comment below => // is $value a category id ?

    public function updatedCategory($value): void 
    {
        $this->sizes = collect();
        $this->reset('size', 'product');

        $this->products = CourseModel::select('class_date.id', 'Date', 'Course_Name', 'FLA', 'Location_Name', 'Max_Students', 'Is_Primary')
        ->join('class_date','class_date.Course_ID','=','course.id')
        ->join('class_location','class_date.Location_ID','=','class_location.id')
        ->where('Course_ID', $value) // is $value a category id ?
        ->get();
    } 

If the $posts variable is empty, this can occur because there is a category update, or another reason. So you need to explore all possible causes, even those who are unbelievable.

Jdubstep1357's avatar

@vincent15000 I see what you mean.

$value is tied into id of the selected dropdown field listed above.

There are 3 different queries:

  1. The selection of the FLA field, which is tied into ID of the course table
  2. The radio button is tied into the table, whose value is the Course_ID inside of the course table, which relates back to the ID of the course table
  3. The final table is based upon the the value of one of the foreign keys on a different table: class_date, whose value is that of the second query

I know this may sound confusing and I am going to attach a document if you still need some clarification.

1 like
Jdubstep1357's avatar

@vincent15000 It's not null. It display normally as the referenced value above: in this case 1406.

The value stays the same regardless of whether I dd($this->category) in the display function or the updatedCategory function

1 like
vincent15000's avatar

@Jdubstep1357 You should install the Livewire devtool for your browser. This will help you to observe all the Livewire components, variables, ...

1 like
Jdubstep1357's avatar

@vincent15000 Thank you for the recommendation!

I used Livewire dev tools, and can show you the output. What's weird is that nothing seems to be passed into arrays. It recognizes the products value, and also the size of the bottom table. But as to 'why' the top data is disappearing, I am befuddled.

First before any selection: https://imgur.com/a/h0nPg2z

Second after clicking on the dropdown: https://imgur.com/7DLvkDU

Finally, after clicking on the first radio button: https://imgur.com/o1vjdoJ

1 like
Jdubstep1357's avatar

What's strange, is that I can continuously requery so to speak. Meaning:

  1. I can take the drop-down
  2. Click on the radio button to display the lower table, but get rid of the upper table's data
  3. Can reselect option from upper dropdown
  4. Rinse and repeat
1 like
Jdubstep1357's avatar
Jdubstep1357
OP
Best Answer
Level 2

@vincent15000 I think I know what my problem is.

Earlier on, I was able to successfully create a 3 level dropdown with a simpler, more intuitive database. I literally copied and pasted all the code except for the queries into the current project I am working on.

Here is MY take:

In my simpler database, all of the dropdowns were related to each other, whose values were dependent on each other For example Query1->Query2->Query3

The other example I have has multiple connections across different tables, with many of the tables not relating to each other. I believe this issue is a query error and nothing to do withsomuch as a logical error on livewire's part. I am going to try and update my query to make sure that all of the connections are in straight path, instead of sprawling all over the place.

vincent15000's avatar

@Jdubstep1357 Do you have your code on github ? I would be interested in solving your problem because there is no reason why the products become null when you click on a radio button. You necessarily have something wrong in your code.

1 like
Jdubstep1357's avatar

@vincent15000 Your comments have helped me tremendously. I have a much better understanding of livewire as a whole. As it turns out I had an issue with my query itself. Once I fixed that, it worked perfectly.

1 like

Please or to participate in this conversation.