I have a list displayed in a dropdownlist, but it displays the default as a blank and not as the first item in the dropdown.
I have tried adding let i = 0 and then [selected]="i = 0", but this does not seem to set the default item to the first item, however I am receiving the correct value back from i.
Below is my code:
<div class="form-group">
<label for="userName">User Name</label>
<select formControlName="userName" class="form-control" (change)="userChange($event)">
<option *ngFor="let row of usersModel;let i = index" value="{{ row.id }}" [selected]="i == 0">{{ row.userName }} {{ i }}</option>
</select>
</div>
Here is my TypeScript File:
import { Component, OnInit } from '#angular/core';
import { UserAdminService } from '../../services/user-admin.service';
import { FormBuilder, Form, FormControl, FormGroup } from '#angular/forms';
import { Router } from '#angular/router';
#Component({
selector: 'lib-add-user-to-role',
templateUrl: './add-user-to-role.component.html',
styleUrls: ['./add-user-to-role.component.css']
})
export class AddUserToRoleComponent implements OnInit {
addUserToRoleForm: FormGroup;
rolesModel: any[];
usersModel: any[];
selectedRole: string;
selectedUser: string;
constructor(private userAdminService: UserAdminService, private formBuilder: FormBuilder, private router: Router) {
var roleControl = new FormControl('');
var userControl = new FormControl('');
this.addUserToRoleForm = formBuilder.group({ roleName: roleControl, userName: userControl });
}
ngOnInit() {
this.userAdminService.getRoles().subscribe(roles => {
this.rolesModel = roles;
this.selectedRole = this.rolesModel[0].name;
this.userAdminService.getUsersNotInRole(this.selectedRole).subscribe(users => {
this.usersModel = users;
this.selectedUser = this.usersModel[0].id;
console.log(this.usersModel[0].userName);
this.addUserToRoleForm.controls['roleName'].setValue(this.rolesModel[0].name);
this.addUserToRoleForm.controls['userName'].setValue(this.usersModel[0].userName);
});
});
}
userChange(event: any) {
this.selectedUser = event.target.value;
console.log('Selected ' + this.selectedUser);
}
AddUserToRole() {
this.userAdminService.addUserToRole(this.selectedUser, this.selectedRole)
.subscribe(result => {
if (result.success) {
this.router.navigate(['/roleusermaint']);
}
else {
console.log('Error Received on adding user to role');
}
});
}
}
As you can see I added {{ i }} in the text to make sure it shows the value of i and it does:
What am I missing ?
Thanks for any help!
#Axle, if you're using a Reactive Form, you needn't use [selected] nor (change), just, when you create the form you give value to userName
Using the constructor
const firstId=usersModel[0].id
this.form=new FormGroup({
userName:new FormControl(firstId)
})
Using formBuilder
const firstId=usersModel[0].id
this.form=this.fb.group({
userName:firstId
})
Using setValue, after create the form
const firstId=usersModel[0].id
this.form.get('userName').setValue(firstId)
As you are using Angular reactive form, try to keep the logic in ts file itself.
Using setValue(), you can set the default value to a control.
To set the default value to form control you could to it like,
this.form.controls['country'].setValue(this.countries[0].id)
In template use it like,
<option *ngFor="let country of countries" [value]="country.id">
{{ country.name }}
</option>
Working Stackblitz
Ref:
A complete sample code would be something like,
app.component.ts
import { Component } from '#angular/core';
import { FormGroup, FormControl } from '#angular/forms';
import {Country} from './country';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
countries = [
{
id: 'us',
name: 'United States'
},
{
id: 'uk',
name: 'United Kingdom'
},
{
id: 'ca',
name: 'Canada'
}
];
form: FormGroup;
ngOnInit(){
this.form = new FormGroup({
country: new FormControl('')
});
this.form.controls['country'].setValue(this.countries[0].id)
}
}
app.component.html
<form [formGroup]="form">
<select formControlName="country">
<option *ngFor="let country of countries" [value]="country.id">
{{ country.name }}
</option>
</select>
</form>
Related
I need to get the values that are inside cities from this JSON, but i canĀ“t:
{
"id":0,
"department":"Amazonas",
"cities":["Leticia","Puerto Bayarta",]
},
{
"id":1,
"department":"Antioquia",
"cities":["Medellin","Bello",]
}
These are the components and services that I made:
cities.service.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root',
})
export class CitiesService {
constructor(private http: HttpClient) {}
getJSON(url: string) {
return this.http.get(url);
}
}
Component has an interface:
nueva-organizacion.component.ts
import { Component, OnInit } from '#angular/core';
import { CitiesService } from 'src/app/services/cities.service';
interface City{
department: string;
cities: string[];
}
#Component({
selector: 'app-nueva-organizacion',
templateUrl: './nueva-organizacion.component.html',
styleUrls: ['./nueva-organizacion.component.css'],
})
export class NuevaOrganizacionComponent implements OnInit {
public cities: City[] = [];
constructor(
public cities: CitiesService,
) {}
ngOnInit(): void {
this.cities
.getJSON(
'https://raw.githubusercontent.com/marcovega/colombia-json/master/colombia.min.json'
)
.subscribe((res: any) => {
this.cities = res;
});
}
And finally, i would like to show the cities in a selector:
nueva-organizacion.component.html
<div class="form-input">
<select id="city" class="custom-select">
<option selected>Choose one...</option>
<option *ngFor="let city of cities">
{{ city.cities }}
</option>
</select>
</div>
I would like to get something like this in the selector:
Choose one...
Leticia
Puerto Bayarta
Medellin
Bello
But I get this:
Choose one...
Leticia, Puerto Bayarta
Medellin, Bello
Maybe the correct way is using the index {{ city.cities[] }} but I don't know how.
Please keep in mind that inside NuevaOrganizacionComponent you have to properties with the same name: 'cities', first the cities array and second the cities service.
Also I recommend you to use two selects instead of one, the first to select the department and the second to select the city.
The code will look like this:
nueva-organizacion.component.ts:
import { Component, OnInit } from '#angular/core';
import { CitiesService } from 'src/app/services/cities.service';
#Component({
selector: 'app-nueva-organizacion',
templateUrl: './nueva-organizacion.component.html',
styleUrls: ['./nueva-organizacion.component.css'],
})
export class NuevaOrganizacionComponent implements OnInit {
public departmentsArr = []
public departmentSelected:any = null;
public citySelected:any = null;
constructor(
public citiesServ: CitiesService,
) {}
ngOnInit(): void {
const urlCities = "https://raw.githubusercontent.com/marcovega/colombia-json/master/colombia.min.json"
this.citiesServ.getJSON(urlCities)
.subscribe((res: any) => {
this.departmentsArr = res;
});
}
getCities(){
return this.departmentsArr.find(department => department.id == this.departmentSelected).ciudades
}
alertSelection(){
const departmentName = this.departmentsArr.find(department => department.id == this.departmentSelected).departamento;
const cityName = this.citySelected;
alert(`
You selected the department: ${departmentName} and the city: ${cityName}`)
}
}
nueva-organizacion.component.html
<div class="form-input">
<label for="departmentSelector">Select your department</label>
<select id="departmentSelected" class="custom-select" name="departmentSelector" [(ngModel)]="departmentSelected">
<option value="null">Choose one department...</option>
<option
*ngFor="let department of departmentsArr"
[value]="department.id">
{{ department.departamento }}
</option>
</select>
</div>
<div class="form-input" *ngIf="departmentSelected">
<label for="citySelector">Select your city</label>
<select id="citySelector" class="custom-select" name="citySelector" [(ngModel)]="citySelected">
<option selected>Choose one city...</option>
<option
*ngFor="let city of getCities()"
[value]="city">
{{ city }}
</option>
</select>
</div>
<button (click)="alertSelection()">WHAT WAS SELECTED?</button>
Also please verify FormsModule is imported into your app.module.ts or yourSubmodule.module.ts. This is important to enable the ([ngModule]) functionality.
import {FormsModule} from "#angular/forms";
// Other things
imports: [
// Other modules
FormsModule
],
ngOnInit(): void {
this.cities
.getJSON(
'https://raw.githubusercontent.com/marcovega/colombia-json/master/colombia.min.json'
)
.subscribe((res: any) => {
this.cities = [];
foreach(entry in res){
foreach(citi in entry.cities){
this.cities.push(citi);
}
}
});
}
On this side, you have an array of entries that has an array of cities inside. You need to flatten first all the cities inside ans, something like the code above. My code isn't exact but should give you an idea of what to write.
In my component I have 2 Strings that I need to display on Angular Form as Dropdown, I am struggling to get the values on HTML page
Demo - https://stackblitz.com/edit/angular-dc4s7d?file=src%2Fapp%2Fapp.component.ts
Here is my ts code
export class EmployeeComponent implements OnInit {
constructor(public employeeService: EmployeeService) {}
public listItem: string[];
ngOnInit() {
this.listItem = ["A", "B"]; ----->>>>> Dropdown values
}
Html code
<div class="m-3 input-group; padding:10px; color:red; border: 3px solid ">
<span class="input-group-text">Type</span>
<select type="text" name="type" #type="ngModel"
[(ngModel)]="employeeService.selectedEmployee.type "placeholder="Type">
<option *ngFor="let dl of listItem" [value]="dl">{{dl}}</option>
</select>
</div>
Something may be wrong with your code but I can provide you a sample code to bind data with dropdown list. Please check and let me know.
HTML
<select name="city" (change)="onChange($event.target.value)">
<option *ngFor="let country of countries" [value]="country.id">{{country.name}}</option>
</select>
TS:
countries = [{
id: 1, name: 'France', cities: ['Paris', 'Marseille', 'Nice']
},
{
id: 2, name: 'Germany', cities: ['Hamburg', 'Berlin', 'Munich']
},
{
id: 3, name: 'Italy', cities: ['Roma', 'Milan', 'Napoli']
},
];
onChange(deviceValue) {
//do something
}
Note: Please Check the link of Stackblitz for more information LINK
NEW UPDATE
I think employeeService.selectedEmployee is not available on that link. That's the reason why your code was not working and You have to make a little change in listitem. Finally, code will look like =>
TS:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
selectedtype: any;
listItems= [{ name: 'A'},{ name: 'B'}];
ngOnInit() {
}
onChange(deviceValue) {
}
}
HTML:
<select name="dt" (change)="onChange($event.target.value)"
[(ngModel)]="selectedtype" placeholder="Type"
#type="ngModel" type="text">
<option *ngFor="let data of listItems" [value]="data.name">{{data.name}}</option>
</select>
NOTE: Provide link contain 4 errors.
Try Using :
You need to initialize your selectedEmployee in you service file
#Injectable({
providedIn: "root"
})
export class EmployeeService {
public selectedEmployee: Employee = {
_id: '',
name: '',
date: null,
designation: '',
salary: null,
type: null
};
constructor() {}
}
Check in your stackblitz demo path.
I think this will help you...
I have a checkboxes and selectbox whose values are coming from loop,but here I need to get some checkboxes checked by default based on an array of object.Here checkbox and selectbox value is coming from usersg and usersr variable.But the checked and selected by default should be from variable usersg_checked and usersr_selected inside ngOnInit(). Here is the code below
home.component.html
<p *ngFor="let group of usersg"><input type="checkbox" checked="checked.id" value="{{group.id}}" />{{group.name}}</p>
<p><select><option *ngFor="let role of usersr" value="{{role.id}}">{{role.name}}</option></select></p>
home.component.html
import { Component, OnInit } from '#angular/core';
import { CommonserviceService } from './../utilities/services/commonservice.service';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
submitted = false;
usersg_checked:any;
usersr_selected:any;
constructor(private formBuilder: FormBuilder) {
}
public usersg = [{"id":1,"name":"test1"},{"id":2,"name":"test2"},{"id":3,"name":"test3"},{"id":4,"name":"test4"}];
public usersr = [{"id":1,"name":"test1"},{"id":2,"name":"test2"}];
ngOnInit() {
this.usersg_checked = [{"id":1,"name":"test1"},{"id":2,"name":"test2"}];
this.usersr_selected = [{"id":1,"name":"test1"}];
}
}
Add isChecked() method in component to check if a checkbox must be selected.
Component:
isChecked(id) {
return this.usersg_checked.some(item => item.id === id);
}
Template:
<p *ngFor="let group of usersg">
<input type="checkbox" [checked]="isChecked(group.id)" value="{{group.id}}" />{{group.name}}
</p>
For <select> elements better to use [(ngModel)].
Template:
<p><select [(ngModel)]="usersr_selected.id">
<option *ngFor="let role of usersr" value="{{role.id}}">{{role.name}}</option>
</select></p>
Component:
And change usersr_selected to an object.
ngOnInit() {
this.usersr_selected = {"id":1,"name":"test1"};
}
If usersr_selected is an array, use the first element of the array as NgModel.
ngOnInit() {
this.usersr_selected = this.usersr_selected[0];
}
I have a select dropdown ,I am getting option's data and value from an array through loop. Here I need to get the value of selected drop down when page loads without onchange(in this case Recent). Here is code below.
app.component.html
<select>
<option *ngFor="let v of values" [value]="v.id">
{{v.name}}
</option>
</select>
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
title = 'projectchart';
public values = [
{ id: 3432, name: "Recent" },
{ id: 3442, name: "Most Popular" },
{ id: 3352, name: "Rating" }
];
ngOnInit(){
alert('The default selected value is');
}
}
you could make use of reactive forms
constructor(private fb: FormBuilder) { }
// create a form group using the form builder service
formName = this.fb.group({
name: ['']
})
in the template
<form [formGroup]="formName">
<select formControlName="name">
<option *ngFor="let v of values" [value]="v.id">
{{v.name}}
</option>
</select>
</>
and then get the value in the ts:
this.formName.controls['name'].value
I am attempting to dynamically present users a set of questions for every product selected.
I have created the questions FormGroup, and then I iterate through the selected products and nest the group of questions beneath each product.
To a degree, this seems to work. The form is created, I can see it via the JSON pipe, and can interact with it.
The problem, however, is that all of the form controls for each product only update the controls for the last product (which I can see via {{form.value | JSON}}
Sample Code:
https://stackblitz.com/edit/angular-py4sam
app.component.ts
import { Component, NgModule, VERSION, OnInit } from '#angular/core'
import { BrowserModule } from '#angular/platform-browser'
import { FormControl, FormGroup, FormArray, ReactiveFormsModule, Validators } from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
questionsForm: FormGroup;
qaForm: FormGroup;
questions = [
{
'question': 'like?',
'value': ''
},
{
'question': 'own?',
'value': ''
}
]
products = [
{
'make': 'fender'
},
{
'make': 'gibson'
}
]
createQuestionsForm() {
this.questionsForm = new FormGroup({
questions: new FormArray([])
});
const qArray = <FormArray>this.questionsForm.controls['questions'];
this.questions.forEach((item, index) => {
const aGroup = new FormGroup({
answer: new FormControl(item.question),
value: new FormControl(item.value)
})
qArray.push(aGroup);
})
}
ngOnInit() {
this.createQuestionsForm();
this.qaForm = new FormGroup(
{
qa: new FormArray([])
});
const qaFormArray = <FormArray>this.qaForm.controls['qa'];
this.products.forEach((item, index) => {
const fg = new FormGroup({
make: new FormControl(item.make),
form: this.questionsForm
})
qaFormArray.push(fg);
})
}
}
app.component.html
<h3>FORM</h3>
<form [formGroup]="qaForm">
<div formArrayName='qa'>
<div *ngFor="let prod of products; let productCount = index">
<h3>{{ prod.make }}</h3>
<div [formArrayName]=productCount>
<div formGroupName="form">
<div formArrayName="questions">
<div *ngFor="let q of questions; let qCount = index">
<div [formArrayName]=qCount>
<input type="checkbox" formControlName="value"> {{ q.question }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<p>qaform {{ qaForm.value | json }}</p>
The issue here is that you use the same questionsForm for all products:
const fg = new FormGroup({
make: new FormControl(item.make),
form: this.questionsForm
^^^^^^^^^^^^^^^
})
In order to fix it you need to create questionsForm per product.
Here is how it could be accomplish:
createQuestionsForm() {
const questionsForm = new FormGroup({
questions: new FormArray([])
});
const qArray = <FormArray>questionsForm.controls['questions'];
this.questions.forEach((item, index) => {
const aGroup = new FormGroup({
answer: new FormControl(item.question),
value: new FormControl(item.value)
})
qArray.push(aGroup);
})
return questionsForm;
}
...
this.products.forEach(
...
const fg = new FormGroup({
make: new FormControl(item.make),
form: this.createQuestionsForm()
})
Forked Stackblitz