Problem <mat-chip> on angular material design - javascript

My problem is: i have mat-chip list and if i close the first item it's ok and if i close the last item all are close:
this is my html:
<mat-form-field>
<mat-chip-list #chipList>
<mat-chip *ngFor="let keyword of keywords" [removable]="removable" (removed)="remove(keyword)">
{{ keyword }}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input placeholder="{{ 'consultantSearchPage.searchForConsultantOrSkills' | translate }}" [matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
(matChipInputTokenEnd)="addSearch($event)">
</mat-chip-list>
</mat-form-field>
and this is my ts:
remove(keyword): void {
const index = this.keywords.indexOf(keyword);
if (index >= 0) {
this._store.dispatch({ type: UPDATE_KEYWORDS, payload: index});
}
}
and if i use:
remove(keyword): void {
const index = this.keywords.indexOf(keyword);
if (index >= 0) {
this.keywords.splice(index, 1);
}
}
it's ok but my data are not update
and this is my reducer code:
export const UPDATE_KEYWORDS = 'UPDATE_KEYWORDS';
.......
case UPDATE_KEYWORDS:
console.log( state.keywords.splice(0, 1));
return Object.assign({}, state, { keywords: state.keywords.splice(action.payload, 1) });

From your comment you are doing this:
case UPDATE_KEYWORDS:
console.log( state.keywords.splice(0, 1));
return Object.assign({}, state, { keywords: state.keywords.splice(action.payload, 1) });
whereas you should do this:
case UPDATE_KEYWORDS:
state.keywords.splice(action.payload, 1);
console.log(state.keywords);
return Object.assign({}, state, { keywords: state.keywords });
You want to use the array that has been spliced, not the array returned from the splice.
https://www.w3schools.com/jsref/jsref_splice.asp

Related

Navigating Through an Array Of Elements

In my code, I'm trying to navigate through an array of strings. I'm also using observable and I try to map it through next and previous buttons. I can see the first element of the array on the input field but I want to navigate to the next elements and see them in the input field using next button. My code is below, how can I achieve this?
HTML:
<div>
<input type="input" value="{{ slider$ | async }}" />
{{ slider$ | async }}
</div>
<div>
<button mat-button (click)="previous()">Previous</button>
<button mat-button (click)="next()">Next</button>
</div>
TS:
slides: string[] = ['Slide 1', 'Slide 2', 'Slide 3', 'Slide 4'];
slider$: Observable<any> = of(this.slides).pipe(
tap(console.log),
map((arr: string[]) => {
return arr[0];
}),
tap(console.log)
);
previous() {
this.slider$.pipe(
map((arr: string[]) => {
return arr[0];
}),
tap(console.log)
);
}
next() {
this.slider$.pipe(
map((arr: string[]) => {
return arr[1];
}),
tap(console.log)
);
}
You should subscribe only once to slider$. You could navigate through the array like so:
template HTML
<ng-container *ngIf="current$ | async as current">
<input type="input" [value]="current" /> <!-- use property binding -->
<p>{{ current }}</p>
</ng-container>
<div>
<button mat-button (click)="navigate(false)">Previous</button>
<button mat-button (click)="navigate(true)">Next</button>
</div>
component
#Component({...})
export class TheComponent {
index = 0;
slides: string[] = ['Slide 1', 'Slide 2', 'Slide 3', 'Slide 4'];
slider$ = of(this.slides)
current$!: Observable<string>;
ngOnInit(): void {
this.current$ = this.slider$.pipe(map(arr => arr[this.index]));
}
navigate(add: boolean): void {
this.index = add ? ++this.index : --this.index;
console.log('index', this.index)
this.current$ = this.slider$.pipe(map(arr => arr[this.index]));
}
}

Mat-Error Required validation error message shows when form is first open

I have a custom control component that is used to show a required validation error for mat-chip-lists. On the form that I'm using this component, when I first open this form the required validation message shows. I only want it to show when the field is not populated with any data. Can someone please provide a reason why and a solution to what I need to do to get the validation to work properly.
I could be overcomplicating this and it's much simpler than I thought.
html where mat-error element for required show:
<mat-form-field [floatLabel]="floatLabel">
<mat-label>{{ label }}</mat-label>
<mat-chip-list #optionList aria-label="label" required>
<mat-chip *ngFor="let item of selectedOptions" (removed)="removed(item)"
[removable]="!item.disabled" [disabled]="item.disabled">
{{ item.text }}
<mat-icon *ngIf="!item.disabled" matChipRemove>cancel</mat-icon>
</mat-chip>
<input
#optionInput
type="text"
[placeholder]="placeholder"
[formControl]="formControl"
[matAutocomplete]="optionAutoComplete"
[matChipInputFor]="optionList"
[required]="required"
/>
</mat-chip-list>
<mat-autocomplete #optionAutoComplete="matAutocomplete"
(optionSelected)="selected($event.option.value)">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.text }}
</mat-option>
</mat-autocomplete>
<mat-hint *ngIf="hint">{{ hint }}</mat-hint>
</mat-form-field>
<mat-error *ngIf="required === true && hasValue === false &&
isInitialized === true"> {{ label }} is
<strong>required</strong> </mat-error>
Typescript for the custom control
The removed function fires when you remove selected items from the list. It turns the check back on and sends the update to the parent component.
Component({
selector: 'app-chips',
templateUrl: './chips.component.html',
})
export class ChipsComponent implements OnInit, DoCheck {
#Input() label = '';
#Input() placeholder = '';
#Input() options: Options[] = [];
#Input() selectedOptions: Options[] = [];
#Input() floatLabel: FloatLabelType = 'auto';
#Input() hint!: string | undefined;
#Input() required = true;
hasValue: boolean = this.selectedOptions.length > 0;
isInitialized: boolean | undefined;
#ViewChild('optionInput') optionInput: ElementRef | undefined;
#Output() onRemoved = new EventEmitter<Options>();
#Output() selectedOptionsChanged = new EventEmitter<Options[]>();
formControl = new FormControl('');
filteredOptions: Observable<Options[]> | undefined;
iterableDiffer: IterableDiffer<Options>;
constructor(private readonly iterableDiffers: IterableDiffers) {
this.iterableDiffer = this.iterableDiffers.find([]).create();
}
ngDoCheck(): void {
const optionChanges = this.iterableDiffer.diff(this.options);
if (optionChanges) {
this.filteredOptions = of(this.options);
}
if (this.required === undefined) {
this.required = false;
}
}
ngOnInit(): void {
this.subscribeFilterOptions();
this.isInitialized = true;
}
ngAfterViewInit(): void {
this.isInitialized = true;
}
selected(value: Options): void {
if (this.optionInput) {
this.optionInput.nativeElement.value = '';
}
if (!this.selectedOptions.find((x) => x.text === value.text)) {
this.selectedOptions.push(value);
this.selectedOptionsChanged.emit(this.selectedOptions);
}
this.hasValue = this.selectedOptions.length > 0;
}
private subscribeFilterOptions() {
this.filteredOptions = this.formControl.valueChanges.pipe(
startWith(''),
map((value: string | Options) =>
value && typeof value === 'string' ? this.options.filter((o) =>
o.text.toLowerCase().includes(value.toLowerCase())) :
this.options.slice()
)
);
}
removed(value: Options): void {
this.onRemoved.emit(value);
this.hasValue = this.selectedOptions.length > 0;
}
}
Mat-chip-list component on the form
<div class="col-md-12">
<app-linq-chips
label="Entities"
placeholder="Add Entity..."
[options]="entityOptions"
[selectedOptions]="selectedEntities"
[hint]="
entityListHasDisabledOptions === true
? 'Please remove this contact from any roles for an entity prior to removing their
association to that entity.'
: undefined
"
(onRemoved)="removeEntity($event)"
>
</app-linq-chips>
</div>
Your variable hasValue is only set when a chip is selected or removed. When the component is initialized it's value is false as the number of selected options is zero.
hasValue: boolean = this.selectedOptions.length > 0;
The required variable is initialized to true, so the mat error condition below:
<mat-error *ngIf="required === true && hasValue === false"> {{ label }} is
<strong>required</strong> </mat-error>
will be true, so the error will show initially.
To fix this issue, add an extra boolean variable, isInitialized (or whatever you want to name it), set it to false in the ngOnInit(), then set it to true in the ngAfterViewinit().
Update your mat-error condition like follows:
<mat-error *ngIf="required === true && hasValue === false && isInitialized === true"> {{ label }} is
<strong>required</strong> </mat-error>
Try the above and it should only error check after the component selections are made.

Vue array changes add or remove using treeview from vuetify

I use vuetify and treeview. I want to list object fill with items and nested array in every of them.
export interface IExamMenuItem {
id?: number | string;
title: string;
link: string;
children: IExamMenuItem[];
}
<v-treeview :items="items" item-text="title" item-key="items.id" dense hoverable>
<template #prepend="{ item, open }">
<v-icon v-if="item.title === 'Амбулаторен лист'">
{{ 'home' }}
</v-icon>
<v-icon v-else-if="!item.name != 'Амбулаторен лист'">
{{ open ? 'mdi-folder-open' : 'mdi-folder' }}
</v-icon>
</template>
<template #label="{ item }">
<v-list-item
v-if="item.children"
:key="item.id"
style="background-color: beige"
:to="item.link"
link
>
{{ item.title }}
</v-list-item>
<v-list-item v-else :key="item.id" :to="item.link" link>
{{ item.title }}
</v-list-item>
</template>
</v-treeview>
When im trying to add or remove from 'items' i doesnt effect the tree, 'items' are update but not in the tree.
Here is the add method
private createReferralEventHandler(id: number | null, typeOfReferral: string | null) {
if (id != null && typeOfReferral != null) {
let item: IExamMenuItem = {} as IExamMenuItem;
const main = this.items.filter(x => x.id === typeOfReferral)[0];
if (main) {
item = {
id: id,
title: `${main.title} №${id}`,
link: `/Exam/${typeOfReferral}/Edit/${id}`
} as IExamMenuItem;
if (!main.children) {
main.children = [];
}
this.$set(this.items.filter(x => x.id === typeOfReferral)[0]['children'], main.children.length, item)
main.children.push(item);
this.titleOfReferral = item.title;
this.alertCreate = true;
}
}
Here is the the delete method
private deleteReferralEventHandler(id: number | null, typeOfReferral: string | null) {
if (id != null) {
const main = this.items.filter((x) => x.id === typeOfReferral)[0];
if (main) {
let remove = main.children.findIndex((i) => i.id === id);
this.titleOfReferral = main.children.filter((i) => i.id === id)[0].title;
main.children.splice(remove, 1);
this.alertDelete = true;
}
}
}
You have to re-assign items value to force vue to re-render the tree.
Should use something like this to remove an item:
this.items = this.items.filter((x) => x.id !== idToRemove)
And something like this to add an item:
this.items = [...this.items, newItem]

Remove and add object item into array and change object key if specific item already exists in the array

I have this array of recipes where each object is a specific recipe and each recipe has an array of ingredients and each ingredient it's an object made of _id name quantity. My problem added below if you guys have any idea why is this happening please let me know. I am struggling for 3 days...any advice would be really appreciated. Thanks a lot!
(3) [{…}, {…}, {…}]
0:
ingredients: Array(4)
0: {_id: "5f6628d0029e87e02c79ce0a", name: "chia", quantity: 10}
1: {_id: "5f6628d0029e87e02c79ce0b", name: "apple", quantity: 15}
2: {_id: "5f6628d0029e87e02c79ce0c", name: "honey", quantity: 30}
3: {_id: "5f6628d0029e87e02c79ce0d", name: "almond flour", quantity: 35}
length: 4
__proto__: Array(0)
name: "Coconut Chia Pudding"
__v: 0
_id: "5f6628d0029e87e02c79ce09"
__proto__: Object
1: {_id: "5f6628d0029e87e02c79ce0e", name: "Peanut Butter Cookies", ingredients: Array(4), __v: 0}
2: {_id: "5f6628d0029e87e02c79ce13", name: "Caprese Avocado Bowls", ingredients: Array(3), __v: 0}
length: 3
__proto__: Array(0)
What I have in UI it's a list with the above recipes which a user can tick and untick and after a recipe has been ticked its ingredients are showed into a list.
HTML
<ion-content>
<ion-grid>
<ion-row>
<ion-col>
<ion-list>
<ion-item
*ngFor="let recipe of loadedRecipes; let lastRecipe = last"
[ngClass]="{ 'last-recipe': lastRecipe }"
>
<ion-checkbox
(ionChange)="onCheckRecipe($event)"
value="{{recipe.name}}"
></ion-checkbox>
<ion-label>{{recipe.name}}</ion-label>
<ion-button
[routerLink]="['/','recipes','recipe-details', recipe._id]"
>></ion-button
>
</ion-item>
</ion-list>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<h6 class="ion-padding-start" *ngIf="groceryList.length > 0">
Grocery List
</h6>
<ion-list *ngIf="groceryList.length > 0">
<ion-item *ngFor="let ingredient of groceryList">
<ion-label>{{ingredient.name}}</ion-label>
<ion-note slot="end">{{ingredient.quantity}} g</ion-note>
</ion-item>
</ion-list>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
What I want to achieve (and I've done it below, but I have a bug) is when the user ticks a recipe its ingredients to be added into an array called groceryList and when unticks the recipe to remove the ingredients from my groceryList array. Also, if I have ticked 1 recipe and if the next one I am going to tick has the same ingredient as the one ticked before, just to increment that common ingredient quantity that already exists, and NOT to add it twice and if I want to untick a recipe to remove the uncommon ingredients and subtract the quantity of the common ingredient. I already managed to do it, BUT I have a big problem and I don't know where is coming from. at some point in UI if I tick and untick recipes and I tick the ones that have the same ingredient one after another it removes the common ingredient even though I still have a ticked recipe that has that ingredient. Again, if you guys have any idea why is this happening please let me know I would appreciate any advice you have
My TS
import { Component, OnInit } from "#angular/core";
import { Subscription } from "rxjs";
import { RecipesService } from "src/app/services/recipes.service";
#Component({
selector: "app-recipes",
templateUrl: "./recipes.page.html",
styleUrls: ["./recipes.page.scss"],
})
export class RecipesPage implements OnInit {
loadedRecipes: any;
private _recipesSub: Subscription;
constructor(private recipesService: RecipesService) {}
groceryList = [];
ngOnInit() {
this._recipesSub = this.recipesService.recipes.subscribe((receivedData) => {
this.loadedRecipes = receivedData;
});
}
onCheckRecipe(e) {
if (e.detail.checked === true) {
for (let recipe of this.loadedRecipes) {
console.log(this.loadedRecipes);
if (recipe.name === e.detail.value) {
for (let eachIngredient of recipe.ingredients) {
let matchedIng = this.groceryList.find(function (foundIng) {
return foundIng.name === eachIngredient.name;
});
if (matchedIng) {
matchedIng.quantity =
matchedIng.quantity + eachIngredient.quantity;
} else {
this.groceryList.push(eachIngredient);
}
}
}
}
} else {
for (let recipe of this.loadedRecipes) {
if (recipe.name === e.detail.value) {
for (let eachIngredient of recipe.ingredients) {
let matched = this.groceryList.find(function (foundIngre) {
return foundIngre.name === eachIngredient.name;
});
if (
matched.name === eachIngredient.name &&
matched._id === eachIngredient._id
) {
let index = this.groceryList.findIndex(
(x) => x._id === matched._id
);
this.groceryList.splice(index, 1);
} else {
matched.quantity = matched.quantity - eachIngredient.quantity;
}
}
}
}
}
}
ionViewWillEnter() {
this.recipesService.fetchRecipes().subscribe();
}
ngOnDestroy() {
if (this._recipesSub) this._recipesSub.unsubscribe();
}
}
The problem lies in the flow of your if statements. In the "onRemove" section of your code, you are saying "If the ingredient is in the list, remove it from the list. If not, decrement its quantity." That second part doesn't make any sense and more importantly, you'll never reach it because the ingredient should always be in the list.
for (let eachIngredient of recipe.ingredients) {
let matched = this.groceryList.find(function(foundIngre) {
return foundIngre.name === eachIngredient.name;
});
if (
matched.name === eachIngredient.name &&
matched._id === eachIngredient._id
) {
let index = this.groceryList.findIndex(
(x) => x._id === matched._id
);
// Problem e ca eachIngredient.quantity se schimba
this.groceryList.splice(index, 1);
} else {
matched.quantity = matched.quantity - eachIngredient.quantity;
}
}
Based on what you've said, what you want to do is:
subtract the quantity which was attributed to the removed recipe
if the new quantity is zero, remove the ingredient from the list (though you could also leave it and ignore ingredients with zero quantity)
Try this instead:
for (let eachIngredient of recipe.ingredients) {
// I am assuming that ids are unique so I am not checking foundIngre.name at all,
// since I assume that ingredients with the same name must also have the same name
// I am also using findIndex first so that you don't need a second find when removing
const matchIndex = this.groceryList.findIndex(
(foundIngre) => foundIngre._id === eachIngredient._id
);
if ( matchIndex ) { // this should always be true
const matched = this.groceryList[matchIndex];
// preserve the entry if there is still some quantity
if ( matched.quantity > eachIngredient.quantity ) {
matched.quantity = matched.quantity - eachIngredient.quantity; // can use -= to shorten
}
// remove from the list only if there is no quantity remaining
else {
this.groceryList.splice(matchIndex, 1);
}
}
}
EDIT:
Trying to update and remove items in an array is an unnecessary pain. The reworked version of your code stores the _groceryList in a keyed dictionary instead. I initially intended to key by ingredient id, but after reviewing your demo I see that I was incorrect in my assumption that the same ingredient in multiple recipes would share the same id. So instead I am keying by ingredient name. This way you can write to _groceryList[name] and it doesn't matter whether it previously existed or not.
The class has a public getter groceryList which converts the private _groceryList dictionary into an array.
I've also tried to remove unnecessary code duplication across scenario branches by using a generic toggleIngredient function which uses the boolean checked to control whether it is adding or subtracting by multiplying by plus or minus one.
import { Component } from "#angular/core";
import { Platform } from "#ionic/angular";
import { SplashScreen } from "#ionic-native/splash-screen/ngx";
import { StatusBar } from "#ionic-native/status-bar/ngx";
import { Subscription } from "rxjs";
export interface Ingredient {
_id: string;
name: string;
quantity: number;
}
export interface Recipe {
_id: string;
name: string;
ingredients: Ingredient[];
}
#Component({
selector: "app-root",
templateUrl: "app.component.html"
})
export class AppComponent {
private _recipesSub: Subscription;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
private loadedRecipes: Recipe[] = [/*...*/]
// store the groceryList in a dictionary keyed by name
private _groceryList: Record<string, Ingredient> = {};
// getter returns the groceryList in array format, ignoring 0 quantities
get groceryList(): Ingredient[] {
return Object.values(this._groceryList).filter( ing => ing.quantity > 0 );
}
// get the current quantity for an ingredient by name, or 0 if not listed
currentQuantity( name: string ): number {
const ingredient = this._groceryList[name];
return ingredient ? ingredient.quantity : 0;
}
// update the quantity for an ingredient when checked or unchecked
// will add new ingredients, but never removes old ones
toggleIngredient( ingredient: Ingredient, checked: boolean ): void {
// add to or remove from quantity depending on the value of checked
const quantity = this.currentQuantity(ingredient.name) + (checked ? 1 : -1 ) * ingredient.quantity;
// replace the object in the grocery list dictionary
this._groceryList[ingredient.name] = {
...ingredient,
quantity
}
}
onCheckRecipe(e) { // you'll want to add a type for e here
for (let recipe of this.loadedRecipes) {
// find the matching recipe
if (recipe.name === e.detail.value) {
// loop through the recipe ingredients
for (let eachIngredient of recipe.ingredients) {
this.toggleIngredient(eachIngredient, e.detail.checked)
}
}
}
}
}
I think the issue seems to be with this section of the code
if (
matched.name === eachIngredient.name &&
matched._id === eachIngredient._id
) {
let index = this.groceryList.findIndex(
(x) => x._id === matched._id
);
// Problem e ca eachIngredient.quantity se schimba
this.groceryList.splice(index, 1);
} else {
matched.quantity = matched.quantity - eachIngredient.quantity;
}
The if statement should be checking on the quanity instead of validating the name and id again , something like
if(matched.quantity <= eachIngredient.quantity){
// splice the item and remove it.
}
else
{
// decrease the quantity
}
A small suggestion to finding the matched ingredient. First use findIndex() to retrieve matchedIndex, and use grocerylist[matchedIndex] to retrieve the item, to avoid iterating through the grocerylist again to find the index for splicing.

Angular 5 : ERROR TypeError: Cannot read property 'toLowerCase' of undefined

I am having this error every time I try to filter a column of a column of a table.I fetch my data from a FireStore cloud collection and the the field auteur is well defined in each documents.
here's what my component looks like
import { Component, OnInit, ViewChild} from '#angular/core';
import { Router } from '#angular/router';
import { DataService } from '../../services/data.service';
import { Observable } from 'rxjs/Observable';
import { AngularFirestore } from 'angularfire2/firestore';
import { AuthentificationService } from '../../services/authentification.service';
#Component({
selector: 'app-data-preview',
templateUrl: './data-preview.component.html',
styleUrls: ['./data-preview.component.css']
})
export class DataPreviewComponent implements OnInit {
rows = [];
temp = [];
selected: any[] = [];
columns;
panelOpenState = false;
id: any;
#ViewChild(DataPreviewComponent) table: DataPreviewComponent;
constructor(private router: Router, private dataService: DataService,
private afs: AngularFirestore,public authService: AuthentificationService) {
this.dataService.getData().subscribe((datas) => {
this.temp = [...datas];
this.rows = datas;
console.log(datas);
});
}
ngOnInit() {
}
updateFilter(event) {
const val = event.target.value.toLowerCase();
// filter our data
const temp = this.temp.filter(function(d) {
return d.nom.toLowerCase().indexOf(val) !== -1 || !val;
});
// update the rows
this.rows = temp;
// Whenever the filter changes, always go back to the first page
}
updateFilter1(event) {
const val1 = event.target.value.toLowerCase();
// filter our data
const temp = this.temp.filter(function(d) {
return d.prenom.toLowerCase().indexOf(val1) !== -1 || !val1;
});
// update the rows
this.rows = temp;
// Whenever the filter changes, always go back to the first page
}
updateFilter2(event) {
const val2 = event.target.value.toLowerCase();
// filter our data
console.log(val2);
const temp = this.temp.filter(function(d) {
return d.auteur.toLowerCase().indexOf(val2) !== -1 || !val2;
});
// update the rows
this.rows = temp;
// Whenever the filter changes, always go back to the first page
}
updateFilter3(event) {
const val3 = event.target.value.toLowerCase();
// filter our data
const temp = this.temp.filter(function(d) {
return d.departement.toLowerCase().indexOf(val3) !== -1 || !val3;
});
// update the rows
this.rows = temp;
// Whenever the filter changes, always go back to the first page
}
updateFilter4(event) {
const val4 = event.target.value.toLowerCase();
// filter our data
const temp = this.temp.filter(function(d) {
return d.commune.toLowerCase().indexOf(val4) !== -1 || !val4;
});
// update the rows
this.rows = temp;
// Whenever the filter changes, always go back to the first page
}
updateFilter5(event) {
const val5 = event.target.value.toLowerCase();
// filter our data
const temp = this.temp.filter(function(d) {
return d.typeF.toLowerCase().indexOf(val5) !== -1 || !val5;
});
// update the rows
this.rows = temp;
// Whenever the filter changes, always go back to the first page
}
// onSelect({ selected }) {
// console.log('Select Event', selected, this.selected);
// }
onActivate(event) {
if (event.type === 'click') {
console.log('Event: activate', event);
this.id = event.row.id;
this.router.navigate(['/data', this.id]);
}
}
}
and the component associated with it
<!-- panneau de recherche -->
<div *ngIf="authService.user | async">
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<b> Panneau de recherche </b>
</mat-panel-title>
</mat-expansion-panel-header>
<mat-form-field>
<input matInput placeholder="Nom" id="nom" (keyup)="updateFilter($event)">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Prénom" id="prenom" (keyup)="updateFilter1($event)">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Auteur" id="auteur" (keydown)="updateFilter2($event)">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Département" (keyup)="updateFilter3($event)">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Commune" (keyup)="updateFilter4($event)">
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Formation" (keyup)="updateFilter5($event)">
</mat-form-field>
</mat-expansion-panel>
<mat-expansion-panel (opened)="panelOpenState = true"
(closed)="panelOpenState = false">
</mat-expansion-panel>
</mat-accordion>
<!-- fin panneau de recheche -->
<div class="table" style="width: 100%">
<ngx-datatable
class="material"
[headerHeight]="50"
[columnMode]="'force'"
[rowHeight]="'auto'"
[footerHeight]="50"
[count]="true"
[limit]="50"
[rows]="rows"
[selectionType]="'single'"
(activate)="onActivate($event)"
>
<ngx-datatable-column name="Nom" class="name">
<ng-template ngx-datatable-cell-template let-value="value" >
{{value}}
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Prenom">
<ng-template ngx-datatable-cell-template let-value="value">
{{value}}
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name='Telephone'>
<ng-template ngx-datatable-cell-template let-value="value">
{{value}}
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name='Auteur'>
<ng-template ngx-datatable-cell-template let-value="value">
{{value}}
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Departement">
<ng-template ngx-datatable-cell-template let-value="value">
{{value}}
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Commune">
<ng-template ngx-datatable-cell-template let-value="value">
{{value}}
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="TypeF">
<ng-template ngx-datatable-cell-template let-value="value">
{{value}}
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Statut">
<ng-template ngx-datatable-cell-template let-value="value">
{{value}}
</ng-template>
</ngx-datatable-column>
</ngx-datatable>
</div>
</div>
I tried to console.log(auteur.id) and it displayed the content in the console.
PS: I have tried to filter other fileds of my document it works perfectly.
Any idea of how to solve this?
When this happens I usually check if the data is there before, in your case:
if(d && d.auteur){
return d.auteur.toLowerCase().indexOf(val2) !== -1 || !val2;
}
In angular material, there is no event.target.value, but instead event.value. You should try using this.
updateFilter2(event) {
const val2 = event.value.toLowerCase(); // filter our data
const temp = this.temp.filter(function(d) {
if(d && d.auteur){
return d.auteur.toLowerCase().indexOf(val2) !== -1 || !val2;
}
});
this.rows = temp;
}

Categories

Resources