From 5e5928a8a6092d5250ebaf027796d56d2f37e609 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 6 Aug 2017 18:01:49 +0100 Subject: [PATCH] Added vanilla JS component system --- package.json | 1 + resources/assets/js/components/dropdown.js | 48 ++++++++++++++++++++++ resources/assets/js/components/index.js | 21 ++++++++++ resources/assets/js/directives.js | 39 ------------------ resources/assets/js/global.js | 2 + 5 files changed, 72 insertions(+), 39 deletions(-) create mode 100644 resources/assets/js/components/dropdown.js create mode 100644 resources/assets/js/components/index.js diff --git a/package.json b/package.json index 429572882..3d3b9c11c 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "angular-sanitize": "^1.5.5", "angular-ui-sortable": "^0.17.0", "axios": "^0.16.1", + "babel-polyfill": "^6.23.0", "babel-preset-es2015": "^6.24.1", "clipboard": "^1.5.16", "codemirror": "^5.26.0", diff --git a/resources/assets/js/components/dropdown.js b/resources/assets/js/components/dropdown.js new file mode 100644 index 000000000..0401efce0 --- /dev/null +++ b/resources/assets/js/components/dropdown.js @@ -0,0 +1,48 @@ +/** + * Dropdown + * Provides some simple logic to create simple dropdown menus. + */ +class DropDown { + + constructor(elem) { + this.container = elem; + this.menu = elem.querySelector('ul'); + this.toggle = elem.querySelector('[dropdown-toggle]'); + this.setupListeners(); + } + + show() { + this.menu.style.display = 'block'; + this.menu.classList.add('anim', 'menuIn'); + this.container.addEventListener('mouseleave', this.hide.bind(this)); + + // Focus on first input if existing + let input = this.menu.querySelector('input'); + if (input !== null) input.focus(); + } + + hide() { + this.menu.style.display = 'none'; + this.menu.classList.remove('anim', 'menuIn'); + } + + setupListeners() { + // Hide menu on option click + this.container.addEventListener('click', event => { + let possibleChildren = Array.from(this.menu.querySelectorAll('a')); + if (possibleChildren.indexOf(event.target) !== -1) this.hide(); + }); + // Show dropdown on toggle click + this.toggle.addEventListener('click', this.show.bind(this)); + // Hide menu on enter press + this.container.addEventListener('keypress', event => { + if (event.keyCode !== 13) return true; + event.preventDefault(); + this.hide(); + return false; + }); + } + +} + +module.exports = DropDown; \ No newline at end of file diff --git a/resources/assets/js/components/index.js b/resources/assets/js/components/index.js new file mode 100644 index 000000000..983b25d8f --- /dev/null +++ b/resources/assets/js/components/index.js @@ -0,0 +1,21 @@ + +let componentMapping = { + 'dropdown': require('./dropdown'), +}; + +window.components = {}; + +let componentNames = Object.keys(componentMapping); + +for (let i = 0, len = componentNames.length; i < len; i++) { + let name = componentNames[i]; + let elems = document.querySelectorAll(`[${name}]`); + if (elems.length === 0) continue; + + let component = componentMapping[name]; + if (typeof window.components[name] === "undefined") window.components[name] = []; + for (let j = 0, jLen = elems.length; j < jLen; j++) { + let instance = new component(elems[j]); + window.components[name].push(instance); + } +} \ No newline at end of file diff --git a/resources/assets/js/directives.js b/resources/assets/js/directives.js index d8745462d..cd9cc0283 100644 --- a/resources/assets/js/directives.js +++ b/resources/assets/js/directives.js @@ -114,45 +114,6 @@ module.exports = function (ngApp, events) { }; }]); - /** - * Dropdown - * Provides some simple logic to create small dropdown menus - */ - ngApp.directive('dropdown', [function () { - return { - restrict: 'A', - link: function (scope, element, attrs) { - const menu = element.find('ul'); - - function hide() { - menu.hide(); - menu.removeClass('anim menuIn'); - } - - function show() { - menu.show().addClass('anim menuIn'); - element.mouseleave(hide); - - // Focus on input if exist in dropdown and hide on enter press - let inputs = menu.find('input'); - if (inputs.length > 0) inputs.first().focus(); - } - - // Hide menu on option click - element.on('click', '> ul a', hide); - // Show dropdown on toggle click. - element.find('[dropdown-toggle]').on('click', show); - // Hide menu on enter press in inputs - element.on('keypress', 'input', event => { - if (event.keyCode !== 13) return true; - event.preventDefault(); - hide(); - return false; - }); - } - }; - }]); - /** * TinyMCE * An angular wrapper around the tinyMCE editor. diff --git a/resources/assets/js/global.js b/resources/assets/js/global.js index 2ef062a5b..979310777 100644 --- a/resources/assets/js/global.js +++ b/resources/assets/js/global.js @@ -1,4 +1,5 @@ "use strict"; +require("babel-polyfill"); // Url retrieval function window.baseUrl = function(path) { @@ -22,6 +23,7 @@ window.$http = axiosInstance; Vue.prototype.$http = axiosInstance; require("./vues/vues"); +require("./components"); // AngularJS - Create application and load components