livewire: Select element with pre-selected value not rendering correctly
Describe the bug: A select element with a pre selected value does not render correctly for the user
To Reproduce
- Create a blade template with a select element
- Pass a value from livewire to the blade template
- Use standard blade syntax to set the pre-selected value
Expected result: If the second option in the select element is selected then this should be visible to the user when the dom renders.
Actual result: Always the first option in the select element is visible to the user even though another option has the correct html selected tag.
Blade Input:
<select id="role_id" wire:model="role_id">
<option value="1" {{ $role_id == 1 ? 'selected="selected"' : '' }}>Owner</option>
<option value="2" {{ $role_id == 2 ? 'selected="selected"' : '' }}>Collaborator</option>
</select>
HTML Output
<select id="role_id" wire:model="role_id">
<option value="1">Owner</option>
<option value="2" selected="selected">Collaborator</option>
</select>
Screenshots

Desktop (please complete the following information):
- Browser: chrome
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 6
- Comments: 38 (3 by maintainers)
Ok I figured this. to anybody who is still looking.
That’s all you have to do. But initially it won’t be having any value, so you have to set value in mount method like this
and then It will be automatically selected. You can do this in render method too incase you want to set every time component refreshes.
It’s still isn’t fixed.
Here’s the solution in case anyone else is beating their head to the table:
Just don’t refresh the select and no need to add “selected” Basically wrap your select with wire:ignore
<div wire:ignore><select wire:model="mode-name-here"><option>1</option><option>2</option><option>3</option></select></div>Ok, just fixed it and it was quite trivial. My mistake… Setting the
wire:keyfor every item fixed the behavior. The$qpvariable contains the query parameters.@LewisLarsen I use that without issue
<option value="">Select a category</option>(make sure to remove the selected) and set your wire:model item to ‘’ in your component and have it validate to an integer if you want to force a choicealternatively you can set the default value to -1
<option value="-1">Select a category</option>validate you item to ‘required|numeric|min:1’ or ‘digits_between:1,x’ for example if you have X elements and each element is increasing in value. go with the first one 😃
Seeing as this thread comes from 2019, and Livewire has been updated 2 major versions, it’s surprising to see something like this still be an issue. However, reading all these comments, and testing some things, I think it’s clear that this will never be fixed, as this is against how Livewire is functioning.
Let me explain: The Livewire component passes data to a view, and renders it using this data. Because of this, values get manipulated after the HTML is prepared. A simple test can be done with an
input. When you give thisinputa value, and awire:modellinked to a variable with no value, the input is empty. This ties in to what @calebporzio has said about the select:When the linked variable has a value that is in the select, it will automatically be selected on the first render. But, a lot of people forget this, as it doesn’t feel natural. I hit this wall as well. Because HTML automatically sets the first option to render as selected, it feels like it should be selected. However, Livewire has not gotten a value for this select yet. Therefore, on instant submit, it is still empty.
The solution is however relatively simple, and all one has to do is set the value in the component, either the variable itself, or in the
mountfunction, what @jiteshdhamaniya already mentioned:I feel like this issue could simply be closed by giving a hint to this behaviour on the docs.
How and where? I could find nothing in the documentation.
@evergreenwebsystems - this should be fixed in the latest release.
I think the problem is that
$role_idneeds to be a string, and you were setting it to a numeric value. I fixed livewire to handle strings to set the value of a select input.This should be fixed in the latest release (will probably be in v0.1.2)
Also, Livewire intelligently sets selected states, so you can get rid of the manually echoing out
selected="selected"to all who is Still facing this issue use
wire:changeinstead ofwire:modelthis fixed my problem@iforaberepo I understand that it’s still not quite clear. Livewire is, after all, quite a jump from your normal use case in Laravel. I’ll give you some code samples:
Livewire component:
View:
Explanation: When opening this view, and immediately clicking the submit button, the output for this code block will be
null. This is because in Livewire, the value currently set for$statusisnull. However, because HTML by default displays the first option in a select, it looks like an item is selected.There are 2 suggested ways of ensuring the value of
$status:The mount function, as described under the tag ‘Receiving Parameters’, is the
__constructmethod for Livewire components.When adding this function (I usually place it right above the
renderfunction), you can do things to your own wishes before the component is first initialized. By setting$statusin the mount function, it will contain a value, and so when then immediately pressing the submit button, the output will be1; In my most use cases, themountfunction is great for pre-filling variables from a model. This can easily be done using$this->fill($model->getAttributes());.Instead of using the
mountfunction, you can also simply set a default value when setting the public parameter.public $status = 1;will also give the same result.When playing around with these values, you will see that the select will change value upon first render, even though you haven’t touched it. The same goes for inputs, checkboxes, textareas and such. When the
wire:modelis linked, Livewire handles all the necessary steps to fill the fields with data.I hope this clears things up a bit more!
P.S. When typehinting these attributes, an exception will be thrown if the value is not type hinted as
nullable(e.g.?string) when trying to access it without value.I changed $id to string.
'selected'still doesn’t work for my.my code:
This is the only solution that seems to work for me. This is still broken.
Setting
$role_idas a string does indeed fix the issue. Amazing that it also intelligently sets the selected state.Thanks!