setting display of select in angular 2 - html

I am trying to set the display of select tag to a value obtained through another call. But I am not able to do so even after trying [selected] ,[ngValue],[value],etc.
<select class="form-control" [(ngModel)]="selectedRegion" name="Region" (ngModelChange)="onRegionChange(selectedRegion)" val="true" id="cloud-region" >
<option *ngFor="let region of regions" [selected]="selectedRegion.Name===region.Name?'region.Name':null">{{region.Name}}</option>
</select>
I set the value of "selectedRegion" after obtaining data through a http response in an Observable. I basically want to display the region that is received in another call as the selected display of select out of a pre-decided array which also contains this value.
Tried it in this plunker. Couldn't do it.
https://plnkr.co/edit/njGlIV?p=preview
Thanks.

I believe you're missing a [value] attribute on your <option>
<select
class="form-control"
[(ngModel)]="selectedRegion" name="Region"
(ngModelChange)="onRegionChange(selectedRegion)"
val="true"
id="cloud-region">
<option
*ngFor="let region of regions"
[value]="region.Name"
[selected]="selectedRegion.Name===region.Name?'region.Name':null">{{region.Name}}</option>
</select>
I don't think selected is actually needed if you've already tied up your select element with a model. The reason why your select isn't reflecting because your options have no value.
UPDATED:
Based on your plunkr, I've added a simulated http call to retrieve a value from an Observable. Once i've received a value from the stream, I immediately updated my model.
//our root app component
import {Component, Directive, Output, EventEmitter, Input, SimpleChange} from 'angular2/core'
import {Observable} from 'rxjs/Observable';
import {Observer} from 'rxjs/Observer';
//import 'rxjs/Rx';
#Component({
selector: 'my-app',
template:`
<h1>Selecting Number</h1>
<select type="number" [(ngModel)]="levelNum" (ngModelChange)="toNumber()">
<option *ngFor="let level of levels" [ngValue]="level.num">{{level.name}}</option>
</select>
{{levelNum}}
`,
})
export class AppComponent {
levelNum:number = 0;
levels:Array<Object> = [
{num: 0, name: "AA"},
{num: 1, name: "BB"}
];
ngOnInit(){
this.fakeHttpCall()
.subscribe(res => {
this.levelNum = res;
});
}
toNumber(){
this.levelNum = +this.levelNum;
console.log(this.levelNum);
}
fakeHttpCall(){
let request = new Observable(
obs => {
let timeout = setTimeout(() => {
obs.next(1);
obs.complete();
clearTimeout(timeout);
},2000);
}
);
return request;
}
}

Related

Can I get values from a dynamically created multiple select element?

