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>
Related
Selected value in one dropdown should not appear in other two dropdowns in Angular material. How to remove the selected value in one dropdown from all other dropdowns? (I have dynamic dropdown which gets added each time a button in clicked)
I tried using this https://stackblitz.com/edit/angular-dqvvf5?file=src%2Fapp%2Fapp.component.html but the logic is not working for angular material.
I've taken your Stackblitz and managed to get it working using mat-select instead of the standard HTML select. Please see this Stackblitz for a working demo.
The main changes were in the HTML...
HTML
<div *ngFor="let field of fieldArray; index as idx" style="margin-bottom: 8px">
<mat-form-field appearance="fill">
<mat-label>Select Language</mat-label>
<mat-select #selectLang (selectionChange)="selected(selectLang.value,i)">
<ng-container *ngFor="let lang of languageList" >
<mat-option *ngIf="selectLang.value === lang.name || !isSelected(lang.name)" [value]="lang.name">
{{lang.name}}
</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
<button (click)="deleteFieldValue(idx, selectLang.value)" style="margin-left: 8px">X</button>
</div>
<button (click)="addFieldValue()">Add Select</button>
The Typescript is pretty much the same as in your example, except I've modified the signature of the selected() function to read selected(value: string, idx: number) as you're passing 2 parameters into that from your HTML.
I spent a lot of time solving this problem and failed. I want to select to display the name and get the id. The problem is, as soon as a value is selected, the number (id) of that value is displayed. My code:
<mat-form-field class="example-full-width">
<input
matInput
placeholder="Search your product"
formControlName="id"
[matAutocomplete] = "auto">
<mat-autocomplete #auto="matAutocomplete" >
<mat-option *ngFor="let option of allProducts; let i = index" [value]="option.id" >
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
I tried to create a function (onSelectionChange) but could not display the name and take the value as (id)
Well, you have to use the input function of auto-complete called displayWith.
you can find the solution to your problem in this link here
plus I 've made a stackblitz example for you to simplify it more.
Example
to describe the solution:
you have to add to your autocomplete component an input called displayWith
<mat-autocomplete #auto="matAutocomplete" [displayWith]="checkValue">
and then in your component you have to create the function checkValue
checkValue(value: any) {
// here you can get your id or whatever you want
console.log(value)
}
then you have to add to your mat option the value and give it your whole object as value
<mat-option *ngFor="let option of options" [value]="option" >
{{option.name}}
</mat-option>
Please check the stackblitz example for more details
<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.
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 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>