Angular Dropdown Doesn't Work, Looks Like a List - html

In my code, I defined a mat-chip-list so that a user can select multiple items from a list of elements. The code doesn't have any errors, but the mat-chip-list doesn't appear as a dropdown. I should be able to select elements from it, but I can't do that either. It just looks like a list as it shown below. What should I do to fix this?
HTML:
<div fxLayout="row" fxLayoutAlign="start center">
<mat-form-field appearance="outline" class="w-100-p" fxFlex>
<mat-label>Product</mat-label>
<mat-chip-list #chipList>
<mat-chip *ngFor="let prm of receiptList"
[selectable]="selectable"
[removable]="removable"
(removed)="removeReceipt(prm)">
{{prm.StockIntegrationCode +' - '+ prm.StockShortName}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<input #receiptInput
[formControl]="receiptCtrl"
[matAutocomplete]="auto"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="addReceipt($event)">
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="receiptSelected($event)">
<mat-option *ngFor="let receipt of filteredReceipts| async" [value]="receipt">
{{receipt.StockIntegrationCode +' - '+ receipt.StockShortName}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
TS:
receiptList: IReceipt[] = [];
receipt: IReceipt[];
allReceipts: IReceipt[] = [];
selectable = true;
removable = true;
addOnBlur = true;
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
receiptCtrl = new FormControl();
filteredReceipts: Observable<IReceipt[]>;
#ViewChild('receiptInput', { read: MatAutocompleteTrigger, static: false }) trigger: MatAutocompleteTrigger;
#ViewChild('receiptInput', { static: false }) receiptInput: ElementRef<HTMLInputElement>;
#ViewChild('auto', { static: false }) matAutocomplete: MatAutocomplete;
constructor(
private _labService: LabService,
) {
_labService.onReceiptListChanged.subscribe(
(response: IReceipt[]) => {
this.receiptList = response;
}
);
this.filteredReceipts = this.receiptCtrl.valueChanges.pipe(
startWith(null),
map((prm: IReceipt | null) =>
prm ? this._filterSupplier(prm) : this.allReceipts.slice()
)
);
}
addReceipt(event: MatChipInputEvent): void {
if (!this.matAutocomplete.isOpen) {
let input = event.input;
let value: IReceipt = event.value as IReceipt;
// Add our approver
if (value) {
this.receipt.push(value);
}
// Reset the input value
if (input) {
input.value = '';
}
this.receiptCtrl.setValue(null);
}
}
removeReceipt(receipt: IReceipt): void {
const index = this.receiptList.indexOf(receipt);
if (index >= 0) {
this.receiptList.splice(index, 1);
}
}
private _filterSupplier(value: IReceipt): IReceipt[] {
let filterValue = value;
if (isString(filterValue)) {
let filterValue = (value as any).toLocaleLowerCase('tr');
return this.allReceipts.filter((prm: IReceipt) => {
return (prm.StockShortName as any).toLocaleLowerCase('tr').indexOf(filterValue) >= 0
});
}
else {
return this.allReceipts.filter((prm: IReceipt) => {
return prm.StockIntegrationCode === prm.StockIntegrationCode;
});
}
}
receiptSelected(event: MatAutocompleteSelectedEvent): void {
let sUser: IReceipt = event.option.value;
if (this.receiptList.filter((f: IReceipt) => f.StockIntegrationCode == sUser.StockIntegrationCode).length == 0) {
this.receiptList.push(sUser);
}
this.receiptInput.nativeElement.value = '';
this.receiptCtrl.setValue(null);
}

Related

How to set the default/prefilled value of a input element in mat-form-field on load?

So I want to implement an html element such that the default data(the variable 'preselectedValue') should be already be entered/prefilled into the input field when the component loads and the user should be able to directly edit the search string.
autocomplete-display-example.html
<mat-form-field appearance="fill">
<mat-label>Assignee</mat-label>
<input type="text" matInput [formControl]="myControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{option.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
autocomplete-display-example.ts
export class AutocompleteDisplayExample implements OnInit {
myControl = new FormControl<string | User>('');
options: User[] = [{name: 'Mary'}, {name: 'Shelley'}, {name: 'Igor'}];
filteredOptions: Observable<User[]>;
preselectedValue = "John";
ngOnInit() {
this.filteredOptions = this.myControl.valueChanges.pipe(
startWith(''),
map(value => {
const name = typeof value === 'string' ? value : value?.name;
return name ? this._filter(name as string) : this.options.slice();
}),
);
}
displayFn(user: User): string {
return user && user.name ? user.name : '';
}
private _filter(name: string): User[] {
const filterValue = name.toLowerCase();
return this.options.filter(option => option.name.toLowerCase().includes(filterValue));
}
}
Any help would be appreciated.
The value of your mat-option is of type User. So you have to pass it a preselected value of that type. The code in your question does not show the definition of the User class but you could try something like this:
preselectedValue = {name: 'John} as User;
ngOnInit() {
this.myControl.value = preselectedValue;
this.filteredOptions = this.myControl.valueChanges.pipe(
startWith(''),
map(value => {
const name = typeof value === 'string' ? value : value?.name;
return name ? this._filter(name as string) : this.options.slice();
}),
);
}

Angular filter and binding (ngModelChange)

I'm working on the hotel project. I have a reservation screen. Here I ask the hotel name, region name, check-in and check-out dates, the number of adults and children. When the necessary information is entered, when I press the search button, I filter according to the values ​​there. I connected the date filter with html using the (NgModelChange) method, but I couldn't connect the html with the hotel and region methods correctly. I made a filter as an experiment, but I got the wrong result. I don't know where I'm making a mistake. How can I fix this?
.html
<form [formGroup]="form">
<mat-form-field>
<label>Which Hotel?</label>
<input type="text" matInput [matAutocomplete]="name" formControlName="name" (change)="changeHotel()" />
<mat-autocomplete #name="matAutocomplete">
<mat-option *ngFor="let hotel of filteredHotels | async" [value]="hotel">
{{hotel}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-form-field>
<label>Which Region?</label>
<input type="text" matInput [matAutocomplete]="region" formControlName="region" (change)="changeRegion()" />
<mat-autocomplete #region="matAutocomplete">
<mat-option *ngFor="let region of filteredRegions | async" [value]="region">
{{region}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-form-field>
<label>Entry Date?</label>
<input matInput [matDatepicker]="mdpStartDate" formControlName="startDate" (ngModelChange)="changeDate()">
<mat-datepicker-toggle matSuffix [for]="mdpStartDate"></mat-datepicker-toggle>
<mat-datepicker #mdpStartDate></mat-datepicker>
</mat-form-field>
<mat-form-field>
<label>Pay Date?</label>
<input matInput [matDatepicker]="mdpEndDate" formControlName="endDate" (ngModelChange)="changeDate()">
<mat-datepicker-toggle matSuffix [for]="mdpEndDate"></mat-datepicker-toggle>
<mat-datepicker #mdpEndDate></mat-datepicker>
</mat-form-field>
<br />
<mat-form-field>
<label>Adult Number?</label>
<input type="number" min="1" matInput formControlName="adult" (ngModelChange)="filterAge()">
</mat-form-field>
<mat-form-field>
<label>Chd Number?</label>
<input type="number" min="0" max="3" value="0" matInput formControlName="chd" (ngModelChange)="filterAge()">
</mat-form-field>
<button type="button" class="btn btn-success" (click)="search()">Search</button>
.ts
form = new FormGroup({
name: new FormControl(''),
region: new FormControl(''),
adult: new FormControl(1),
chd: new FormControl(0),
startDate: new FormControl(),
endDate: new FormControl(),
});
filtered: any[];
showList = false;
name = '';
regions: string[];
hotels: Hotel[] = [];
filteredHotels: Observable<string[]>;
filteredRegions: Observable<string[]>;
ngOnInit() {
this.regions = this.hotels.reduce((arr: string[], current) => {
if (!arr.includes(current.regionName)) {
arr.push(current.regionName);
}
return arr;
}, []);
this.filteredHotels = this.form.get("name").valueChanges
.pipe(
startWith(''),
map(v => {
return this.filterHotels(v)
})
);
this.filteredRegions = this.form.get("region").valueChanges
.pipe(
startWith(''),
map(value => this.filterRegions(value).map(h => h.regionName))
);
this.form.get("adult").valueChanges.
subscribe(v => {
this.adult = new Array(v).map(e => new Object)
});
this.form.get("chd").valueChanges
.subscribe(v => {
this.children = new Array(v).map(e => new Object)
});
this.hotelservice.getHotels().subscribe(
data => {
this.hotels = data;
this.dsHotels.data = data;
this.dsHotels.paginator = this.paginator;
},
err => {
console.error("Hata oluştu: ", err);
}
);
}
private filterHotels(value: string): string[] {
const name = value.toLowerCase();
return this.hotels
.map(x => x.hotelName)
.filter(option => option.toLowerCase().includes(name));
}
private filterRegions(value: string): Hotel[] {
const region = value.toLowerCase();
return this.hotels
.filter(hotel => hotel.regionName.toLowerCase().includes(region));
}
private isEqual(date1: Date, date2: Date) {
return date1.getDate() == date2.getDate() && date1.getMonth() == date2.getMonth() && date1.getFullYear() == date2.getFullYear();
}
private isDataEqualToDate(value1: any, date2: Date) {
if (value1 == null) return true;
return this.isEqual(new Date(value1), date2);
}
private getFilteredDate(): Hotel[] {
return this.hotels.filter(
x => this.isDataEqualToDate(this.form.get("startDate").value, new Date(x.checkInDate))
&& this.isDataEqualToDate(this.form.get("endDate").value, new Date(x.payDate))
);
}
changeHotel() {
this.dsHotels.data = this.filterHotels("value");
}
changeRegion() {
this.dsHotels.data = this.filterRegions("value");
}
changeDate() {
this.dsHotels.data = this.getFilteredDate();
}
filterAge() {
//this.dsHotels.data = this.hotels.filter(x => x.numberOfAd == this.form.get("adult").value && x.numberOfChd == this.form.get("chd").value);
this.dsHotels.data = this.hotels.filter(x => x.numberOfAd == x.numberOfChd);
}
search() {
this.showList = true;
this.filterHotels("");
this.filterRegions("");
this.changeDate();
}
As you created your form with reactive forms you can switch from event binding in template
< ... (change)="changeHotel()"
< ... (ngModelChange)="changeDate()">
to do it inside class.
ngOnInit() {
// ... initial logic
this.form.get('name').valueChanges.subscribe(this.changeHotel.bind(this))
this.form.get('region').valueChanges.subscribe(this.changeRegion.bind(this))
this.form.get('startDate').valueChanges.subscribe(this.changeDate.bind(this))
this.form.get('endDate').valueChanges.subscribe(this.changeDate.bind(this))
this.form.get('adult').valueChanges.subscribe(this.filterAge.bind(this))
this.form.get('chd').valueChanges.subscribe(this.filterAge.bind(this))
}
Reactive form instances like FormGroup and FormControl have a
valueChanges method that returns an observable that emits the latest
values. You can therefore subscribe to valueChanges to update instance
variables or perform operations.
source

Angular flatten inner array

I am trying to get a value from nested array from a Form Values
[['A'], ['B']]-- from this array
['A','B'] --trying to get value like this
stackblitz example
https://stackblitz.com/edit/angular-4d5vfj-p5adyk?file=main.ts
<button (click)="addNewChipList()">Add new Chip</button><br><br>
<form [formGroup]="myForm">
<ng-container formArrayName="names"
*ngFor="let item of myForm.get('names').controls; let i = index;">
<mat-form-field class="example-chip-list" [formGroupName]="i">
<mat-chip-list #chipList >
<mat-chip *ngFor="let val of item.value.val"
[selectable]="selectable"
[removable]="removable"
(removed)="removeChip(item, val)">
{{val}}
<mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
</mat-chip>
<input [placeholder]="item.value.name"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="addChip($event, item)">
</mat-chip-list>
<mat-error>Atleast 1 name need to be added</mat-error>
</mat-form-field>
</ng-container>
<button (click)="save()">save</button><br><br>
</form>
component.ts
The componet file where I am trying to get form value
export class ChipListValidationExample implements OnInit {
#ViewChild('chipList') chipList: MatChipList;
public myForm: FormGroup;
// name chips
visible = true;
selectable = true;
removable = true;
addOnBlur = true;
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
// data
data = {
names: [this.initName('name1'), this.initName('name2', [['A'],
['B']])]
}
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
names: this.fb.array(this.data.names, this.validateArrayNotEmpty)
});
}
ngOnInit() {
this.myForm.get('names').statusChanges.subscribe(
status => this.chipList.errorState = status === 'INVALID'
);
}
initName(name: string, val: string[] = []): FormControl {
return this.fb.control({ name, val});
}
validateArrayNotEmpty(c: FormControl) {
if (c.value && c.value.length === 0) {
return {
validateArrayNotEmpty: { valid: false }
};
}
return null;
}
addChip(event: MatChipInputEvent, ctrl: FormControl): void {
const input = event.input;
const value = event.value;
// Add name
if ((value || '').trim()) {
const control = ctrl;
control.value.val.push(value.trim());
console.log(control.value);
}
// Reset the input value
if (input) {
input.value = '';
}
}
removeChip(ctrl, val) {
const idx = ctrl.value.val.findIndex(item => item === val);
ctrl.value.val.splice(idx, 1);
}
addNewChipList() {
const items = this.myForm.get('names') as FormArray;
items.push(this.initName(`name${items.length + 1}`));
}
save(){
console.log("FormValues",this.myForm.value)
}
}
I am trying to get the form value as ['A','B']
Flattening some arrays is a trivial task with plain JS. Using Array.flat, you can do this in one line.
The flat() method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth.
Syntax
var newArray = arr.flat([depth]);
Parameters
depth Optional
The depth level specifying how deep a nested array structure should be flattened. Defaults to 1.
Return value
A new array with the sub-array elements concatenated into it.
//one level deep
var x = [['A'], ['B']];
console.log(x.flat());
// => ['A', 'B']
//2 levels deep
var y = [[['A', 'B'], ['C']], ['D']];
console.log(y.flat(2));
// => ['A', 'B', 'C', 'D']

How to validate dynamic radio button in ionic 3

I have a series of questions which have radio answer choices. I can't figure out how to use angular validation to require the user to select all answer before clicking save & next.
NOTE: Please note that click save & next button gets the next 5 question from the controller depending on what choice was made. It's basically a dynamic questionnaire. Below is my code.
<ion-content id="testmodeCont" >
<div class="midCont mrgn0" >
<form #f="ngForm" class="login">
<div class="formCont">
<div *ngIf = "questionCategory == 'Diabetes'">
<div class="boxInCont" *ngFor="let question of AllQuestions | slice:numberOfQuestionsToDisplay:numberOfQuestionsToleft; let i = index">
<div *ngIf="mLanguageFlag === 'English'" >
<div class="heading" *ngIf="question.QuestionType=='dropdown'||question.QuestionType=='radio'||question.QuestionType=='toggle'|| question.QuestionType=='multiselect' ">
Q. {{question.QuestionText}}
</div>
</div>
<div *ngIf="mLanguageFlag === 'English'">
<div class="row mrgnB20" *ngIf="question.QuestionType=='radio'">
<div>
<div class="quetxt">
<ion-list radio-group [ngModelOptions]="{standalone: true}" [(ngModel)]="AllGroupAnswers[i].ExpectedAnswerId" >
<ion-item class="opteach" *ngFor="let answer of question.ExpectedAnswers">
<ion-label class="radioBox fr">{{answer.Answer}}
</ion-label>
<ion-radio item-left [value]="answer.ExpectedAnswerId" (ionSelect)="ValueChanged(answer)">
</ion-radio>
</ion-item>
</ion-list>
</div>
</div>
</div>
</div>
<div *ngIf="mLanguageFlag === 'English'">
<ion-item class="row" *ngIf="question.QuestionType=='dropdown'">
<ion-select formControlName="option" okText="Okay" cancelText="Nah" placeholder= "{{'personal.select'|translate}}" interface = "alert">
<ion-option *ngFor="let answer of question.ExpectedAnswers" [value]="answer.Answer" (ionSelect)="ValueChanged(answer)">{{answer.Answer}}
</ion-option>
</ion-select>
</ion-item>
</div>
</div>
</div>
</div>
</form>
</div>
<div class ="testbtn">
<ion-grid>
<ion-row>
<ion-col align-self-center>
<button ion-button block color="button-color" class="prevBtn" type="submit" (click) = "previous()" *ngIf="previousState" >{{"Previous" | translate}}</button>
</ion-col>
<ion-col align-self-end>
<button ion-button block color="button-color" class="saveBtn" type="submit" (click) = "next()" *ngIf="isDataLoad" >{{"Save & Next" | translate}}</button>
</ion-col>
</ion-row>
</ion-grid>
</div>
ts file
import { Component } from '#angular/core';
import { NavController, NavParams, AlertController, ToastController } from 'ionic-angular';
import { UserService } from '../../providers/service/share';
import { Service } from '../../providers/service/service';
import { Functions } from '../../providers/service/functions';
import { Values } from '../../providers/service/values';
import { UtilService } from '../../providers/service/util';
import { FeedsPage } from '../feeds/feeds';
import { TestPage } from '../test/test';
#Component({
templateUrl: 'testmode.html',
})
export class TestmodePage {
questionCategory: any
ckeckedArray: any;
answersID: any;
userPrefernce: any;
AllQuestions: any;
edittest: any;
testQuestionList: any;
TestQuestions: any;
lifestyleAnswers: any;
AllGroupAnswers: any;
AllTestAnswer: any;
ShowlifeStyleSave: boolean = false;
ExpectedAnswers: any;
mLanguageSelect: any;
mLanguageClass: any;
mLanguageFlag: any;
mLanguageClassdisc: any;
mLanguageClassWhite: any;
mLanguageClassGreen: any;
success: any;
numberOfQuestionsToDisplay: any;
numberOfQuestionsToleft: any
previousState: boolean = false;
isDataLoad: boolean = false;
pageIndex: any;
testform: FormGroup;
constructor(public navCtrl: NavController,public alertCtrl: AlertController,private toastCtrl: ToastController, public navParams: NavParams, public functions: Functions, public values: Values, public utilServices: UtilService, public userService: UserService, public service: Service) {
this.numberOfQuestionsToDisplay = 0;
this.numberOfQuestionsToleft = 5;
this.questionCategory = this.navParams.get('questionCategory')
this.mLanguageFlag = 'English';
this.testQuestionList = [];
this.TestQuestions = [];
this.lifestyleAnswers = [];
this.AllGroupAnswers = [];
this.AllTestAnswer = [];
this.ExpectedAnswers = [];
this.AllQuestions = [];
this.pageIndex = 0 ;
console.log(this.questionCategory);
this.setTestInfo();
}
ionViewDidLoad(){
this.mLanguageSelect = this.userService.getLocaleDisplayName();
console.log(this.mLanguageSelect)
if(this.mLanguageSelect == 'english'){
this.mLanguageClass = ' ';
this.mLanguageFlag='English';
this.mLanguageClassWhite = ' ';
this.mLanguageClassGreen = ' ';
}else if(this.mLanguageSelect == 'hindi'){
this.mLanguageClass = 'heading2';
this.mLanguageClassWhite = 'heading3';
this.mLanguageFlag='Hindi';
this.mLanguageClassGreen = 'heading4';
}
}
setTestInfo(){
var url = '/api/JM_TestQuestions?userId=1002&questionCategory='+ this.questionCategory ;
this.service.jivaGetMethod('1234567899','mobile',url).then((results) => {
console.log(results);
this.userService.setLifeStyleInfo(results);
this.edittest = this.userService.getLifeStyleInfo();
console.log("Your question",this.edittest);
this.AllQuestions = this.edittest.TestQuestions;
console.log("Your answer", this.AllQuestions);
for (var i = 0; i < this.AllQuestions.length; i++) {
// console.log("hello", this.AllQuestions[i]);
var obj= this.AllQuestions[i]
this.AllTestAnswer[i] = obj.ExpectedAnswers;
console.log(this.AllTestAnswer[i]+ i);
this.TestQuestions.push(obj);
console.log(this.TestQuestions.push(obj));
if (obj.ExpectedAnswers[0].UserAnswer==true){
this.AllGroupAnswers.push(obj.ExpectedAnswers[0]);
}else if(obj.ExpectedAnswers[1].UserAnswer==true){
this.AllGroupAnswers.push(obj.ExpectedAnswers[1]);
}else {
this.AllGroupAnswers.push({});
}
console.log("working");
this.testQuestionList.push(obj);
this.isDataLoad = true;
}
})
.catch((error)=>{
console.log(error);
})
}
ValueChanged(answer){
console.log(answer);
console.log(this.AllQuestions) ;
for (var i = 0; i < this.AllQuestions.length; i++) {
if (this.AllQuestions[i].QuestionId==answer.QuestionId) {
for (var j = 0; j < this.AllQuestions[i].ExpectedAnswers.length; j++) {
console.log(this.AllQuestions[i].ExpectedAnswers[j].Answer);
if (this.AllQuestions[i].ExpectedAnswers[j].ExpectedAnswerId==answer.ExpectedAnswerId) {
console.log('match-->',this.AllQuestions[i].ExpectedAnswers[j].ExpectedAnswerId,'-------',answer.ExpectedAnswerId);
this.AllQuestions[i].ExpectedAnswers[j].UserAnswer=true;
console.log(this.AllQuestions[i].ExpectedAnswers[j]);
}else {
console.log('not match-->',this.AllQuestions[i].ExpectedAnswers[j].ExpectedAnswerId,'-------',answer.ExpectedAnswerId);
this.AllQuestions[i].ExpectedAnswers[j].UserAnswer=false;
}
}
break;
}
}
}
submitTest(){
console.log(this.testQuestionList);
var TestQuestions = this.testQuestionList ;
var testData = {
"User": {
"UserId": 79163,
"FirstName": null,
"LastName": null,
"MobileNo": null,
"EmailId": null,
"UserSfdcId": null,
"FacebookId": null,
"GooglePlusId": null,
"AccessToken": null,
"AuthType": null,
"UserLanguage": null,
"UserDeviceId": null,
"UserPersonalDetails": null,
"CountryCode": 0
},
"TestQuestions": TestQuestions
};
this.functions.presentLoading(this.values.lan.WaitTitle);
// var identity = this.userService.getUserIdentity();
// var authtype = this.userService.getUserData().AuthType;
var url = 'http:///api/JM_TestQuestions';
this.service.submitSetUser1('1234567899','mobile',url,JSON.stringify(testData)).then((results) => {
console.log(results);
this.success = results
console.log(this.success);
this.functions.dismissLoading();
//this.navCtrl.setRoot(TestresultsPage);
}) .catch((error)=> {
alert("Please try after sometime..");
this.functions.dismissLoading();
})
}
next(){
this.previousState = true;
console.log(this.AllQuestions.length)
console.log(this.numberOfQuestionsToleft)
if(this.AllQuestions.length > this.numberOfQuestionsToleft) {
this.pageIndex++;
console.log(this.pageIndex)
this.numberOfQuestionsToDisplay = this.numberOfQuestionsToDisplay +5;
this.numberOfQuestionsToleft = this.numberOfQuestionsToleft + 5;
console.log(this.numberOfQuestionsToDisplay);
console.log(this.numberOfQuestionsToleft);
this.submitTest();
} else {
this.submitTest();
let toast = this.toastCtrl.create({
message: 'Your answer for ' + this.questionCategory + ' test was saved successfully',
duration: 2000,
position: 'top'
});
toast.onDidDismiss(() => {
console.log('Dismissed toast');
});
toast.present();
this.navCtrl.setRoot(FeedsPage);
}
}
previous() {
this.pageIndex--;
console.log(this.pageIndex)
this.numberOfQuestionsToDisplay = this.numberOfQuestionsToDisplay - 5;
this.numberOfQuestionsToleft = this.numberOfQuestionsToleft - 5;
console.log(this.numberOfQuestionsToDisplay);
console.log(this.numberOfQuestionsToleft);
this.submitTest();
if(this.pageIndex == 0){
console.log(this.pageIndex)
this.previousState = false;
}
}
ionViewWillLeave(){
let alert = this.alertCtrl.create({
title: "Jiva Ayurveda",
message: "Do you want to close the test ?",
buttons:[
{
text:"Yes",
handler: () => {
this.navCtrl.setRoot(TestPage);
}
},
{
text:"No",
handler: () => {
}
}
]
});
alert.present();
}
}
You can use a (click)=function(arg1, arg2) in order to create a function to check the specific validation you need to see happening.
Edit:
In the function you call with (click) add a logic at the beginning:
function(arg1) {
if(!arg1){
return; // eventually output a string in an error message to indicate the user needs to input or tick a box
} else {
// next page
}
}
use formgroup and initialize form like
this.loginForm = this.fb.group({
username: ['', Validators.required],
password: ['', Validators.required]
})

