Search results + suggestions

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

@ -27,6 +27,6 @@
- [ ] Markdown Editor
- [x] Navigation
- [x] Parsing / Tree / Metadata
- [ ] Search
- [x] Search
- [x] UI
- [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 vueHeader = new Vue({
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: {
}
});
//=include components/search.js
// ====================================
// Pages logic
@ -91,3 +73,5 @@ jQuery( document ).ready(function( $ ) {
//=include helpers/form.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);
}
});

@ -7,3 +7,7 @@ html {
//$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";
[v-cloak] {
display: none;
}

@ -27,6 +27,11 @@ h2.nav-item {
}
#search-input {
max-width: 300px;
width: 33vw;
}
.searchresults {
position: fixed;
top: 45px;
@ -35,5 +40,9 @@ h2.nav-item {
margin: 0 auto;
width: 500px;
z-index: 1;
//display: none;
&.slideInDown {
@include prefix(animation-duration, .6s);
}
}

@ -31,7 +31,6 @@ var paths = {
'./node_modules/lodash/lodash.min.js'
],
scriptapps: [
'./client/js/components/*.js',
'./client/js/app.js'
],
scriptapps_watch: [

@ -50,16 +50,43 @@ module.exports = {
.toLower()
.trim()
.replace(/[^a-z0-9 ]/g, '')
.split(' ')
.filter((f) => { return !_.isEmpty(f); })
.value();
let arrTerms = _.chain(terms)
.split(' ')
.filter((f) => { return !_.isEmpty(f); })
.value();
return self._si.searchAsync({
query: {
AND: [{ '*': terms }]
AND: [{ '*': arrTerms }]
},
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": {
"auto-load": "^2.1.0",
"bcryptjs-then": "^1.0.1",
"bluebird": "^3.4.5",
"bluebird": "^3.4.6",
"body-parser": "^1.15.2",
"bson": "^0.5.4",
"cheerio": "^0.22.0",
@ -48,7 +48,7 @@
"express-brute-loki": "^1.0.0",
"express-session": "^1.14.1",
"express-validator": "^2.20.8",
"farmhash": "^1.2.0",
"farmhash": "^1.2.1",
"fs-extra": "^0.30.0",
"git-wrapper2-promise": "^0.2.9",
"highlight.js": "^9.6.0",
@ -77,7 +77,8 @@
"serve-favicon": "^2.3.0",
"simplemde": "^1.11.2",
"socket.io": "^1.4.8",
"validator": "^5.5.0",
"sticky-js": "^1.0.7",
"validator": "^5.6.0",
"validator-as-promised": "^1.0.2",
"winston": "^2.2.0"
},

@ -9,8 +9,9 @@
h1.title Wiki
.nav-center
block rootNavCenter
p.nav-item
input.input(type='text', v-model='searchq', debounce='500' placeholder='Search...', style= { 'max-width': '300px', width: '33vw' })
.nav-item
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
span
@ -32,14 +33,19 @@
i.fa.fa-plus
span Create
.box.searchresults
.box.searchresults.animated(v-show='searchactive', transition='slide', v-cloak, style={'display':'none'})
.menu
p.menu-label
| Search Results
ul.menu-list
li(v-if="searchres.length === 0")
a: em No results matching your query
li(v-for='sres in searchres')
a(href='#') {{ sres.document.title }}
p.menu-label
| Do you mean...?
a(href='/{{ sres.document.entryPath }}', v-bind:class="{ 'is-active': searchmovekey === 'res.' + sres.document.entryPath }") {{ sres.document.title }}
p.menu-label(v-if='searchsuggest.length > 0')
| 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