Skip to content

Instantly share code, notes, and snippets.

@milon
Created April 21, 2020 21:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save milon/5daa9aec64c1bff70e2e1c3678dafbf3 to your computer and use it in GitHub Desktop.
Save milon/5daa9aec64c1bff70e2e1c3678dafbf3 to your computer and use it in GitHub Desktop.
Search functionality with Fuse.js in Jigsaw powered website.
<?php
// Generate search index
$events->afterBuild(App\Listeners\GenerateIndex::class);
<?php
namespace App\Listeners;
use TightenCo\Jigsaw\Jigsaw;
class GenerateIndex
{
public function handle(Jigsaw $jigsaw)
{
$data = collect($jigsaw->getCollection('posts')->map(function ($page) use ($jigsaw) {
return [
'title' => $page->title,
'link' => rightTrimPath($jigsaw->getConfig('baseUrl')) . $page->getPath(),
'excerpt' => $page->excerpt,
'englishSearchTerm' => str_replace('-', ' ', $page->getFilename()),
'categories' => $page->categories ?? []
];
})->values());
file_put_contents($jigsaw->getDestinationPath() . '/index.json', json_encode($data));
}
}
<div class="collapse navbar-collapse" id="navbarResponsive">
<div id="vue-search">
<search></search>
</div>
</div>
<template>
<form class="form-inline my-3 my-lg-0 position-relative" v-on:submit.prevent="() => {}">
<input
id="search"
v-model="query"
ref="search"
class="form-control"
type="text"
placeholder="খুঁজুন..."
@keyup.esc="reset"
>
<button
v-show="query"
class="btn btn-link cancel-btn"
@click="reset"
><i class="fas fa-times"></i></button>
<div v-if="query" class="search-panel">
<div class="search-scroll">
<a
v-for="(result, index) in results"
class="search-item"
:href="result.link"
:title="result.title"
:key="result.link"
@mousedown.prevent>
{{ result.title }}
<span class="excerpt" v-html="result.excerpt"></span>
</a>
</div>
<div v-if="! results.length" class="">
<span class="no-result">{{ query }}-এর জন্যে কোন ফলাফল পাওয়া যায় নি।</span>
</div>
</div>
</form>
</template>
<script>
export default {
data() {
return {
fuse: null,
query: '',
};
},
computed: {
results() {
return this.query ? this.fuse.search(this.query) : [];
},
},
methods: {
reset() {
this.query = '';
},
},
created() {
axios('/index.json').then(response => {
this.fuse = new fuse(response.data, {
minMatchCharLength: 6,
keys: ['title', 'excerpt', 'englishSearchTerm'],
});
});
},
};
</script>
<style>
#search {
width: 350px !important;
border-radius: 0;
}
#search:focus {
border-color: #ced4da;
box-shadow: none;
}
.cancel-btn {
right: 0;
color: #495057;
position: absolute;
}
.cancel-btn:hover {
color: #495057;
}
.search-panel {
width: 100%;
left: 0;
right: 0;
background: white;
top: 100%;
position: absolute;
max-height: 350px;
overflow: scroll;
}
.no-result {
font-size: 16px;
padding: 5px 8px;
}
.search-item {
text-decoration: none !important;
display: block;
padding: 5px 8px;
border-bottom: 1px solid #ccc;
font-size: 16px;
font-weight: bold;
}
.search-item .excerpt {
font-size: 13px;
display: block;
color: #bababa;
font-weight: normal;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment