Angular 2 Html Select model not matching to option value - javascript

I have 2 arrays out of which 1 array values are bound to select dropdown values.
On clearing of another array, I want to render only one option.
Following is the code:
Component
#Component({
selector: 'my-app',
templateUrl : 'app/app.html'
})
export class AppComponent {
arrToClear = [1,2,3,4];
arrToBind = ["NONE", "SOME", "OTHER"];
modelToBind = 'NONE';
}
View
MODEL -> {{modelToBind}}
<button type='button'(click)="arrToClear.length = 0; modelToBind = 'NONE'">Clear Array </button>
<select class="form-control"
id="someId"
name="someName"
[ngModel]="modelToBind"
#someName="ngModel"
>
<ng-container *ngIf="arrToClear.length">
<option *ngFor="let data of arrToBind"
[ngValue]="data"> {{data}}
</option>
</ng-container>
<option value="NONE" *ngIf="!arrToClear.length">
Value
</option>
</select>
Problem is, when I clear "arrToClearArr" array, my selected value is empty. It should get bound to "A" because my model contains "A".
Additionally, I want only one-way binding hence I have used [ngModel].
What am I missing here? Any help will be appreciated.
Thanks.
Plunker Link
Expected behavior:
Change dropdown value
Click 'Clear array' button
Dropdown value should be "A", currently, it is ""

