Closed leecolarelli closed 3 years ago
The option is not being selected because it is disabled. If you remove that attribute, it will be selected correctly.
Disabled options are generally used for default values when the field is required, forcing people to select and option and not letting them choose the default one. In your case though, the field isn't required by the sounds of it so there should be no harm in making that default option active (not disabled) or instead choosing a better default value.
I think what @leecolarelli means is that it should be possible to set the x-data
with the initial value of a form field. Here is an example:
<form x-data='{ name: null }'>
<input type='text' value='John' x-model='name' />
</form>
If the name is set to null
or to an empty string but the input
binded to the x-model
has an initial value, then this value should be used. In this case, the name variable should be initialized with "John".
I don't know about other back-end frameworks but this would play nicely with Ruby on Rails.
How does Vue handle it?
Ah right, I'm following now. Like @KevinBatdorf said, see what Vue does and that's generally best way to go with how Alpine handles it.
v-model no longer cares about the initial value of an inline value attribute. For predictability, it will instead always treat the Vue instance data as the source of truth. https://vuejs.org/v2/guide/migration.html#value-Attribute-with-v-model-removed
So I guess that settles it! Someone released a vue plugin to bring back the functionality. Maybe that would be possible with Alpine too as a plugin.
Sine you write the html, why don't you put the default value in x-data?
@SimoTod Yes, that's how I'm handling it right now. I inject the model values from the backend in the x-data. It's just that model values are already set in the form fields by default in Rails. So it doesn't feel as DRY to set them again in the x-data.
I don't know if the same goes with other frameworks such as Laravel or Django. I just wish there was a way to "glue" this together somehow!
Maybe be a good addition to the magic helpers library? Something like x-init="$formInit()"
, which could scan all input types and find any server set values... maybe? I don't feel too strongly about it.
I wouldn't bother with it unless a big chunk of Alpine users are also Rails devs. Otherwise it's not a big deal to just inject model attributes in the x-data. For future Rails devs bumping into this ticket, this is the most elegant way I found to make this work:
<form x-data='<%= @my_model.attributes.slice('first_name', 'last_name', 'email').to_json %>'>
We good to close this @leecolarelli ?
You should be able to use x-init
(or even x-data
) to read the current value from the DOM into state.
<div
x-data="{
selected: $el.querySelector('option[selected]').value,
inputValue: $el.querySelector('input').value
}"
>
<select x-model="selected">
<option selected value="hello">hello</option>
</select>
<input value="world" x-model="inputValue" />
<p>Selected: <span x-text="selected"></span></p>
<p>Input value: <span x-text="inputValue"></span></p>
</div>
(As a Codepen: https://codepen.io/hugodf/pen/Vwjqrzq)
Yes sounds good! Thanks
I actually would like to see this functionality. This will save a lot of work. I'm working with asp.net framework.
I actually would like to see this functionality. This will save a lot of work. I'm working with asp.net framework.
If you're willing to create a PR go for it.
Unfortunately since there's a userland workaround and equivalent frameworks don't do this it's very unlikely to be accepted.
If there is enough interest, I could give it a go as a simple magic helper bundled with the other magic helpers or in its own repo. Here's what I have in mind.
$formInit
or $mapFormInputsToModel
(or a better name?) helper can only be called in the x-init
and would take no parameters.x-model
directive and set the model variable with the input value.x-data
object and set to either null or an empty string. Otherwise the input value would be ignored.Does that make sense?
@pomartel sure, might be worth moving the discussion to https://github.com/alpine-collective/alpine-magic-helpers/discussions/33 since we're not talking about Alpine.js changes any more.
I know this is a closed issue, but I stumbled on it while I was looking for a solution to handle this same problem.
I ended up coming up with a solution that I figured I'd share here.
To use Alpine to build the options for a <select>
input and set the correct default <option>
, I use x-bind
on the :selected
attribute and then pass a constructed array of potential default values (i.e. [null, 0, '0', '']
) and check this array against the actual value set in x-data
or $store
using the Array.includes()
method. This lets you still use value as a static attribute or set it dynamically with x-bind
and x-data
.
The <option>
tag ends up looking something like <option :selected="[null, 0, '0', ''].includes(var)" x-text=var disabled hidden value></option>
Caveats
false
as a value in the constructed array. You can only set these as a text value in an HTML form anyway, and type juggling would cause it to evaluate truthaly (if that's a word) – the listed options all evaluate as falsy.disabled
, hidden
and value
attributes included with the "default" option. This allows the browser to remove it as an option from the <select>
once a User clicks the input. You can remove those if you want the default also to be an option.I put together my first pen on CodePen as a demo.
Found a small issue today when trying to set up a select option on an alpine form... if the x-data for the select x-model is blank, and the form is submitted, then no data for the select form is included.
This seems obvious since the user didn't choose an option, and the x-model/x-data is blank on page load, but often a user will leave a select form if the correct option is already displayed.
Here's a codepen to highlight the issue - https://codepen.io/leecolarelli/pen/PozxLGY
I think therefore that it would be better if alpine has a way to load the displayed option if no selection is made.
I was going to try and make a pull request but don't currently have time, and probably don't have the skills :)