From 41c0dc4eb2fc5548971ac192e43fba24d14c6b6c Mon Sep 17 00:00:00 2001 From: razonyang Date: Fri, 5 Aug 2022 22:54:00 +0800 Subject: [PATCH] feat(search): add advanced search options --- assets/search/languages.ts | 16 +++++ assets/search/search.ts | 105 +++++++++++++++++++++++------ i18n/en.toml | 3 + i18n/zh-cn.toml | 3 + i18n/zh-hans.toml | 3 + i18n/zh-hant.toml | 3 + i18n/zh-hk.toml | 3 + i18n/zh-tw.toml | 3 + layouts/_default/search.html | 21 +++--- layouts/partials/search/form.html | 41 +++++++++++ layouts/partials/search/index.json | 21 ++++-- purgecss.config.js | 2 +- 12 files changed, 185 insertions(+), 39 deletions(-) create mode 100644 assets/search/languages.ts create mode 100644 layouts/partials/search/form.html diff --git a/assets/search/languages.ts b/assets/search/languages.ts new file mode 100644 index 000000000..ba85a96a9 --- /dev/null +++ b/assets/search/languages.ts @@ -0,0 +1,16 @@ +class Languages { + ele: HTMLSelectElement; + + constructor(callback) { + this.ele = document.querySelector('#languages-select'); + this.ele.addEventListener('change', () => { + callback(); + }); + } + + getValue() { + return this.ele.value; + } +} + +export default Languages; diff --git a/assets/search/search.ts b/assets/search/search.ts index df65bc477..ead01d4e0 100644 --- a/assets/search/search.ts +++ b/assets/search/search.ts @@ -1,6 +1,7 @@ import Fuse from 'fuse.js'; import Mustache from 'mustache'; import Mark from 'mark.js/dist/mark.js'; +import Languages from './languages'; declare global { interface Window { @@ -75,11 +76,25 @@ export class Search { this.loadMore.addEventListener('click', () => { this.poplateResults(); }); + + new Languages(() => { + this.search(this.input.value); + }); } initFuse() { - this.fuseOptions = window.fuseOptions; - console.debug('Fuse options', this.fuseOptions); + this.fuseOptions = Object.assign(window.fuseOptions, { + useExtendedSearch: true, + keys: [ + 'title', + 'content', + 'lang', + 'authors.title', + 'categories.title', + 'series.title', + 'tags.title', + ], + }); const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { @@ -87,7 +102,16 @@ export class Search { console.error({ error: xhr.statusText }); return; } - const pages = xhr.response; + const pages = xhr.response.pages; + const taxonomies = ['categories', 'authors', 'series', 'tags']; + for (let i in taxonomies) { + const datalist = document.querySelector('#' + taxonomies[i] + '-list'); + for (let j in xhr.response[taxonomies[i]]) { + const option = document.createElement('option'); + option.value = xhr.response[taxonomies[i]][j]; + datalist.appendChild(option); + } + } this.fuse = new Fuse(pages, this.fuseOptions); this.search(this.input.value); } @@ -105,15 +129,15 @@ export class Search { } this.updateSearchbar(this.input.value); document.querySelector('.search-bar input'); - this.form.addEventListener('submit', (event) => { - this.handleSubmit(event); + this.form.addEventListener('submit', (e) => { + e.preventDefault(); + this.handleSubmit(); }); } - handleSubmit(event) { + handleSubmit() { this.search(this.input.value); this.updateSearchbar(this.input.value); - event.preventDefault(); } updateSearchbar(value) { @@ -153,22 +177,61 @@ export class Search { this.hideLoadingSpinner(); return; } - this.page = 1; - this.setPage(query); - const results = this.fuse.search(query); - console.debug({ results }); - this.results = results; - this.hideLoadingSpinner(); - if (this.results.length > this.paginate) { - this.showLoadMoreBtn(); - } else { - this.hideLoadMoreBtn(); + try { + this.page = 1; + this.setPage(query); + const params = this.serializeForm(query); + const results = this.fuse.search(params); + this.results = results; + if (this.results.length > this.paginate) { + this.showLoadMoreBtn(); + } else { + this.hideLoadMoreBtn(); + } + if (results.length > 0) { + this.poplateResults(); + } else { + this.stat.innerHTML = this.tmplNoResults; + } + } catch (err) { + console.error(err); + } finally { + this.hideLoadingSpinner(); } - if (results.length > 0) { - this.poplateResults(); - } else { - this.stat.innerHTML = this.tmplNoResults; + } + + serializeForm(query) { + let params = { + $and: [ + { + $or: [ + { title: query }, + { content: query }, + ] + } + ] + } + let author = document.querySelector('#author-input').value; + if (author) { + params.$and.push({'authors.title': author}); + } + let category = document.querySelector('#category-input').value; + if (category) { + params.$and.push({'categories.title': category}); + } + let series = document.querySelector('#series-input').value; + if (series) { + params.$and.push({'series.title': series}); + } + let tag = document.querySelector('#tag-input').value; + if (tag) { + params.$and.push({'tags.title': tag}); + } + let lang = document.querySelector('select[name="lang"]').value; + if (lang) { + params.$and.push({'lang': '=' + lang}); } + return params; } setPage(query) { diff --git a/i18n/en.toml b/i18n/en.toml index e8bdf9b23..5b4202eff 100644 --- a/i18n/en.toml +++ b/i18n/en.toml @@ -197,6 +197,9 @@ other = "Repository" [search] other = "Search" +[search_advanced] +other = "Advanced" + [search_missing_keywords] other = "Please enter search keywords" diff --git a/i18n/zh-cn.toml b/i18n/zh-cn.toml index 0525f906e..edb554587 100644 --- a/i18n/zh-cn.toml +++ b/i18n/zh-cn.toml @@ -187,6 +187,9 @@ other = "仓库" [search] other = "搜索" +[search_advanced] +other = "高级" + [search_missing_keywords] other = "请输入搜索关键词" diff --git a/i18n/zh-hans.toml b/i18n/zh-hans.toml index 0525f906e..edb554587 100644 --- a/i18n/zh-hans.toml +++ b/i18n/zh-hans.toml @@ -187,6 +187,9 @@ other = "仓库" [search] other = "搜索" +[search_advanced] +other = "高级" + [search_missing_keywords] other = "请输入搜索关键词" diff --git a/i18n/zh-hant.toml b/i18n/zh-hant.toml index f3fe5f815..4091b6287 100644 --- a/i18n/zh-hant.toml +++ b/i18n/zh-hant.toml @@ -187,6 +187,9 @@ other = "倉庫" [search] other = "搜尋" +[search_advanced] +other = "高級" + [search_missing_keywords] other = "請輸入搜尋關鍵詞" diff --git a/i18n/zh-hk.toml b/i18n/zh-hk.toml index c21c34895..8420b932b 100644 --- a/i18n/zh-hk.toml +++ b/i18n/zh-hk.toml @@ -187,6 +187,9 @@ other = "倉庫" [search] other = "搜索" +[search_advanced] +other = "高級" + [search_missing_keywords] other = "請輸入搜索關鍵詞" diff --git a/i18n/zh-tw.toml b/i18n/zh-tw.toml index f3fe5f815..4091b6287 100644 --- a/i18n/zh-tw.toml +++ b/i18n/zh-tw.toml @@ -187,6 +187,9 @@ other = "倉庫" [search] other = "搜尋" +[search_advanced] +other = "高級" + [search_missing_keywords] other = "請輸入搜尋關鍵詞" diff --git a/layouts/_default/search.html b/layouts/_default/search.html index bdad33038..cd9c3f450 100644 --- a/layouts/_default/search.html +++ b/layouts/_default/search.html @@ -1,29 +1,24 @@ {{ define "content" }}