Can I get values from a dynamically created multiple select element?
I have fixed categories of products which I intend to load dynamically from an API. Each one of those categories has an array with the options I want to be able to select. I'm stuck with it, I cant retrieve the selected values, and I recently read something that says that we can't get the selected values from a dynamically created select with angular-material. Is that true?
I've tried getting the elements by id using jQuery and have tried multiple ways of getting the selected values.
On my menu-service, which I didn't show, I print form.values but it is empty'; it should contain the selected options, or the opcEscolhidas array should contain the selected values.
Here is my template:
<div id="main" class="row">
<h2>Selecione os itens do Cardápio</h2>
<form (submit)="onCreateMenu(form)" #form="ngForm" id="items-form">
<ul class="collapsible" data-collapsible="accordion">
<li *ngFor="let categoria of categorias">
<div class="collapsible-header">{{categoria.nome}}</div>
<div class="collapsible-body">
<div class="opGroup">
<mat-form-field>
<mat-label>{{categoria.nome}}</mat-label>
<mat-select ([value])="opcEscolhidas" multiple>
<mat-option *ngFor="let opcao of categoria.opcoes" [value]="opcao">{{opcao}}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</li>
</ul>
<button type="submit" class="btn">Montar Cardápio</button>
</form>
</div>
and here is my component:
import { Component, OnInit } from '#angular/core';
// import * as $ from 'jquery';
import { FormControl } from '#angular/forms';
import { MenuService } from '../menu.service';
import { NgForm } from '#angular/forms';
#Component({
selector: 'app-create-menu',
templateUrl: './create-menu.component.html',
styleUrls: ['./create-menu.component.css']
})
export class CreateMenuComponent implements OnInit {
// feijao = "";
// arroz = "";
// macarrao = "";
// carne = "";
// acomp = "";
// salada = "";
opcEscolhidas = [];
categorias = [
{
"id":1,
"nome":"Feijão",
"opcoes": ["Carioca", "Preto", "Verde", "Macassa"]
},
{
"id":2,
"nome":"Arroz",
"opcoes": ["Branco", "Refogado", "Integral"]
},
{
"id":3,
"nome":"Macarrão",
"opcoes": ["Alho e Óleo", "Molho de tomate", "Manteiga e
cebola", "Molho branco"]
},
{
"id":4,
"nome":"Carne",
"opcoes": ["Bisteca/porco", "Carne de sol", "Peito de
frango", "Coxa de frango"]
},
{
"id":5,
"nome":"Acompanhamentos",
"opcoes": ["Purê", "Farofa", "Vinagrete", "Batata frita"]
},
{
"id":6,
"nome":"Salada",
"opcoes": ["Alface", "Tomate", "Rúcula", "Repolho"]
}
];
public menuService;
constructor(menuService: MenuService) {
this.menuService = menuService;
}
ngOnInit() {
}
onCreateMenu(form: NgForm) {
this.menuService.createMenu(form);
}
On my menu-service, which I didnt show, I print form.values, but it is empty, and it should contain the selected options. Or my "opcEscolhidas" array should contain the selected values.strong text
You need to bind ngModel to the control. Go through this video,
https://www.youtube.com/watch?v=hAaoPOx_oIw
Try this
<select
class="custom-select"
name="overallRating"
[ngModel]="inspectionGeneralInfo?.OverallRating">
<option [value]="-1">
Select a rating
</option>
<option
*ngFor="let orc of inspectionGeneralInfo?.OverallRatingChoices"
[value]="orc.AnswerCode">
{{orc.AnswerDescription}}
</option>
</select>

Angular 5: ngModel binding on select element doesn't update

I have this markup for a select element:
<select type="submit" ([ngModel])="selectedValue" #item (change)="onSelectItem(item.value)">
<option>Pick an option</option>
<option *ngFor="let object of objects">{{ object.value }}</option>
</select>
When I update the ngModel binding from typescript, nothing happens. Essentially I am just doing this, in the component:
ngOnInit() {
this.selectedValue = 'something' // One of the options from the list of objects
}
However, nothing happens.
The value I am trying to update it to, are in the list of objects (in the *ngFor) - if that matters.
Change ([ngModel])="selectedValue" to [(ngModel)]="selectedValue"
Just like the docs say:
Visualize a banana in a box to remember that the parentheses go inside the brackets.
Also you do not need the (change) listener if you are using ngModel. You can split your two way binding into [ngModel] and (ngModelChange)
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<select type="submit" [ngModel]="selectedValue" (ngModelChange)="onSelectedChange($event)">
<option *ngFor="let option of options">{{ option }}</option>
</select>
{{ selectedValue }}
` ,
styleUrls: ['./app.component.css']
})
export class AppComponent {
selectedValue = 1;
options = [1,2,3]
onSelectedChange(value: number) {
// do something else with the value
console.log(value);
// remember to update the selectedValue
this.selectedValue = value;
}
}
Live demo
Please change the definition of ([ngModel]) to [(ngModel)] and you should initialize the objects values before assign the value in selectedValue object

binding childcomponent variable with dropdown in parent component Angular 4

I am new to Angular 4 and using MEAN stack to develop an application.
My parent component is admin and child is session. I am trying to set the dropdown value in the parent component based on child component value.I am output emitter event for the same in the insert session method. However I am unable to set the value of dropdown. Pls help.
admin html
<div>
<label for="FormType" class="col-sm-2 col-form-label">Select Type </label>
<select #s (change)="setNav(s.value)">
<option *ngFor="let item of dms" >{{item}}</option>
</select>
</div>
<div *ngIf="regTypeSelectedOption==='Session'">
<code for session></div>
<div *ngIf="regTypeSelectedOption==='webinar'">
<code for webinar>
</div>
<div (notify)='onNotify($event)'></div
admin.ts
onNotify(message: string):void{
this.setNav(message);
alert(JSON.stringify(message));
}
setNav(nav:any){
this.selectedNav = nav;
if(this.selectedNav == "Session"){
this.regTypeSelectedOption = "Session";}
else if(this.selectedNav == "Webinar"){
this.regTypeSelectedOption = "Webinar";
}
else if (this.selectedNav == "Select"){
this.regTypeSelectedOption = "Select";
}
}
session.ts
export class SessionComponent implements OnInit {
insertSession(sessionForm){
this.newSession.deliveryMethod = this.regTypeSelectedOption;
this.newSession.formType = "Session";
let updatedresult;
if(this.updatedid == undefined){
this.dataService.insertNewSession(this.newSession)
.subscribe(
res =>{ this.sessions = res;
console.log('response', res)},
err => this.apiError = err,
() => {
this.notify.emit('Session');
this.router.navigate(['/admin']);
}
)
I am using notify event in parent with div. If I use the notify event with selector of sessioncomponent entire session component is getting displayed
I think you want to send message from one component to another, without using the child component in parent component.
I had a look at your code and found you are navigating to '/admin', after selection.
I would rather recommend you to register a route in your app.routing.ts like below
{path:'/admin/:id',component:AdminComponent}
In the Admincomponent use the below code to fetch the data from the route.
import {Router, NavigationEnd, ActivatedRoute,Params } from "#angular/router";
In Admincomponent implement OnInit and add below code to read the route value
ngOnInit(){
this.activatedRoute.params.subscribe((params: Params) => {
this.params = this.activatedRoute.params;
this.regTypeSelectedOption= this.params.value.id != undefined ? this.params.value.id : "";
});
}
Now in the ChildComponent , replace the below code:
//this.notify.emit('Session');
this.router.navigate(['/admin/Session']);
Now when the session is inserted, it will route you back to the AdminComponent with Session Id

Angular 4 firebase dropdown select tag option

I am using Angular 4 and firebase. I'm trying to build a dropdown selector for a list of properties.
Once a property is selected from the dropdown list, the property location should appear in another input field below.
properties.component.html
<select [(ngModel)]="selectedProperty" (change)="onSelect($event, property)">
<option>--select property--</option>
<option *ngFor="let property of properties">{{property.propertyName}}</option>
</select>
<div *ngIf="selectedProperty">
<label >Location </label>
<input type="text" value="{{selectedProperty.location}}">
</div>
properties.component.ts
import { Component, OnInit } from '#angular/core';
import { PropertyService } from './../services/property.service';
import { Property } from './../models/property';
import { Observable } from 'rxjs/Observable';
#Component({
selector: 'app-property-list',
templateUrl: './property-list.component.html',
styleUrls: ['./property-list.component.scss']
})
export class PropertyListComponent implements OnInit {
properties: Observable<Property[]>;
selectedProperty: Property;
constructor(private propertyService: PropertyService) {}
ngOnInit() {
this.propertyService.getProperties().subscribe(properties => {
this.properties = properties;
})
}
onSelect(event, property: Property){
this.selectedProperty = property;
}
}
I am able to select the property from the dropdown list but the property location does not appear on the input field. I'll appreciate your help.
Instead of value use ngModel
<div *ngIf="selectedProperty">
<label >Location </label>
<input type="text" [(ngModel)]="selectedProperty.location">
</div>
By default selecting option from dropdown selects whatever value provided in selected option tag. So when you select any value in dropdown it putspropertyName inside respective ngModel.
As you want to select the whole object use ngValue in option, what that will do is, when user selects an option it will take down ngValue object value and assigned it to ngModel of select field.
<option [ngValue]="property" *ngFor="let property of properties">
{{property.propertyName}}
</option>

Value not showing for input field using one way binding angular2

Objective: Get a collection of values based on the dropdown selection and place them in hidden input fields to be included in my model;
The relative html:
<select class="selectFoo" (change)="onSelect($event.target.value)" name="FooName" ngModel>
<option selected="selected">--Select--</option>
<option *ngFor="let foo of foos" [value]="foo.ID">{{foo.Name}}
</option>
</select>
<input type="hidden" [value]="fooAddress" name="FooAddress" ngModel/>
In the code above I called a function named OnSelect to get the data about the selected foo. The foos are populated using a webservice call. Here is the snippet from my ts file.
import { Component, OnInit } from '#angular/core';
import { Foo } from './model';
import { DataService } from './data.service';
#Component({
moduleId: module.id,
selector: 'add-on',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
foos : Foo[];
selectedFoo: Foo;
fooAddress: string;
onSelect(fooID){
this.selectedFoo = null;
for(var i = 0; i < this.foos.length; i++)
{
console.log(this.foos[i].ID);
if(this.foos[i].ID == fooID){
this.selectedFoo = this.foos[i];
this.fooAddress = this.selectedFoo.Address.toString();
}
}
}
}
I originally tried one way binding my value to the selectedFoo but I was getting an error indicating my Address value wasn't defined. I noticed I could set the value equal to selectedFoo and it didn't error. So i created a new variable that was set to the fooAddress based on the selected foo. I get no value even though while stepping through the code I see it has a value.
How can I get my value to populate so I can use it in my model? Let me know if I need to provide anything else.
Thanks!
If I am correctly understanding what you are after then something like this would work:
<select name="FooName" [(ngModel)]="selectedFoo">
<option>--Select--</option>
<option *ngFor="let foo of foos" [ngValue]="foo" >{{foo.Name}}</option>
</select>
<input type="hidden" [value]="selectedFoo?.Address" name="FooAddress" />
//Assuming your 'foo' items are e.g. { ID: 1, Name: 'Hello', Address: '123 Hello St'}
Here you can bind the Address property of the selectedFoo directly to your hidden input field, rather than needing to handle the (change) event.