From d4b2422fd753df71be58d1a499194849b6e6d438 Mon Sep 17 00:00:00 2001 From: rtz12 Date: Mon, 25 Jan 2016 20:01:15 +0100 Subject: JavaScript Kram auf Hippe ES6 Kacke umgebaut diff --git a/.babelrc b/.babelrc index 7b37dd5..fc3d89c 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,7 @@ { - "presets": ["es2015"] + "presets": ["es2015"], + "plugins": [ + "syntax-async-functions", + "transform-regenerator" + ] } diff --git a/assets_src/js/lib/ajax.js b/assets_src/js/lib/ajax.js new file mode 100644 index 0000000..048f516 --- /dev/null +++ b/assets_src/js/lib/ajax.js @@ -0,0 +1,60 @@ +export class AjaxError extends Error { + constructor(status, statusText) { + let message = `${status}: ${statusText}` + super(message); + this.name = this.constructor.name; + this.message = message; + this.status = status; + this.statusText = statusText; + Error.captureStackTrace(this, this.constructor.name) + } +} + +function applyOptions(xhr, options) { + options.headers = options.headers || []; + for (let header in options.headers) { + xhr.setRequestHeader(header, options.headers[header]); + } +} + +function createHandler(xhr, success, fail) { + return () => { + if (xhr.readyState !== XMLHttpRequest.DONE) { + return; + } + if (xhr.status === 200) { + success(xhr.response); + } else { + fail(xhr.status, xhr.statusText); + } + }; +} + +function request(method, url, body, options) { + options = options || {}; + return new Promise((resolve, reject) => { + let xhr = new XMLHttpRequest(); + xhr.onreadystatechange = createHandler( + xhr, + (res) => { + resolve(res); + }, + (status, statusText) => { + reject(new AjaxError(status, statusText)); + }); + xhr.open(method, url, true); + applyOptions(xhr, options); + xhr.onerror = function() { + reject(new AjaxError(-1, 'Network error')); + }; + xhr.send(body); + }); +} + +export async function get(url, options) { + return request('GET', url, null, options); +} + +export async function post(url, body, options) { + return request('POST', url, body, options); +} diff --git a/assets_src/js/lib/dom.js b/assets_src/js/lib/dom.js new file mode 100644 index 0000000..33845af --- /dev/null +++ b/assets_src/js/lib/dom.js @@ -0,0 +1,14 @@ +export function ready(fn) { + document.addEventListener('DOMContentLoaded', (e) => { + fn(); + }, false); +} + +export function closest(el, fn) { + while (el) { + if (fn(el)) { + return el; + } + el = el.parentNode + } +} diff --git a/assets_src/js/lib/search.js b/assets_src/js/lib/search.js index 0cb33df..85559ef 100644 --- a/assets_src/js/lib/search.js +++ b/assets_src/js/lib/search.js @@ -1,40 +1,51 @@ -var strokeTimeout = null; +import * as dom from './dom'; +import * as ajax from './ajax'; -function instantSearch() { - if (strokeTimeout) { - clearTimeout(strokeTimeout); - } - strokeTimeout = setTimeout(doSearch, 150); -} - -function doSearch() { - value = document.getElementById("search").value; - - if (value === "") { - strokeTimeout = null; - document.getElementById("search-results").innerHTML = ""; - return; - } - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if (xhr.readyState == XMLHttpRequest.DONE) { - if (xhr.status === 404 || xhr.status === 400 || typeof xhr.response === 'undefined' || xhr.response === '404 not found') { - document.getElementById("search-results").innerHTML = ''; - return +export class InstantSearch { + constructor(element, resultsElem) { + this.resultClicked = () => {}; + this.element = element; + this.resultsElem = resultsElem; + this.strokeTimeout = null; + element.addEventListener('keydown', e => { + if (this.strokeTimeout) { + clearTimeout(this.strokeTimeout); } - if (value === "") { - document.getElementById("search-results").innerHTML = ""; - return; + this.strokeTimeout = setTimeout(() => this.doSearch(), 150); + }, false); + resultsElem.addEventListener('click', e => { + let li = dom.closest(e.target, el => el.tagName.match(/li/i)); + if (!li) { + return true; } + this.resultsElem.innerHTML = ''; + this.resultClicked(li.getAttribute('data-id')); + }, true); + } - document.getElementById("search-results").innerHTML = xhr.response.replace(new RegExp('{ (.*?)(' + value + ')(.*?) }', 'gi'), "$1$2$3").replace(new RegExp('{ (.*?) }', 'gi'), '$1'); + async doSearch() { + let value = this.element.value; + if (value.length < 2) { + this.strokeTimeout = null; + this.resultsElem.innerHTML = ""; + return; + } + let response = null; + try { + response = await ajax.get(`/search/gril_instant/${value}`); + } catch (e) { + this.resultsElem.innerHTML = ''; + return; } + this.resultsElem.innerHTML = response + .replace( + new RegExp('{ (.*?)(' + + value + + ')(.*?) }', 'gi'), + "$1$2$3") + .replace( + new RegExp('{ (.*?) }', 'gi'), + '$1'); + this.strokeTimeout = null; } - xhr.open('GET', '/search/gril_instant/' + value, true); - xhr.send(null); - strokeTimeout = null; } - -function clickSearchResult(resId) { - -} \ No newline at end of file diff --git a/assets_src/js/list.js b/assets_src/js/list.js index 25ff80d..413f517 100644 --- a/assets_src/js/list.js +++ b/assets_src/js/list.js @@ -1,17 +1,29 @@ -function clickSearchResult(resId) { - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if (xhr.readyState == XMLHttpRequest.DONE) { - if (xhr.status !== 200) { - alert(xhr.status + ": " + xhr.response); - return; - } +import 'babel-polyfill'; +import * as search from './lib/search'; +import * as dom from './lib/dom'; +import * as ajax from './lib/ajax'; - data = xhr.responseText; - document.getElementById("gril-list").innerHTML += data; - } +async function resultClicked(grilId) { + let response = null; + try { + response = await ajax.post( + window.location, + 'id=' + grilId, + { headers: { + 'Content-type': 'application/x-www-form-urlencoded' + } }); + } catch (e) { + alert(e.message); + return; } - xhr.open('POST', window.location, true); - xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - xhr.send('id=' + resId); -} \ No newline at end of file + document.getElementById('gril-list').innerHTML += response; +} + +function main() { + let is = new search.InstantSearch( + document.getElementById('gril-add-search'), + document.getElementById('search-results')); + is.resultClicked = resultClicked; +} + +dom.ready(main); diff --git a/package.json.tpl b/package.json.tpl index c2d075b..8d0bb1a 100644 --- a/package.json.tpl +++ b/package.json.tpl @@ -3,7 +3,10 @@ "version": "%($VERSION%)", "devDependencies": { "less": "2.5.3", + "babel-polyfill": "6.3.14", "babel-preset-es2015": "6.3.13", + "babel-plugin-syntax-async-functions": "6.3.13", + "babel-plugin-transform-regenerator": "6.4.4", "browserify": "13.0.0", "babelify": "7.2.0" } diff --git a/views/includes/instant_search_results.html b/views/includes/instant_search_results.html index 0dd445c..acdbb30 100644 --- a/views/includes/instant_search_results.html +++ b/views/includes/instant_search_results.html @@ -1,8 +1,8 @@ {{ define "instant_search_results" }} {{ range .results }} -
  • +
  • { {{ .Name }} }
  • {{ end }} -{{ end }} \ No newline at end of file +{{ end }} diff --git a/views/pages/list.html b/views/pages/list.html index c85e147..c608b77 100644 --- a/views/pages/list.html +++ b/views/pages/list.html @@ -7,7 +7,6 @@ grilist - @@ -35,8 +34,8 @@ Gril hinzufügen
    - - + + close
    -- cgit v0.10.1