Angular 8 Select Option property binding - javascript

I have a Select Option Like This .. In this dropdown i am calling an api just to get some data
<div class="mb-frm_l frm_r">
<div class="dropdown inputs">
<select
[ngClass]="{
error:
billingForm.controls.selectDistrict.errors?.required &&
((billingForm.controls['selectDistrict'].dirty &&
billingForm.controls['selectDistrict'].touched) ||
billingForm.controls['selectDistrict'].errors
.isValidString)
}"
formControlName="selectDistrict"
id="selectDistrict"
(focus)="onFocus()"
(blur)="onBlur()"
(change)="getCityList($event.target.value)" // here i want to pass the District name
>
<option value="">Select District</option>
<option
*ngFor="let district of districtList"
[attr.district-id]="district.district_id"
[value]="district.district_id"
>
{{ district.district }}
</option>
</select>
<div
*ngIf="
billingForm.controls['selectDistrict'].invalid &&
billingForm.controls['selectDistrict'].dirty &&
billingForm.controls['selectDistrict'].touched
"
class="error_txt"
>
Please select state
</div>
</div>
</div>
Here I am passing the selected value in getCityList($event.target.value)
As i want the district.district also in my ts file
My Question is How can i pass the district.district here with the value also ???
Thanks!

A simple find in getCityList is what you need. Since you didnt provide the code, I made up something:
getCityList($event.target.value): void {
const value = '';
const district = this.districtList.find((d) => d.district_id === $event.target.value);
if (district) {
value = district.district;
}
}

Change your Option tag this [value]="district.district_id" into
[value]="district"
Then your (change)="getCityList($event.target.value)" will return selected district object. then you can access any property you want

Related

Set default value option with Angular ReactiveForm setValue method

I am trying to set default value of select option with Angular 7, but it doesnt set default option value;
Here what I tried to do.
At the component I am using setValue() method to set default value.
this.courseForm.controls['selectedTeacher'].setValue(this.course['Teacher'],{onlySelf: true});
And at the template I am using select like this:
<select formControlName="selectedTeacher">
<option *ngFor="let teacher of teachers" [ngValue]="teacher">
{{ teacher.FirstName }} {{teacher.LastName}}
</option>
</select>
Normally when try like this with input text it works but select list doesnt work.
I couldn't realize exactly what the problem is.
Help please,
Thanks
Angular uses objects reference, instead of properties, so if you do this, it will work if you have unique identifier for each teacher
const teacher = this.teachers.find(t=> t.id == this.course['Teacher'].id);
this.courseForm.controls['selectedTeacher'].setValue(teacher,{onlySelf: true});
Or you can find by any unique property
const teacher = this.teachers.find(t=> t.FirstName == this.course['Teacher'].FirstName && t.LastName == this.course['Teacher'].LastName );
change in your component:
this.courseForm.controls['selectedTeacher'].setValue(this.course['Teacher'].id,{onlySelf: true})
in your html:
<select formControlName="selectedTeacher">
<option *ngFor="let teacher of teachers" [value]="teacher.id">
{{ teacher.FirstName }} {{teacher.LastName}}
</option>
</select>

How to get full drop-down object item using Reactive Forms?

In this case I'm not using ngModel directives.
I want to know how to get the full object binded to the drop down when it change.
Basically, this is what I'm doing:
It's an array of objects with properties, but i don't want only the
value, i want the full object selected
<select #tipoTextoItem (change)="handleChange($item)" name="cmbTipoTexto" class="form-control form-control-sm col-sm-7" id="cmbTipoTexto" formControlName="cmbTipoTexto">
<option *ngFor="let item of textTypes" value="{{item.key}} {{item.value}}
</option>
</select>
Then...
handleChange($event) {
console.log($event.ForExampleGetMyObjectInThisWay());
}
You can use compareWith input property provided by angular. In the function you can compare and return the object. You can use it like:-
<select #tipoTextoItem (change)="handleChange($item)"
[compareWith]="compareFn"
name="cmbTipoTexto"
class="form-control form-control-sm col-sm-7"
id="cmbTipoTexto"
formControlName="cmbTipoTexto">
<option *ngFor="let item of textTypes"
value="{{item}}">{{item.value}}</option>
</select>
In your component.ts file,
compareFn(item1, item2) {
return item1 && item2 ? item1.value === item2.value : item1 === item1;
}
You can look into below link for more info:-
https://angular.io/api/forms/SelectControlValueAccessor#customizing-option-selection
you can use selectedIndex, Here you go :
(change)="handleChange($event.target.selectedIndex)" // change method
handleChange(index) {
console.log(this.textTypes[index]);
}
WORKING DEMO

Angular5 select model

