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)
Related
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>
My requirement is to show the content based on selection of dropdown list.
component.ts
OptionList: LookupActionCode[]=[];
public setList(actionType: any):void{
this.anotherOptionList = [];
if(actionType == dataConstant.calendar){
this.List.push(
{
Name: dataConstant.content
},
{
Name: dataConstant.showcontent
},
{
Name: dataConstant.hidecontent
},
)}
switch(actionType){
case dataConstant.memberdata:
this.OptionList = this.memberCodes;
break;
case dataConstant.referral:
this.OptionList= this.optionalCodes;
break;
case dataConstant.Calendar:
this.OptionList = this.List;
break;
}
.component.html
//first dropdown
<label for="OptionList" class="cpp-required"> <b>Action</b></label>
<select id=action class="form-control" required (change) ="setList($event.target.value)">
<option value="" disabled [selected]="true"></option>
<option [value] = "dataConstant.referral">{{dataConstant.referral}}</option>
<option [value] = "dataConstant.memberdata">{{dataConstant.memberdata}}</option>
<option [value] = "dataConstant.calendar">{{dataConstant.content}}</option>
</select>
//second dropdown
<label> <b>Action</b></label>
<select id=action class="form-control" required>
<option value="" disabled [selected]="true"></option>
<option *ngFor="let option of optionList" [value] ="option">{{option.Name}} </option>
</select>
<div *ngIf="logic>
//some content to show and hide the data
</div>
So my requirement is from the first dropdown if i select the dataConstant.content then In secondit will show the realted dropdown lists those are dataConstant.content,dataConstant.showcontent and dataConstant.showcontent (implemented)
So If select the dataConstant.showcontent value then I need to show the data in div
Can anyone help me on this
If you first add a property to your component in ts to hold the selected value:
theProperty: string | undefined;
and on your select list in html add:
<select [(ngModel)]="theProperty" ect...
This will set up two way binding between your property and the select list. (Note reactive forms are good option here but have chose this for simplicity).
You can then add:
*ngIf="theProperty === thingToMatchTo"
But maybe pick a more sensible property name than what I've used.
NOTE - Make sure you add FormsModule to your imports in the Module that this component is declared. It's what makes the ngModel directive available to you.
How to show actual selected option from dropdown list and after stretching the list other available elements. Now I have the dropdownlist with only avaible elements which i can choose element.
HTML:
<div class="pb-1">
<label class="small">Car:</label>
<select formControlName="Car" class="form-control">
<option *ngFor="let x of cars" [ngValue]='x.id'>{{x.id}} : {{x.carName}}</option>
</select>
</div>
TypeScript:
export class PersonDetailsComponent implements OnInit {
cars : Car[];
.
.
.
populateCars()
{
this.personsService.getCars().subscribe(result => {
this.cars = result;
});
}
personsService:
getCars() :Observable<Car[]>
{
return this.http.get(this.apiUrl + 'AviableCars')
.map((result)=>result.json());
};
You need to use the [selected] attribute. I would also add a "Please select" default option:
<option value="" disabled selected> <!-- default selected -->
Please select a car
</option>
<option *ngFor="let x of cars" [ngValue]='x.id' [selected]="Car.id === x.id">
{{x.id}} : {{x.carName}}
</option>
The [selected] attribute requires an expression that evaluates to true or false. If true it will highlight that item (x.id) in the list.
So here it is checking that the Car.id (from your model) matches x.id in the *ngFor - so the expression will be evaluated for each x in the ngFor, and one of them of course should be true.
More info here and here
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.
i have array of available select items:
// Default available date formats
$scope.dateformats = [
{
code: 'YY.MM.DD',
name: 'YY.MM.DD'
},
{
code: 'DD.MM.YY',
name: 'DD.MM.YY'
}
];
And I'm trying to default preselected value like this:
$scope.actualDateformat = $scope.dateformats[0].code;
<select ng-options="dateformat.name for dateformat in dateformats" ng-model="actualDateformat" ng-change="changeDateFormat(dateformat)">
<option style="display:none" value="">{{actualDateformat}}</option>
</select>
Problem is, that "preselected" value appears in list as first option tag>
<option style="display:none" value="">{{actualDateformat}}</option>
After select of any from two remaining dynamically added items is text in first option appended with text (and value) of the selected item.
How can in solve it please?
I would like to have result like this:
<select>
<option value="YY.MM.DD">YY.MM.DD</option>
<option value="DD.MM.YY" selected>DD.MM.YY</option>
</select>
Thanks for any help.
Here is FIDDLE
Your problem is you are selecting entire object not code field of that object.
dateformat.name for dateformat in dateFormats
label : dateformat.name
object : dateformat
dateformat.code as dateformat.name for dateformat in dateformats
label : dateformat.name
object : dateformat.code
Also I don't understand the need of option withdisplay:none.
You can select dateformat.code like this.
<select ng-options="dateformat.code as dateformat.name for dateformat in dateformats" ng-model="actualDateformat" ng-change="changeDateFormat(dateformat)">
</select>
Change:
<select ng-options="dateformat.name for dateformat in dateformats"
ng-model="actualDateformat" ng-change="changeDateFormat(dateformat)">
<option style="display:none" value="">{{actualDateformat}}</option>
</select>
To:
<select ng-options="dateformat.code as dateformat.name for dateformat in dateformats"
ng-model="actualDateformat" ng-change="changeDateFormat(dateformat)">
</select>
This way, the select should recognize the item where the dateformat.code matches actualDateformat.
This blog has some good examples about ng-options.
To give you an example:
Assume:
$scope.array = [
{ key: 1, value: 'Display text 1!' },
{ key: 2, value: 'Display text 2!' },
{ key: 3, value: 'Display text 3!' }
]
Then, using the following options:
<select ng-options="item.key as item.value for item in array" ng-model="result">
Would result in:
<select ...>
<option value="1">Display text 1!</option>
<option value="2">Display text 2!</option>
<option value="3">Display text 3!</option>
</select>
$scope.result would be set to these option elements' value attribute.
If you initialize $scope.result as 2, "Display text 2!" should be selected.