Snippets

Duane Blake Search filter and facet in VueJs

Created by Duane Blake

File index.html Added

  • Ignore whitespace
  • Hide word diff
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>VueJs search filter and facet</title>
+    <link href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css" rel="stylesheet">
+</head>
+<body class="bg-grey-lighter">
+    <div class="container mx-auto" id="app">
+        <div class="flex w-3/4 mx-auto my-6">
+            <input type="search" v-model="searchQuery" name="" id="" class="rounded p-2 w-full bg-grey-light border-grey-light focus:bg-white border border-solid focus:border-indigo-light text-blue-darkest" placeholder="Enter a search here!" />
+        </div><!-- .class -->
+        <div class="flex w-3/4 mx-auto text-indigo-darkest">
+            <div class="w-1/4 mr-4">
+                <div class="bg-white p-4 border border-solid border-grey-light ">
+                    <p class="text-lg border-b pb-2 mb-2 ">Filter by:</p>
+                    <dl class="list-reset">
+                        <dt class="font-bold text-purple-dark  pb-2 uppercase">Users</dt>
+                        <dd class="mb-2">
+                            <input id="user1" type="checkbox" name="facet" v-model="facet" :value="1"> 
+                            <label for="user1"> User 1</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user2" type="checkbox" name="facet" v-model="facet" :value="2" /> 
+                            <label for="user2"> User 2</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user3" type="checkbox" name="facet" v-model="facet" :value="3"> 
+                            <label for="use3"> User 3</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user4" type="checkbox" name="facet" v-model="facet" :value="4"> 
+                            <label for="user4"> User 4</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user5" type="checkbox" name="facet" v-model="facet" :value="5"  />     
+                            <label for="user5">User 5</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user6" type="checkbox" name="facet" v-model="facet" :value="6"> 
+                            <label for="user6"> User 6</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user7" type="checkbox" name="facet" v-model="facet" :value="7"> 
+                            <label for="user7"> User 7</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user8" type="checkbox" name="facet" v-model="facet" :value="8"> 
+                            <label for="use8"> User 8</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user9" type="checkbox" name="facet" v-model="facet" :value="9"> 
+                            <label for="user9"> User 9</label>
+                        </dd>
+                        <dd class="mb-2">
+                            <input id="user10" type="checkbox" name="facet" v-model="facet" :value="10"  />     
+                            <label for="user10">User 10</label>
+                        </dd>
+                    </dl>
+                </div><!-- .dsadsadsadsadsds-->
+            </div>
+            <div class="w-3/4">
+                <p class="mb-2 text-right" v-if="searchQuery && filterPosts.length > 1 ">{{filterPosts.length}} results</p>
+                <ul class="list-reset bg-white p-4 border border-solid border-grey-light ">
+                    <li v-if="!searchQuery">
+                        <h2 class=" text-indigo-darker pb-2 text-xl">Search</h2>
+                        <p class="text-black">Please use the search above</p>
+                    </li>
+                    <li v-for="post in filterPosts" v-else :key="post.id" class="mb-6">
+                        <h2 class=" text-indigo-darker pb-2 text-xl">{{post.title}}</h2>
+                        <p class="pb-2 text-black">{{post.body}}</p>
+                        <p class="text-sm text-grey-darker">Posted by: User {{post.userId}}</p>
+                    </li>
+                    <li v-if="filterPosts.length == 0" >
+                        <h2 class=" text-indigo-darker pb-2 text-xl">Sorry</h2>
+                        <p class="text-black">There seem to be no posts under your criteria</p>
+                    </li>
+                </ul>
+            </div>
+        </div>
+    </div><!-- .bg-blue-lightest --> 
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.22/vue.js"></script>
+    <script>
+        let app = new Vue({
+            el: '#app',
+            data() {
+                return{
+                    endpoint:      "https://jsonplaceholder.typicode.com/posts",
+                    posts: [],
+                    searchQuery: null,
+                    facet: [],
+                }
+            },
+            methods: {
+                fetchposts() {
+                    fetch(this.endpoint)
+                        .then(blob => blob.json())
+                        .then(data => this.posts.push(...data));
+                }
+            },
+            computed: {
+                filterPosts(){
+                    return this.posts.filter(result => {
+                        const myRegex = new RegExp(this.searchQuery, 'gi');
+                        let resultFacet = this.facet;
+                        if (resultFacet.length == 0) {
+                            return (result.title.match(myRegex) || result.body.match(myRegex))
+                        }
+                        return (result.title.match(myRegex) || result.body.match(myRegex)) && (resultFacet.includes(result.userId)); 
+                    })
+                }
+            },
+            mounted(){
+                this.fetchposts();
+            }
+        });
+    </script>
+</body>
+</html>
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.