Filter for multiple values in a column in mat-filter












0















I want to filter a column in an Angular Material table for multiple values.



This is what my table looks like



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










share|improve this question





























    0















    I want to filter a column in an Angular Material table for multiple values.



    This is what my table looks like



    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










    share|improve this question



























      0












      0








      0








      I want to filter a column in an Angular Material table for multiple values.



      This is what my table looks like



      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










      share|improve this question
















      I want to filter a column in an Angular Material table for multiple values.



      This is what my table looks like



      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







      angular angular-material






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 22 '18 at 11:40









      SiddAjmera

      15.6k31238




      15.6k31238










      asked Nov 22 '18 at 11:22









      user3414175user3414175

      31




      31
























          2 Answers
          2






          active

          oldest

          votes


















          1














          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: '' };





          share|improve this answer


























          • 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





















          0














          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






          share|improve this answer























            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
            });


            }
            });














            draft saved

            draft discarded


















            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









            1














            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: '' };





            share|improve this answer


























            • 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


















            1














            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: '' };





            share|improve this answer


























            • 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
















            1












            1








            1







            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: '' };





            share|improve this answer















            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: '' };






            share|improve this answer














            share|improve this answer



            share|improve this answer








            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





















            • 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















            0














            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






            share|improve this answer




























              0














              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






              share|improve this answer


























                0












                0








                0







                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






                share|improve this answer













                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







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 22 '18 at 13:05









                Yousef khanYousef khan

                598411




                598411






























                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    MongoDB - Not Authorized To Execute Command

                    How to fix TextFormField cause rebuild widget in Flutter

                    in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith