search

Home  >  Q&A  >  body text

How to filter results of checkboxes (array) in Vue

I am unable to display results for news articles that have multiple tags/checkboxes assigned to them in Vue 2. If I check a single label/checkbox my results display correctly. What might I be doing wrong here?

var tagData = [
    {
        id: 1,
        title: "Internal"
    },
    {
        id: 2,
        title: "Industry"
    },
    {
        id: 3,
        title: "Company"
    }
];

var articleData = [
    {
        id: 1,
        pagetitle: "Card title that wraps to a new line",
        image: "https://via.placeholder.com/500x250/171717/222222?text=500x250",
        tags: [
            "Internal",
            "Industry",
            "Company",
        ],
        content: "This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.",
        alias: "/news-article-1",
        published: 1672668835
    },
    {
        id: 2,
        pagetitle: "Card title",
        image: "https://via.placeholder.com/500x250/171717/222222?text=500x250",
        tags: [
            "Company",
        ],
        content: "This card has supporting text below as a natural lead-in to additional content.",
        alias: "/news-article-2",
        published: 1672668835
    },
    {
        id: 3,
        pagetitle: "Card with no image",
        image: "",
        tags: [
            "Internal",
            "Company",
        ],
        content: "This is another card with title and supporting text below. This card has some additional content to make it slightly taller overall.",
        alias: "/news-article-3",
        published: 1672668835
    },
    {
        id: 4,
        pagetitle: "Yet another article",
        image: "",
        tags: [
            "Industry"
        ],
        content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
        alias: "/news-article-4",
        published: 1672668835
    },
];

var vm = new Vue({
    el: "#app",
    data: {
        articles: articleData,
        search: '',
        tags: tagData,
        checkedTags: []
    },
    computed: {
        searchArticles: function searchArticles() {
            var result = this.articles.filter(function (article) {
                // articles can have more than one tag/category assigned
                //if any checkboxes have been checked...
                if(this.checkedTags.length) {
                    return article.tags.some(tag => tag.includes(this.checkedTags)) && (article.pagetitle.toLowerCase().match(this.search.toLowerCase()) || article.content.toLowerCase().match(this.search.toLowerCase()) )
                } else {
                    return article.pagetitle.toLowerCase().match(this.search.toLowerCase()) || article.content.toLowerCase().match(this.search.toLowerCase())   
                }
            }, this);
            return result;
        }
    }
});

checkedTags contains an array. For example: ["Internal", "Industry"] I've tried variations of .some and .every, but obviously my logic is incorrect.

P粉440453689P粉440453689470 days ago657

reply all(1)I'll reply

  • P粉094351878

    P粉0943518782023-09-07 00:08:10

    You must change your tag check from this:

    article.tags.some(tag => tag.includes(this.checkedTags))

    Regarding:

    this.checkedTags.every( tag => article.tags.includes(tag))

    You must check if all selected tags are present in the article.

    Your check .some(tag => tag.includes is wrong because you are applying includes to a tag item. It should be something else. includes < /code> Should be applied to arrays.

    tags.includes(tag), but not tag.includes(tags)

    If tags.length > 1

    ,

    tag.includes(tags) will always be false

    This is a work playground.

    var tagData = [
        {
            id: 1,
            title: "Internal"
        },
        {
            id: 2,
            title: "Industry"
        },
        {
            id: 3,
            title: "Company"
        }
    ];
    
    var articleData = [
        {
            id: 1,
            pagetitle: "Card title that wraps to a new line",
            image: "https://via.placeholder.com/500x250/171717/222222?text=500x250",
            tags: [
                "Internal",
                "Industry",
                "Company",
            ],
            content: "This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.",
            alias: "/news-article-1",
            published: 1672668835
        },
        {
            id: 2,
            pagetitle: "Card title",
            image: "https://via.placeholder.com/500x250/171717/222222?text=500x250",
            tags: [
                "Company",
            ],
            content: "This card has supporting text below as a natural lead-in to additional content.",
            alias: "/news-article-2",
            published: 1672668835
        },
        {
            id: 3,
            pagetitle: "Card with no image",
            image: "",
            tags: [
                "Internal",
                "Company",
            ],
            content: "This is another card with title and supporting text below. This card has some additional content to make it slightly taller overall.",
            alias: "/news-article-3",
            published: 1672668835
        },
        {
            id: 4,
            pagetitle: "Yet another article",
            image: "",
            tags: [
                "Industry"
            ],
            content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
            alias: "/news-article-4",
            published: 1672668835
        },
    ];
    
    var vm = new Vue({
        el: "#app",
        productionTip: false,
        data: {
            articles: articleData,
            search: '',
            tags: tagData,
            checkedTags: []
        },
        computed: {
            searchArticles: function searchArticles() {
                var result = this.articles.filter(function (article) {
                    // articles can have more than one tag/category assigned
                    //if any checkboxes have been checked...
                    if(this.checkedTags.length) {
                        return this.checkedTags.every( tag => article.tags.includes(tag)) &&  (article.pagetitle.toLowerCase().match(this.search.toLowerCase()) || article.content.toLowerCase().match(this.search.toLowerCase()) )
                    } else {
                        return article.pagetitle.toLowerCase().match(this.search.toLowerCase()) || article.content.toLowerCase().match(this.search.toLowerCase())   
                    }
                }, this);
                return result;
            }
        }
    });
    .search {
      margin: 8px 4px 8px 4px;
    }
    <div id="app">
    <div class="search">
    <label>Search:</label> <input v-model="search" />&nbsp;
    <label>Tags:</label> 
    <span v-for="tag in tags">
    <input type="checkbox" name="tags" :id="tag.id" :value="tag.title" v-model="checkedTags" /> 
    <label for="tag.id">{{tag.title}}</label>&nbsp;
    </span>
    </div>
    <table border=1>
    <thead><tr><th>Id</th><th>Title</th><th>Tags</th></tr></thead>
    <tbody>
    <tr v-for="item in searchArticles">
      <td>{{item.id}}</td>
      <td>{{item.pagetitle}}</td>
      <td>{{item.tags}}</td>
    </tr>  
    </tbody>
    </table>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

    reply
    0
  • Cancelreply