Add default value to select with Angular 2 - javascript

I'm developing an Angular 2 app with ASP.NET Core 2.0 using the Visual Studio 2017 ASP.NET Angular Web application template.
I have a controller whose method get returns all the legislations that I'm using in my app (they come from an Enum):
[Route("api/[controller]")]
public class LawController : Controller
{
[HttpGet]
public IEnumerable<Models.LawPresentation> Get()
{
List<LawPresentation> laws = new List<LawPresentation>();
// Arrange
byte[] values = (byte[])Enum.GetValues(typeof(LawTypes));
foreach (byte value in values)
{
string enumName = Enum.GetName(typeof(LawTypes), value);
LawPresentation law = new LawPresentation()
{
Value = value,
Name = enumName
};
laws.Add(law);
}
return laws;
}
}
I this is the component that shows all these values in a select:
<p *ngIf="!laws"><em>Loading...</em></p>
Legislaciones:
<select>
<option *ngFor="let l of laws" [ngValue]="l">{{l.name}}</option>
</select>
I don't think that return the default value (a blank option) from the controller is a good idea, so I wondering if I can add something to the html component to add the default option.
Is there any way to add the default option to the select into the html component?

I would do something like this:
<p *ngIf="!laws"><em>Loading...</em></p>
Legislaciones:
<select>
<option></option>
<option *ngFor="let l of laws" [ngValue]="l">{{l.name}}</option>
</select>

You can add a default option as below.
selected property will make option selected at initial.
disable property will restrict option to be selected by user.
You can remove them as per requirement
<p *ngIf="!laws"><em>Loading...</em></p>
Legislaciones:
<select>
<option value="" selected disabled>SELECT</option>
<option *ngFor="let l of laws" [ngValue]="l">{{l.name}}</option>
</select>

Related

When I'm scraping Angular app nothing happens when I change select options [duplicate]

I am using Angular 2 (TypeScript).
I want to do something with the new selection, but what I get in onChange() is always the last selection. How can I get the new selection?
<select [(ngModel)]="selectedDevice" (change)="onChange($event)">
<option *ngFor="#i of devices">{{i}}</option>
</select>
onChange($event) {
console.log(this.selectedDevice);
// I want to do something here with the new selectedDevice, but what I
// get here is always the last selection, not the one I just selected.
}
If you don't need two-way data-binding:
<select (change)="onChange($event.target.value)">
<option *ngFor="let i of devices">{{i}}</option>
</select>
onChange(deviceValue) {
console.log(deviceValue);
}
For two-way data-binding, separate the event and property bindings:
<select [ngModel]="selectedDevice" (ngModelChange)="onChange($event)" name="sel2">
<option [value]="i" *ngFor="let i of devices">{{i}}</option>
</select>
export class AppComponent {
devices = 'one two three'.split(' ');
selectedDevice = 'two';
onChange(newValue) {
console.log(newValue);
this.selectedDevice = newValue;
// ... do other stuff here ...
}
If devices is array of objects, bind to ngValue instead of value:
<select [ngModel]="selectedDeviceObj" (ngModelChange)="onChangeObj($event)" name="sel3">
<option [ngValue]="i" *ngFor="let i of deviceObjects">{{i.name}}</option>
</select>
{{selectedDeviceObj | json}}
export class AppComponent {
deviceObjects = [{name: 1}, {name: 2}, {name: 3}];
selectedDeviceObj = this.deviceObjects[1];
onChangeObj(newObj) {
console.log(newObj);
this.selectedDeviceObj = newObj;
// ... do other stuff here ...
}
}
Plunker - does not use <form>
Plunker - uses <form> and uses the new forms API
You can pass the value back into the component by creating a reference variable on the select tag #device and passing it into the change handler onChange($event, device.value) should have the new value
<select [(ng-model)]="selectedDevice" #device (change)="onChange($event, device.value)">
<option *ng-for="#i of devices">{{i}}</option>
</select>
onChange($event, deviceValue) {
console.log(deviceValue);
}
Just use [ngValue] instead of [value]!!
export class Organisation {
description: string;
id: string;
name: string;
}
export class ScheduleComponent implements OnInit {
selectedOrg: Organisation;
orgs: Organisation[] = [];
constructor(private organisationService: OrganisationService) {}
get selectedOrgMod() {
return this.selectedOrg;
}
set selectedOrgMod(value) {
this.selectedOrg = value;
}
}
<div class="form-group">
<label for="organisation">Organisation
<select id="organisation" class="form-control" [(ngModel)]="selectedOrgMod" required>
<option *ngFor="let org of orgs" [ngValue]="org">{{org.name}}</option>
</select>
</label>
</div>
I ran into this problem while doing the Angular 2 forms tutorial (TypeScript version) at https://angular.io/docs/ts/latest/guide/forms.html
The select/option block wasn't allowing the value of the selection to be changed by selecting one of the options.
Doing what Mark Rajcok suggested worked, although I'm wondering if there's something I missed in the original tutorial or if there was an update. In any case, adding
onChange(newVal) {
this.model.power = newVal;
}
to hero-form.component.ts in the HeroFormComponent class
and
(change)="onChange($event.target.value)"
to hero-form.component.html in the <select> element made it work
use selectionChange in angular 6 and above. example
(selectionChange)= onChange($event.value)
I was has same problem and i solved using the below code :
(change)="onChange($event.target.value)"
In Angular 8 you can simply use "selectionChange" like this:
<mat-select [(value)]="selectedData" (selectionChange)="onChange()" >
<mat-option *ngFor="let i of data" [value]="i.ItemID">
{{i.ItemName}}
</mat-option>
</mat-select>
Angular 7/8
As of angular 6,the use of ngModel input property with reactive forms directive have been deprecated and removed altogether in angular 7+. Read official doc here.
Using reactive form approach you can get/set selected data as;
//in your template
<select formControlName="person" (change)="onChange($event)"class="form-control">
<option [value]="null" disabled>Choose person</option>
<option *ngFor="let person of persons" [value]="person">
{{person.name}}
</option>
</select>
//in your ts
onChange($event) {
let person = this.peopleForm.get("person").value
console.log("selected person--->", person);
// this.peopleForm.get("person").setValue(person.id);
}
Another option is to store the object in value as a string:
<select [ngModel]="selectedDevice | json" (ngModelChange)="onChange($event)">
<option [value]="i | json" *ngFor="let i of devices">{{i}}</option>
</select>
component:
onChange(val) {
this.selectedDevice = JSON.parse(val);
}
This was the only way I could get two way binding working to set the select value on page load. This was because my list that populates the select box was not the exact same object as my select was bound to and it needs to be the same object, not just same property values.
If you don't need two-way data-binding:
<select (change)="updateSorting($event)">
<option disabled selected>Sorting</option>
<option value="pointDes">pointDes</option>
<option value="timeDes">timeDes</option>
<option value="timeAsc">timeAsc</option>
<option value="pointAsc">pointAsc</option>
</select>
updateSorting(e: any) {
// console.log((e.target as HTMLSelectElement)?.value); // also work
console.log(e.target.value);
}
<mat-form-field>
<mat-select placeholder="Vacancies" [(ngModel)]="vacanciesSpinnerSelectedItem.code" (ngModelChange)="spinnerClick1($event)"
[ngModelOptions]="{standalone: true}" required>
<mat-option *ngFor="let spinnerValue of vacanciesSpinnerValues" [value]="spinnerValue?.code">{{spinnerValue.description}}</mat-option>
</mat-select>
I used this for angular Material dropdown. works fine
I tried all the suggestions and nothing works for me.
Imagine the situation: you need a 2-way binding and you have a lookup with NUMBER values and you want to fill your SELECT with the values from this lookup and highlight the chosen option.
Using [value] or (ngModelChange) is a no-go, because you won't be able to select the chosen option after user initiated the change: [value] considers everything a string, as to (ngModelChange) - it obviously should not be used when user initiates the change, so it ruins the proper selection. Using [ngModel] guarantees the fixed format of received VALUE as INDEX: VALUE and it's easy to parse it correspondingly, HOWEVER once again - it ruins the selected option.
So we go with [ngValue] (which will take care of proper types), (change) and... [value], which guarantees the handler receives VALUE, not a DISPLAYED VALUE or INDEX: VALUE :) Below is my working clumsy solution:
<select
class="browser-default custom-select"
(change)="onEdit($event.target.value)"
>
<option [value]="">{{
'::Licences:SelectLicence' | abpLocalization
}}</option>
<ng-container *ngIf="licencesLookupData$ | async">
<option
*ngFor="let l of licencesLookupData$ | async"
[ngValue]="l.id"
[value]="l.id"
[selected]="l.id == selected.id"
>
{{ l.id }} {{ l.displayName | defaultValue }}
</option>
</ng-container>
</select>
onEdit(idString: string) {
const id = Number(idString);
if (isNaN(id)) {
this.onAdd();
return;
}
this.licencesLoading = true;
this.licencesService
.getById(id)
.pipe(finalize(() => (this.licencesLoading = false)), takeUntil(this.destroy))
.subscribe((state: Licences.LicenceWithFlatProperties) => {
this.selected = state;
this.buildForm();
this.get();
});
}
latest ionic 3.2.0 have modified (change) to (ionChange)
eg:
HTML
<ion-select (ionChange)="function($event)"> <ion-option>1<ion-option>
</ion-select>
TS
function($event){
// this gives the selected element
console.log($event);
}
In Angular 5 I did with the following way. get the object $event.value instead of $event.target.value
<mat-form-field color="warn">
<mat-select (ngModelChange)="onChangeTown($event)" class="form-width" formControlName="branch" [(ngModel)]="branch" placeholder="Enter branch">
<mat-option *ngFor="let branch of branchs" [value]="branch.value">
{{ branch.name }}
</mat-option>
</mat-select>
</mat-form-field>
onChangeTown(event): void {
const selectedTown = event;
console.log('selectedTown: ', selectedTown);
}

Angular - Display another part of the Object after selected in Select

I am displaying a few objects inside a select. But I want to show the user something different after selection than while picking his/her option.
Is that even possible in Angular as it is in WPF?
My select looks like this:
<select class="vstatus-select" [(ngModel)]="rezept.kunde.versichertenstatus1" name="kunde_vstatus1">
<option *ngFor="let vstatus of versichertenstatus1"[ngValue]="vstatus">
{{vstatus.name}} - {{vstatus.kennung}}
</option>
</select>
The Model:
export interface IVersichertenstatus{
name: string;
kennung: string;
}
The Key Problem is, that I want to show "kennung" and "name" while picking an option and only "kennung" afterwards.
I also need ngValue to be the whole object and not just "kennung".
Cheers
You can try this.
<select class="vstatus-select" [(ngModel)]="rezept.kunde.versichertenstatus1" name="kunde_vstatus1">
<option *ngFor="let vstatus of versichertenstatus1"[ngValue]="vstatus">
<span *ngIf="your-condition-to-show-name">{{vstatus.name}} -</span> {{vstatus.kennung}}
</option>
</select>
I hope this help you, regards
Thanks to #Carles Ramos!
I've set two events - and functions which change a boolean. This boolean is used for the *ngIf tag.
<select class="vstatus-select"
[(ngModel)]="rezept.kunde.versichertenstatus1"
name="kunde_vstatus1"
(focus)="vselect_focus(1)"
(change)="vselect_focusout(1)">
<option *ngFor="let vstatus of versichertenstatus1" [ngValue]="vstatus">
<span *ngIf="selectedVersichertenstatus[0]">
{{vstatus.name}} -
</span>
{{vstatus.kennung}}
</option>
</select>
The events look like this:
public selectedVersichertenstatus:boolean[] = [false, false, false];
vselect_focus(selector:number){
this.selectedVersichertenstatus[selector-1] = true;
}
vselect_focusout(selector:number){
this.selectedVersichertenstatus[selector-1] = false;
}

selected in select option give wrong attribute value

I want to display a select with all the option of my enum and change the value to update my database.
To do so:
I have an enum:
export enum SubscriptionEnum {
DAILY= 'DAILY',
ANNUAL= 'ANNUAL',
HALF-YEARLY = 'HALF-YEARLY ',
QUARTERLY = 'QUARTERLY ',
MONTHLY = 'MONTHLY ',
}
In my .ts file i create my enum var:
SubscriptionEnum = SubscriptionEnum ;
And then i display the option in my .html:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select #subscriptionid="subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
This example give me the select with all option and the value change in the view page when i clicked on a new option.
Then, i add the (change) in the select to call a method that change the content of the client subscription in the db. I did it like that:
.html:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select (change)="changeInfo(subscription )" #subscription id="subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
In my changeInfo i send the event and take the event.id and the event.value to update my db and it works because the select option change when i click on it and the <p>{{client.subscription}}</p> that is a value of my db take the good value.
Then i wanted to add a selector so my option value take directly the good value and this is not working ...
I add it like that:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select (change)="changeInfo(subscription )" #subscription id="subscription">
<option value="{{option.key}}"
selected="{{option.key == client.subscription}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
This give highlight me my sentence and tell me "Wrong attribute method" and when i reload my page my div contains the good value which is "ANNUAL" but my option is equal to QUARTERLY. If i click to change the option, the good value will be saved in my db but the display of my select selector will be wrong.
What do i not understand ? Thank you for your help
There is a subtle difference between two similar Angular syntaxes:
selected="{{option.key == client.subscription}}"
and
[selected]="option.key == client.subscription"
There are both property bindings but the former assigns interpolated value to property.
It means that even in case of falsy values selected property will get true;
el.selected = 'false'
because string is a truthy value in js.
So you can consider the following options:
Use correct property binding:
[selected]="option.key == client.subscription"
Use value binding on <select> tag instead:
<select #subscription id="subscription" [value]="client.subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}} {{option.key == client.subscription}}
</option>
</select>

