<mat-form-field appearance="outline" fxFlex="25" class="pr-12" *ngFor="let htmlMarketLevel of marketLevels">
<mat-label>{{htmlMarketLevel.MarketLevelName}}</mat-label>
<mat-select name="Market{{htmlMarketLevel.Rank}}" [(ngModel)]="selectedMarket[htmlMarketLevel.Rank]" [compareWith]="compareMarkets" (selectionChange)="populateChildrenMarkets( $event )">
<mat-option>All</mat-option>
<mat-option *ngFor="let market of markets[htmlMarketLevel.Rank]" [value]="market">{{market.MarketName}}</mat-option>
</mat-select>
</mat-form-field>
I have multiple select fields that are generated dynamically. Now I have an issue, if my select field is populated and an option is selected it's not firing the selectionChange event. But if it's a user action then it's firing the event.
Related
I want to call a function, once the value of dropdown is changed.
I have done this without Angular Material.
Here's my ts and html files.
selected="pending";
getRequests(event: any) {
this.selected = event.target.value;
if(this.selected=="pending")
console.log("Inside Pending Requests")
else
console.log("Inside Granted Requests")
}
<div style="margin-left: 70%;" appearance="fill">
<select (change)="getRequests($event)">
<option value="pending">Pending</option>
<option value="granted">Granted</option>
</select>
</div>
Now, I want to implement this with the help of Angular Material Select Component.
Calling the getRequests() function is not working as expected. Somebody please help me on this one. Thanks in advance.
<mat-form-field style="margin-left: 70%;" appearance="fill">
<mat-label>Status</mat-label>
<mat-select [(value)]="selected" (change)="getRequests($event)" >
<mat-option value="pending">Pending</mat-option>
<mat-option value="granted">Granted</mat-option>
</mat-select>
The api is selectionChange i.e. (selectionChange)="getRequests($event)".
See the docs https://material.angular.io/components/select/api
In Angular Material Design 6 and above, the (change) method was removed. Instead use selectionChange
<mat-select (selectionChange)="doSomething($event)">
Read more about here: Angular 6 Material mat-select change method removed
Use selectionChange intead of change
<mat-form-field style="margin-left: 70%;" appearance="fill">
<mat-label>Status</mat-label>
<mat-select [(value)]="selected" (selectionChange)="getRequests($event)" >
<mat-option value="pending">Pending</mat-option>
<mat-option value="granted">Granted</mat-option>
</mat-select>
Then you should be able to access value from event object value property
getRequests(event: MatSelectChange) {
this.selected = event.value;
if(this.selected=="pending")
console.log("Inside Pending Requests")
else
console.log("Inside Granted Requests")
}
Working Example
your mat-select has an event that is emitted every time selection is changed. It is called selectionChange as per angular documentation: https://material.angular.io/components/select/api
so maybe try to chage your (change) to (selectionChange) like this:
<mat-form-field style="margin-left: 70%;" appearance="fill">
<mat-label>Status</mat-label>
<mat-select [(value)]="selected" (selectionChange)="getRequests($event)" >
<mat-option value="pending">Pending</mat-option>
<mat-option value="granted">Granted</mat-option>
</mat-select>
I have a dropdown code and i have used angular material 6.4.1.
<mat-form-field floatLabel="never">
<mat-select name="country" [formControl]="userForm['country']"
(selectionChange)="onCountryChange($event)">
<mat-option [value]="null">
None
</mat-option>
<mat-option *ngFor="let country of countries" [value]="country.id">
{{country.name}}
</mat-option>
</mat-select>
</mat-form-field>
If i select any country from the dropdown list onCountryChange() will trigger once, but if i change country value to None onCountryChange() is triggering 2 times.
Can any one help with this, i have tried different ways to resolve it but no luck.
I need to set default value if there is one one option in the mat-select. otherwise leave black to select by user.
This is my code in HTML
<mat-form-field>
<mat-select (selectionChange)="CompartSelected($event, element, cmpart)" disableRipple [value]="element.Compart.Id" name="cmpart" >
<mat-option *ngIf="getAvailableCompartList(element.Compart.CompartType.Id).length > 1" value="">-- Please Select an Option --</mat-option>
<mat-option *ngFor="let cmpart of getAvailableCompartList(element.Compart.CompartType.Id)" title="{{Translate(cmpart.CompartNote)}}"
[value]="cmpart.Id">{{cmpart.CompartTitle}}
</mat-option>
according to the #Sean solution I have update the code. But it doesn't set the value to the mat-select.
I have attached some pic of those mat-select.
Edit: Sorry - misunderstood. You want the value selected when there is only one option (default behavior), otherwise leave blank when 2+ options are available. Add an additional mat-option outside of your ngFor only when the ngFor expression returns more than 1 item.
<mat-form-field>
<mat-select (selectionChange)="CompartSelected($event, element, cmpart)" disableRipple [value]="element.Compart.Id" name="cmpart" >
<mat-option *ngIf="getAvailableCompartList(element.Compart.CompartType.Id).length > 1" value="">-- Please Select an Option --</mat-option>
<mat-option *ngFor="let cmpart of getAvailableCompartList(element.Compart.CompartType.Id)" title="{{Translate(cmpart.CompartNote)}}"
[value]="cmpart.Id">{{cmpart.CompartTitle}}
</mat-option>
</mat-select>
</mat-form-field>
You can clean this up a little by placing the function call to getAvailableCompartList inside your component so you're not eval'ing the function twice as the template is rendered.
In case someone still looking for a hint.
Normally when your select vary the size, means it is coming from an observable.
So you could do this:
Typescript code:
//HERE IS THE FUNCTION THAT LOADS YOUR OPTIONS. IN THIS CASE 'val' IS MY API RETURN.
//IN CASE SIZE IS 1, PASS THE FIRST VALUE TO YOUR VARIABLE MODEL.
loadParameter(){
this.service.getParameters().subscribe((val: any) => {
this.parameters = val;
if (val.length == 1) {
this.selectedParameter = val[0].ParameterId;
}
});
}
----------------------------------------------------------------------------
Here the front code:
<mat-label>Example</mat-label>
<mat-select [(ngModel)]="selectedParameter">
<mat-option *ngFor="let parameter of parameters" [value]="parameter.ParameterId">{{parameter.ParameterValue}}</mat-option>
</mat-select>
------------------------------------------------------------------------
I have datatable which will show the elements with edit button also top of the page i have add button .
Add is for adding elements into list edit is for editing the particular row data
when user click add button one popup will come with two dropdownlist
Element Name and Element symbol
here based on Element Name selection Element symbol list will come.
My expectation >
when i click first row edit button(which means Hydrogen H ) same popup should open and we need to populate these Hydrogen(Element Name) and H(Element symbol) in dropdown like this
when i click 2nd row edit buttin (Hydrogen ,H1) it should populate these data
here is my Dialogue html
<h1 mat-dialog-title>{{data.element.ModalName.name}} </h1>
<form [formGroup]="addTaskForm" (ngSubmit)="save()" >
<mat-form-field>
<mat-select formControlName="name" placeholder="Element Name"
(selectionChange)="elementSelectionChange($event)">
<mat-option *ngFor="let element of Elements" [value]="element.name">
{{ element.name }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select formControlName="symbol" placeholder="Element symbol">
<mat-option *ngFor="let element of selectedElementSymbols" [value]="element.symbol">
{{ element.symbol }}
</mat-option>
</mat-select>
</mat-form-field>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">Cancel</button>
<button type="submit" mat-button cdkFocusInitial>{{data.element.ModalName.button}}</button>
</div>
</form>
https://stackblitz.com/edit/angular-talrct-prnwvr
In above template I basically made two changes one on line 27 commented re initialization of element and in constructor to update list of symbols based on selection.
You need to add (click)="onEditClick()" event to HTML of your popup button. Then in TS file add onEditClick(){} and there you can catch data you have chosen in dropdowns
store the selected table value to a variable like public
selected2 = this.options2[1].id ...
and bind with mat-option
<mat-select [(ngModel)]="selected2">
<mat-option *ngFor="let option of options2" [value]="option.id">{{
option.name }}</mat-option>
</mat-select>
I have a simple form which operates on the logic of:
Select Box 1 (Yes/No)
Select Box 2 (Show if Yes)
Select Box 3 (Show if No)
Only the shown selection box should be set to required, the other is not required.
<mat-select placeholder='Show First Options' formControlName='b' [(ngModel)]="view">
<mat-option [value]="'first'">
First
</mat-option>
<mat-option [value]="'second'">
Second
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field *ngIf="view === 'first'">
<mat-select
placeholder='First Items'
formControlName='one'
[required]="view === 'first'">
<mat-option *ngFor="let item of items1" [value]="item">
{{item}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field *ngIf="view === 'second'">
<mat-select
placeholder='Second Items'
formControlName='two'
[required]="view === 'second'">
<mat-option *ngFor="let item of items2" [value]="item">
{{item}}
</mat-option>
</mat-select>
</mat-form-field>
This works fine for the first, default select box. However, when you change to the second box, the first box seems to keep its required validator.
I have written a demo to demonstrate this:
https://stackblitz.com/edit/angular-9eoffq
How can I ensure only the viewed select box is required?
Apologies for editing the demo provided as people were reviewing it which caused confusion, however I seemed to have solved it - the issue seemed to stem from the DOM re-rendering to remove the mat-form-field before removing the required tag. This meant that the form still had the required attribute.
The demo has been updated with the solution - I had to programatically remove the required validator and add it to the appropriate form control. Then I had to update the value and validity to clear the errors after the validators were changed.
this.form.valueChanges.subscribe(value => {
if(value.b === 'first') {
this.form.controls['one'].setValidators(Validators.required)
this.form.controls['two'].clearValidators()
} else {
this.form.controls['two'].setValidators(Validators.required)
this.form.controls['one'].clearValidators()
}
this.form.controls['one'].updateValueAndValidity({onlySelf:true})
this.form.controls['two'].updateValueAndValidity({onlySelf:true})
})
Instead of using ngModel you can instead make full use of your reactive form, and utilize the form controls. Also, by disabling and enabling fields they are either included/excluded from the form object, therefore also validations will not apply.
You could listen to valueChanges of form, but I like to avoid it since if you are having a large form, it will be fired excessively. But if you want to only listen to a specific control changes, you can also do that. I like a simple change event here though:
<mat-select formControlName='b' (change)="onChange()">
and then hiding/showing the other select:
<mat-form-field *ngIf="form.controls.b.value === 'first'">
<!-- -->
<mat-form-field *ngIf="form.controls.b.value === 'second'">
and the change event:
onChange() {
if(this.form.get('b').value === 'first') {
this.form.get('one').enable()
this.form.get('two').disable()
} else {
this.form.get('one').disable()
this.form.get('two').enable()
}
}
DEMO
With this, we need to remember that the disabled control(s) are excluded from the form object, if you want all values (disabled included), you need to call this.form.getRawValue()
Still some one is looking for another solution, this may help.
<mat-select placeholder='Show First Options' formControlName='b' [(ngModel)]="view" #optionsSelector>
<mat-option value="first"> First </mat-option>
<mat-option value="second"> Second </mat-option>
</mat-select>
</mat-form-field>
<mat-form-field *ngIf="optionsSelector.value === 'first'">
<mat-select placeholder='First Items' formControlName='one'>
<mat-option *ngFor="let item of items1" [value]="item">
{{item}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field *ngIf="optionsSelector.value === 'second'">
<mat-select placeholder='Second Items' formControlName='two'>
<mat-option *ngFor="let item of items2" [value]="item">
{{item}}
</mat-option>
</mat-select>
</mat-form-field>