/* Copyright (c) 2015, Aaron van Geffen All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. */ 'use strict'; function AutoSuggest(opt) { if (typeof opt.inputElement === "undefined" || typeof opt.listElement === "undefined" || typeof opt.baseUrl === "undefined" || typeof opt.appendCallback === "undefined") { return; } this.input = document.getElementById(opt.inputElement); this.input.autocomplete = "off"; this.list = document.getElementById(opt.listElement); this.appendCallback = opt.appendCallback; this.baseurl = opt.baseUrl; var self = this; this.input.addEventListener('keydown', function(event) { self.doSelection(event); }, false); this.input.addEventListener('keyup', function(event) { self.onType(this, event); }, false); } AutoSuggest.prototype.doSelection = function(event) { if (typeof this.container === "undefined" || this.container.children.length === 0) { return; } switch (event.keyCode) { case 13: // Enter event.preventDefault(); this.container.children[this.selectedIndex].click(); break; case 38: // Arrow up case 40: // Arrow down event.preventDefault(); this.findSelectedElement().className = ''; this.selectedIndex += event.keyCode === 38 ? -1 : 1; if (this.selectedIndex < 0) { this.selectedIndex = this.container.children.length - 1; } else if (this.selectedIndex === this.container.children.length) { this.selectedIndex = 0; } var new_el = this.findSelectedElement().className = 'selected'; break; } }; AutoSuggest.prototype.findSelectedElement = function() { return this.container.children[this.selectedIndex]; }; AutoSuggest.prototype.onType = function(input, event) { if (event.keyCode === 13 || event.keyCode === 38 || event.keyCode === 40) { return; } var tokens = input.value.split(/\s+/).filter(function(token) { return token.length >= 3; }); if (tokens.length === 0) { if (typeof this.container !== "undefined") { this.clearContainer(); } return false; } var request_uri = this.baseurl + '/suggest/?type=tags&data=' + window.encodeURIComponent(tokens.join(" ")); var request = new HttpRequest('get', request_uri, {}, this.onReceive, this); }; AutoSuggest.prototype.onReceive = function(response, self) { self.openContainer(); self.clearContainer(); self.fillContainer(response); }; AutoSuggest.prototype.openContainer = function() { if (this.container) { if (!this.container.parentNode) { this.input.parentNode.appendChild(this.container); } return this.container; } this.container = document.createElement('ul'); this.container.className = 'autosuggest'; this.input.parentNode.appendChild(this.container); return this.container; }; AutoSuggest.prototype.clearContainer = function() { while (this.container.children.length > 0) { this.container.removeChild(this.container.children[0]); } }; AutoSuggest.prototype.clearInput = function() { this.input.value = ""; this.input.focus(); }; AutoSuggest.prototype.closeContainer = function() { this.container.parentNode.removeChild(this.container); }; AutoSuggest.prototype.fillContainer = function(response) { var self = this; this.selectedIndex = 0; response.items.forEach(function(item, i) { var node = document.createElement('li'); var text = document.createTextNode(item.label); node.jsondata = item; node.addEventListener('click', function(event) { self.appendCallback(this.jsondata); self.closeContainer(); self.clearInput(); }); node.appendChild(text); self.container.appendChild(node); if (self.container.children.length === 1) { node.className = 'selected'; } }); }; function TagAutoSuggest(opt) { AutoSuggest.prototype.constructor.call(this, opt); this.type = "tags"; } TagAutoSuggest.prototype = Object.create(AutoSuggest.prototype); TagAutoSuggest.prototype.constructor = TagAutoSuggest; TagAutoSuggest.prototype.fillContainer = function(response) { if (response.items.length > 0) { AutoSuggest.prototype.fillContainer.call(this, response); } else { var node = document.createElement('li') node.innerHTML = "Tag does not exist yet. Create it?"; var self = this; node.addEventListener('click', function(event) { self.createNewTag(function(response) { console.log('Nieuwe tag!!'); console.log(response); self.appendCallback(response); }); self.closeContainer(); self.clearInput(); }); self.container.appendChild(node); this.selectedIndex = 0; node.className = 'selected'; } }; TagAutoSuggest.prototype.createNewTag = function(callback) { var request_uri = this.baseurl + '/managetags/?create'; var request = new HttpRequest('post', request_uri, 'tag=' + encodeURIComponent(this.input.value), callback, this); }