How to get VALUE of mat select

I have a mat select and I want to get the value of the dropdown that user selects. How can I do this? ALso if the user changes the value by reselecting how can I capture that also.
Html code:
<mat-form-field appearance="fill">
<mat-label>Country</mat-label>
<select matNativeControl formControlName='country' (change)="selected($event)">
<option disabled>Select</option>
<option *ngFor="let option of country" [value]="option">{{option}}</option>
</select>
</mat-form-field>
Typescript Code:
country = ['au', 'kr', 'gb'];
Check this sandbox : https://stackblitz.com/edit/angular-1k7ykb-cfmaq7?file=app%2Fselect-value-binding-example.ts
ngModel binds the value of the select picker with the one in TS file. You don't need a separate change handler for that
In your HTML
<mat-select [(ngModel)]="selected">
<mat-option *ngFor="let o of arr" [value]="o">{{o}}</mat-option>
</mat-select>
<div> Seleced: {{selected}}</div>
In you TS file using your array( we can even set the default value)
export class SelectValueBindingExample {
selected: string;
arr: string[] = [];
constructor() {
this.arr.push("au");
this.arr.push("kr");
this.arr.push("gb");
this.selected = 'gb';
}
}
If you use the Select as matNativeControl you have to use the native
(change)="handler($event)"
EventHandler. The Material Event selectionChange wont work here. Of course you could just use Angulars reactive-forms approach but for simple use cases (e.g. you just have one select field) thats enough.
In your implementation file:
handler($event): void {
console.log('selected value:: ', $event.target.value)
}
(selectionChange) and MatSelectChange are well designed for this purpose.
html:
<select formControlName='country' (selectionChange)="getSelected($event)">
... your options
</select>
ts:
getSelected(event: MatSelectChange): void {
console.log(event.value); // get selected value
console.log(event.source); // get all source options
}

proper way to implement dropdowns in ng2?

What is the proper way to implement dropdowns in ng2? I did some googling but I wasn't finding a lot of consistency.
My search.component.ts has a searchMetadata property which gets set via ngOnInit().
searchMetadata.Authors looks like [{Id=1, Value="Bob Smith"},{Id=2, Value="Mary Jones"}]
The final ng2 dropdown should be something like this:
<select #ddlAuthor (change)="updateSearchResults()">
<option value="1">John Smith</option>
<option value="2">Jane Doe</option>
<option value="3">John Denver</option>
</select>
What is the proper way to implement ng2 for this in the component.html?
You can use *ngFor to iterate over an array/collection populate the value and text accordingly. I've updated the answer to simulate a delay of 3000ms before setting the values to mimic an HTTP API call.
HTML:
<select #ddlAuthor (change)="updateSearchResults($event)">
<option *ngFor="let option of options" [value]="option.Id">{{option.Value}}</option>
</select>
TS:
export class App {
options: any[];
constructor() {}
ngOnInit() {
// simulated delay for API call
Observable
.of([
{Id:1, Value:"Bob Smith"},
{Id:2, Value:"Mary Jones"}
]).delay(3000).subscribe(values => {
this.options = values;
});
}
updateSearchResults($event) {
console.log($event);
}
}
Here is a plunker demonstrating the functionality.
Note: The array you referenced in your question [{Id=1, Value="Bob Smith"},{Id=2, Value="Mary Jones"}] is not valid JavaScript syntax. Objects are structured as { key: value }, it would need be a colon ":" character between the key and value rather than a equal sign "=" like in C# Object Initialization. Having the "=" will cause errors in your Angular application.
Hopefully that helps!
This works:
<select (change)="updateSearchResults()" #ddlAuthor>
<option *ngFor="let author of blogSearchMetadata.Authors">{{author.Value}}</option>
</select>

Categories