mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-07-21 22:29:40 +02:00
search implementation
This commit is contained in:
parent
f05eb15b72
commit
79592f0a1d
12 changed files with 440 additions and 28 deletions
137
src/frontend/js/modules/search.js
Normal file
137
src/frontend/js/modules/search.js
Normal file
|
@ -0,0 +1,137 @@
|
|||
import { debounce } from '../utils/decorators';
|
||||
import Shortcut from '@codexteam/shortcuts';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
export default class Search {
|
||||
constructor() {
|
||||
this.nodes = {
|
||||
overlay: null,
|
||||
searchWrapper: null,
|
||||
searchInput: null,
|
||||
searchResultsWrapper: null
|
||||
};
|
||||
|
||||
this.isVisible = false;
|
||||
|
||||
this.shortcut = null;
|
||||
this.TOGGLER_SHORTCUT = 'CMD+SHIFT+F';
|
||||
|
||||
this.debouncedSearch = null;
|
||||
this.DEBOUNCE_TIME = 500;
|
||||
}
|
||||
|
||||
init(settings = {}, moduleEl) {
|
||||
console.log('search init');
|
||||
|
||||
this.createSearchOverlay();
|
||||
this.createDebouncedSearch();
|
||||
this.enableShortcutListening();
|
||||
|
||||
// ! force open search overlay
|
||||
// this.toggleSearchOverlay(true);
|
||||
}
|
||||
|
||||
createSearchOverlay() {
|
||||
this.nodes.overlay = document.createElement('div');
|
||||
this.nodes.overlay.classList.add('search-overlay');
|
||||
this.nodes.overlay.addEventListener('click', this.searchOverlayClickProcessor.bind(this));
|
||||
|
||||
this.nodes.searchWrapper = document.createElement('div');
|
||||
this.nodes.searchWrapper.classList.add('search-wrapper');
|
||||
|
||||
this.nodes.searchInput = document.createElement('input');
|
||||
this.nodes.searchInput.classList.add('search-input');
|
||||
this.nodes.searchInput.setAttribute('type', 'search');
|
||||
this.nodes.searchInput.setAttribute('placeholder', 'Find in documents...');
|
||||
this.nodes.searchInput.setAttribute('autocomplete', 'off');
|
||||
this.nodes.searchInput.addEventListener('input', this.searchInputOnchangeProcessor.bind(this));
|
||||
this.nodes.searchWrapper.appendChild(this.nodes.searchInput);
|
||||
|
||||
this.nodes.searchResultsWrapper = document.createElement('div');
|
||||
this.nodes.searchResultsWrapper.classList.add('search-results-wrapper');
|
||||
this.nodes.searchWrapper.appendChild(this.nodes.searchResultsWrapper);
|
||||
|
||||
this.nodes.overlay.appendChild(this.nodes.searchWrapper);
|
||||
document.body.appendChild(this.nodes.overlay);
|
||||
}
|
||||
|
||||
searchOverlayClickProcessor(event) {
|
||||
if (event.target !== this.nodes.overlay) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.toggleSearchOverlay(false);
|
||||
}
|
||||
|
||||
searchInputOnchangeProcessor(event) {
|
||||
// close search overlay if ESC key is pressed
|
||||
if (event.keyCode === 27) {
|
||||
this.toggleSearchOverlay(false);
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
console.log(event.target.value);
|
||||
|
||||
this.debouncedSearch(event.target.value);
|
||||
}
|
||||
|
||||
enableShortcutListening() {
|
||||
this.shortcut = new Shortcut({
|
||||
name : this.TOGGLER_SHORTCUT,
|
||||
on : document.body,
|
||||
callback: (event) => {
|
||||
this.toggleSearchOverlay();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toggleSearchOverlay(force) {
|
||||
this.isVisible = force || !this.isVisible;
|
||||
|
||||
this.nodes.overlay.classList.toggle('search-overlay--visible', this.isVisible);
|
||||
document.body.classList.toggle('noscroll', this.isVisible);
|
||||
|
||||
this.nodes.searchInput.focus();
|
||||
}
|
||||
|
||||
createDebouncedSearch() {
|
||||
this.debouncedSearch = debounce(this.getSearchResults, this.DEBOUNCE_TIME);
|
||||
}
|
||||
|
||||
getSearchResults(text) {
|
||||
// this.showSearchResult(text);
|
||||
|
||||
// call api to get search results
|
||||
axios.get('/api/search', {
|
||||
params: {
|
||||
text: text
|
||||
}
|
||||
})
|
||||
.then(this.showSearchResult.bind(this));
|
||||
}
|
||||
|
||||
showSearchResult({ data }) {
|
||||
console.log(data);
|
||||
|
||||
this.nodes.searchResultsWrapper.innerHTML = '';
|
||||
|
||||
|
||||
data.result.pages.forEach(page => {
|
||||
const result = document.createElement('a');
|
||||
result.classList.add('search-results-item');
|
||||
result.setAttribute('href', `/${page.uri}`);
|
||||
|
||||
const title = document.createElement('div');
|
||||
title.classList.add('search-results-item__title');
|
||||
title.innerHTML = page.title;
|
||||
result.appendChild(title);
|
||||
|
||||
// const description = document.createElement('div');
|
||||
// description.classList.add('search-results-item__description');
|
||||
// result.appendChild(description);
|
||||
|
||||
this.nodes.searchResultsWrapper.appendChild(result);
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue