Set other value other than default value in angular 7 dropdown - angular7

I have a drop-down list where it shows 'US' as a default value which
is right but suppose a user
is from India so Instead of this i want 'India' in the drop-down.If user is from 'US' or any
other country then it shows 'US' in the drop-down.
So i want to store the current location of the user in the drop-down.But
By default it should shows 'US' in the drop-down. If the user is from
India then set 'India' in the drop-down.
Simply if a user is from 'US' or any other country then by default it shows
'US' in the drop-down but if the user is from 'India' then it shows India in
the drop-down.
app.component.ts -
countries = [
{ name: 'USA', id: '0' },
{ name: 'India', id: '1' }
];
public onChange() {
const userCountry = sessionStorage.getItem(this.appConstants.StorageKeys.UserCountry);
if (userCountry !== null || userCountry !== '') {
return userCountry;
console.log(userCountry);
} else {
return this.countries;
}
}
Here userCountry gives the current location of user i.e; India , Us, OR Any
other country that we fetch from the api .
app.component.html
<select (click)="onChange()">
<option *ngFor="let country of countries" [value]="country">{{ country.name }}
</option>
</select>
What should i do in the app.component.html to bind when the current location of the user is
India or any other country.
Also i don't want to use ngModel for binding.
Kindly Please Help!

countries = [
{ name: 'USA' },
{ name: 'India'}
];
public selectedCountry: string = 'India';
<select>
<option *ngFor="let country of countries" [value]="country"
[selected]="country === selectedCountry">
{{ country }}
</option>
</select>
For reactive form use syntax for drodown -
<select>
<option *ngFor="let country of countries" value="{{country }}"
selected="country === {{selectedCountry}}">{{ country }}
</option>
</select>
For Another way of dropdown binding reactive form you can also visit-
Using select controls in a reactive form
The following examples show how to use a select control in a reactive form.
import {Component} from '#angular/core';
import {FormControl, FormGroup} from '#angular/forms';
#Component({
selector: 'example-app',
template: `
<form [formGroup]="form">
<select formControlName="state">
<option *ngFor="let state of states" [ngValue]="state">
{{ state.abbrev }}
</option>
</select>
</form>
<p>Form value: {{ form.value | json }}</p>
<!-- {state: {name: 'New York', abbrev: 'NY'} } -->
`,
})
export class ReactiveSelectComp {
states = [
{name: 'Arizona', abbrev: 'AZ'},
{name: 'California', abbrev: 'CA'},
{name: 'Colorado', abbrev: 'CO'},
{name: 'New York', abbrev: 'NY'},
{name: 'Pennsylvania', abbrev: 'PA'},
];
form = new FormGroup({
state: new FormControl(this.states[3]),
});
}

Related

Select2 with tags and suggestions

