disable selected option from select using vue - vue.js

i have this select and i want to make it so that when I press any of the options, the option i pressed gets disabled so the user can see the option he selected easier.
<select v-model="modalIU.inpIdSpecialitate" v-on:change="disableEnable()">
<option :value='null'>.:: fără legătură specialitate ::.</option>
<option v-for="item in allSectiiSpecialitati.filter(el => el.idSpecialitate !== null).sort((a, b) => (a.denumireSpecialitate > b.denumireSpecialitate) ? 1 : -1)" :value="item.idSpecialitate">#{{ item.denumireSpecialitate }}</option>
</select>

I just created a codesandbox example for this functionality, I added a disabled property for each option, and on change event listner, I get the option index, and make it disabled.
https://codesandbox.io/s/elated-smoke-lwcriw?file=/src/components/DisabledOptionOnSelect.vue:351-513

There's no need to add a custom method, you can work with v-model and the data you already have.
Add a :disabled='modalIU.inpIdSpecialitate === item.inpIdSpecialitate' on the option with the v-for, so you conditionally disable the option if it is the one currently selected.
You can then remove the v-on:change="disableEnable()". Also consider adding a :key attribute to your v-for for best practice.

Related

How can I use the selected prop in a <select> that has a v-model?

Problem:
I have a <select> that uses a v-model to save the selected options into an array. The problem is that I can't use the selected properties on one of the <options> because the v-model ingores that and instead uses the bound JavaScript as it's source of truth.
What I have tried:
I tried looking up my problem on StackOverflow and I have found two questions but they didn't really help nor explain why and how. Here are the posts I have looked at:
using v-model on makes first option not appear in select - I tried this but nothing changed. My selected appear as selected but it was disabled.
Vue v-model with select input - the accepted answer wants me to define it in data and set it to null but that doesn't work when you take a quick glance at my code.
Code:
<select v-model="payload[index]" type="text">
<option v-if="entry.system_role !== null" selected :value="entry.system_role">
{{ entry.system_role }}
</option>
<option v-for="role in entry.roles" :key="entry.id" :value="role">
{{ role }}
</option>
</select>
That is the section with the select and as you can see the v-model is an array which I simply can't set to null. index is from a higher up v-for that renders the amount of <select>.
I tried setting selected to disabled and :value="entry.system_role" to value="" and leaving it empty (but I need the value of this option). Is there anything I can do to make it work? Maybe with a computed or method?

option not being selected by default unless it's value is null vue

I have a select with multiple options. What I'm trying to achieve is to have one option which is selected by default and disabled so you can't click it again (I want it to work similar to a placeholder).
The problem is that the disabled and selected tags don't work unless the value is null.
I already have an option with the value null (the 2nd option), which means that when I try to press it, it automatically selects the disabled option.
This is my code:
<label>Selectează specialitatea</label>
<select v-model="modalIU.inpIdSpecialitate">
<option :value="null" disabled selected class="uk-text-muted">Selectează specialitatea</option>
<option :value='null'>Fără legătură specialitate</option>
<option v-for="item in allSectiiSpecialitati.filter(el => el.idSpecialitate !== null).sort((a, b) => (a.denumireSpecialitate > b.denumireSpecialitate) ? 1 : -1)">#{{ item.denumireSpecialitate }}</option>
</select>
And this what i'm trying to achieve with the first option being selected by default, but disabled so you can't select it again.
Found the solution. Instead of giving both of my option the value null, I give null to the disabled option and the other selectable option is "".

Why are my Vue/Nuxt Select field states valid by default?

I have a variety of HTML select elements inside of Nuxt.js. I'm also using Vuelidate for validation and this is working as expected. This is a typical select box in my form:
<select
id="location"
name="location"
v-model="form.location"
#blur="$v.form.location.$touch()"
:class="{error: appendErrorClass($v.form.location)}"
>
<option :value="null" hidden>Choose...</option>
<option
v-for="(item, index) in $store.state.quotes.data.practiceStates"
:key="index"
:value="item.data">
{{item.display}}
</option>
</select>
Before selecting any of the options, I'm noticing the following on all select fields.
I've tried removing any Vue magic on a test select field to see if the same results happen.
<select id="location1" name="location1">
<option value="" hidden>Choose...</option>
<option value="one">one</option>
<option value="two">two</option>
<option value="three">three</option>
</select>
Still seeing valid: true. Is there anything I'm overlooking that would cause the validity to default to true? Thanks in advance for any help or guidance on this issue.
UPDATE For Clarification:
Vuelidate validation works just fine. The issue I'm dealing with is the select field property Validity.validate. I only mention Vuelidate to give full context.
HTML Select is a sort of "strange" form element in that validity is typically checking to see if there's a readable value. Since a select always has something picked, it validates...
This is different from say a telephone input that has a specific pattern required to be valid.
I haven't used Vuelidate specifically, but I read the docs as saying, if you left the v-model="form.location" there's a good chance it's simply validating that a value exists so Any selcted item would qualify.
In my original post, I referenced the dynamic style based on the vuelidate library: :class="{error: appendErrorClass($v.form.location)}"
#PierreSaid responded to this post and later deleted his/her reply. Turns out, his response was helpful in pointing me to some Vuelidate attributes that were able to assist in a workaround for my issue. Thank you, PierreSaid.
I have since updated that dynamic class to be a mixin that looks like this:
export default {
methods: {
appendErrorAndValidityClass(field) {
return {
error: field.$error,
invalid: field.$invalid,
};
}
}
};
After importing the mixin into the Vue partial, my select box looks like this:
<select
id="location"
name="location"
v-model="form.location"
#blur="$v.form.location.$touch()"
:class="appendErrorAndValidityClass($v.form.location)"
>
This appends a class of invalid when the select field has not been updated. It also updates the error style accordingly. Now, I can assign styles for when the select field has an invalid class. This solves the overall issue for me. Thanks for your help PierreSaid and Bryce.

Access directive state and populate ngFor

I have settings in a backend exposed via a service. It's very common to wire up widgets over and over to settings, so I created a directive to allow setting the unique name of the setting to attach a widget to:
<dropdown appSetting="uniqueName">
I've got the two way binding working.
Now in settings that represent groups there's an enum that defines the options. I'd like to use the bound setting to populate the ngFor for the children:
<dropdown appSetting="uniqueName" #selector>
<option *ngFor="let option of selector.setting.options">
Obviously that doesn't work. I can't access directive state. Most of the things I tried ended up with an undefined ngForOf or the wonderful ExpressionChangedAfterItHasBeenCheckedError. Is there a clean way to leverage the existing directive to populate the children?
(I've tried a custom *appFor, but couldn't quite get it working)
Better Answer:
Directives have an export ability that allows them to be referenced. Just needed to add:
#Directive({
selector: '[appSetting]',
exportAs: 'appSetting'
})
Then access as:
<dropdown
appSetting="uniqueName" #varId="appSetting"
[(ngModel)]="varId.settingValue">
<option *ngFor="let option of varId.options" [value]="option">{{ option }}</option>
</dropdown>
Original Answer
A simple wrapper component did the job giving access to the state of a setting for any object in the template:
<setting-group #setting
[uniqueName]="foo">
<dropdown
[(ngModel)]="setting.settingValue">
<option *ngFor="let option of setting.options">{{ option }}</option>
</dropdown>
</setting-group>
If there's a way to avoid the one-off wrapper for this, please let me know.

Filtering Select - How to add a blank option '-' that allows submission in Dojo

Been trying to fix this for a while now. I have loads of Dojo Filtering Select elements in my form. I need them to have a blank option which should be selected by default. Here is an example (of a normal <select> structure) that I want to emulate:
<select>
<option value="">-</option>
<option value="foo">Bar</option>
</select>
At present when I load up my filtering selects that have the options set as above, there is no element selected. This in turn disables form submission. This is totally unusable for my end users as they would have no idea why the form is not working. The selects are not even required fields.
The problem lies in the way the FilteringSelect stores it's data. It keeps them in a data store that requires an identifier and a label. You can't quite emulate the functionality of a plain select because of this.
You can 'get around' this by putting a fake item in your options with a value of 'XXXX' (or another fake value).
<select>
<option value="XXXX">-</option>
<option value="foo">Bar</option>
</select>
One downside of this kludge is that you need to change your validation functions to look for this fake value (instead of an empty value).
I set up a test on jsbin.com where you can see it in action.