I have dynamically generated multiple select elements in a page. And I have used
v-model = "selected_option"
for getting the value of the option selected . But all the select elements in the page have different option values and none of the select elements have any common default option value. All the select elements need to have the first option element as the default selected value. But if I write
selected_option = ''
then all the select elements are showing blank by default.
I can get the first option value as the default selected value if I remove
v-model = "selected_option"
and
selected_option = ''
but then I am not being able to get the selected value in the #change method . Here is my code
<div v-if="row.answer_input_type === 'Dropdown'">
<template v-for="answer in answers">
<template v-if="answer.AnswerTypeID === row.answer_type_id">
<select class="dropdown_cl" v-bind:disabled="row.is_enabled == 1 ? false : true" #change="selectChange(row.question_id)" v-model="selected_option">
<option v-for="option in answer.AnswerDescription" v-bind:value="option.AnswerMasterID" >{{option.AnswerDescription}}</option>
</select>
<p v-for="option in answer.AnswerDescription">{{option.AnswerMasterID}}</p>
</template>
</template>
</div>
the default value has been assigned as follows -
el : '...'
data : {
...
selected_option: '';
},
methods: {
selectChange: function(question_id) {
var self=this;
alert(question_id + " " + self.selected_option);
},
...
},
....
I need each select to have the first option as the default selected value. How can I do this? thanks
Here is a quick example of what I was explaining in comments.
<select v-for="answer in answers"
v-model="answer.selectedOption">
<option v-for="option in answer.options"
:value="option">
{{option}}
</option>
</select>
Example.
If you take this approach, you can manage the default option for each individual select. You also will know what was selected for each answer automatically.
Related
I have created a Select Option, in which one option is by default selected. In example one below, the default selected option is visibly selected within the select bar before opening it.
<select v-model="formData.replyMethod">
<option value="" selected {{ $t(`files.homeName`)}}</option> # This is visibly selected
<option value="1" selected {{ $t(`files.foo`)}}</option>
<option value="2" selected {{ $t(`files.bar`)}}</option>
</select>
However when moving to a Computed Property & V-For, the selected option is selected, but not visibly (you have to open the list to see that now), in its place is a blank bar.
What is causing the difference in output between these two ways of creating a list?
Example 2:
<select v-model="formData.replyMethod">
<option v-bind:value="selectedOption.id" selected>{{ $t(selectedOption.name) }}</option>
<option v-bind:value="selectOpts.id" v-for="selectOpt in selectOpts">{{ $t(selectOpt.name) }}</option>
</select>
const selectedOption = computed(() => {
if(fooBarVariable) {
let opt = {id: 1, name: 'Foo'};
return opt
}
});
const selectOpts = [{ id: null, name: 'files.placeholder'},{id: 1, name: 'files.reply'},{id: 2, name: 'files.example'}]
When using v-model with select input, don't use selected attribute to set a default value for your select input.
If you're setting the value for each option by selectedOption.id then simply type the id of the option you would like it to be visible in formData.replyMethod.
For example:
const selectOpts = [{ id: 1, name: 'files.placeholder'}];
const formData = {
replyMethod: 1,
};
<select v-model="formData.replyMethod">
<option v-for="option in selectOpts" :value="option.id">
{{ option.text }}
</option>
</select>
This will set an initial value for your input on component mount which will be overridden upon the user action (Same behavior as selected attribute)
I have a custom X-Select that acts like a select input. It expects two props - value and options.
The problem is that when options are reloaded in the parent component (root), they are usually prepended with a new item. In that case, select changes its label (like the index stayed the same) even if value hasn't changed.
Example:
options = [{value:'3', text:'3'},{value:'2', text:'2'},{value:'1', text:'1'},}]
current value = '2', current label = '2'
// options have been reloaded and one more item appeared at the beginning
options = [{value:'4', text:'4'},{value:'3', text:'3'},{value:'2', text:'2'},{value:'1', text:'1'},}]
current value = '2', current label = '3'
As you can see the value now does not correspond to the label. I think it's because something wasn't refreshed properly (label '2' was on index 1 and now label '3' is on that index).
<template>
<select id="type" name="type" :value="value" #input="$emit('input',$event.target.value)"
class="select form-control w-75 mx-auto">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
</template>
<script>
module.exports = {
name: "XSelect",
props: ['options', 'value'],
}
</script>
ROOT
<x-select :key="form.sourceUniAccountId" v-model="form.sourceUniAccountId"
:options="sourceInputOptions"
class="form-select"></x-select>
COMPUTED
sourceAppUniAccounts() {
if (!this.userUniAccounts) return []
return this.userUniAccounts.filter(obj => obj.name_or_provider === this.journeySourceAppName)
},
sourceInputOptions() {
return this.sourceAppUniAccounts.map(obj => ({text: obj.identifier, value: obj.uni_account_id}))
}
The variable userUniAccounts is the one that is in fact reloaded.
Do you know how to make this work? Setting key to combination of value and options works but I think there is a more "elegant" option.
<x-select :key="form.sourceUniAccountId+sourceInputOptions.length" v-model="form.sourceUniAccountId"
:options="sourceInputOptions"
class="form-select"></x-select>
I want to display a select with all the option of my enum and change the value to update my database.
To do so:
I have an enum:
export enum SubscriptionEnum {
DAILY= 'DAILY',
ANNUAL= 'ANNUAL',
HALF-YEARLY = 'HALF-YEARLY ',
QUARTERLY = 'QUARTERLY ',
MONTHLY = 'MONTHLY ',
}
In my .ts file i create my enum var:
SubscriptionEnum = SubscriptionEnum ;
And then i display the option in my .html:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select #subscriptionid="subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
This example give me the select with all option and the value change in the view page when i clicked on a new option.
Then, i add the (change) in the select to call a method that change the content of the client subscription in the db. I did it like that:
.html:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select (change)="changeInfo(subscription )" #subscription id="subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
In my changeInfo i send the event and take the event.id and the event.value to update my db and it works because the select option change when i click on it and the <p>{{client.subscription}}</p> that is a value of my db take the good value.
Then i wanted to add a selector so my option value take directly the good value and this is not working ...
I add it like that:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select (change)="changeInfo(subscription )" #subscription id="subscription">
<option value="{{option.key}}"
selected="{{option.key == client.subscription}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
This give highlight me my sentence and tell me "Wrong attribute method" and when i reload my page my div contains the good value which is "ANNUAL" but my option is equal to QUARTERLY. If i click to change the option, the good value will be saved in my db but the display of my select selector will be wrong.
What do i not understand ? Thank you for your help
There is a subtle difference between two similar Angular syntaxes:
selected="{{option.key == client.subscription}}"
and
[selected]="option.key == client.subscription"
There are both property bindings but the former assigns interpolated value to property.
It means that even in case of falsy values selected property will get true;
el.selected = 'false'
because string is a truthy value in js.
So you can consider the following options:
Use correct property binding:
[selected]="option.key == client.subscription"
Use value binding on <select> tag instead:
<select #subscription id="subscription" [value]="client.subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}} {{option.key == client.subscription}}
</option>
</select>
I have a select in angular6 in which option is iterating over an array.
That array has one pipe which dynamically changes array value.
The problem is that when I have one selected value in model and array get changed and that value is not available in that array on which it iterates. Then select by default showing the first element but it should show empty select.
Kindly suggest me the best way to do it.
<select
(change)="handleOfferChange()"
class="alc-form-control"
name="offer"
id="offer"
[(ngModel)]="detailCopy.allowedOffers">
<option
*ngFor="let offer of providerMaster | active: activeOnly"
[ngValue]="[offer.csaid]"
>{{ offer.csaid }}</option
>
</select>
You can manually reset the ngModel, to do this you have to pass ngModel to you pipe as an argument and in your pipe when your array changes, reset the ngModel to empty value (Shown below)
//yourTemplate.html
<select [(ngModel)]="detailCopy.allowedOffers" #mySelectModel="ngModel">
<option *ngFor="let offer of providerMaster | active: activeOnly : mySelectModel" [ngValue]="[offer.csaid]" >{{ offer.csaid }}</option>
</select>
//yourPipe.ts
......
import { NgModel } from '#angular/forms';
transform(arr: any[], mySelectModel: NgModel): any {
if (your logic and conditions) {
mySelectModel.reset();
return arr;
}
}
Currently the onClick method is toggling open class, showing 3 dropdown at one time.
I want to open the dropdown for the selected option, 1 dropdown at a time.
methods: {
onClick: function(event) {
this.is_open = !this.is_open;
}
}
http://jsfiddle.net/bs9Lh73m/
The problem with that approach is you need to be able to distinguish three different states, one for each button. Here's an approach that changes to tracking which of the items should be currently displayed by index:
http://jsfiddle.net/bs9Lh73m/2/
<label for="i_{{$index}}" v-on="click : onClick($index)">{{ model.type }}</label>
<div class="item_details" v-class="open : $index == openedCount">
<span>Count
<select v-model="modelCount">
<option v-repeat="count : model.features[0].count" value="{{ count.int }}">
{{ count.int }}
</option>
</select>
</span>
</div>
and
onClick: function ($index) {
this.openedCount = $index;
}
The $index == openedCount is a conditional that will resolve to true or false which is what is needed to get v-class to apply the class. $index is a special Vue variable which is set in the current model by v-repeat. I added a property called openedCount that indicates which button should currently be considered to be opened. The onClick call uses $index to update this value.