Filter for multiple values in a column in mat-filter
I want to filter a column in an Angular Material table for multiple values.
I have added two filters on this. A dropdown filter for position with checkboxes corresponding to each position and a text based filter for the name. I want the filter to work in such a way that if I click the checkbox for 1 and 10 in the position dropdown, both the rows are visible. But, if I write H in the name filter when those 2 checkboxes are ticked, only row 1 is visible. Basically, an OR in the multiple filters of one column and an AND between the filters of different columns.
Right now, my code works for the AND part between the two separate filters. However, if I select two checkboxes in the position dropdown menu, neither column is visible.
Attaching my code on Stackblitz for reference

add a comment |
I want to filter a column in an Angular Material table for multiple values.
I have added two filters on this. A dropdown filter for position with checkboxes corresponding to each position and a text based filter for the name. I want the filter to work in such a way that if I click the checkbox for 1 and 10 in the position dropdown, both the rows are visible. But, if I write H in the name filter when those 2 checkboxes are ticked, only row 1 is visible. Basically, an OR in the multiple filters of one column and an AND between the filters of different columns.
Right now, my code works for the AND part between the two separate filters. However, if I select two checkboxes in the position dropdown menu, neither column is visible.
Attaching my code on Stackblitz for reference

add a comment |
I want to filter a column in an Angular Material table for multiple values.
I have added two filters on this. A dropdown filter for position with checkboxes corresponding to each position and a text based filter for the name. I want the filter to work in such a way that if I click the checkbox for 1 and 10 in the position dropdown, both the rows are visible. But, if I write H in the name filter when those 2 checkboxes are ticked, only row 1 is visible. Basically, an OR in the multiple filters of one column and an AND between the filters of different columns.
Right now, my code works for the AND part between the two separate filters. However, if I select two checkboxes in the position dropdown menu, neither column is visible.
Attaching my code on Stackblitz for reference

I want to filter a column in an Angular Material table for multiple values.
I have added two filters on this. A dropdown filter for position with checkboxes corresponding to each position and a text based filter for the name. I want the filter to work in such a way that if I click the checkbox for 1 and 10 in the position dropdown, both the rows are visible. But, if I write H in the name filter when those 2 checkboxes are ticked, only row 1 is visible. Basically, an OR in the multiple filters of one column and an AND between the filters of different columns.
Right now, my code works for the AND part between the two separate filters. However, if I select two checkboxes in the position dropdown menu, neither column is visible.
Attaching my code on Stackblitz for reference


edited Nov 22 '18 at 11:40
SiddAjmera
15.6k31238
15.6k31238
asked Nov 22 '18 at 11:22
user3414175user3414175
31
31
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
I have changed some codes in customFilterPredicate
customFilterPredicate() {
return (data: PeriodicElement, filter: string): boolean => {
let searchString = JSON.parse(filter) as MyFilter;
let isPositionAvailable = false;
if (searchString.position.length) {
for (const d of searchString.position) {
// equal validate
if (data.position.toString().trim() == d) {
// OR
// Checking index of
if (data.position.toString().trim().indexOf(d) !== -1) {
isPositionAvailable = true;
}
}
} else {
isPositionAvailable = true;
}
return isPositionAvailable && data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase()) !== -1;
}
}
Add some interface for better typing
export interface MyFilter {
position: string,
name: string,
weight: string,
symbol: string
}
Also add interface in filteredValues
filteredValues: MyFilter = { position: , name: '', weight: '', symbol: '' };
Thanks! This works just as I wanted. I just noticed that when I click the checkbox for position 1, poistion 10's row is also visible because of the partial matching of the string. Do you know how I can make it match to the exact string instead of partial string?
– user3414175
Nov 22 '18 at 12:54
instead of checking indefOf, check whether the value is equal or not. I have updated the answer
– Sheik Althaf
Nov 22 '18 at 12:57
add a comment |
You can simply filter the data yourself and set the data
of dataSource
. Like following code.
Method for filtering the options.
filterOptions(positionValue: string, nameValue: string): PeriodicElement {
if ((!positionValue || positionValue.length === 0) && !nameValue) {
return ELEMENT_DATA;
}
const filtered = ELEMENT_DATA.filter((periodicElement) => {
return (nameValue? periodicElement.name.toLowerCase().includes(nameValue.toLowerCase()): false)
|| (positionValue ? positionValue.indexOf(periodicElement.position+'') !==-1: false)});
return filtered;
}
You can use this on both filter change like following
this.positionFilter.valueChanges.subscribe((positionFilterValue) => {
this.dataSource.data = this.filterOptions(positionFilterValue, this.nameFilter.value);
});
this.nameFilter.valueChanges.subscribe((nameFilterValue) => {
this.dataSource.data = this.filterOptions(this.positionFilter.value, nameFilterValue);
});
Here is your updated code with above changes https://stackblitz.com/edit/angular-hbakxo-e4njon
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429860%2ffilter-for-multiple-values-in-a-column-in-mat-filter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I have changed some codes in customFilterPredicate
customFilterPredicate() {
return (data: PeriodicElement, filter: string): boolean => {
let searchString = JSON.parse(filter) as MyFilter;
let isPositionAvailable = false;
if (searchString.position.length) {
for (const d of searchString.position) {
// equal validate
if (data.position.toString().trim() == d) {
// OR
// Checking index of
if (data.position.toString().trim().indexOf(d) !== -1) {
isPositionAvailable = true;
}
}
} else {
isPositionAvailable = true;
}
return isPositionAvailable && data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase()) !== -1;
}
}
Add some interface for better typing
export interface MyFilter {
position: string,
name: string,
weight: string,
symbol: string
}
Also add interface in filteredValues
filteredValues: MyFilter = { position: , name: '', weight: '', symbol: '' };
Thanks! This works just as I wanted. I just noticed that when I click the checkbox for position 1, poistion 10's row is also visible because of the partial matching of the string. Do you know how I can make it match to the exact string instead of partial string?
– user3414175
Nov 22 '18 at 12:54
instead of checking indefOf, check whether the value is equal or not. I have updated the answer
– Sheik Althaf
Nov 22 '18 at 12:57
add a comment |
I have changed some codes in customFilterPredicate
customFilterPredicate() {
return (data: PeriodicElement, filter: string): boolean => {
let searchString = JSON.parse(filter) as MyFilter;
let isPositionAvailable = false;
if (searchString.position.length) {
for (const d of searchString.position) {
// equal validate
if (data.position.toString().trim() == d) {
// OR
// Checking index of
if (data.position.toString().trim().indexOf(d) !== -1) {
isPositionAvailable = true;
}
}
} else {
isPositionAvailable = true;
}
return isPositionAvailable && data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase()) !== -1;
}
}
Add some interface for better typing
export interface MyFilter {
position: string,
name: string,
weight: string,
symbol: string
}
Also add interface in filteredValues
filteredValues: MyFilter = { position: , name: '', weight: '', symbol: '' };
Thanks! This works just as I wanted. I just noticed that when I click the checkbox for position 1, poistion 10's row is also visible because of the partial matching of the string. Do you know how I can make it match to the exact string instead of partial string?
– user3414175
Nov 22 '18 at 12:54
instead of checking indefOf, check whether the value is equal or not. I have updated the answer
– Sheik Althaf
Nov 22 '18 at 12:57
add a comment |
I have changed some codes in customFilterPredicate
customFilterPredicate() {
return (data: PeriodicElement, filter: string): boolean => {
let searchString = JSON.parse(filter) as MyFilter;
let isPositionAvailable = false;
if (searchString.position.length) {
for (const d of searchString.position) {
// equal validate
if (data.position.toString().trim() == d) {
// OR
// Checking index of
if (data.position.toString().trim().indexOf(d) !== -1) {
isPositionAvailable = true;
}
}
} else {
isPositionAvailable = true;
}
return isPositionAvailable && data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase()) !== -1;
}
}
Add some interface for better typing
export interface MyFilter {
position: string,
name: string,
weight: string,
symbol: string
}
Also add interface in filteredValues
filteredValues: MyFilter = { position: , name: '', weight: '', symbol: '' };
I have changed some codes in customFilterPredicate
customFilterPredicate() {
return (data: PeriodicElement, filter: string): boolean => {
let searchString = JSON.parse(filter) as MyFilter;
let isPositionAvailable = false;
if (searchString.position.length) {
for (const d of searchString.position) {
// equal validate
if (data.position.toString().trim() == d) {
// OR
// Checking index of
if (data.position.toString().trim().indexOf(d) !== -1) {
isPositionAvailable = true;
}
}
} else {
isPositionAvailable = true;
}
return isPositionAvailable && data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase()) !== -1;
}
}
Add some interface for better typing
export interface MyFilter {
position: string,
name: string,
weight: string,
symbol: string
}
Also add interface in filteredValues
filteredValues: MyFilter = { position: , name: '', weight: '', symbol: '' };
edited Nov 22 '18 at 12:58
answered Nov 22 '18 at 12:24


Sheik AlthafSheik Althaf
27717
27717
Thanks! This works just as I wanted. I just noticed that when I click the checkbox for position 1, poistion 10's row is also visible because of the partial matching of the string. Do you know how I can make it match to the exact string instead of partial string?
– user3414175
Nov 22 '18 at 12:54
instead of checking indefOf, check whether the value is equal or not. I have updated the answer
– Sheik Althaf
Nov 22 '18 at 12:57
add a comment |
Thanks! This works just as I wanted. I just noticed that when I click the checkbox for position 1, poistion 10's row is also visible because of the partial matching of the string. Do you know how I can make it match to the exact string instead of partial string?
– user3414175
Nov 22 '18 at 12:54
instead of checking indefOf, check whether the value is equal or not. I have updated the answer
– Sheik Althaf
Nov 22 '18 at 12:57
Thanks! This works just as I wanted. I just noticed that when I click the checkbox for position 1, poistion 10's row is also visible because of the partial matching of the string. Do you know how I can make it match to the exact string instead of partial string?
– user3414175
Nov 22 '18 at 12:54
Thanks! This works just as I wanted. I just noticed that when I click the checkbox for position 1, poistion 10's row is also visible because of the partial matching of the string. Do you know how I can make it match to the exact string instead of partial string?
– user3414175
Nov 22 '18 at 12:54
instead of checking indefOf, check whether the value is equal or not. I have updated the answer
– Sheik Althaf
Nov 22 '18 at 12:57
instead of checking indefOf, check whether the value is equal or not. I have updated the answer
– Sheik Althaf
Nov 22 '18 at 12:57
add a comment |
You can simply filter the data yourself and set the data
of dataSource
. Like following code.
Method for filtering the options.
filterOptions(positionValue: string, nameValue: string): PeriodicElement {
if ((!positionValue || positionValue.length === 0) && !nameValue) {
return ELEMENT_DATA;
}
const filtered = ELEMENT_DATA.filter((periodicElement) => {
return (nameValue? periodicElement.name.toLowerCase().includes(nameValue.toLowerCase()): false)
|| (positionValue ? positionValue.indexOf(periodicElement.position+'') !==-1: false)});
return filtered;
}
You can use this on both filter change like following
this.positionFilter.valueChanges.subscribe((positionFilterValue) => {
this.dataSource.data = this.filterOptions(positionFilterValue, this.nameFilter.value);
});
this.nameFilter.valueChanges.subscribe((nameFilterValue) => {
this.dataSource.data = this.filterOptions(this.positionFilter.value, nameFilterValue);
});
Here is your updated code with above changes https://stackblitz.com/edit/angular-hbakxo-e4njon
add a comment |
You can simply filter the data yourself and set the data
of dataSource
. Like following code.
Method for filtering the options.
filterOptions(positionValue: string, nameValue: string): PeriodicElement {
if ((!positionValue || positionValue.length === 0) && !nameValue) {
return ELEMENT_DATA;
}
const filtered = ELEMENT_DATA.filter((periodicElement) => {
return (nameValue? periodicElement.name.toLowerCase().includes(nameValue.toLowerCase()): false)
|| (positionValue ? positionValue.indexOf(periodicElement.position+'') !==-1: false)});
return filtered;
}
You can use this on both filter change like following
this.positionFilter.valueChanges.subscribe((positionFilterValue) => {
this.dataSource.data = this.filterOptions(positionFilterValue, this.nameFilter.value);
});
this.nameFilter.valueChanges.subscribe((nameFilterValue) => {
this.dataSource.data = this.filterOptions(this.positionFilter.value, nameFilterValue);
});
Here is your updated code with above changes https://stackblitz.com/edit/angular-hbakxo-e4njon
add a comment |
You can simply filter the data yourself and set the data
of dataSource
. Like following code.
Method for filtering the options.
filterOptions(positionValue: string, nameValue: string): PeriodicElement {
if ((!positionValue || positionValue.length === 0) && !nameValue) {
return ELEMENT_DATA;
}
const filtered = ELEMENT_DATA.filter((periodicElement) => {
return (nameValue? periodicElement.name.toLowerCase().includes(nameValue.toLowerCase()): false)
|| (positionValue ? positionValue.indexOf(periodicElement.position+'') !==-1: false)});
return filtered;
}
You can use this on both filter change like following
this.positionFilter.valueChanges.subscribe((positionFilterValue) => {
this.dataSource.data = this.filterOptions(positionFilterValue, this.nameFilter.value);
});
this.nameFilter.valueChanges.subscribe((nameFilterValue) => {
this.dataSource.data = this.filterOptions(this.positionFilter.value, nameFilterValue);
});
Here is your updated code with above changes https://stackblitz.com/edit/angular-hbakxo-e4njon
You can simply filter the data yourself and set the data
of dataSource
. Like following code.
Method for filtering the options.
filterOptions(positionValue: string, nameValue: string): PeriodicElement {
if ((!positionValue || positionValue.length === 0) && !nameValue) {
return ELEMENT_DATA;
}
const filtered = ELEMENT_DATA.filter((periodicElement) => {
return (nameValue? periodicElement.name.toLowerCase().includes(nameValue.toLowerCase()): false)
|| (positionValue ? positionValue.indexOf(periodicElement.position+'') !==-1: false)});
return filtered;
}
You can use this on both filter change like following
this.positionFilter.valueChanges.subscribe((positionFilterValue) => {
this.dataSource.data = this.filterOptions(positionFilterValue, this.nameFilter.value);
});
this.nameFilter.valueChanges.subscribe((nameFilterValue) => {
this.dataSource.data = this.filterOptions(this.positionFilter.value, nameFilterValue);
});
Here is your updated code with above changes https://stackblitz.com/edit/angular-hbakxo-e4njon
answered Nov 22 '18 at 13:05


Yousef khanYousef khan
598411
598411
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429860%2ffilter-for-multiple-values-in-a-column-in-mat-filter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown