I'm new to Angular so forgive me if I have this whole thing wrong. I'm attempting to get a created list in a dropdown and when the user selects it, it should record the information to the database.
Here is my code:
Component.html
<mat-form-field appearance="fill">
<mat-label>Retrieval Reason</mat-label>
<mat-select [formControl]="RR" required>
<mat-option>--</mat-option>
<mat-option *ngFor="let reason of reasons" [value]="reason">
{{reason.reason}}
</mat-option>
</mat-select>
<mat-error *ngIf="RR.hasError('required')">Please choose a reason</mat-error>
</mat-form-field>
<button
mat-raised-button
(click)="done()"
color="primary"
[disabled]="selection.selected.length === 0 || RR.hasError('required')"
>
Retrieve
</button>
Component.ts
retrievalReason: Reasons;
RR = new FormControl('', Validators.required);
reasons: Reasons[] = [
{reason: 'Cycle Count'},
{reason: 'Purge Request'},
{reason: 'Picking'},];
done() {
this.dialogRef.close({
carrier: this.carrier,
destination: this.selection.selected[0].dstId,
retrievalReason: this.RR.get('reasons').value,
});
}
I've looked up the Angular method to reading a value from a dropdown list and have tried different variable names, nothing's worked so far.
The only thing I see that could be wrong is that you try retrievalReason: this.RR.get('reasons').value but this is for a form to get the formcontrol.
You only have a formcontrol so just retrievalReason:this.RR.value should be enough.
Related
Based on what it is selected on this field, I want to fill with data the Tasks field below.
<mat-form-field>
<mat-label>Position</mat-label>
<mat-select [(ngModel)]="position" (ngModelChange)="change(position)" multiple formControlName="position">
<mat-option *ngFor="let position of positionArray" [value]="position">
{{position}}
</mat-option>
</mat-select>
</mat-form-field>
This is the Tasks field:
<mat-form-field>
<mat-label>Tasks</mat-label>
<mat-select formControlName="tasks">
<mat-option *ngFor="let res of tasksItems" [value]="res">
{{res}}
</mat-option>
</mat-select>
</mat-form-field>
Typescript code is as below:
private tasksItems= [];
change(position) {
if (position == "IT") {
this.tasksItems= ["one", "two"];
}
else if (position == "Design") {
this.tasksItems= ["three", "four"];
}
else {
this.tasksItems= [];
}
Edit: This is the positionArray in ts. The values are stored in database and the change(position) method works fine. The problem is the field Tasks doesn't get the value that is stored and I am assuming it has something to do with [(ngModel)].
positionArray: string[] = ['IT', 'Design'];
Data is stored to database. But the problem is [(ngModel)] doesn't read the data (when I want to edit the field). Can someone explain to me why and how do I fix it?
You shouldn't need to use ngModel if you are already using formControlName.
I can't see the whole code but I assume you have something like [formGroup]="form" on the form element which would bind to the FormGroup in your ts file.
As long as your form.position form control is updated, it should reflect in your template.
If you are using reactive form controls try removing [(ngModel)]="position" and make sure the form control is set correctly in your ts file.
Edit
Also, try changing your template variable names. position seems to be used for different variables.
try:
<mat-option *ngFor="let pos of positionArray" [value]="pos">
{{pos}}
</mat-option>
Here is is my code HTML:
<mat-list-item class="primary-imenu-item" role="listitem">
<mat-select class="form-control" multiple formControlName="statusCode" (selectionChange)="getSelectedOptionText($event)">
<mat-option *ngFor="let list of statusList" [value]="list.id" checkboxPosition="before">
{{list.code}}
</mat-option>
</mat-select>
</mat-list-item>
TS Code:
getSelectedOptionText(event: MatSelectChange) {
let selectedData = {
code: (event.source.selected as MatOption).viewValue,
value: event.source.value
};
console.log(selectedData);
}
In that 'selectedData' I am getting the code value is undefined. I need to get code value from dropdown.
The event object has "value" array attribute which will always have one item. So, instead of (event.source.selected as MatOption).viewValue, you can do event.value[0]. Look at the screenshot for more details. Hope it helps.
I want to whenever I have a , when I choose an option, add it at the end of the list, instead of placing it as its order...
You can check material's stackblitz:
https://stackblitz.com/angular/jdgkdlbeldj?file=src%2Fapp%2Fselect-multiple-example.ts
If I have this list:
toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
And I select initially Mushroom and Pepperoni ->MyList = [Mushroom, Pepperoni].
If I add a new option, such as Onion, I would like to be having MyList as:
[Mushroom, Pepperoni, Onion], but I get it as [Mushroom, Onion, Pepperoni].
How can I do it?
Angular material select provide sortComparator input property. It will accept comparater fuction to sort the selected value.
component.html
<mat-form-field>
<mat-label>Toppings</mat-label>
<mat-select [sortComparator]="sortComparator" [formControl]="toppings" multiple>
<mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
</mat-select>
</mat-form-field>
component.ts
sortComparator(a:any, b:any){
return 1;
}
Example
Instead using a form binding manually check when selectionChange event gets triggered and then compare the new selection with your saved selection. When a new selected element isn't selected in your list then push it into it when when in your new selection is an item missing remove this from your list.
<mat-form-field>
<mat-select (selectionChange)="changeMySelection($event)" [value]="myList">
// your options ....
</mat-select>
</mat-form-field>
I am passing in an object as my value and need to use [ngValue] as opposed to [value].
My HTML looks like this:
<mat-input-container fxFlex="18" fxFlexOffset="1">
<input
matInput
placeholder="Example"
[matAutocomplete]="autocomplete"
[ngModel]="user?.UserName"
(ngModelChange)="filter($event)"
[disabled]="disabled"/>
<mat-autocomplete #autocomplete="matAutocomplete"
(optionSelected)="optionSelected($event)" >
<mat-option *ngFor="let selectedUser of availableUsers" [ngValue]="selectedUser">
<span>{{ selectedUser?.UserName }}</span>
</mat-option>
</mat-autocomplete>
</mat-input-container>
As a demo, I also have a stackblitz with my error provided here:
https://stackblitz.com/edit/angular-5wk4rl?file=app%2Fautocomplete-simple-example.html
I am getting the error:
Template parse errors:
Can't bind to 'ngValue' since it isn't a known property of 'mat-option'.
1. If 'mat-option' is an Angular component and it has 'ngValue' input, then verify that
it is part of this module.
2. If 'mat-option' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the
'#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the
'#NgModule.schemas' of this component.
As mentioned in other answer on stack, Angular - Can't bind to 'ngValue' since it isn't a known property of 'mat-option'
Users are suggesting that adding it to the modules file will solve the issue but when I tried that (as seen in my material-module.ts in my stackblitz), the error persists.
Any suggestions? I would appreciate any help!
<mat-option *ngFor="let option of options" [value]="option">
Check the documentation here: https://material.angular.io/components/autocomplete/overview
To use the object:
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option
*ngFor="let selectedUser of availableUsers" [value]="selectedUser">
{{selectedUser.name}}
</mat-option>
</mat-autocomplete>
in xxx.ts file:
displayFn(user?): string | undefined {
return user ? user.name : undefined;
}
I'm new to Angular and html, so I'm looking for help. I have this code:
<mat-form-field>
<mat-select (valueChange)="changeStatus(list.name, card.name)">
<mat-option *ngFor="let i of lists"> {{i.name}} </mat-option>
</mat-select>
</mat-form-field>
What I need to do, is to pass {{i.name}} (instead of list.name) into changeStatus() function.
Basically what happens, is when I choose option in drop-box, I want to pass option I chose into function. Any ideas on how to do that? Thanks in advice
You can use onSelectionChange provided by MatSelect component and pass the $event variable.
Taken from the documentation: selectionChange: EventEmitter<MatSelectChange>
MatSelectChange has two properties:
source: MatSelect
value: any
You have to change:
<mat-select (valueChange)="changeStatus(list.name, card.name)">
To:
<mat-select (selectionChange)="onSelectionChange($event)">
And on your component.ts you can handle the event like this:
onSelectionChange($event: MatSelectChange) {
const list = $event.value; // const or let depending on your handle logic
// Your logic here
}
PS: 80% of the times simple tasks that you look for in Angular Material are straight forward. Make sure you check the API + Examples so you can learn the "Angular Way" of doing stuff.
It is the actual purpose of Angular Material "Our goal is to build a set of high-quality UI components built with Angular and TypeScript, following the Material Design spec. These components will serve as an example of how to write Angular code following best practices."
Use selectionChange event with Template reference variables for it
<mat-form-field>
<mat-select #ref (selectionChange)="changeStatus(ref.value)">
<mat-option *ngFor="let i of lists" [value]="i"> {{i.name}} > </mat-option>
</mat-select>
</mat-form-field>
Component
changeStatus(value)
{
console.log(value);
}
LIVE DEMO