_examples/xkcdsearch/web/application.js (103 lines of code) (raw):

/* globals Vue */ (function () { 'use strict' var app = new Vue({ el: '#app', data: { state: { error: null, loading: true, fetching: false, replaceResults: true }, isBottom: false, query: '', results: [], total: 0, search_after: [] }, methods: { loadResults: function () { var self = this if (self.state.fetching) { return } self.state.fetching = true if (self.query === '') { window.history.pushState({}, '', '?') } else { window.history.pushState({}, '', '?q=' + encodeURIComponent(self.query)) } if (self.state.replaceResults) { self.search_after = [] } window.fetch(`/search.json?q=${encodeURIComponent(self.query)}&a=${self.search_after.join(',')}`) .then(function (response) { if (!response.ok) { return Promise.reject(response) } return response.json() }) .then(function (response) { var results = [] response.hits.forEach(function (r) { var result = { id: r.id, url: r.url, image_url: r.image_url, published: r.published } if (r.highlights && r.highlights.title) { result.title = r.highlights.title[0] } else { result.title = r.title } if (r.highlights && r.highlights.alt) { result.alt = r.highlights.alt[0] } if (r.highlights && r.highlights.transcript) { result.transcript = r.highlights.transcript.join('…') } results.push(result) }) self.total = response.total if (self.state.replaceResults) { self.results = results } else { self.results = self.results.concat(results) } if (response.hits.length > 0) { self.search_after = response.hits[response.hits.length - 1].sort } }) .then(function () { self.state.loading = false self.state.fetching = false }) .catch(function (response) { self.state.loading = false self.state.fetching = false self.state.error = response }) }, toggle: function (event) { event.currentTarget.closest('div.result').classList.toggle('expanded') } }, watch: { query: function () { this.state.replaceResults = true this.loadResults() }, isBottom: function () { if (this.total > this.results.length) { this.state.replaceResults = false this.loadResults() } } }, created: function () { var self = this var q = document.location.search.split('q=')[1] if (q) { self.query = decodeURIComponent(q) } self.loadResults() window.onscroll = function () { self.isBottom = (document.documentElement.scrollTop || document.body.scrollTop) + window.innerHeight === document.documentElement.scrollHeight } } }) return app })()