This is optional but personally I would not use the [ngModel] and try using Template-driven forms for this issue as I believe it would be clearer to just bind the variable directly.Just as you did with the for loop.
<select class="form-control" id="someId" formControlName="someName" name="someName">
<ng-container *ngIf="arrToClear.length">
<option *ngFor="let data of arrToBind" [value]="data"> {{data}}</option>
</ng-container>
<option [value]="modelToBind" *ngIf="!arrToClear.length">{{modelToBind}</option>
</select>
Alternatively could you not keep everything the same and just edit the last option.
<select class="form-control" id="someId" [ngModel]="modelToBind" #someName="ngModel" name="someName">
<ng-container *ngIf="arrToClear.length">
<option *ngFor="let data of arrToBind" [ngValue]="data"> {{data}}</option>
</ng-container>
<option [value]="modelToBind" *ngIf="!arrToClear.length">{{modelToBind}</option>
</select>

Related

How to set a disabled default option on a select element that uses ngModel (angular 11)

I had a select element that looked like this:
<select (change)="handleEvent($event)">
<option [value]="null" selected disabled>Select thing</option>
<ng-container *ngIf="data">
<ng-container *ngFor="let item of data">
<option [value]="item.id">{{ item.name }}</option>
</ng-container>
</ng-container>
</select>
Note that the default option did not come from the dynamic data and I disabled it from being selected. I wanted to access the entire data object rather than just the id when an option was selected so I did this:
<select [(ngModel)]="selectedItem" (change)="handleItemSelected()">
<option [value]="null" selected disabled>Select thing</option>
<ng-container *ngIf="data">
<ng-container *ngFor="let item of data">
<option [ngValue]="item">{{ item.name }}</option>
</ng-container>
</ng-container>
</select>
This worked except the disabled default option no longer showed up until I opened the select box. I did some reading and learned that this is because the default select option becomes whatever the value of
selectedItem
is when the component initializes which in this case was undefined. However, adding
this.selectedItem = {
name: "Select a thing"
}
did not populate the field either. I tried it both on init and in the constructor. Does anyone know:
1: why the default option is not populating
2: how to make the the default option disabled while still using ngModel
Define selectedItem as null since the option has value null
selectedItem = null;

Disabling a lowest value from dropdown

I have a dropdown list array which is shown in my UI How can I disable all highest elements in array and I want to enable only the lowest value in array
<select class="select-option" name="tier" required [ngModel]="tierDropDown">
<option value="select Tier" selected>Select Tier</option>
<option class="option" *ngFor="let tier of tierList" let i="index" value="{{tier}}" [disabled]="arr">
{{ tier }}
</option>
</select>
.TS file:
tierList = ["Tier1", "Tier2", "Tier3", "Tier4", "Tier5"]
this.arr = [];
let min = this.tierList;
this.arr = min.sort();
this.arr.splice(this.arr[0], 1);
console.log(this.arr);
this.arr.splice(this.arr[0], 1);
console.log(this.arr);
this will return splicing lower element and all higher elements so I am binding that value in [disabled] property in HTML file but the result is all my dropdown values are disabled
You can store the lowest value from array in a local variable and then use for that variable for [disabled] attribute:
HTML Code:
<select class="select-option" name="tier" required [ngModel]="tierDropDown">
<option value="select Tier" selected>Select Tier</option>
<option class="option" *ngFor="let tier of tierList" let i="index" value="{{tier}}" [disabled]="tier != LowestValue">
{{ tier }}
</option>
</select>
TS:
#Component({
selector: 'select-overview-example',
templateUrl: 'select-overview-example.html',
styleUrls: ['select-overview-example.css'],
})
export class SelectOverviewExample {
tierList = ["Tier1", "Tier5", "Tier3", "Tier4", "Tier2"]
LowestValue: any;
constructor() {
this.LowestValue = this.tierList.sort()[0];
}
}
Working_Demo
There seems to be a much easier way to do this than the answers provided here. ngFor has exported values that can be aliased to local variables (Source: docs). We can use the first local variable to disable all elements but the first in the dropdown.
As per the docs
first: boolean: True when the item is the first item in the iterable.
With this in mind, we can disable every value that is not the first item in the dropdown using [disabled]="!first"
Here's how your HTML will now look
<select class="select-option" name="tier" required [ngModel]="tierDropDown">
<option value="select Tier" selected>Select Tier</option>
<option class="option" *ngFor="let tier of tierList; let first = first" value="{{tier}}" [disabled]="!first">
{{ tier }}
</option>
</select>
Then in your component just sort tierList.
[disabled] should bind to a boolean. Now you are binding it to an array arr. So it Will always be true. The arr exists. I don’t understand completely what you want to do but if you add en object to your tierList you could calculate an property isDisabled for every element and bind that to the disabled.
Ex: {name:tier1,disabled:true}
You can use the following answer ,
Your html file
<select class="select-option" name="tier" required >
<option value="select Tier" selected>Select Tier</option>
<option class="option" [disabled]="arr" *ngIf="arr">
{{arr}}
</option>
<option class="option" *ngFor="let tier of tierList" let i="index" value="{{tier}}" >
{{ tier }}
</option>
</select>
In .ts file ,
tierList =["Tier1","Tier2","Tier3","Tier4","Tier5"];
arr = [];
let min = this.tierList;
this.arr = min.sort();
this.arr.splice(this.arr[0], 1);
this.arr = this.arr.splice(this.arr[0], 1);
this.arr = this.arr[0]
console.log(this.arr[0]);
console.log(this.tierList);
This answer will work for you.

angular2 getting the whole object selected in a select box

In the past I was able to pass out the 'object' that was used for the select options. I'd like to capture that information off a regular select, but I cannot remember how.
So When you do an *ngFor in your select option, you specify a N of N's like this
<option *ngFor="let thing of things" value= {{thing.name}}>
{{thing.family}} - {{thing.name}}
</option>
I'm hoping I can get that 'whole' thing that was selected, by calling a function on change.
<select class="form-control input-sm "
(change)="changeThing($event)"
name="thing"
formControlName="thing" >
<option *ngFor="let thing of things" value= {{thing.name}}>
{{thing.family}} - {{thing.name}}
</option>
</select>
because I want to change some form options based on the 'family' of the thing, not the value that gets passed.
my function looks like this.
changeThing (thing) {
console.log('thing:', thing);
selectedFamily = ??;
}
The $event is probably the wrong thing to be looking at - I can get the value selected there, but I cannot find the whole "thing" that was selected.
Thanks for any help.
You can do that with the help of index
Template Side :
<select class="form-control input-sm "
[(ngModel)]="selectedValue"
(change)="changeThing($event.target.value)"
name="thing" >
<option *ngFor="let thing of things; let i = index;" [value]="i">
{{thing.family}} - {{thing.name}}
</option>
</select>
Component Side :
changeThing(index){
alert(this.things[index].family +' '+this.things[index].name );
console.log(this.things[index]);
}
WORKING DEMO
I hope it will help
<option *ngFor="let thing of things" value= {{thing}}>
{{thing.family}} - {{thing.name}}
</option>
You can use ngModel with ngModelChange
<select [(ngModel)] ="selectedType" (ngModelChange)="changeThing(selectedType)">
<option *ngFor="let thing of things" [ngValue]="thing ">
{{type.name}}
</option>
</select>

