Skip to content

Instantly share code, notes, and snippets.

@onefriendaday
Created April 4, 2018 08:17
Show Gist options
  • Select an option

  • Save onefriendaday/bde0c02ad653b42be0e410249baee4d9 to your computer and use it in GitHub Desktop.

Select an option

Save onefriendaday/bde0c02ad653b42be0e410249baee4d9 to your computer and use it in GitHub Desktop.
searchblok.js
<script>
import Util from './libs/Utils'
import App from './App.html'
import axios from 'axios'
import _ from 'lodash'
export default {
template: Util.template('#searchblok-app', App),
name: 'searchblok',
props: ['settings'],
computed: {
results: function() {
if (this.page == 0) {
this.highlights = []
}
if (_.isUndefined(this.result.hits)) {
return []
}
_.forEach(this.result.hits.hits, (elem) => {
let item = {}
if(elem.highlight) {
item.title = this.checkFields(elem, 'title', ['title', 'h1', 'h2', 'h3', 'h4', 'h5'])
if (_.isArray(item.title)) {
item.title = item.title.join(' ... ')
}
item.excerpt = this.checkFields(elem, 'content', ['content', 'description', 'keywords'])
} else {
item.title = elem._source.title
item.excerpt = elem._source.content
}
if (item.excerpt.length > 0) {
item.excerpt = _.filter(item.excerpt, (i) => { return i != '…' })
item.excerpt = item.excerpt.join(' ')
} else {
item.excerpt = ''
}
item.excerpt = _.truncate(item.excerpt, {
length: 160,
omission: ' ...'
})
item.url = elem._source.url
this.highlights.push(item)
})
return this.highlights
},
shownResults: function() {
return this.page * this.pageSize
}
},
created() {
if (window.location.hash.indexOf('#search/') > -1) {
this.term = decodeURIComponent(window.location.hash.replace('#search/', ''))
}
if(this.settings.pageSize) {
this.pageSize = this.settings.pageSize;
}
},
data () {
return {
loading: false,
result: {
hits: {
hits: []
}
},
term: '',
page: 0,
total: 0,
pageSize: 10,
highlights: []
}
},
watch: {
term: function() {
this.page = 0
if (this.term.length > 1) {
this.search()
} else {
this.result = []
this.total = 0
this.loading = false
}
},
page: function() {
if (this.page > 0) {
this.search()
}
}
},
methods: {
nextPage() {
this.page = this.page + 1
},
checkFields(item, fallback, fields) {
for (var i = 0; i < fields.length; i++) {
if (typeof item.highlight[fields[i]] !== 'undefined') {
return item.highlight[fields[i]]
}
}
if (item._source[fallback]) {
return item._source[fallback]
}
return []
},
search: _.throttle(
function () {
this.loading = true
var searchTerm = this.term
var query = {
query: {
bool: {
must: {
multi_match: {
query: searchTerm,
fields: [ 'title^4', 'h1^3', 'h2^2', 'h3^1', 'h4', 'h5', 'content', 'description', 'keywords' ],
type: 'phrase_prefix'
}
},
filter: {}
}
},
size: this.pageSize,
from: this.shownResults,
highlight: {
pre_tags: [`<${this.settings.highlight}>`],
post_tags: [`</${this.settings.highlight}>`],
fields: {'*': {}},
require_field_match: false
}
}
if (_.isArray(this.settings.queryFields)) {
query.query.bool.must.multi_match.fields = this.settings.queryFields
}
if (!_.isUndefined(this.settings.urlPrefix)) {
query.query.bool.filter = {prefix: {url: this.settings.urlPrefix}}
}
if (!_.isUndefined(this.settings.highlightFields)) {
query.highlight.fields = this.settings.highlightFields
}
axios({
method:'post',
url: `https://sapi.searchblok.com/v1/${this.settings.tenant}/_search`,
data: query
})
.then((response) => {
// console.log('Result: ' + JSON.stringify(response.data, null, 2))
if (this.term == searchTerm) {
this.result = response.data
this.total = response.data.hits.total
this.loading = false
window.location.hash = 'search/' + encodeURIComponent(searchTerm)
}
})
.catch((error) => {
this.result = 'Error! Could not reach the API.'
})
},
500
)
}
}
</script>
<style>
.searchblok {
font-family: "Helvetica Neue", "Helvetica", sans-serif;
text-align: left;
font-size: 16px;
}
.searchblok__results {
margin: 20px 0;
}
.searchblok__result-title {
font-size: 1.3em;
margin: 0 0 5px 0;
display: block;
color: #000;
text-decoration: none;
}
.searchblok__result-excerpt {
font-size: 0.9em;
}
.searchblok__result {
margin-bottom: 25px;
}
.searchblok__result em {
font-style: normal;
font-weight: bold;
}
.searchblok__input {
width: 100%;
font-size: 16px;
font-family: "Helvetica Neue", "Helvetica", sans-serif;
padding: 10px;
box-sizing: border-box;
}
.searchblok__result-url {
font-size: 0.8em;
margin: 0 0 5px 0;
text-decoration: underline;
display: block;
color: #000;
}
.searchblok__load-more {
text-align: center;
padding: 20px 0 40px 0;
border-top: 1px solid #CCC;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment