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

krutsednar's avatar

Larave Livewire show input field if Others is selected

I'm struggling to show input field when others is selected. In my code, the input field appears and disappears after a few second. I tried removing the wire:model on my selection and the input field does not disappear but I can't mount the data.

Controller:

<?php

namespace App\Http\Livewire\User;

use App\Models\Role;
use App\Models\User;
use Livewire\Component;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class Create extends Component
{
    public User $user;

    public array $roles = [];

    public string $password = '';

    public array $listsForFields = [];


    public function mount(User $user, Request $request)
    {

        $this->user = $user;
        $this->initListsForFields();
    }

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

    public function submit(Request $request)
    {
        $this->validate();
        $this->user->password = $this->password;
        
        $this->user->save();
        $this->user->roles()->sync($this->roles);

        return redirect()->route('admin.users.index');
    }

    protected function rules(): array
    {
        return [
            'user.name' => [
                'string',
                'required',
            ],
            'user.email' => [
                'email:rfc',
                'required',
                'unique:users,email',
            ],
            'password' => [
                'string',
                'required',
            ],
            'roles' => [
                'required',
                'array',
            ],
            'roles.*.id' => [
                'integer',
                'exists:roles,id',
            ],
            'user.locale' => [
                'string',
                'nullable',
            ],
            'user.test' => [
                'nullable',
            ],
        ];
    }

    protected function initListsForFields(): void
    {
        $this->listsForFields['roles'] = Role::pluck('title', 'id')->toArray();
    }
}

Blade:

<form wire:submit.prevent="submit" class="pt-3">

    <div class="form-group {{ $errors->has('user.name') ? 'invalid' : '' }}">
        <label class="form-label required" for="name">{{ trans('cruds.user.fields.name') }}</label>
        <input class="form-control" type="text" name="name" id="name" required wire:model.defer="user.name">
        <div class="validation-message">
            {{ $errors->first('user.name') }}
        </div>
        <div class="help-block">
            {{ trans('cruds.user.fields.name_helper') }}
        </div>
    </div>
    <div class="form-group {{ $errors->has('user.email') ? 'invalid' : '' }}">
        <label class="form-label required" for="email">{{ trans('cruds.user.fields.email') }}</label>
        <input class="form-control" type="email" name="email" id="email" required wire:model.defer="user.email">
        <div class="validation-message">
            {{ $errors->first('user.email') }}
        </div>
        <div class="help-block">
            {{ trans('cruds.user.fields.email_helper') }}
        </div>
    </div>
    <div class="form-group {{ $errors->has('user.password') ? 'invalid' : '' }}">
        <label class="form-label required" for="password">{{ trans('cruds.user.fields.password') }}</label>
        <input class="form-control" type="password" name="password" id="password" required wire:model.defer="password">
        <div class="validation-message">
            {{ $errors->first('user.password') }}
        </div>
        <div class="help-block">
            {{ trans('cruds.user.fields.password_helper') }}
        </div>
    </div>
    <div class="form-group {{ $errors->has('roles') ? 'invalid' : '' }}">
        <label class="form-label required" for="roles">{{ trans('cruds.user.fields.roles') }}</label>
        <x-select-list class="form-control" required id="roles" name="roles" wire:model="roles" :options="$this->listsForFields['roles']" multiple />
        <div class="validation-message">
            {{ $errors->first('roles') }}
        </div>
        <div class="help-block">
            {{ trans('cruds.user.fields.roles_helper') }}
        </div>
    </div>
    <div class="form-group {{ $errors->has('user.locale') ? 'invalid' : '' }}">
        <label class="form-label" for="locale">{{ trans('cruds.user.fields.locale') }}</label>
        <input class="form-control" type="text" name="locale" id="locale" wire:model.defer="user.locale">
        <div class="validation-message">
            {{ $errors->first('user.locale') }}
        </div>
        <div class="help-block">
            {{ trans('cruds.user.fields.locale_helper') }}
        </div>
    </div>
    <div class="form-group {{ $errors->has('user.test') ? 'invalid' : '' }}">
        <label class="form-label">{{ trans('cruds.user.fields.test') }}</label>
        <select onchange="testCheck(this);" class="form-control" name="test" wire:model="user.test">
            <option selected value="null" disabled>{{ trans('global.pleaseSelect') }}...</option>
            <option selected value="Yes" >Yes</option>
			<option selected value="No" >No</option>
			<option selected value="Others" >Others</option>
        </select>
        <div class="validation-message">
            {{ $errors->first('user.test') }}
        </div>
        <div class="help-block">
            {{ trans('cruds.user.fields.test_helper') }}
        </div>
    </div>

    <div id="testInput" style="display: none;" class="form-group">
        <label class="form-label required" for="testInput">Input Test</label>
        <input class="form-control" type="text" name="testInput" id="testInput" wire:model="user.test" style="text-transform:uppercase">
    </div>

    <div class="form-group">
        <button class="mr-2 btn btn-indigo" type="submit">
            {{ trans('global.save') }}
        </button>
        <a href="{{ route('admin.users.index') }}" class="btn btn-secondary">
            {{ trans('global.cancel') }}
        </a>
    </div>
</form>

<script>
function testCheck(that) {
    if (that.value == "Others") {
        document.getElementById("testInput").style.display = "block";
    } else {
        document.getElementById("testInput").style.display = "none";
    }
}

</script>


if I remove wire:model="user.test" then the input field won't disapper after selecting Others

Can anyone help?

0 likes
3 replies
vincent15000's avatar

According to what I usually do, you have 3 ways to do that :

  • with vanilla JS or jQuery, you have to listen to the select or change event on your select field and test if the selected option is Others (for now you only test the value, but you don't listen to any event

  • with Livewire, you check the user.test value with updatedUserTest() in the controller and you set a $othersVisible variable to true or false according to the selected value and you use this variable to display the other inputs @if ($othersVisible) ... @endif

  • with AlpineJS, this is also very easy to do with x-if

krutsednar's avatar

@vincent15000 thank you for your reply sir. can you show me how to do the 2nd option? if it's ok with you

1 like
vincent15000's avatar

@krutsednar In your Livewire controller, you can add this.

public function updatedUserTest($value)
{
	// dd('test');
	$this->othersVisible = $value == 'Others'; 
}

I only have some doubt about the method updatedUserTest(), I already used it with a model, so you have to test if the event is thrown or not when you change the selection (via the commented dd()).

If it doesn't work, this will work instead.

public function updatedUser()
{
	// dd($this->user->test);
    $this->othersVisible = $this->user->test == 'Others'; 
}

And in your view, you can add this.

@if ($othersVisible)
    <div id="testInput" class="form-group">
        <label class="form-label required" for="testInput">Input Test</label>
        <input class="form-control" type="text" name="testInput" id="testInput" wire:model="user.test" style="text-transform:uppercase">
    </div>
@endif

Please or to participate in this conversation.