create when click on option in select tag and check value create a input

im trying to create a application with angular 2 , i have a form and select tag and option.i want when user click on each option check option's value and if for example value was equalto "aaa" an input field generate bottom of select tag.
i trying to much but cant resolve this problem :)
I'll really appreciate if someone can clarify on the above listed concerns I have.
Thanks...
<select name="delivery_architecture" class="form-control testing">
<option selected="selected">plz select</option>
<option value="static">static</option>
<option value="dynamic">dynamic</option>
<option value="aaa" >aaa</option>
</select>
You can fill an array when an option is selected and then generate input elements using *ngFor.
#Component({
selector: 'my-app',
template: `
<select name="delivery_architecture" class="form-control testing" (change)="addInput($event.target.value)">
<option selected="selected">plz select</option>
<option value="static">static</option>
<option value="dynamic">dynamic</option>
<option value="aaa" >aaa</option>
</select>
<div *ngFor="#inp of inputs" >{{inp.name}}<input [ngModel]="inp.value"></div>
<div><button (click)="showValues()">show values</button></div>
<div>values: {{values}}</div>
`,
})
export class AppComponent {
inputs = [];
addInput(name) {
this.inputs.push({name: name, value: ''});
}
}
The values written into the input elements are stored in the array as well.
Plunker example

Multiple sorts operation triggered by 2 different select box

I need to implement 2 different sort operation on two different columns of datagrid, Its becoming tough by using 2 different select boxes. I tried with below code, as I new to this i couldn't solved this...
In HTML:
<select ng-model="reverse">
<option value="false">Top Sr</option>
<option value="true">Bottom Sr</option>
</select>
<select ng-model="reverse">
<option value="false">Top Rank</option>
<option value="true">Bottom Rank</option>
</select>
In datagrid:
<tr ng-repeat="items in empList | orderBy : ['-TR', 'SR']" >
In controller:
In controller : $scope.reverse = false;
I would recommend you following solution:
<select ng-model="sr">
<option value="+sr">Top Sr</option>
<option value="-sr">Bottom Sr</option>
</select>
<select ng-model="tr">
<option value="+tr">Top Rank</option>
<option value="-tr">Bottom Rank</option>
</select>
Then you should apply following ng-repeat statement to table:
<tr ng-repeat="items in empList | orderBy : [tr, sr]" >
And also set default values in controller:
$scope.sr = '+sr';
$scope.tr = '+tr';
You should substitute 'sr' and 'tr' with your objects (single element from empList) properties names that you want to sort by.
When you modify $scope variables via selecting other option in select then it's automatically evaluated into correct orderBy statement, ex:
<tr ng-repeat="items in empList | orderBy : [sr, tr]" >
Here is updated plunker. I've modified property name to 'tr' and now it works, but I'm not sure if that's what you wanted -> currently it'll sort by first column and only if values are equal then it'll compare objects by another property (which is 'tr').
UPDATE:
If you want to always sort by property associated with recently changed dropdown then you need to change a bit (another plunker):
1)add this initialization:
$scope.srRecentlyChanged = true;
2)add event on selects change:
<select ng-model="sr" ng-change="srRecentlyChanged = true;">
<option value="+sr">Top Sr</option>
<option value="-sr">Bottom Sr</option>
</select>
<select ng-model="tr" ng-change="srRecentlyChanged = false;">
<option value="+tr">Top Rank</option>
<option value="-tr">Bottom Rank</option>
</select>
3)modify orderBy expression:
<tr ng-repeat="items in empList | orderBy : (srRecentlyChanged? sr : tr)" >

Categories

Resources