Refreshing angular ag-grid data

I have an ag-grid which is rendering table from a .json file and an external Quick filter that is searching through ag-grid on key input on the filter. After someone searches the search term is displayed in the form of angular material chip with a "X" sign to close the chip with remove function. I want to reload the ag-grid to its default state once someone cancel/close the chip and also to include multiple filters in it using the chip. Here is my sample code, but I'm struggling with setting it up.
Html-
<div class="container">
<mat-form-field class="demo-chip-list" *ngIf="gridApi">
<mat-chip-list #chipList>
<div style="width:100%; margin-left:10%;"><label><span class="search-button">Search Funds</span></label>.
<input class="search-input"
[ngModel]="filterText"
(ngModelChange)=
"gridApi.setQuickFilter
($event)"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="addOnBlur"
(matChipInputTokenEnd)="add($event)" />.
</div><br/><div style="width:100%; margin-left:10%;"><mat-chip *ngFor="let fruit of fruits"
[selectable]="selectable"
[removable]="removable"
(click)="onGridReady(params)"
(remove)="remove(fruit)">
{{fruit.name}}
<mat-icon matChipRemove *ngIf="removable" ><sup>x</sup></mat-icon></mat-chip></div></mat-chip-list>.
</mat-form-field>
<div class="header" style="display:inline"></div><div> <ag-grid-angular
style="position:absolute;padding-left:5%; bottom:0px;width: 90%; height: 350px;" #agGrid id="myGrid" class="ag-fresh" [columnDefs]="columnDefs"
[animateRows]="true"
[enableRangeSelection]="true"
[enableSorting]="true"
[enableFilter]="true"
[pagination]="true"
(gridReady)="onGridReady($event)">
</ag-grid-angular></div></div>
Component-
#Component({
selector:
'app-funds-table',
templateUrl:
'./funds-table.component.html',
styleUrls:
['./funds-table.component.css']
})
export class
FundsTableComponent
implements OnInit {
visible: boolean = true;
selectable: boolean = true;
removable: boolean = true;
addOnBlur: boolean = true;
// Enter, comma
separatorKeysCodes = [ENTER, COMMA];
fruits = [
{ name: 'ABC' }
];
add(event: MatChipInputEvent): void
{
let input = event.input;
let value = event.value;
// Add our fruit
if ((value || '').trim()) {
this.fruits.push({ name:
value.trim() });
}
// Reset the input value
if (input) {
input.value = '';
}
}
remove(fruit: any): void {
let index =
this.fruits.indexOf(fruit);
if (index >= 0) {
this.fruits.splice(index, 1);
}
}
private gridApi;
private gridColumnApi;
private columnDefs;
private filterText = "";
ngOnInit() {}
constructor(private http:
HttpClient ){
this.columnDefs = [{headerName:
"Ticker", field: "Ticker"},
{headerName: "Id", field: "Id"},
{headerName: "Utilities", field:
"Utilities"}
];
}
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi =
params.columnApi;
this.http.get
("/fundsData/fund_info.json". )
.subscribe
(data =>
{this.gridApi.setRowData(data);
});
}
}
According doc:
You can reset filter via direct api call
api.setQuickFilter(''); - empty for reset filter