"selected" not working in dropdown list

Hi all, learning Livewire today and having a few issues. Here’s another.

TL;DR the selected attribute isn’t working even though its definitely being rendered in the right place.

If I do this:

<option value="{{$g->token}}" @if($track->group->token == $g->token) selected @endif>{{$g->name}} </option>

Nothing is selected. However if I change it “disabled” NOTE: changing nothing except what is inside the if statement from “selected” to “disabled” like this

<option value="{{$g->token}}" @if($track->group->token == $g->token) disabled @endif>{{$g->name}} </option>

Then the correct option is disabled.

So the logic if working, the string “selected” is being output in the correct place. It’s just simply not working.

1 Like

Do you have wire:model or something in your JS on the element that is changing the selected option?

If you do try dumping out your $g->token value and the wire:model value and comparing them. It could be something to do with the types. I.e. one is an (string) $g->token and the other is a (int) $g->token

Na it’s not that I don’t think. I tested all that by changing “selected” to “disabled” and when I do that the correct dropdown option IS disabled.

Also I can see via inspect element that the word “selected” is being output at the correct place. It’s just not having the correct behaviour.

If you’re using livewire you shouldn’t need to apply the “selected” string at all.

wire:model on the select should take care of selecting the correct element for you. If you have for example wire:model('optionSelected') on the <select> element and then you set $optionSelected to $g->token then the correct option should automatically be selected. Does that make sense?

**Updated from wire:model(‘optionSelected’) to wire:model=“optionSelected” (sorry that was a typo)

1 Like

Yeah it makes sense… I didn’t know any of that so that’s a whole new avenue for me to explore. Thanks so much for the pointer.

I may be back…

Hmmm, tried this and it stops the form from working

<form wire:submit.prevent="selectNewGroup" class="d-flex flex-row align-items-center">
            @csrf

            <select wire:model('optionSelected')="newlyselectedgroup" name="nsg" id="" class="custom-select py-1">
                <option>Select a group</option>
                @foreach($group as $g)
                    <option {{$optionSelected = $g->token}} value="{{$g->token}}">{{$g->name}} </option>
                @endforeach
            </select>
            <input wire:model="trackid" type="hidden" value="{{$track->id}}">
            <button class="btn-sbx ml-2 btn-sbx-small" type="submit">Save</button>

        </form>

Am I doing it wrong?

This is the way where the form works but the “selected” does not:

<form wire:submit.prevent="selectNewGroup" class="d-flex flex-row align-items-center">
            @csrf

            <select wire:model="newlyselectedgroup" name="nsg" id="" class="custom-select py-1">
                <option>Select a group</option>
                @foreach($group as $g)
                    <option @if($track->group->token ?? "" == $g->token) selected @endif value="{{$g->token}}">{{$g->name}} </option>
                @endforeach
            </select>
            <input wire:model="trackid" type="hidden" value="{{$track->id}}">
            <button class="btn-sbx ml-2 btn-sbx-small" type="submit">Save</button>

        </form>
<form wire:submit.prevent="selectNewGroup" class="d-flex flex-row align-items-center">
    @csrf // I believe this isn't needed in Livewire as it has in-build CSRF protection

    <select wire:model="selectedGroup" name="nsg" id="" class="custom-select py-1">
        <option value="" disabled>Select a group</option>
        @foreach($groups as $group)
            <option value="{{ $group->token }}">{{ $group->name }} </option>
        @endforeach
    </select>
    <input wire:model="trackId" type="hidden" value="{{ $track->id }}"> // Likely not needed. See component example
    <button class="btn-sbx ml-2 btn-sbx-small" type="submit">Save</button>
</form>

Okay so using that as your form looks okay. Then for your component:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Example extends Component
{
    public $groups;
    public $selectedGroup = '';

    public function mount($groups, $track)
    {
        $this->groups = $groups; // These can be passed in or retrieved from the DB here
        $this->track = $track; // These can be passed in or retrieved from the DB here
    }

    public function selectNewGroup()
    {
        // $this->selectedGroup contains the selected value of $group->token
        // $this->track->id contains the value you were using the hidden field for before
        
        // Store it in the database here
    }
}

Try something like this and let me know how you get on. It’s hard to debug without seeing the full component but hopefully this will get you closer to a working solution

OK, from the top… here is the new component and class in full. I believe I have implemented your changes and it all works apart from the original problem of selected dropdown now being auto-selected

<div class="d-flex flex-row align-items-center justify-content-between">

    <p class="card-text m-0 p-0 mr-5" wire:poll>{{$track->track}}</p>
    <div class="d-flex flex-row align-items-center">
        <p class="card-text m-0 p-0 mr-2 text-muted">{{$track->group->name ?? ""}}</p>
        <form wire:submit.prevent="selectNewGroup" class="d-flex flex-row align-items-center">                  <select wire:model="selectedGroup" name="nsg" id="" class="custom-select py-1">
                <option value="">Select a group</option>
                @foreach($groups as $group)
                    <option value="{{ $group->token }}">{{ $group->name }} </option>
                @endforeach
            </select>
            <button class="btn-sbx ml-2 btn-sbx-small" type="submit">Save</button>
        </form>
    </div>
</div>

<?php

namespace App\Http\Livewire;

use App\Group;
use App\Track;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;


class SelectGroup extends Component
{

    public $groups;
    public $tracks;
    public $track;
    public $selectedGroup = '';


    protected $listeners = ['groupsChanged2' => 'recountGroups2'];

    public function mount()
    {
        $user = Auth::user();
        $this->groups = Group::query()->where('user_id', $user->id)->get();
        $this->tracks = Track::query()->where('user_id', $user->id)->orderBy('id', 'asc')->get();
    }

    public function render()
    {
        return view('livewire.select-group');
    }

    public function selectNewGroup()
    {
        $track = Track::query()->where('id', $this->track->id)->first();
        $track->group_token = $this->selectedGroup;
        $track->save();

        $this->emit('groupsChanged');
    }

    public function recountGroups2()
    {
        $user = Auth::user();
        $this->groups = Group::query()->where('user_id', $user->id)->get();
    }
}