Search results + suggestions

pull/1/head
NGPixel 8 years ago
parent 7945d024ad
commit dca6b71610

@ -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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -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
@ -90,4 +72,6 @@ jQuery( document ).ready(function( $ ) {
}); });
//=include helpers/form.js //=include helpers/form.js
//=include helpers/pages.js //=include helpers/pages.js
//=include components/alerts.js

@ -0,0 +1,78 @@
"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);
}
});

@ -6,4 +6,8 @@ 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;
}

@ -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 {
margin: 0 auto; margin: 0 auto;
width: 500px; width: 500px;
z-index: 1; z-index: 1;
//display: none;
&.slideInDown {
@include prefix(animation-duration, .6s);
}
} }

@ -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 = {
.toLower() .toLower()
.trim() .trim()
.replace(/[^a-z0-9 ]/g, '') .replace(/[^a-z0-9 ]/g, '')
.split(' ')
.filter((f) => { return !_.isEmpty(f); })
.value(); .value();
let arrTerms = _.chain(terms)
.split(' ')
.filter((f) => { return !_.isEmpty(f); })
.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 @@
"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 @@
"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 @@
"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 @@
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 @@
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 }}

Loading…
Cancel
Save