Commit dca6b716 authored by NGPixel's avatar NGPixel

Search results + suggestions

parent 7945d024
...@@ -27,6 +27,6 @@ ...@@ -27,6 +27,6 @@
- [ ] Markdown Editor - [ ] Markdown Editor
- [x] Navigation - [x] Navigation
- [x] Parsing / Tree / Metadata - [x] Parsing / Tree / Metadata
- [ ] Search - [x] Search
- [x] UI - [x] UI
- [x] View Entry Source - [x] View Entry Source
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -58,25 +58,7 @@ jQuery( document ).ready(function( $ ) { ...@@ -58,25 +58,7 @@ jQuery( document ).ready(function( $ ) {
var socket = io(ioHost); var socket = io(ioHost);
var vueHeader = new Vue({ //=include components/search.js
el: '#header-container',
data: {
searchq: '',
searchres: []
},
watch: {
searchq: (val, oldVal) => {
if(val.length >= 3) {
socket.emit('search', { terms: val }, (data) => {
vueHeader.$set('searchres', data);
});
}
}
},
methods: {
}
});
// ==================================== // ====================================
// Pages logic // Pages logic
...@@ -91,3 +73,5 @@ jQuery( document ).ready(function( $ ) { ...@@ -91,3 +73,5 @@ jQuery( document ).ready(function( $ ) {
//=include helpers/form.js //=include helpers/form.js
//=include helpers/pages.js //=include helpers/pages.js
//=include components/alerts.js
\ No newline at end of file
"use strict";
jQuery( document ).ready(function( $ ) {
if($('#search-input').length) {
$('#search-input').focus();
Vue.transition('slide', {
enterClass: 'slideInDown',
leaveClass: 'fadeOutUp'
});
$('.searchresults').css('display', 'block');
var vueHeader = new Vue({
el: '#header-container',
data: {
searchq: '',
searchres: [],
searchsuggest: [],
searchload: 0,
searchactive: false,
searchmoveidx: 0,
searchmovekey: '',
searchmovearr: []
},
watch: {
searchq: (val, oldVal) => {
searchmoveidx: 0;
if(val.length >= 3) {
vueHeader.searchactive = true;
vueHeader.searchload++;
socket.emit('search', { terms: val }, (data) => {
vueHeader.searchres = data.match;
vueHeader.searchsuggest = data.suggest;
if(vueHeader.searchload > 0) { vueHeader.searchload--; }
});
} else {
vueHeader.searchactive = false;
vueHeader.searchres = [];
vueHeader.searchsuggest = [];
vueHeader.searchload = 0;
}
},
searchmoveidx: (val, oldVal) => {
}
},
methods: {
useSuggestion: (sug) => {
vueHeader.searchq = sug;
},
closeSearch: () => {
vueHeader.searchq = '';
vueHeader.searchactive = false;
},
moveSelectSearch: () => {
},
moveDownSearch: () => {
if(vueHeader.searchmoveidx < vueHeader.searchmovearr) {
vueHeader.searchmoveidx++;
}
},
moveUpSearch: () => {
if(vueHeader.searchmoveidx > 0) {
vueHeader.searchmoveidx--;
}
}
}
});
$('main').on('click', vueHeader.closeSearch);
}
});
\ No newline at end of file
...@@ -7,3 +7,7 @@ html { ...@@ -7,3 +7,7 @@ html {
//$family-sans-serif: "Roboto", "Helvetica", "Arial", sans-serif; //$family-sans-serif: "Roboto", "Helvetica", "Arial", sans-serif;
$family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; $family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
[v-cloak] {
display: none;
}
\ No newline at end of file
...@@ -27,6 +27,11 @@ h2.nav-item { ...@@ -27,6 +27,11 @@ h2.nav-item {
} }
#search-input {
max-width: 300px;
width: 33vw;
}
.searchresults { .searchresults {
position: fixed; position: fixed;
top: 45px; top: 45px;
...@@ -35,5 +40,9 @@ h2.nav-item { ...@@ -35,5 +40,9 @@ h2.nav-item {
margin: 0 auto; margin: 0 auto;
width: 500px; width: 500px;
z-index: 1; z-index: 1;
//display: none;
&.slideInDown {
@include prefix(animation-duration, .6s);
}
} }
\ No newline at end of file
...@@ -31,7 +31,6 @@ var paths = { ...@@ -31,7 +31,6 @@ var paths = {
'./node_modules/lodash/lodash.min.js' './node_modules/lodash/lodash.min.js'
], ],
scriptapps: [ scriptapps: [
'./client/js/components/*.js',
'./client/js/app.js' './client/js/app.js'
], ],
scriptapps_watch: [ scriptapps_watch: [
......
...@@ -50,16 +50,43 @@ module.exports = { ...@@ -50,16 +50,43 @@ module.exports = {
.toLower() .toLower()
.trim() .trim()
.replace(/[^a-z0-9 ]/g, '') .replace(/[^a-z0-9 ]/g, '')
.value();
let arrTerms = _.chain(terms)
.split(' ') .split(' ')
.filter((f) => { return !_.isEmpty(f); }) .filter((f) => { return !_.isEmpty(f); })
.value(); .value();
return self._si.searchAsync({ return self._si.searchAsync({
query: { query: {
AND: [{ '*': terms }] AND: [{ '*': arrTerms }]
}, },
pageSize: 10 pageSize: 10
}).get('hits'); }).get('hits').then((hits) => {
if(hits.length < 5) {
return self._si.matchAsync({
beginsWith: terms,
threshold: 3,
limit: 5,
type: 'simple'
}).then((matches) => {
return {
match: hits,
suggest: matches
};
});
} else {
return {
match: hits,
suggest: []
};
}
});
}, },
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
"dependencies": { "dependencies": {
"auto-load": "^2.1.0", "auto-load": "^2.1.0",
"bcryptjs-then": "^1.0.1", "bcryptjs-then": "^1.0.1",
"bluebird": "^3.4.5", "bluebird": "^3.4.6",
"body-parser": "^1.15.2", "body-parser": "^1.15.2",
"bson": "^0.5.4", "bson": "^0.5.4",
"cheerio": "^0.22.0", "cheerio": "^0.22.0",
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
"express-brute-loki": "^1.0.0", "express-brute-loki": "^1.0.0",
"express-session": "^1.14.1", "express-session": "^1.14.1",
"express-validator": "^2.20.8", "express-validator": "^2.20.8",
"farmhash": "^1.2.0", "farmhash": "^1.2.1",
"fs-extra": "^0.30.0", "fs-extra": "^0.30.0",
"git-wrapper2-promise": "^0.2.9", "git-wrapper2-promise": "^0.2.9",
"highlight.js": "^9.6.0", "highlight.js": "^9.6.0",
...@@ -77,7 +77,8 @@ ...@@ -77,7 +77,8 @@
"serve-favicon": "^2.3.0", "serve-favicon": "^2.3.0",
"simplemde": "^1.11.2", "simplemde": "^1.11.2",
"socket.io": "^1.4.8", "socket.io": "^1.4.8",
"validator": "^5.5.0", "sticky-js": "^1.0.7",
"validator": "^5.6.0",
"validator-as-promised": "^1.0.2", "validator-as-promised": "^1.0.2",
"winston": "^2.2.0" "winston": "^2.2.0"
}, },
......
...@@ -9,8 +9,9 @@ ...@@ -9,8 +9,9 @@
h1.title Wiki h1.title Wiki
.nav-center .nav-center
block rootNavCenter block rootNavCenter
p.nav-item .nav-item
input.input(type='text', v-model='searchq', debounce='500' placeholder='Search...', style= { 'max-width': '300px', width: '33vw' }) p.control(v-bind:class="{ 'is-loading': searchload > 0 }")
input.input#search-input(type='text', v-model='searchq', @keyup.esc='closeSearch', @keyup.down='moveDownSearch', @keyup.up='moveUpSearch', debounce='400', placeholder='Search...')
span.nav-toggle span.nav-toggle
span span
span span
...@@ -32,14 +33,19 @@ ...@@ -32,14 +33,19 @@
i.fa.fa-plus i.fa.fa-plus
span Create span Create
.box.searchresults .box.searchresults.animated(v-show='searchactive', transition='slide', v-cloak, style={'display':'none'})
.menu .menu
p.menu-label p.menu-label
| Search Results | Search Results
ul.menu-list ul.menu-list
li(v-if="searchres.length === 0")
a: em No results matching your query
li(v-for='sres in searchres') li(v-for='sres in searchres')
a(href='#') {{ sres.document.title }} a(href='/{{ sres.document.entryPath }}', v-bind:class="{ 'is-active': searchmovekey === 'res.' + sres.document.entryPath }") {{ sres.document.title }}
p.menu-label p.menu-label(v-if='searchsuggest.length > 0')
| Do you mean...? | Did you mean...?
ul.menu-list(v-if='searchsuggest.length > 0')
li(v-for='sug in searchsuggest')
a(v-on:click="useSuggestion(sug)") {{ sug }}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment