skip to Main Content

When i have a mini multistep form the radio button value of step 2 is overwriting the value of step 1. See code below.

enter image description here

The component

<?php
// app/Livewire/Counter.php
namespace AppLivewire;

use LivewireComponent;

class Counter extends Component
{
    public $count = 1;
    public $one;
    public $two;

    public function increment()
    {
        $this->count++;
    }

    public function decrement()
    {
        $this->count--;
    }


    public function render()
    {
        return view('livewire.counter');
    }
}

The view

<div>
    <div class="p-10">
        <button wire:click="decrement" class="bg-green-500 p-4">-</button>
        <button wire:click="increment" class="bg-green-500 p-4">+</button>

        <h1>Count: {{ $count }}</h1>

        <br>

        @if ($count == 1)
            <input type="radio" name="page1" wire:model.live="one" value="1">
            <input type="radio" name="page1" wire:model.live="one" value="2">
            <input type="radio" name="page1" wire:model.live="one" value="3">
        @elseif($count == 2)
            <input type="radio" name="page2" wire:model.live="two" value="1">
            <input type="radio" name="page2" wire:model.live="two" value="2">
            <input type="radio" name="page2" wire:model.live="two" value="3">
        @endif

        <br>

        <p>Page one: {{ $one }}</p>
        <p>Page two: {{ $two }}</p>
    </div>
</div>

Layout

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])
    </head>
    <body class="font-sans antialiased">
        <livewire:counter />
    </body>
</html>

  • Livewire version v3.5.9
  • Laravel version v11.26.0
  • PHP 8.2

Steps To Reproduce

  1. Create component with below details.
  2. Choose a value for radio button
  3. Confirm the answer is displayed on screen
  4. Go to next step with + button
  5. Choose another value for the second set of radio buttons
  6. Confirm the answer is displayed on screen

What I expect:
The radio buttons on page one and page two should work independently

What I actually get:
The radio button value of step one is overwritten as soon as I pick a value in step two

Live testable demo: https://wirebox.app/b/4oedw

2

Answers


  1. Chosen as BEST ANSWER

    The Livewire solution is to add wire:key to the inputs. Like so:

    @if ($count == 1)
                <input type="radio" name="page1" wire:key="page1-1" wire:model.live="one" value="1">
                <input type="radio" name="page1" wire:key="page1-2" wire:model.live="one" value="2">
                <input type="radio" name="page1" wire:key="page1-3" wire:model.live="one" value="3">
            @elseif($count == 2)
                <input type="radio" name="page2" wire:key="page2-1" wire:model.live="two" value="1">
                <input type="radio" name="page2" wire:key="page2-2" wire:model.live="two" value="2">
                <input type="radio" name="page2" wire:key="page2-3" wire:model.live="two" value="3">
            @endif
    

    Credits to Josh Hanley on the livewire discord who said: Livewire doesn’t know that you’ve changed the inputs without help. So you need to use wire:key on each of the inputs inside the conditionals to tell livewire that they are different.


  2. i found whats wrong it has mostly to do with the dissapearing of the input fields. i belive this can cause it to search for the next valid value the fix that i found was with using class="hidden" so it doesnt dissapear

         <div class="@if ($count != 1) hidden @endif">
            <input type="radio" name="page1" wire:model.live="one" value="1">
            <input type="radio" name="page1" wire:model.live="one" value="2">
            <input type="radio" name="page1" wire:model.live="one" value="3">
        </div>
        <div class="@if ($count != 2) hidden @endif">
            <input type="radio" name="page2" wire:model.live="two" value="4">
            <input type="radio" name="page2" wire:model.live="two" value="5">
            <input type="radio" name="page2" wire:model.live="two" value="6">
        </div>
    

    or

    this is another solution i found but its realy wierd and i dont uderstand why it works. It looks like it doesnt seperate the radios on thier name but for all of them that are currently on the page also the solotion for this one is to give them all unique ids

        @if ($count == 1)
            <input id="1" type="radio" name="random" wire:model.live="one" value="1">
            <input id="2" type="radio" name="page1" wire:model.live="one" value="2">
            <input id="3" type="radio" name="page1" wire:model.live="one" value="3">
        @elseif($count == 2)
            <input id="4" type="radio" name="page2" wire:model.live="two" value="4">
            <input id="5" type="radio" name="page2" wire:model.live="two" value="5">
            <input id="6" type="radio" name="page2" wire:model.live="two" value="6">
        @endif
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search