I was using Select2 to have a list of brands and categories, each grouped by <optgroup>.
So far so good, because the list was not changing. Now I have to implement a Product search, which will have no specific values, so you can search for everything you type in.
For example, if the user types in "sho", i want to have:
**Products**
- sho (exactly what the user enters)
**Brands** (suggestions from a list)
- Adidas Shoes
- Nike Shoes
**Categories** (suggestions from a list)
- Shoes for women
- Shoes for men
And as the user types more characters, the sho under Products keeps updating to show what they entered.
The code for the previous version was:
<select id="search_bar">
<option></option>
<optgroup label="Stores">
{% for merchant in all_merchants %}
<option value="{% url %}">{{ merchant.display_name }}</option>
{% endfor %}
</optgroup>
<optgroup label="Categories">
{% for category in all_categories %}
<option value="{% url %}">{{ category.name }}</option>
{% endfor %}
</optgroup>
</select>
I tried enabling tags, by doing tags: true, and it works but not entirely, because if I type in something that matches a brand or a category, the tag will disappear. I.E, if i type "Adidas", it will show only the Adidas under brands (so if i click it, I'm taken to the brand page), but not as a tag that i can click and be taken to the product search page.
Does that make sense?
Ok its first try, i you click on new tag to create, i keep it in the list of firstdropdown and you have propagation in the second dropdown (at least 2 character minimun):
$('#source').select2({
tags:true
});
$('#search').select2({
tags:true,
insertTag:function (data, tag) {
data.push(tag);
},
createTag: function (params) {
return {
id: params.term,
text: params.term,
newTag: true
}
},
matcher: matchCustom,
}).on("select2:select", function(e) {
// if( e.params.data.newTag){
select2_search($("#source"), e.params.data.text);
$(this).find('[value="'+e.params.data.id+'"]').replaceWith('<option selected value="'+e.params.data.id+'">'+e.params.data.text+'</option>');
// }
//uncomment if you want to play the same search
//$("#search").val("0").trigger("change");
});
function matchCustom(params, data) {
// If there are no search terms, return all of the data
if ($.trim(params.term) === '') {
return data;
}
// Do not display the item if there is no 'text' property
if (typeof data.text === 'undefined') {
return null;
}
// Return `null` if the term should not be displayed
return null;
}
function select2_search ($el, term) {
$el.select2('open');
// Get the search box within the dropdown or the selection
// Dropdown = single, Selection = multiple
var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;
// This is undocumented and may change in the future
$search.val(term);
$search.trigger('input');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet"/>
<select id ="search" class="myselect" style="width:50%;" >
<option value="0"></option>
</select> <prev><== Type new tag into search</prev>
<br><br><br><br><br><br><br><br>
<select style="width:100%;" id="source" multiple="" tabindex="-1" aria-hidden="true">
<optgroup class="select2-result-selectable" label="Brand" >
<option value="Adidas shoes">Adidas shoes</option>
<option value="Pantalon">Pantalon</option>
<option value="short">short</option>
</optgroup>
<optgroup class="select2-result-selectable" label="Categories" >
<option value="Shoes for men">Shoes for men</option>
<option value="Shoes for women">Shoes for women</option>
<option value="Other things for wommen">Other things for women</option>
<option value="Other things for men">Other things for men</option>
</optgroup>
</select>

Angular Reactive Forms validations

I have a form with 3 inputs, 2 of the inputs are required and the third isn't.
My problem is that when I go the page of the form I see that the field that isn't required is in a valid state and is already colored with green, even tho the field isn't dirty or touched.
Is there anything I can do to make the input be grayed out until I validate the field / form or is it like this by design?
Here's the code I use in the component:
export class SystemSettingsComponent implements OnInit {
form: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.form = new FormGroup({});
}
ngOnInit() {
this.form = this.formBuilder.group({
serviceName: ['', Validators.required],
serviceDesc: [''],
serviceId: [{value: SystemSettingsComponent.generateId(), disabled: true}, Validators.required]
});
}
static generateId() {
return Math.random().toString(36).substr(2, 9);
}}
And the template :
<form [formGroup]="form" novalidate>
<div class="row">
<div class="col-lg-4">
<mat-form-field>
<input matInput placeholder="שם השירות" formControlName="serviceName"/>
</mat-form-field>
<mat-form-field>
<textarea matInput placeholder="תיאור השירות" formControlName="serviceDesc"></textarea>
</mat-form-field>
<mat-form-field>
<input matInput class="ltr text-align-left" placeholder="מזהה שירות" formControlName="serviceId"/>
</mat-form-field>
</div>
</div>
<div>
<button mat-raised-button class="mat-raised-button mat-primary" matStepperNext>הבא</button>
</div>
You can listen to the form's status changes and set the optional form control's disabled state accordingly. Something like:
ngOnInit() {
this.form = this.formBuilder.group({
serviceName: ['', Validators.required],
serviceDesc: [{value: '', disabled: true}],
serviceId: [{value: SystemSettingsComponent.generateId(), disabled: true}, Validators.required]
});
this.form.statusChanges.subscribe(status => {
if (status === 'VALID' && this.form.controls.serviceDesc.disabled) {
this.form.controls.serviceDesc.enable();
} else if (status !== 'VALID' && this.form.controls.serviceDesc.enabled) {
this.form.controls.serviceDesc.disable();
}
});
}

How to display data from firebase database in Ionic 3?

I want to display my database data into ionic view.
here detail data in my database:
{firstName: "John", lastName: "Doe", username: "jhondoe"}
my code in page controller:
import { AngularFireDatabase, FirebaseObjectObservable } from 'angularfire2/database';
profile : FirebaseObjectObservable<Profile>;
this.afAuth.authState.subscribe(data => {
if(data.email && data.uid){
this.afDatabase.object(`profile/${data.uid}`).valueChanges().subscribe(profile => {
this.profile = profile;
console.log(profile);
});
});
view page:
<ion-content padding>
<p>Username: {{ profile?.username | async }}</p>
<p>First Name: {{ profile?.firstName | async }}</p>
<p>Last Name: {{ profile?.LastName | async }}</p>
</ion-content>
but it not work, and display error:
InvalidPipeArgument: 'John' for pipe 'AsyncPipe'
profile is not a promise/observable since you are setting data after subscription here:
this.afDatabase.object(`profile/${data.uid}`).valueChanges().subscribe(profile => {
this.profile = profile;
console.log(profile);
});
Either declare profile as a regular object and remove async:
profile : Profile;
Html:
<p>Username: {{ profile?.username }}</p>
<p>First Name: {{ profile?.firstName}}</p>
<p>Last Name: {{ profile?.LastName}}</p>
OR.
declare as an observable and do not subscribe in ts.
profile : Observable<Profile>;
this.profile = this.afDatabase.object(`profile/${data.uid}`).valueChanges();

Form array validation not working in Angular 2

This is my form object
this.userFormGroup = this.fb.group({
name : ["", Validators.required],
email : "",
phone : ""
address : this.fb.group({
city : ["", Validators.required],
state : ""
}),
hobbies : this.fb.array([
this.fb.group({
name : ["", Validators.required]
}),
])
})
I have used this object in the below mentioned HTML.
<div formArrayName="hobbies">
<div formGroupName="0">
Name <input type="text" formControlN!ame="name"> <br><br>
<div *ngIf="userFormGroup.get('hobbies[0].city').hasError('required')">
City Required
</div>
</div>
</div>
Other validations are working but form validations are not working.
Thanks in advance.
Try this
<div *ngIf="userFormGroup.get('hobbies').controls[i].get('name').errors">
City Required
</div>

Cannot set the default option in select in angular2

I am trying to select a default option in select. Below is my code
<select [id]="index" class="form-control" (change)="onChange($event.target.selectedIndex,$event.target.value)" (focus)="onFocus($event.target.selectedIndex)">
<option value="" [selected]="true" disabled="true">{{'rec.select' | translate}}</option>
<option *ngFor="let attributeType of attributeTypeValues" [disabled]="attributeType.disabled" [value]="attributeType.attrTypeNm"
[selected]="attributeType.attrTypeNm===attributeEditForm.controls['attrType'].value">
{{attributeType.attrTypeDesc}}
</option>
</select>
I can see ng-reflect-selected as true. Yet nothing gets selected in UI.
The code works fine on first time load. But as the selection changes the changes are not reflected in UI. For example, if the form value is changed, then the selection condition changes and the same selected option does not get reflected in ui.
I personally would use a [(ngModel)] approach in this situation:
<select [(ngModel)]="selectedValue">
<option *ngFor="let v of values" [ngValue]="v">{{v.name}}</option>
</select>
with the following in the controller:
values = [
{ id: 0, name: "Value0" },
{ id: 1, name: "Value1" },
{ id: 2, name: "Value2" },
{ id: 3, name: "Value3" },
];
selectedValue = this.values[0];
important is that the default selection needs to be the correct object instance than the one used in the value list. Another object instance even with the same properties and values won't do => object identity is checked.
The easy way and fastest way would be to check if your *ngFor fresh new variable is equal to your logic in the [selected] : (example)
<select (change)="size($event.target.value)" class="size-option" name="size">
<option *ngFor="let number of [14, 16, 18, 20, 22]" value="{{number}}" [selected]="number == 16">{{number}}</option>
</select>

Resources