I have a Angular5 <select> bound to array of customers. See below:
<select class="form-control" [ngModel]="record.customer_id" (ngModelChange)="setCustomer($event)" name="customer_id">
<option *ngFor="let x of customers" [ngValue]="x.id">{{x.name}}</option>
</select>
In setCustomer function I get an customer's id as 'event'.
Property record.customer_id is type of number, not object. Is there any way how to get a whole customer entity in setCustomer method and also preserve binding to record.customer_id ?
I found on Angular docu a way [compareWith] so I tried:
<select class="form-control" [compareWith]="compareCustomer" [ngModel]="record.customer_id" (ngModelChange)="setCustomer($event)" name="customer_id">
<option *ngFor="let x of customers" [ngValue]="x">{{x.name}}</option>
</select>
and
compareCustomer(c1: customer, c2: number) : boolean {
if (c1 == null || c1 == undefined) {
return false;
}
if (c1.id == c2) {
return true;
}
return false;
}
Does not work. When I select any option, setCustomer is executed, record.customer_id gets selected id. However, after select loses focus, selected option is reset to blank.
There is a workaround (iteration in customers array and manual match by id) that I want to avoid:
setCustomer(event) {
this.record.customer_id = Number.parseInt(event);
customers.forEach(c => {
if (c.id === this.record.customer_id) {
// some logic with selected customer
}
});
}
Any advice?
Thanks!
Instead of bind customer_id, bind the whole object:
<select class="form-control" [ngModel]="record" (ngModelChange)="setCustomer($event)" name="customer_id">
<option *ngFor="let x of customers" [ngValue]="x">{{x.name}}</option>
</select>

content select option based on previous select option angularjs

i want to create 2 select option which the content of the other one selected option based to previous option. here is my html
<div class="col-sm-2">
<select class="form-control" ng-model="y">
<option value="1">a</option>
<option value="2">b</option>
</select>
</div>
<div class="col-sm-2">
<select class="form-control" ng-model="z">
<option ng-repeat = "x in list" value="{{x.idproduct}}">{{x.descproduct}}</option>
</select>
</div>
but there is error, the other select option wont showing the option like in this picture
here is my js file
if ($scope.y === 1) {
$scope.list = [
{idproduct:"13", descproduct:"cc"},
{idproduct:"14", descproduct:"dd"}
];
}
if ($scope.y === 2) {
$scope.list = [
{idproduct:"15", descproduct:"ee"}
];
}
You need to bind the change event so that your list gets updated at the time that your value is updated. Plus your === can cause an issue. With === your string value is being compared to integers 1 and 2.
Here is a plunker: ng-change for change in dropdown
<select class="form-control" ng-model="y" ng-change="updateList()">
<option value="1">a</option>
<option value="2">b</option>
</select>
$scope.updateList()={
if ($scope.y == 1) {
$scope.list = [
{idproduct:"13", descproduct:"cc"},
{idproduct:"14", descproduct:"dd"}
];
}
if ($scope.y == 2) {
$scope.list = [
{idproduct:"15", descproduct:"ee"}
];
}
}
The value of your option is String value="2"
And you're comparing it to an Integer if ($scope.y === 2)
You should compare it like if ($scope.y === '2') or if (parseInt($scope.y) === 2)
Create a function and put your Js code in that function and call function on ng-change of the first dropdown. Here you if condition executes once during app initialization. So by triggering ng-change we can call function and update the lists based on the selection.

Angular model change isn't reflected to html select box

I have an html list with a form for defining filter values. In this form there is a select box:
<div style="...">
<label for="lstCategory">Category:</label><br/>
<select name="category" id="lstCategory" ng-model="category" ng-change="loadActivities()">
<option value="0">default1</option>
<option value="1">default2</option>
<option ng-repeat="category in categories" value="{{ category.id }}">{{ category.id }}</option>
</select>
</div>
In my controller I bind the "categories" model to a REST resource:
.controller('AppointmentsHomeCtrl', [
...
function(
...
) {
$scope.location = typeof $location.search().location != 'undefined' ?
$location.search().location :
'0';
$scope.category = typeof $location.search().category != 'undefined' ?
$location.search().category :
'0';
$scope.categories = CategoriesResource.query();
Now I want to preselect a value in this select box, depending on the dearch parameter "location" in my url, which is done by the $scope.category = typeof $locati....... part of the code.
My problem is, that this preselection isn't reflected to my HTML while the mnodel itself has the correct value.
I already tryed to set the value after the query to the resource is done by watching the resource or giving a callback function to the "query" method but this also isn't working.
Did I missed something here? What is the correct way to solve this problem?
Edit:
It seems to recognise the options since:
$scope.category = "foo"; adds a pseudo option which gets selected.
But when I choose an existiong id, nothing happens at all:
$scope.category = "3";
at controller you can try this method for preselect value
$scope.precategory = '0'; //just for example value
then on your html code make sure ng-model having different variable with ng-repeat like this one
<select name="category" id="lstCategory" ng-model="precategory " ng-change="loadActivities()">
<option value="0">default1</option>
<option value="1">default2</option>
<option ng-repeat="category in categories" value="{{ category.id }}">{{ category.id }}</option>
that method will help solve your problem, because i was getting same problem before :)
Instead of $scope.categories = CategoriesResource.query(); try:
CategoriesResource.query().then(function(result) {
$scope.categories = result;
});
You may have to tweak it a bit if the result is not an array...

Categories

Resources