summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke "Jared" Bennett <lbennett@gitlab.com>2016-11-26 09:56:22 +0000
committerLuke "Jared" Bennett <lbennett@gitlab.com>2017-03-07 16:43:32 +0000
commitbeb52cf71f5798e598f1af4440f0edf9fc7e40ae (patch)
treea3badeaf5266ae9325b1659fa3050f2dcf3e9c17
parenta9cfc33cd3d11c68bc3bc3ca7cd8443a0ecfb2ea (diff)
downloadgitlab-ce-infinite-scroll-droplab-group-links.tar.gz
Added droplab and implemented in groups dropdowninfinite-scroll-droplab-group-links
Started on infinite scroll plugin integration
-rw-r--r--.eslintrc4
-rw-r--r--app/assets/javascripts/dispatcher.js5
-rw-r--r--app/assets/javascripts/droplab/droplab.js3
-rw-r--r--app/assets/javascripts/droplab/droplab.js.map1
-rw-r--r--app/assets/javascripts/droplab/droplab_infinite_scroll.js119
-rw-r--r--app/assets/javascripts/droplab/droplab_input_setter.js41
-rw-r--r--app/assets/javascripts/droplab/droplab_remote_filter.js85
-rw-r--r--app/assets/javascripts/droplab/plugins/ajax.js3
-rw-r--r--app/assets/javascripts/droplab/plugins/ajax.js.map1
-rw-r--r--app/assets/javascripts/droplab/plugins/ajax_filter.js3
-rw-r--r--app/assets/javascripts/droplab/plugins/ajax_filter.js.map1
-rw-r--r--app/assets/javascripts/droplab/plugins/filter.js3
-rw-r--r--app/assets/javascripts/droplab/plugins/filter.js.map1
-rw-r--r--app/assets/javascripts/groups_droplab.js.es644
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss21
-rw-r--r--app/assets/stylesheets/pages/projects.scss4
-rw-r--r--app/views/projects/group_links/_index.html.haml2
-rw-r--r--app/views/shared/_groups_droplab.html.haml12
18 files changed, 347 insertions, 6 deletions
diff --git a/.eslintrc b/.eslintrc
index b0ae2a31919..0599cc18f5a 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -9,7 +9,9 @@
"_": false,
"gl": false,
"gon": false,
- "localStorage": false
+ "localStorage": false,
+ "jQuery": false,
+ "droplab": false
},
"plugins": [
"filenames",
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 31f10f89245..a9114a01ed3 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -228,6 +228,11 @@ const UserCallout = require('./user_callout');
new gl.MemberExpirationDate();
new gl.Members();
new UsersSelect();
+
+ const trigger = document.querySelector('#link_group_id_trigger');
+ const list = document.querySelector('#groups-droplab');
+ const input = document.querySelector('#link_group_id');
+ gl.GroupsDroplab.init(trigger, list, input);
break;
case 'groups:new':
case 'admin:groups:new':
diff --git a/app/assets/javascripts/droplab/droplab.js b/app/assets/javascripts/droplab/droplab.js
index ef6e439ee84..c84396011b9 100644
--- a/app/assets/javascripts/droplab/droplab.js
+++ b/app/assets/javascripts/droplab/droplab.js
@@ -1 +1,2 @@
-!function(n){function e(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return n[i].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var t={};e.m=n,e.c=t,e.i=function(n){return n},e.d=function(n,t,i){e.o(n,t)||Object.defineProperty(n,t,{configurable:!1,enumerable:!0,get:i})},e.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(t,"a",t),t},e.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},e.p="",e(e.s=9)}([function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar DATA_TRIGGER = 'data-dropdown-trigger';\nvar DATA_DROPDOWN = 'data-dropdown';\nvar SELECTED_CLASS = 'droplab-item-selected';\nvar ACTIVE_CLASS = 'droplab-item-active';\n\nvar constants = {\n DATA_TRIGGER: DATA_TRIGGER,\n DATA_DROPDOWN: DATA_DROPDOWN,\n SELECTED_CLASS: SELECTED_CLASS,\n ACTIVE_CLASS: ACTIVE_CLASS\n};\n\nexports.default = constants;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/constants.js\n// module id = 0\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/constants.js?")},function(module,exports){eval("// Polyfill for creating CustomEvents on IE9/10/11\n\n// code pulled from:\n// https://github.com/d4tocchini/customevent-polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill\n\ntry {\n var ce = new window.CustomEvent('test');\n ce.preventDefault();\n if (ce.defaultPrevented !== true) {\n // IE has problems with .preventDefault() on custom events\n // http://stackoverflow.com/questions/23349191\n throw new Error('Could not prevent default');\n }\n} catch(e) {\n var CustomEvent = function(event, params) {\n var evt, origPrevent;\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n\n evt = document.createEvent(\"CustomEvent\");\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n origPrevent = evt.preventDefault;\n evt.preventDefault = function () {\n origPrevent.call(this);\n try {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function () {\n return true;\n }\n });\n } catch(e) {\n this.defaultPrevented = true;\n }\n };\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n window.CustomEvent = CustomEvent; // expose definition to window\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/custom-event-polyfill/custom-event-polyfill.js\n// module id = 1\n// module chunks = 0\n\n//# sourceURL=webpack:///./~/custom-event-polyfill/custom-event-polyfill.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _dropdown = __webpack_require__(6);\n\nvar _dropdown2 = _interopRequireDefault(_dropdown);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar Hook = function Hook(trigger, list, plugins, config) {\n this.trigger = trigger;\n this.list = new _dropdown2.default(list);\n this.type = 'Hook';\n this.event = 'click';\n this.plugins = plugins || [];\n this.config = config || {};\n this.id = trigger.id;\n};\n\nObject.assign(Hook.prototype, {\n\n addEvents: function addEvents() {},\n\n constructor: Hook\n});\n\nexports.default = Hook;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/hook.js\n// module id = 2\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/hook.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar DATA_TRIGGER = _constants2.default.DATA_TRIGGER,\n DATA_DROPDOWN = _constants2.default.DATA_DROPDOWN;\n\n\nvar utils = {\n toCamelCase: function toCamelCase(attr) {\n return this.camelize(attr.split('-').slice(1).join(' '));\n },\n t: function t(s, d) {\n for (var p in d) {\n if (Object.prototype.hasOwnProperty.call(d, p)) {\n s = s.replace(new RegExp('{{' + p + '}}', 'g'), d[p]);\n }\n }\n return s;\n },\n camelize: function camelize(str) {\n return str.replace(/(?:^\\w|[A-Z]|\\b\\w)/g, function (letter, index) {\n return index === 0 ? letter.toLowerCase() : letter.toUpperCase();\n }).replace(/\\s+/g, '');\n },\n closest: function closest(thisTag, stopTag) {\n while (thisTag && thisTag.tagName !== stopTag && thisTag.tagName !== 'HTML') {\n thisTag = thisTag.parentNode;\n }\n return thisTag;\n },\n isDropDownParts: function isDropDownParts(target) {\n if (!target || target.tagName === 'HTML') return false;\n return target.hasAttribute(DATA_TRIGGER) || target.hasAttribute(DATA_DROPDOWN);\n }\n};\n\nexports.default = utils;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/utils.js\n// module id = 3\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/utils.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function () {\n var DropLab = function DropLab(hook, list) {\n if (!this instanceof DropLab) return new DropLab(hook);\n\n this.ready = false;\n this.hooks = [];\n this.queuedData = [];\n this.config = {};\n\n this.eventWrapper = {};\n\n !hook ? this.loadStatic() : this.addHook(hook, list);\n };\n\n Object.assign(DropLab.prototype, {\n loadStatic: function loadStatic() {\n var dropdownTriggers = [].slice.apply(document.querySelectorAll('[' + DATA_TRIGGER + ']'));\n this.addHooks(dropdownTriggers).init();\n },\n\n addData: function addData() {\n var args = [].slice.apply(arguments);\n this.applyArgs(args, '_addData');\n },\n\n setData: function setData() {\n var args = [].slice.apply(arguments);\n this.applyArgs(args, '_setData');\n },\n\n destroy: function destroy() {\n this.hooks.forEach(function (hook) {\n return hook.destroy();\n });\n this.hooks = [];\n this.removeEvents();\n },\n\n applyArgs: function applyArgs(args, methodName) {\n if (this.ready) return this[methodName].apply(this, args);\n\n this.queuedData = this.queuedData || [];\n this.queuedData.push(args);\n },\n\n _addData: function _addData(trigger, data) {\n this._processData(trigger, data, 'addData');\n },\n\n _setData: function _setData(trigger, data) {\n this._processData(trigger, data, 'setData');\n },\n\n _processData: function _processData(trigger, data, methodName) {\n this.hooks.forEach(function (hook) {\n if (Array.isArray(trigger)) hook.list[methodName](trigger);\n\n if (hook.trigger.id === trigger) hook.list[methodName](data);\n });\n },\n\n addEvents: function addEvents() {\n this.eventWrapper.documentClicked = this.documentClicked.bind(this);\n document.addEventListener('click', this.eventWrapper.documentClicked);\n },\n\n documentClicked: function documentClicked(e) {\n var thisTag = e.target;\n\n if (thisTag.tagName !== 'UL') thisTag = _utils2.default.closest(thisTag, 'UL');\n if (_utils2.default.isDropDownParts(thisTag, this.hooks) || _utils2.default.isDropDownParts(e.target, this.hooks)) return;\n\n this.hooks.forEach(function (hook) {\n return hook.list.hide();\n });\n },\n\n removeEvents: function removeEvents() {\n document.removeEventListener('click', this.eventWrapper.documentClicked);\n },\n\n changeHookList: function changeHookList(trigger, list, plugins, config) {\n var _this = this;\n\n var availableTrigger = typeof trigger === 'string' ? document.getElementById(trigger) : trigger;\n\n this.hooks.forEach(function (hook, i) {\n hook.list.list.dataset.dataDropdownActive = false;\n\n if (hook.trigger !== availableTrigger) return;\n\n hook.destroy();\n _this.hooks.splice(i, 1);\n _this.addHook(availableTrigger, list, plugins, config);\n });\n },\n\n addHook: function addHook(hook, list, plugins, config) {\n var availableHook = typeof hook === 'string' ? document.querySelector(hook) : hook;\n var availableList = void 0;\n\n if (typeof list === 'string') {\n availableList = document.querySelector(list);\n } else if (list instanceof Element) {\n availableList = list;\n } else {\n availableList = document.querySelector(hook.dataset[_utils2.default.toCamelCase(DATA_TRIGGER)]);\n }\n\n availableList.dataset.dataDropdownActive = true;\n\n var HookObject = availableHook.tagName === 'INPUT' ? _hook_input2.default : _hook_button2.default;\n this.hooks.push(new HookObject(availableHook, availableList, plugins, config));\n\n return this;\n },\n\n addHooks: function addHooks(hooks, plugins, config) {\n var _this2 = this;\n\n hooks.forEach(function (hook) {\n return _this2.addHook(hook, null, plugins, config);\n });\n return this;\n },\n\n setConfig: function setConfig(obj) {\n this.config = obj;\n },\n\n fireReady: function fireReady() {\n var readyEvent = new CustomEvent('ready.dl', {\n detail: {\n dropdown: this\n }\n });\n document.dispatchEvent(readyEvent);\n\n this.ready = true;\n },\n\n init: function init() {\n var _this3 = this;\n\n this.addEvents();\n\n this.fireReady();\n\n this.queuedData.forEach(function (data) {\n return _this3.addData(data);\n });\n this.queuedData = [];\n\n return this;\n }\n });\n\n return DropLab;\n};\n\n__webpack_require__(1);\n\nvar _hook_button = __webpack_require__(7);\n\nvar _hook_button2 = _interopRequireDefault(_hook_button);\n\nvar _hook_input = __webpack_require__(8);\n\nvar _hook_input2 = _interopRequireDefault(_hook_input);\n\nvar _utils = __webpack_require__(3);\n\nvar _utils2 = _interopRequireDefault(_utils);\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar DATA_TRIGGER = _constants2.default.DATA_TRIGGER;\n\n;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/droplab.js\n// module id = 4\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/droplab.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function () {\n var currentKey;\n var currentFocus;\n var isUpArrow = false;\n var isDownArrow = false;\n var removeHighlight = function removeHighlight(list) {\n var itemElements = Array.prototype.slice.call(list.list.querySelectorAll('li:not(.divider)'), 0);\n var listItems = [];\n for (var i = 0; i < itemElements.length; i++) {\n var listItem = itemElements[i];\n listItem.classList.remove(_constants2.default.ACTIVE_CLASS);\n\n if (listItem.style.display !== 'none') {\n listItems.push(listItem);\n }\n }\n return listItems;\n };\n\n var setMenuForArrows = function setMenuForArrows(list) {\n var listItems = removeHighlight(list);\n if (list.currentIndex > 0) {\n if (!listItems[list.currentIndex - 1]) {\n list.currentIndex = list.currentIndex - 1;\n }\n\n if (listItems[list.currentIndex - 1]) {\n var el = listItems[list.currentIndex - 1];\n var filterDropdownEl = el.closest('.filter-dropdown');\n el.classList.add(_constants2.default.ACTIVE_CLASS);\n\n if (filterDropdownEl) {\n var filterDropdownBottom = filterDropdownEl.offsetHeight;\n var elOffsetTop = el.offsetTop - 30;\n\n if (elOffsetTop > filterDropdownBottom) {\n filterDropdownEl.scrollTop = elOffsetTop - filterDropdownBottom;\n }\n }\n }\n }\n };\n\n var mousedown = function mousedown(e) {\n var list = e.detail.hook.list;\n removeHighlight(list);\n list.show();\n list.currentIndex = 0;\n isUpArrow = false;\n isDownArrow = false;\n };\n var selectItem = function selectItem(list) {\n var listItems = removeHighlight(list);\n var currentItem = listItems[list.currentIndex - 1];\n var listEvent = new CustomEvent('click.dl', {\n detail: {\n list: list,\n selected: currentItem,\n data: currentItem.dataset\n }\n });\n list.list.dispatchEvent(listEvent);\n list.hide();\n };\n\n var keydown = function keydown(e) {\n var typedOn = e.target;\n var list = e.detail.hook.list;\n var currentIndex = list.currentIndex;\n isUpArrow = false;\n isDownArrow = false;\n\n if (e.detail.which) {\n currentKey = e.detail.which;\n if (currentKey === 13) {\n selectItem(e.detail.hook.list);\n return;\n }\n if (currentKey === 38) {\n isUpArrow = true;\n }\n if (currentKey === 40) {\n isDownArrow = true;\n }\n } else if (e.detail.key) {\n currentKey = e.detail.key;\n if (currentKey === 'Enter') {\n selectItem(e.detail.hook.list);\n return;\n }\n if (currentKey === 'ArrowUp') {\n isUpArrow = true;\n }\n if (currentKey === 'ArrowDown') {\n isDownArrow = true;\n }\n }\n if (isUpArrow) {\n currentIndex--;\n }\n if (isDownArrow) {\n currentIndex++;\n }\n if (currentIndex < 0) {\n currentIndex = 0;\n }\n list.currentIndex = currentIndex;\n setMenuForArrows(e.detail.hook.list);\n };\n\n document.addEventListener('mousedown.dl', mousedown);\n document.addEventListener('keydown.dl', keydown);\n};\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/keyboard.js\n// module id = 5\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/keyboard.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _Object$assign;\n\n__webpack_require__(1);\n\nvar _utils = __webpack_require__(3);\n\nvar _utils2 = _interopRequireDefault(_utils);\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar DropDown = function DropDown(list) {\n this.currentIndex = 0;\n this.hidden = true;\n this.list = typeof list === 'string' ? document.querySelector(list) : list;\n this.items = [];\n\n this.eventWrapper = {};\n\n this.getItems();\n this.initTemplateString();\n this.addEvents();\n\n this.initialState = list.innerHTML;\n};\n\nObject.assign(DropDown.prototype, (_Object$assign = {\n getItems: function getItems() {\n this.items = [].slice.call(this.list.querySelectorAll('li'));\n return this.items;\n },\n\n initTemplateString: function initTemplateString() {\n var items = this.items || this.getItems();\n\n var templateString = '';\n if (items.length > 0) templateString = items[items.length - 1].outerHTML;\n this.templateString = templateString;\n\n return this.templateString;\n },\n\n clickEvent: function clickEvent(e) {\n var selected = _utils2.default.closest(e.target, 'LI');\n if (!selected) return;\n\n this.addSelectedClass(selected);\n\n e.preventDefault();\n this.hide();\n\n var listEvent = new CustomEvent('click.dl', {\n detail: {\n list: this,\n selected: selected,\n data: e.target.dataset\n }\n });\n this.list.dispatchEvent(listEvent);\n },\n\n addSelectedClass: function addSelectedClass(selected) {\n this.removeSelectedClasses();\n selected.classList.add(_constants2.default.SELECTED_CLASS);\n },\n\n removeSelectedClasses: function removeSelectedClasses() {\n var items = this.items || this.getItems();\n\n items.forEach(function (item) {\n item.classList.remove(_constants2.default.SELECTED_CLASS);\n });\n },\n\n addEvents: function addEvents() {\n this.eventWrapper.clickEvent = this.clickEvent.bind(this);\n this.list.addEventListener('click', this.eventWrapper.clickEvent);\n },\n\n toggle: function toggle() {\n this.hidden ? this.show() : this.hide();\n },\n\n setData: function setData(data) {\n this.data = data;\n this.render(data);\n },\n\n addData: function addData(data) {\n this.data = (this.data || []).concat(data);\n this.render(this.data);\n },\n\n render: function render(data) {\n var children = data ? data.map(this.renderChildren.bind(this)) : [];\n var renderableList = this.list.querySelector('ul[data-dynamic]') || this.list;\n\n renderableList.innerHTML = children.join('');\n },\n\n renderChildren: function renderChildren(data) {\n var html = _utils2.default.t(this.templateString, data);\n var template = document.createElement('div');\n\n template.innerHTML = html;\n this.setImagesSrc(template);\n template.firstChild.style.display = data.droplab_hidden ? 'none' : 'block';\n\n return template.firstChild.outerHTML;\n },\n\n setImagesSrc: function setImagesSrc(template) {\n var images = [].slice.call(template.querySelectorAll('img[data-src]'));\n\n images.forEach(function (image) {\n image.src = image.getAttribute('data-src');\n image.removeAttribute('data-src');\n });\n },\n\n show: function show() {\n if (!this.hidden) return;\n this.list.style.display = 'block';\n this.currentIndex = 0;\n this.hidden = false;\n },\n\n hide: function hide() {\n if (this.hidden) return;\n this.list.style.display = 'none';\n this.currentIndex = 0;\n this.hidden = true;\n }\n\n}, _defineProperty(_Object$assign, 'toggle', function toggle() {\n this.hidden ? this.show() : this.hide();\n}), _defineProperty(_Object$assign, 'destroy', function destroy() {\n this.hide();\n this.list.removeEventListener('click', this.eventWrapper.clickEvent);\n}), _Object$assign));\n\nexports.default = DropDown;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/dropdown.js\n// module id = 6\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/dropdown.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\n__webpack_require__(1);\n\nvar _hook = __webpack_require__(2);\n\nvar _hook2 = _interopRequireDefault(_hook);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar HookButton = function HookButton(trigger, list, plugins, config) {\n _hook2.default.call(this, trigger, list, plugins, config);\n\n this.type = 'button';\n this.event = 'click';\n\n this.eventWrapper = {};\n\n this.addEvents();\n this.addPlugins();\n};\n\nHookButton.prototype = Object.create(_hook2.default.prototype);\n\nObject.assign(HookButton.prototype, {\n addPlugins: function addPlugins() {\n var _this = this;\n\n this.plugins.forEach(function (plugin) {\n return plugin.init(_this);\n });\n },\n\n clicked: function clicked(e) {\n var buttonEvent = new CustomEvent('click.dl', {\n detail: {\n hook: this\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(buttonEvent);\n\n this.list.toggle();\n },\n\n addEvents: function addEvents() {\n this.eventWrapper.clicked = this.clicked.bind(this);\n this.trigger.addEventListener('click', this.eventWrapper.clicked);\n },\n\n removeEvents: function removeEvents() {\n this.trigger.removeEventListener('click', this.eventWrapper.clicked);\n },\n\n restoreInitialState: function restoreInitialState() {\n this.list.list.innerHTML = this.list.initialState;\n },\n\n removePlugins: function removePlugins() {\n this.plugins.forEach(function (plugin) {\n return plugin.destroy();\n });\n },\n\n destroy: function destroy() {\n this.restoreInitialState();\n\n this.removeEvents();\n this.removePlugins();\n },\n\n constructor: HookButton\n});\n\nexports.default = HookButton;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/hook_button.js\n// module id = 7\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/hook_button.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\n__webpack_require__(1);\n\nvar _hook = __webpack_require__(2);\n\nvar _hook2 = _interopRequireDefault(_hook);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar HookInput = function HookInput(trigger, list, plugins, config) {\n _hook2.default.call(this, trigger, list, plugins, config);\n\n this.type = 'input';\n this.event = 'input';\n\n this.eventWrapper = {};\n\n this.addEvents();\n this.addPlugins();\n};\n\nObject.assign(HookInput.prototype, {\n addPlugins: function addPlugins() {\n var _this = this;\n\n this.plugins.forEach(function (plugin) {\n return plugin.init(_this);\n });\n },\n\n addEvents: function addEvents() {\n this.eventWrapper.mousedown = this.mousedown.bind(this);\n this.eventWrapper.input = this.input.bind(this);\n this.eventWrapper.keyup = this.keyup.bind(this);\n this.eventWrapper.keydown = this.keydown.bind(this);\n\n this.trigger.addEventListener('mousedown', this.eventWrapper.mousedown);\n this.trigger.addEventListener('input', this.eventWrapper.input);\n this.trigger.addEventListener('keyup', this.eventWrapper.keyup);\n this.trigger.addEventListener('keydown', this.eventWrapper.keydown);\n },\n\n removeEvents: function removeEvents() {\n this.hasRemovedEvents = true;\n\n this.trigger.removeEventListener('mousedown', this.eventWrapper.mousedown);\n this.trigger.removeEventListener('input', this.eventWrapper.input);\n this.trigger.removeEventListener('keyup', this.eventWrapper.keyup);\n this.trigger.removeEventListener('keydown', this.eventWrapper.keydown);\n },\n\n input: function input(e) {\n if (this.hasRemovedEvents) return;\n\n this.list.show();\n\n var inputEvent = new CustomEvent('input.dl', {\n detail: {\n hook: this,\n text: e.target.value\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(inputEvent);\n },\n\n mousedown: function mousedown(e) {\n if (this.hasRemovedEvents) return;\n\n var mouseEvent = new CustomEvent('mousedown.dl', {\n detail: {\n hook: this,\n text: e.target.value\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(mouseEvent);\n },\n\n keyup: function keyup(e) {\n if (this.hasRemovedEvents) return;\n\n this.keyEvent(e, 'keyup.dl');\n },\n\n keydown: function keydown(e) {\n if (this.hasRemovedEvents) return;\n\n this.keyEvent(e, 'keydown.dl');\n },\n\n keyEvent: function keyEvent(e, eventName) {\n this.list.show();\n\n var keyEvent = new CustomEvent(eventName, {\n detail: {\n hook: this,\n text: e.target.value,\n which: e.which,\n key: e.key\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(keyEvent);\n },\n\n restoreInitialState: function restoreInitialState() {\n this.list.list.innerHTML = this.list.initialState;\n },\n\n removePlugins: function removePlugins() {\n this.plugins.forEach(function (plugin) {\n return plugin.destroy();\n });\n },\n\n destroy: function destroy() {\n this.restoreInitialState();\n\n this.removeEvents();\n this.removePlugins();\n\n this.list.destroy();\n }\n});\n\nexports.default = HookInput;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/hook_input.js\n// module id = 8\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/hook_input.js?")},function(module,exports,__webpack_require__){"use strict";eval('\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\n\nvar _droplab = __webpack_require__(4);\n\nvar _droplab2 = _interopRequireDefault(_droplab);\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nvar _keyboard = __webpack_require__(5);\n\nvar _keyboard2 = _interopRequireDefault(_keyboard);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar DATA_TRIGGER = _constants2.default.DATA_TRIGGER;\nvar keyboard = (0, _keyboard2.default)();\n\nvar setup = function setup() {\n window.DropLab = (0, _droplab2.default)();\n};\n\nsetup();\n\nexports.default = setup;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/index.js\n// module id = 9\n// module chunks = 0\n\n//# sourceURL=webpack:///./src/index.js?')}]); \ No newline at end of file
+!function(t){function e(n){if(i[n])return i[n].exports;var s=i[n]={i:n,l:!1,exports:{}};return t[n].call(s.exports,s,s.exports,e),s.l=!0,s.exports}var i={};e.m=t,e.c=i,e.i=function(t){return t},e.d=function(t,i,n){e.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(i,"a",i),i},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=9)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n="data-dropdown-trigger",s="data-dropdown",r="droplab-item-selected",o="droplab-item-active",a={DATA_TRIGGER:n,DATA_DROPDOWN:s,SELECTED_CLASS:r,ACTIVE_CLASS:o};e.default=a},function(t,e){try{var i=new window.CustomEvent("test");if(i.preventDefault(),i.defaultPrevented!==!0)throw new Error("Could not prevent default")}catch(t){var n=function(t,e){var i,n;return e=e||{bubbles:!1,cancelable:!1,detail:void 0},i=document.createEvent("CustomEvent"),i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n=i.preventDefault,i.preventDefault=function(){n.call(this);try{Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})}catch(t){this.defaultPrevented=!0}},i};n.prototype=window.Event.prototype,window.CustomEvent=n}},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0});var s=i(6),r=n(s),o=function(t,e,i,n){this.trigger=t,this.list=new r.default(e),this.type="Hook",this.event="click",this.plugins=i||[],this.config=n||{},this.id=t.id};Object.assign(o.prototype,{addEvents:function(){},constructor:o}),e.default=o},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0});var s=i(0),r=n(s),o=r.default.DATA_TRIGGER,a=r.default.DATA_DROPDOWN,d={toCamelCase:function(t){return this.camelize(t.split("-").slice(1).join(" "))},t:function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t=t.replace(new RegExp("{{"+i+"}}","g"),e[i]));return t},camelize:function(t){return t.replace(/(?:^\w|[A-Z]|\b\w)/g,function(t,e){return 0===e?t.toLowerCase():t.toUpperCase()}).replace(/\s+/g,"")},closest:function(t,e){for(;t&&t.tagName!==e&&"HTML"!==t.tagName;)t=t.parentNode;return t},isDropDownParts:function(t){return!(!t||"HTML"===t.tagName)&&(t.hasAttribute(o)||t.hasAttribute(a))}};e.default=d},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){var t=function t(e,i){if(!this instanceof t)return new t(e);this.ready=!1,this.hooks=[],this.queuedData=[],this.config={},this.eventWrapper={},e?this.addHook(e,i):this.loadStatic()};return Object.assign(t.prototype,{loadStatic:function(){var t=[].slice.apply(document.querySelectorAll("["+h+"]"));this.addHooks(t).init()},addData:function(){var t=[].slice.apply(arguments);this.applyArgs(t,"_addData")},setData:function(){var t=[].slice.apply(arguments);this.applyArgs(t,"_setData")},destroy:function(){this.hooks.forEach(function(t){return t.destroy()}),this.hooks=[],this.removeEvents()},applyArgs:function(t,e){if(this.ready)return this[e].apply(this,t);this.queuedData=this.queuedData||[],this.queuedData.push(t)},_addData:function(t,e){this._processData(t,e,"addData")},_setData:function(t,e){this._processData(t,e,"setData")},_processData:function(t,e,i){this.hooks.forEach(function(n){Array.isArray(t)&&n.list[i](t),n.trigger.id===t&&n.list[i](e)})},addEvents:function(){this.eventWrapper.documentClicked=this.documentClicked.bind(this),document.addEventListener("click",this.eventWrapper.documentClicked)},documentClicked:function(t){var e=t.target;"UL"!==e.tagName&&(e=u.default.closest(e,"UL")),u.default.isDropDownParts(e,this.hooks)||u.default.isDropDownParts(t.target,this.hooks)||this.hooks.forEach(function(t){return t.list.hide()})},removeEvents:function(){document.removeEventListener("click",this.eventWrapper.documentClicked)},changeHookList:function(t,e,i,n){var s=this,r="string"==typeof t?document.getElementById(t):t;this.hooks.forEach(function(t,o){t.list.list.dataset.dataDropdownActive=!1,t.trigger===r&&(t.destroy(),s.hooks.splice(o,1),s.addHook(r,e,i,n))})},addHook:function(t,e,i,n){var s="string"==typeof t?document.querySelector(t):t,o=void 0;o="string"==typeof e?document.querySelector(e):e instanceof Element?e:document.querySelector(t.dataset[u.default.toCamelCase(h)]),o.dataset.dataDropdownActive=!0;var d="INPUT"===s.tagName?a.default:r.default;return this.hooks.push(new d(s,o,i,n)),this},addHooks:function(t,e,i){var n=this;return t.forEach(function(t){return n.addHook(t,null,e,i)}),this},setConfig:function(t){this.config=t},fireReady:function(){var t=new CustomEvent("ready.dl",{detail:{dropdown:this}});document.dispatchEvent(t),this.ready=!0},init:function(){var t=this;return this.addEvents(),this.fireReady(),this.queuedData.forEach(function(e){return t.addData(e)}),this.queuedData=[],this}}),t},i(1);var s=i(7),r=n(s),o=i(8),a=n(o),d=i(3),u=n(d),c=i(0),l=n(c),h=l.default.DATA_TRIGGER},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){var t,e=!1,i=!1,n=function(t){for(var e=Array.prototype.slice.call(t.list.querySelectorAll("li:not(.divider)"),0),i=[],n=0;n<e.length;n++){var s=e[n];s.classList.remove(r.default.ACTIVE_CLASS),"none"!==s.style.display&&i.push(s)}return i},s=function(t){var e=n(t);if(t.currentIndex>0&&(e[t.currentIndex-1]||(t.currentIndex=t.currentIndex-1),e[t.currentIndex-1])){var i=e[t.currentIndex-1],s=i.closest(".filter-dropdown");if(i.classList.add(r.default.ACTIVE_CLASS),s){var o=s.offsetHeight,a=i.offsetTop-30;a>o&&(s.scrollTop=a-o)}}},o=function(t){var s=t.detail.hook.list;n(s),s.show(),s.currentIndex=0,e=!1,i=!1},a=function(t){var e=n(t),i=e[t.currentIndex-1],s=new CustomEvent("click.dl",{detail:{list:t,selected:i,data:i.dataset}});t.list.dispatchEvent(s),t.hide()},d=function(n){var r=(n.target,n.detail.hook.list),o=r.currentIndex;if(e=!1,i=!1,n.detail.which){if(13===(t=n.detail.which))return void a(n.detail.hook.list);38===t&&(e=!0),40===t&&(i=!0)}else if(n.detail.key){if("Enter"===(t=n.detail.key))return void a(n.detail.hook.list);"ArrowUp"===t&&(e=!0),"ArrowDown"===t&&(i=!0)}e&&o--,i&&o++,o<0&&(o=0),r.currentIndex=o,s(n.detail.hook.list)};document.addEventListener("mousedown.dl",o),document.addEventListener("keydown.dl",d)};var s=i(0),r=n(s)},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}function s(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}Object.defineProperty(e,"__esModule",{value:!0});var r;i(1);var o=i(3),a=n(o),d=i(0),u=n(d),c=function(t){this.currentIndex=0,this.hidden=!0,this.list="string"==typeof t?document.querySelector(t):t,this.items=[],this.eventWrapper={},this.getItems(),this.initTemplateString(),this.addEvents(),this.initialState=t.innerHTML};Object.assign(c.prototype,(r={getItems:function(){return this.items=[].slice.call(this.list.querySelectorAll("li")),this.items},initTemplateString:function(){var t=this.items||this.getItems(),e="";return t.length>0&&(e=t[t.length-1].outerHTML),this.templateString=e,this.templateString},clickEvent:function(t){var e=a.default.closest(t.target,"LI");if(e){this.addSelectedClass(e),t.preventDefault(),this.hide();var i=new CustomEvent("click.dl",{detail:{list:this,selected:e,data:t.target.dataset}});this.list.dispatchEvent(i)}},addSelectedClass:function(t){this.removeSelectedClasses(),t.classList.add(u.default.SELECTED_CLASS)},removeSelectedClasses:function(){(this.items||this.getItems()).forEach(function(t){t.classList.remove(u.default.SELECTED_CLASS)})},addEvents:function(){this.eventWrapper.clickEvent=this.clickEvent.bind(this),this.list.addEventListener("click",this.eventWrapper.clickEvent)},toggle:function(){this.hidden?this.show():this.hide()},setData:function(t){this.data=t,this.render(t)},addData:function(t){this.data=(this.data||[]).concat(t),this.render(this.data)},render:function(t){var e=t?t.map(this.renderChildren.bind(this)):[];(this.list.querySelector("ul[data-dynamic]")||this.list).innerHTML=e.join("")},renderChildren:function(t){var e=a.default.t(this.templateString,t),i=document.createElement("div");return i.innerHTML=e,this.setImagesSrc(i),i.firstChild.style.display=t.droplab_hidden?"none":"block",i.firstChild.outerHTML},setImagesSrc:function(t){[].slice.call(t.querySelectorAll("img[data-src]")).forEach(function(t){t.src=t.getAttribute("data-src"),t.removeAttribute("data-src")})},show:function(){this.hidden&&(this.list.style.display="block",this.currentIndex=0,this.hidden=!1)},hide:function(){this.hidden||(this.list.style.display="none",this.currentIndex=0,this.hidden=!0)}},s(r,"toggle",function(){this.hidden?this.show():this.hide()}),s(r,"destroy",function(){this.hide(),this.list.removeEventListener("click",this.eventWrapper.clickEvent)}),r)),e.default=c},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0}),i(1);var s=i(2),r=n(s),o=function(t,e,i,n){r.default.call(this,t,e,i,n),this.type="button",this.event="click",this.eventWrapper={},this.addEvents(),this.addPlugins()};o.prototype=Object.create(r.default.prototype),Object.assign(o.prototype,{addPlugins:function(){var t=this;this.plugins.forEach(function(e){return e.init(t)})},clicked:function(t){var e=new CustomEvent("click.dl",{detail:{hook:this},bubbles:!0,cancelable:!0});t.target.dispatchEvent(e),this.list.toggle()},addEvents:function(){this.eventWrapper.clicked=this.clicked.bind(this),this.trigger.addEventListener("click",this.eventWrapper.clicked)},removeEvents:function(){this.trigger.removeEventListener("click",this.eventWrapper.clicked)},restoreInitialState:function(){this.list.list.innerHTML=this.list.initialState},removePlugins:function(){this.plugins.forEach(function(t){return t.destroy()})},destroy:function(){this.restoreInitialState(),this.removeEvents(),this.removePlugins()},constructor:o}),e.default=o},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0}),i(1);var s=i(2),r=n(s),o=function(t,e,i,n){r.default.call(this,t,e,i,n),this.type="input",this.event="input",this.eventWrapper={},this.addEvents(),this.addPlugins()};Object.assign(o.prototype,{addPlugins:function(){var t=this;this.plugins.forEach(function(e){return e.init(t)})},addEvents:function(){this.eventWrapper.mousedown=this.mousedown.bind(this),this.eventWrapper.input=this.input.bind(this),this.eventWrapper.keyup=this.keyup.bind(this),this.eventWrapper.keydown=this.keydown.bind(this),this.trigger.addEventListener("mousedown",this.eventWrapper.mousedown),this.trigger.addEventListener("input",this.eventWrapper.input),this.trigger.addEventListener("keyup",this.eventWrapper.keyup),this.trigger.addEventListener("keydown",this.eventWrapper.keydown)},removeEvents:function(){this.hasRemovedEvents=!0,this.trigger.removeEventListener("mousedown",this.eventWrapper.mousedown),this.trigger.removeEventListener("input",this.eventWrapper.input),this.trigger.removeEventListener("keyup",this.eventWrapper.keyup),this.trigger.removeEventListener("keydown",this.eventWrapper.keydown)},input:function(t){if(!this.hasRemovedEvents){this.list.show();var e=new CustomEvent("input.dl",{detail:{hook:this,text:t.target.value},bubbles:!0,cancelable:!0});t.target.dispatchEvent(e)}},mousedown:function(t){if(!this.hasRemovedEvents){var e=new CustomEvent("mousedown.dl",{detail:{hook:this,text:t.target.value},bubbles:!0,cancelable:!0});t.target.dispatchEvent(e)}},keyup:function(t){this.hasRemovedEvents||this.keyEvent(t,"keyup.dl")},keydown:function(t){this.hasRemovedEvents||this.keyEvent(t,"keydown.dl")},keyEvent:function t(e,i){this.list.show();var t=new CustomEvent(i,{detail:{hook:this,text:e.target.value,which:e.which,key:e.key},bubbles:!0,cancelable:!0});e.target.dispatchEvent(t)},restoreInitialState:function(){this.list.list.innerHTML=this.list.initialState},removePlugins:function(){this.plugins.forEach(function(t){return t.destroy()})},destroy:function(){this.restoreInitialState(),this.removeEvents(),this.removePlugins(),this.list.destroy()}}),e.default=o},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0});var s=i(4),r=n(s),o=i(0),a=n(o),d=i(5),u=n(d),c=(a.default.DATA_TRIGGER,(0,u.default)(),function(){window.DropLab=(0,r.default)()});c(),e.default=c}]);
+//# sourceMappingURL=droplab.js.map \ No newline at end of file
diff --git a/app/assets/javascripts/droplab/droplab.js.map b/app/assets/javascripts/droplab/droplab.js.map
new file mode 100644
index 00000000000..2cb9a51b98f
--- /dev/null
+++ b/app/assets/javascripts/droplab/droplab.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///dist/droplab.js","webpack:///webpack/bootstrap 595d943f775089263f5d","webpack:///./src/constants.js","webpack:///./~/custom-event-polyfill/custom-event-polyfill.js","webpack:///./src/hook.js","webpack:///./src/utils.js","webpack:///./src/droplab.js","webpack:///./src/keyboard.js","webpack:///./src/dropdown.js","webpack:///./src/hook_button.js","webpack:///./src/hook_input.js","webpack:///./src/index.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","value","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","DATA_TRIGGER","DATA_DROPDOWN","SELECTED_CLASS","ACTIVE_CLASS","constants","default","ce","window","CustomEvent","preventDefault","defaultPrevented","Error","e","event","params","evt","origPrevent","bubbles","cancelable","detail","undefined","document","createEvent","initCustomEvent","this","Event","_interopRequireDefault","obj","_dropdown","_dropdown2","Hook","trigger","list","plugins","config","type","id","assign","addEvents","constructor","_constants","_constants2","utils","toCamelCase","attr","camelize","split","slice","join","t","replace","RegExp","str","letter","index","toLowerCase","toUpperCase","closest","thisTag","stopTag","tagName","parentNode","isDropDownParts","target","hasAttribute","DropLab","hook","ready","hooks","queuedData","eventWrapper","addHook","loadStatic","dropdownTriggers","apply","querySelectorAll","addHooks","init","addData","args","arguments","applyArgs","setData","destroy","forEach","removeEvents","methodName","push","_addData","data","_processData","_setData","Array","isArray","documentClicked","bind","addEventListener","_utils2","hide","removeEventListener","changeHookList","_this","availableTrigger","getElementById","dataset","dataDropdownActive","splice","availableHook","querySelector","availableList","Element","HookObject","_hook_input2","_hook_button2","_this2","setConfig","fireReady","readyEvent","dropdown","dispatchEvent","_this3","_hook_button","_hook_input","_utils","currentKey","isUpArrow","isDownArrow","removeHighlight","itemElements","listItems","length","listItem","classList","remove","style","display","setMenuForArrows","currentIndex","el","filterDropdownEl","add","filterDropdownBottom","offsetHeight","elOffsetTop","offsetTop","scrollTop","mousedown","show","selectItem","currentItem","listEvent","selected","keydown","which","key","_defineProperty","writable","_Object$assign","DropDown","hidden","items","getItems","initTemplateString","initialState","innerHTML","templateString","outerHTML","clickEvent","addSelectedClass","removeSelectedClasses","item","toggle","render","concat","children","map","renderChildren","html","template","createElement","setImagesSrc","firstChild","droplab_hidden","image","src","getAttribute","removeAttribute","_hook","_hook2","HookButton","addPlugins","create","plugin","clicked","buttonEvent","restoreInitialState","removePlugins","HookInput","input","keyup","hasRemovedEvents","inputEvent","text","mouseEvent","keyEvent","eventName","_droplab","_droplab2","_keyboard","_keyboard2","setup"],"mappings":"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","file":"./dist/droplab.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 9);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar DATA_TRIGGER = 'data-dropdown-trigger';\nvar DATA_DROPDOWN = 'data-dropdown';\nvar SELECTED_CLASS = 'droplab-item-selected';\nvar ACTIVE_CLASS = 'droplab-item-active';\n\nvar constants = {\n DATA_TRIGGER: DATA_TRIGGER,\n DATA_DROPDOWN: DATA_DROPDOWN,\n SELECTED_CLASS: SELECTED_CLASS,\n ACTIVE_CLASS: ACTIVE_CLASS\n};\n\nexports.default = constants;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\n// Polyfill for creating CustomEvents on IE9/10/11\n\n// code pulled from:\n// https://github.com/d4tocchini/customevent-polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill\n\ntry {\n var ce = new window.CustomEvent('test');\n ce.preventDefault();\n if (ce.defaultPrevented !== true) {\n // IE has problems with .preventDefault() on custom events\n // http://stackoverflow.com/questions/23349191\n throw new Error('Could not prevent default');\n }\n} catch(e) {\n var CustomEvent = function(event, params) {\n var evt, origPrevent;\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n\n evt = document.createEvent(\"CustomEvent\");\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n origPrevent = evt.preventDefault;\n evt.preventDefault = function () {\n origPrevent.call(this);\n try {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function () {\n return true;\n }\n });\n } catch(e) {\n this.defaultPrevented = true;\n }\n };\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n window.CustomEvent = CustomEvent; // expose definition to window\n}\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _dropdown = __webpack_require__(6);\n\nvar _dropdown2 = _interopRequireDefault(_dropdown);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar Hook = function Hook(trigger, list, plugins, config) {\n this.trigger = trigger;\n this.list = new _dropdown2.default(list);\n this.type = 'Hook';\n this.event = 'click';\n this.plugins = plugins || [];\n this.config = config || {};\n this.id = trigger.id;\n};\n\nObject.assign(Hook.prototype, {\n\n addEvents: function addEvents() {},\n\n constructor: Hook\n});\n\nexports.default = Hook;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar DATA_TRIGGER = _constants2.default.DATA_TRIGGER,\n DATA_DROPDOWN = _constants2.default.DATA_DROPDOWN;\n\n\nvar utils = {\n toCamelCase: function toCamelCase(attr) {\n return this.camelize(attr.split('-').slice(1).join(' '));\n },\n t: function t(s, d) {\n for (var p in d) {\n if (Object.prototype.hasOwnProperty.call(d, p)) {\n s = s.replace(new RegExp('{{' + p + '}}', 'g'), d[p]);\n }\n }\n return s;\n },\n camelize: function camelize(str) {\n return str.replace(/(?:^\\w|[A-Z]|\\b\\w)/g, function (letter, index) {\n return index === 0 ? letter.toLowerCase() : letter.toUpperCase();\n }).replace(/\\s+/g, '');\n },\n closest: function closest(thisTag, stopTag) {\n while (thisTag && thisTag.tagName !== stopTag && thisTag.tagName !== 'HTML') {\n thisTag = thisTag.parentNode;\n }\n return thisTag;\n },\n isDropDownParts: function isDropDownParts(target) {\n if (!target || target.tagName === 'HTML') return false;\n return target.hasAttribute(DATA_TRIGGER) || target.hasAttribute(DATA_DROPDOWN);\n }\n};\n\nexports.default = utils;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function () {\n var DropLab = function DropLab(hook, list) {\n if (!this instanceof DropLab) return new DropLab(hook);\n\n this.ready = false;\n this.hooks = [];\n this.queuedData = [];\n this.config = {};\n\n this.eventWrapper = {};\n\n !hook ? this.loadStatic() : this.addHook(hook, list);\n };\n\n Object.assign(DropLab.prototype, {\n loadStatic: function loadStatic() {\n var dropdownTriggers = [].slice.apply(document.querySelectorAll('[' + DATA_TRIGGER + ']'));\n this.addHooks(dropdownTriggers).init();\n },\n\n addData: function addData() {\n var args = [].slice.apply(arguments);\n this.applyArgs(args, '_addData');\n },\n\n setData: function setData() {\n var args = [].slice.apply(arguments);\n this.applyArgs(args, '_setData');\n },\n\n destroy: function destroy() {\n this.hooks.forEach(function (hook) {\n return hook.destroy();\n });\n this.hooks = [];\n this.removeEvents();\n },\n\n applyArgs: function applyArgs(args, methodName) {\n if (this.ready) return this[methodName].apply(this, args);\n\n this.queuedData = this.queuedData || [];\n this.queuedData.push(args);\n },\n\n _addData: function _addData(trigger, data) {\n this._processData(trigger, data, 'addData');\n },\n\n _setData: function _setData(trigger, data) {\n this._processData(trigger, data, 'setData');\n },\n\n _processData: function _processData(trigger, data, methodName) {\n this.hooks.forEach(function (hook) {\n if (Array.isArray(trigger)) hook.list[methodName](trigger);\n\n if (hook.trigger.id === trigger) hook.list[methodName](data);\n });\n },\n\n addEvents: function addEvents() {\n this.eventWrapper.documentClicked = this.documentClicked.bind(this);\n document.addEventListener('click', this.eventWrapper.documentClicked);\n },\n\n documentClicked: function documentClicked(e) {\n var thisTag = e.target;\n\n if (thisTag.tagName !== 'UL') thisTag = _utils2.default.closest(thisTag, 'UL');\n if (_utils2.default.isDropDownParts(thisTag, this.hooks) || _utils2.default.isDropDownParts(e.target, this.hooks)) return;\n\n this.hooks.forEach(function (hook) {\n return hook.list.hide();\n });\n },\n\n removeEvents: function removeEvents() {\n document.removeEventListener('click', this.eventWrapper.documentClicked);\n },\n\n changeHookList: function changeHookList(trigger, list, plugins, config) {\n var _this = this;\n\n var availableTrigger = typeof trigger === 'string' ? document.getElementById(trigger) : trigger;\n\n this.hooks.forEach(function (hook, i) {\n hook.list.list.dataset.dataDropdownActive = false;\n\n if (hook.trigger !== availableTrigger) return;\n\n hook.destroy();\n _this.hooks.splice(i, 1);\n _this.addHook(availableTrigger, list, plugins, config);\n });\n },\n\n addHook: function addHook(hook, list, plugins, config) {\n var availableHook = typeof hook === 'string' ? document.querySelector(hook) : hook;\n var availableList = void 0;\n\n if (typeof list === 'string') {\n availableList = document.querySelector(list);\n } else if (list instanceof Element) {\n availableList = list;\n } else {\n availableList = document.querySelector(hook.dataset[_utils2.default.toCamelCase(DATA_TRIGGER)]);\n }\n\n availableList.dataset.dataDropdownActive = true;\n\n var HookObject = availableHook.tagName === 'INPUT' ? _hook_input2.default : _hook_button2.default;\n this.hooks.push(new HookObject(availableHook, availableList, plugins, config));\n\n return this;\n },\n\n addHooks: function addHooks(hooks, plugins, config) {\n var _this2 = this;\n\n hooks.forEach(function (hook) {\n return _this2.addHook(hook, null, plugins, config);\n });\n return this;\n },\n\n setConfig: function setConfig(obj) {\n this.config = obj;\n },\n\n fireReady: function fireReady() {\n var readyEvent = new CustomEvent('ready.dl', {\n detail: {\n dropdown: this\n }\n });\n document.dispatchEvent(readyEvent);\n\n this.ready = true;\n },\n\n init: function init() {\n var _this3 = this;\n\n this.addEvents();\n\n this.fireReady();\n\n this.queuedData.forEach(function (data) {\n return _this3.addData(data);\n });\n this.queuedData = [];\n\n return this;\n }\n });\n\n return DropLab;\n};\n\n__webpack_require__(1);\n\nvar _hook_button = __webpack_require__(7);\n\nvar _hook_button2 = _interopRequireDefault(_hook_button);\n\nvar _hook_input = __webpack_require__(8);\n\nvar _hook_input2 = _interopRequireDefault(_hook_input);\n\nvar _utils = __webpack_require__(3);\n\nvar _utils2 = _interopRequireDefault(_utils);\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar DATA_TRIGGER = _constants2.default.DATA_TRIGGER;\n\n;\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function () {\n var currentKey;\n var currentFocus;\n var isUpArrow = false;\n var isDownArrow = false;\n var removeHighlight = function removeHighlight(list) {\n var itemElements = Array.prototype.slice.call(list.list.querySelectorAll('li:not(.divider)'), 0);\n var listItems = [];\n for (var i = 0; i < itemElements.length; i++) {\n var listItem = itemElements[i];\n listItem.classList.remove(_constants2.default.ACTIVE_CLASS);\n\n if (listItem.style.display !== 'none') {\n listItems.push(listItem);\n }\n }\n return listItems;\n };\n\n var setMenuForArrows = function setMenuForArrows(list) {\n var listItems = removeHighlight(list);\n if (list.currentIndex > 0) {\n if (!listItems[list.currentIndex - 1]) {\n list.currentIndex = list.currentIndex - 1;\n }\n\n if (listItems[list.currentIndex - 1]) {\n var el = listItems[list.currentIndex - 1];\n var filterDropdownEl = el.closest('.filter-dropdown');\n el.classList.add(_constants2.default.ACTIVE_CLASS);\n\n if (filterDropdownEl) {\n var filterDropdownBottom = filterDropdownEl.offsetHeight;\n var elOffsetTop = el.offsetTop - 30;\n\n if (elOffsetTop > filterDropdownBottom) {\n filterDropdownEl.scrollTop = elOffsetTop - filterDropdownBottom;\n }\n }\n }\n }\n };\n\n var mousedown = function mousedown(e) {\n var list = e.detail.hook.list;\n removeHighlight(list);\n list.show();\n list.currentIndex = 0;\n isUpArrow = false;\n isDownArrow = false;\n };\n var selectItem = function selectItem(list) {\n var listItems = removeHighlight(list);\n var currentItem = listItems[list.currentIndex - 1];\n var listEvent = new CustomEvent('click.dl', {\n detail: {\n list: list,\n selected: currentItem,\n data: currentItem.dataset\n }\n });\n list.list.dispatchEvent(listEvent);\n list.hide();\n };\n\n var keydown = function keydown(e) {\n var typedOn = e.target;\n var list = e.detail.hook.list;\n var currentIndex = list.currentIndex;\n isUpArrow = false;\n isDownArrow = false;\n\n if (e.detail.which) {\n currentKey = e.detail.which;\n if (currentKey === 13) {\n selectItem(e.detail.hook.list);\n return;\n }\n if (currentKey === 38) {\n isUpArrow = true;\n }\n if (currentKey === 40) {\n isDownArrow = true;\n }\n } else if (e.detail.key) {\n currentKey = e.detail.key;\n if (currentKey === 'Enter') {\n selectItem(e.detail.hook.list);\n return;\n }\n if (currentKey === 'ArrowUp') {\n isUpArrow = true;\n }\n if (currentKey === 'ArrowDown') {\n isDownArrow = true;\n }\n }\n if (isUpArrow) {\n currentIndex--;\n }\n if (isDownArrow) {\n currentIndex++;\n }\n if (currentIndex < 0) {\n currentIndex = 0;\n }\n list.currentIndex = currentIndex;\n setMenuForArrows(e.detail.hook.list);\n };\n\n document.addEventListener('mousedown.dl', mousedown);\n document.addEventListener('keydown.dl', keydown);\n};\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _Object$assign;\n\n__webpack_require__(1);\n\nvar _utils = __webpack_require__(3);\n\nvar _utils2 = _interopRequireDefault(_utils);\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar DropDown = function DropDown(list) {\n this.currentIndex = 0;\n this.hidden = true;\n this.list = typeof list === 'string' ? document.querySelector(list) : list;\n this.items = [];\n\n this.eventWrapper = {};\n\n this.getItems();\n this.initTemplateString();\n this.addEvents();\n\n this.initialState = list.innerHTML;\n};\n\nObject.assign(DropDown.prototype, (_Object$assign = {\n getItems: function getItems() {\n this.items = [].slice.call(this.list.querySelectorAll('li'));\n return this.items;\n },\n\n initTemplateString: function initTemplateString() {\n var items = this.items || this.getItems();\n\n var templateString = '';\n if (items.length > 0) templateString = items[items.length - 1].outerHTML;\n this.templateString = templateString;\n\n return this.templateString;\n },\n\n clickEvent: function clickEvent(e) {\n var selected = _utils2.default.closest(e.target, 'LI');\n if (!selected) return;\n\n this.addSelectedClass(selected);\n\n e.preventDefault();\n this.hide();\n\n var listEvent = new CustomEvent('click.dl', {\n detail: {\n list: this,\n selected: selected,\n data: e.target.dataset\n }\n });\n this.list.dispatchEvent(listEvent);\n },\n\n addSelectedClass: function addSelectedClass(selected) {\n this.removeSelectedClasses();\n selected.classList.add(_constants2.default.SELECTED_CLASS);\n },\n\n removeSelectedClasses: function removeSelectedClasses() {\n var items = this.items || this.getItems();\n\n items.forEach(function (item) {\n item.classList.remove(_constants2.default.SELECTED_CLASS);\n });\n },\n\n addEvents: function addEvents() {\n this.eventWrapper.clickEvent = this.clickEvent.bind(this);\n this.list.addEventListener('click', this.eventWrapper.clickEvent);\n },\n\n toggle: function toggle() {\n this.hidden ? this.show() : this.hide();\n },\n\n setData: function setData(data) {\n this.data = data;\n this.render(data);\n },\n\n addData: function addData(data) {\n this.data = (this.data || []).concat(data);\n this.render(this.data);\n },\n\n render: function render(data) {\n var children = data ? data.map(this.renderChildren.bind(this)) : [];\n var renderableList = this.list.querySelector('ul[data-dynamic]') || this.list;\n\n renderableList.innerHTML = children.join('');\n },\n\n renderChildren: function renderChildren(data) {\n var html = _utils2.default.t(this.templateString, data);\n var template = document.createElement('div');\n\n template.innerHTML = html;\n this.setImagesSrc(template);\n template.firstChild.style.display = data.droplab_hidden ? 'none' : 'block';\n\n return template.firstChild.outerHTML;\n },\n\n setImagesSrc: function setImagesSrc(template) {\n var images = [].slice.call(template.querySelectorAll('img[data-src]'));\n\n images.forEach(function (image) {\n image.src = image.getAttribute('data-src');\n image.removeAttribute('data-src');\n });\n },\n\n show: function show() {\n if (!this.hidden) return;\n this.list.style.display = 'block';\n this.currentIndex = 0;\n this.hidden = false;\n },\n\n hide: function hide() {\n if (this.hidden) return;\n this.list.style.display = 'none';\n this.currentIndex = 0;\n this.hidden = true;\n }\n\n}, _defineProperty(_Object$assign, 'toggle', function toggle() {\n this.hidden ? this.show() : this.hide();\n}), _defineProperty(_Object$assign, 'destroy', function destroy() {\n this.hide();\n this.list.removeEventListener('click', this.eventWrapper.clickEvent);\n}), _Object$assign));\n\nexports.default = DropDown;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\n__webpack_require__(1);\n\nvar _hook = __webpack_require__(2);\n\nvar _hook2 = _interopRequireDefault(_hook);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar HookButton = function HookButton(trigger, list, plugins, config) {\n _hook2.default.call(this, trigger, list, plugins, config);\n\n this.type = 'button';\n this.event = 'click';\n\n this.eventWrapper = {};\n\n this.addEvents();\n this.addPlugins();\n};\n\nHookButton.prototype = Object.create(_hook2.default.prototype);\n\nObject.assign(HookButton.prototype, {\n addPlugins: function addPlugins() {\n var _this = this;\n\n this.plugins.forEach(function (plugin) {\n return plugin.init(_this);\n });\n },\n\n clicked: function clicked(e) {\n var buttonEvent = new CustomEvent('click.dl', {\n detail: {\n hook: this\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(buttonEvent);\n\n this.list.toggle();\n },\n\n addEvents: function addEvents() {\n this.eventWrapper.clicked = this.clicked.bind(this);\n this.trigger.addEventListener('click', this.eventWrapper.clicked);\n },\n\n removeEvents: function removeEvents() {\n this.trigger.removeEventListener('click', this.eventWrapper.clicked);\n },\n\n restoreInitialState: function restoreInitialState() {\n this.list.list.innerHTML = this.list.initialState;\n },\n\n removePlugins: function removePlugins() {\n this.plugins.forEach(function (plugin) {\n return plugin.destroy();\n });\n },\n\n destroy: function destroy() {\n this.restoreInitialState();\n\n this.removeEvents();\n this.removePlugins();\n },\n\n constructor: HookButton\n});\n\nexports.default = HookButton;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\n__webpack_require__(1);\n\nvar _hook = __webpack_require__(2);\n\nvar _hook2 = _interopRequireDefault(_hook);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar HookInput = function HookInput(trigger, list, plugins, config) {\n _hook2.default.call(this, trigger, list, plugins, config);\n\n this.type = 'input';\n this.event = 'input';\n\n this.eventWrapper = {};\n\n this.addEvents();\n this.addPlugins();\n};\n\nObject.assign(HookInput.prototype, {\n addPlugins: function addPlugins() {\n var _this = this;\n\n this.plugins.forEach(function (plugin) {\n return plugin.init(_this);\n });\n },\n\n addEvents: function addEvents() {\n this.eventWrapper.mousedown = this.mousedown.bind(this);\n this.eventWrapper.input = this.input.bind(this);\n this.eventWrapper.keyup = this.keyup.bind(this);\n this.eventWrapper.keydown = this.keydown.bind(this);\n\n this.trigger.addEventListener('mousedown', this.eventWrapper.mousedown);\n this.trigger.addEventListener('input', this.eventWrapper.input);\n this.trigger.addEventListener('keyup', this.eventWrapper.keyup);\n this.trigger.addEventListener('keydown', this.eventWrapper.keydown);\n },\n\n removeEvents: function removeEvents() {\n this.hasRemovedEvents = true;\n\n this.trigger.removeEventListener('mousedown', this.eventWrapper.mousedown);\n this.trigger.removeEventListener('input', this.eventWrapper.input);\n this.trigger.removeEventListener('keyup', this.eventWrapper.keyup);\n this.trigger.removeEventListener('keydown', this.eventWrapper.keydown);\n },\n\n input: function input(e) {\n if (this.hasRemovedEvents) return;\n\n this.list.show();\n\n var inputEvent = new CustomEvent('input.dl', {\n detail: {\n hook: this,\n text: e.target.value\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(inputEvent);\n },\n\n mousedown: function mousedown(e) {\n if (this.hasRemovedEvents) return;\n\n var mouseEvent = new CustomEvent('mousedown.dl', {\n detail: {\n hook: this,\n text: e.target.value\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(mouseEvent);\n },\n\n keyup: function keyup(e) {\n if (this.hasRemovedEvents) return;\n\n this.keyEvent(e, 'keyup.dl');\n },\n\n keydown: function keydown(e) {\n if (this.hasRemovedEvents) return;\n\n this.keyEvent(e, 'keydown.dl');\n },\n\n keyEvent: function keyEvent(e, eventName) {\n this.list.show();\n\n var keyEvent = new CustomEvent(eventName, {\n detail: {\n hook: this,\n text: e.target.value,\n which: e.which,\n key: e.key\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(keyEvent);\n },\n\n restoreInitialState: function restoreInitialState() {\n this.list.list.innerHTML = this.list.initialState;\n },\n\n removePlugins: function removePlugins() {\n this.plugins.forEach(function (plugin) {\n return plugin.destroy();\n });\n },\n\n destroy: function destroy() {\n this.restoreInitialState();\n\n this.removeEvents();\n this.removePlugins();\n\n this.list.destroy();\n }\n});\n\nexports.default = HookInput;\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _droplab = __webpack_require__(4);\n\nvar _droplab2 = _interopRequireDefault(_droplab);\n\nvar _constants = __webpack_require__(0);\n\nvar _constants2 = _interopRequireDefault(_constants);\n\nvar _keyboard = __webpack_require__(5);\n\nvar _keyboard2 = _interopRequireDefault(_keyboard);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar DATA_TRIGGER = _constants2.default.DATA_TRIGGER;\nvar keyboard = (0, _keyboard2.default)();\n\nvar setup = function setup() {\n window.DropLab = (0, _droplab2.default)();\n};\n\nsetup();\n\nexports.default = setup;\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// dist/droplab.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 9);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 595d943f775089263f5d","const DATA_TRIGGER = 'data-dropdown-trigger';\nconst DATA_DROPDOWN = 'data-dropdown';\nconst SELECTED_CLASS = 'droplab-item-selected';\nconst ACTIVE_CLASS = 'droplab-item-active';\n\nconst constants = {\n DATA_TRIGGER,\n DATA_DROPDOWN,\n SELECTED_CLASS,\n ACTIVE_CLASS,\n};\n\nexport default constants;\n\n\n\n// WEBPACK FOOTER //\n// ./src/constants.js","// Polyfill for creating CustomEvents on IE9/10/11\n\n// code pulled from:\n// https://github.com/d4tocchini/customevent-polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill\n\ntry {\n var ce = new window.CustomEvent('test');\n ce.preventDefault();\n if (ce.defaultPrevented !== true) {\n // IE has problems with .preventDefault() on custom events\n // http://stackoverflow.com/questions/23349191\n throw new Error('Could not prevent default');\n }\n} catch(e) {\n var CustomEvent = function(event, params) {\n var evt, origPrevent;\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n\n evt = document.createEvent(\"CustomEvent\");\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n origPrevent = evt.preventDefault;\n evt.preventDefault = function () {\n origPrevent.call(this);\n try {\n Object.defineProperty(this, 'defaultPrevented', {\n get: function () {\n return true;\n }\n });\n } catch(e) {\n this.defaultPrevented = true;\n }\n };\n return evt;\n };\n\n CustomEvent.prototype = window.Event.prototype;\n window.CustomEvent = CustomEvent; // expose definition to window\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/custom-event-polyfill/custom-event-polyfill.js\n// module id = 1\n// module chunks = 0","import DropDown from './dropdown';\n\nvar Hook = function(trigger, list, plugins, config){\n this.trigger = trigger;\n this.list = new DropDown(list);\n this.type = 'Hook';\n this.event = 'click';\n this.plugins = plugins || [];\n this.config = config || {};\n this.id = trigger.id;\n};\n\nObject.assign(Hook.prototype, {\n\n addEvents: function(){},\n\n constructor: Hook,\n});\n\nexport default Hook;\n\n\n\n// WEBPACK FOOTER //\n// ./src/hook.js","import constants from './constants';\n\nconst { DATA_TRIGGER, DATA_DROPDOWN } = constants;\n\nconst utils = {\n toCamelCase(attr) {\n return this.camelize(attr.split('-').slice(1).join(' '));\n },\n\n t(s, d) {\n for (const p in d) {\n if (Object.prototype.hasOwnProperty.call(d, p)) {\n s = s.replace(new RegExp(`{{${p}}}`, 'g'), d[p]);\n }\n }\n return s;\n },\n\n camelize(str) {\n return str.replace(/(?:^\\w|[A-Z]|\\b\\w)/g, (letter, index) => {\n return index === 0 ? letter.toLowerCase() : letter.toUpperCase();\n }).replace(/\\s+/g, '');\n },\n\n closest(thisTag, stopTag) {\n while (thisTag && thisTag.tagName !== stopTag && thisTag.tagName !== 'HTML') {\n thisTag = thisTag.parentNode;\n }\n return thisTag;\n },\n\n isDropDownParts(target) {\n if (!target || target.tagName === 'HTML') return false;\n return target.hasAttribute(DATA_TRIGGER) || target.hasAttribute(DATA_DROPDOWN);\n },\n};\n\n\nexport default utils;\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils.js","import 'custom-event-polyfill';\nimport HookButton from './hook_button';\nimport HookInput from './hook_input';\nimport utils from './utils';\nimport constants from './constants';\nconst DATA_TRIGGER = constants.DATA_TRIGGER;\n\nexport default function () {\n var DropLab = function(hook, list) {\n if (!this instanceof DropLab) return new DropLab(hook);\n\n this.ready = false;\n this.hooks = [];\n this.queuedData = [];\n this.config = {};\n\n this.eventWrapper = {};\n\n !hook ? this.loadStatic() : this.addHook(hook, list);\n };\n\n Object.assign(DropLab.prototype, {\n loadStatic: function(){\n var dropdownTriggers = [].slice.apply(document.querySelectorAll(`[${DATA_TRIGGER}]`));\n this.addHooks(dropdownTriggers).init();\n },\n\n addData: function () {\n var args = [].slice.apply(arguments);\n this.applyArgs(args, '_addData');\n },\n\n setData: function() {\n var args = [].slice.apply(arguments);\n this.applyArgs(args, '_setData');\n },\n\n destroy: function() {\n this.hooks.forEach(hook => hook.destroy());\n this.hooks = [];\n this.removeEvents();\n },\n\n applyArgs: function(args, methodName) {\n if (this.ready) return this[methodName].apply(this, args);\n\n this.queuedData = this.queuedData || [];\n this.queuedData.push(args);\n },\n\n _addData: function(trigger, data) {\n this._processData(trigger, data, 'addData');\n },\n\n _setData: function(trigger, data) {\n this._processData(trigger, data, 'setData');\n },\n\n _processData: function(trigger, data, methodName) {\n this.hooks.forEach((hook) => {\n if (Array.isArray(trigger)) hook.list[methodName](trigger);\n\n if (hook.trigger.id === trigger) hook.list[methodName](data);\n });\n },\n\n addEvents: function() {\n this.eventWrapper.documentClicked = this.documentClicked.bind(this)\n document.addEventListener('click', this.eventWrapper.documentClicked);\n },\n\n documentClicked: function(e) {\n let thisTag = e.target;\n\n if (thisTag.tagName !== 'UL') thisTag = utils.closest(thisTag, 'UL');\n if (utils.isDropDownParts(thisTag, this.hooks) || utils.isDropDownParts(e.target, this.hooks)) return;\n\n this.hooks.forEach(hook => hook.list.hide());\n },\n\n removeEvents: function(){\n document.removeEventListener('click', this.eventWrapper.documentClicked);\n },\n\n changeHookList: function(trigger, list, plugins, config) {\n const availableTrigger = typeof trigger === 'string' ? document.getElementById(trigger) : trigger;\n\n\n this.hooks.forEach((hook, i) => {\n hook.list.list.dataset.dataDropdownActive = false;\n\n if (hook.trigger !== availableTrigger) return;\n\n hook.destroy();\n this.hooks.splice(i, 1);\n this.addHook(availableTrigger, list, plugins, config);\n });\n },\n\n addHook: function(hook, list, plugins, config) {\n const availableHook = typeof hook === 'string' ? document.querySelector(hook) : hook;\n let availableList;\n\n if (typeof list === 'string') {\n availableList = document.querySelector(list);\n } else if (list instanceof Element) {\n availableList = list;\n } else {\n availableList = document.querySelector(hook.dataset[utils.toCamelCase(DATA_TRIGGER)]);\n }\n\n availableList.dataset.dataDropdownActive = true;\n\n const HookObject = availableHook.tagName === 'INPUT' ? HookInput : HookButton;\n this.hooks.push(new HookObject(availableHook, availableList, plugins, config));\n\n return this;\n },\n\n addHooks: function(hooks, plugins, config) {\n hooks.forEach(hook => this.addHook(hook, null, plugins, config));\n return this;\n },\n\n setConfig: function(obj){\n this.config = obj;\n },\n\n fireReady: function() {\n const readyEvent = new CustomEvent('ready.dl', {\n detail: {\n dropdown: this,\n },\n });\n document.dispatchEvent(readyEvent);\n\n this.ready = true;\n },\n\n init: function () {\n this.addEvents();\n\n this.fireReady();\n\n this.queuedData.forEach(data => this.addData(data));\n this.queuedData = [];\n\n return this;\n },\n });\n\n return DropLab;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/droplab.js","import constants from './constants';\n\nexport default function () {\n var currentKey;\n var currentFocus;\n var isUpArrow = false;\n var isDownArrow = false;\n var removeHighlight = function removeHighlight(list) {\n var itemElements = Array.prototype.slice.call(list.list.querySelectorAll('li:not(.divider)'), 0);\n var listItems = [];\n for(var i = 0; i < itemElements.length; i++) {\n var listItem = itemElements[i];\n listItem.classList.remove(constants.ACTIVE_CLASS);\n\n if (listItem.style.display !== 'none') {\n listItems.push(listItem);\n }\n }\n return listItems;\n };\n\n var setMenuForArrows = function setMenuForArrows(list) {\n var listItems = removeHighlight(list);\n if(list.currentIndex>0){\n if(!listItems[list.currentIndex-1]){\n list.currentIndex = list.currentIndex-1;\n }\n\n if (listItems[list.currentIndex-1]) {\n var el = listItems[list.currentIndex-1];\n var filterDropdownEl = el.closest('.filter-dropdown');\n el.classList.add(constants.ACTIVE_CLASS);\n\n if (filterDropdownEl) {\n var filterDropdownBottom = filterDropdownEl.offsetHeight;\n var elOffsetTop = el.offsetTop - 30;\n\n if (elOffsetTop > filterDropdownBottom) {\n filterDropdownEl.scrollTop = elOffsetTop - filterDropdownBottom;\n }\n }\n }\n }\n };\n\n var mousedown = function mousedown(e) {\n var list = e.detail.hook.list;\n removeHighlight(list);\n list.show();\n list.currentIndex = 0;\n isUpArrow = false;\n isDownArrow = false;\n };\n var selectItem = function selectItem(list) {\n var listItems = removeHighlight(list);\n var currentItem = listItems[list.currentIndex-1];\n var listEvent = new CustomEvent('click.dl', {\n detail: {\n list: list,\n selected: currentItem,\n data: currentItem.dataset,\n },\n });\n list.list.dispatchEvent(listEvent);\n list.hide();\n }\n\n var keydown = function keydown(e){\n var typedOn = e.target;\n var list = e.detail.hook.list;\n var currentIndex = list.currentIndex;\n isUpArrow = false;\n isDownArrow = false;\n\n if(e.detail.which){\n currentKey = e.detail.which;\n if(currentKey === 13){\n selectItem(e.detail.hook.list);\n return;\n }\n if(currentKey === 38) {\n isUpArrow = true;\n }\n if(currentKey === 40) {\n isDownArrow = true;\n }\n } else if(e.detail.key) {\n currentKey = e.detail.key;\n if(currentKey === 'Enter'){\n selectItem(e.detail.hook.list);\n return;\n }\n if(currentKey === 'ArrowUp') {\n isUpArrow = true;\n }\n if(currentKey === 'ArrowDown') {\n isDownArrow = true;\n }\n }\n if(isUpArrow){ currentIndex--; }\n if(isDownArrow){ currentIndex++; }\n if(currentIndex < 0){ currentIndex = 0; }\n list.currentIndex = currentIndex;\n setMenuForArrows(e.detail.hook.list);\n };\n\n document.addEventListener('mousedown.dl', mousedown);\n document.addEventListener('keydown.dl', keydown);\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/keyboard.js","import 'custom-event-polyfill';\nimport utils from './utils';\nimport constants from '../src/constants';\n\nvar DropDown = function(list) {\n this.currentIndex = 0;\n this.hidden = true;\n this.list = typeof list === 'string' ? document.querySelector(list) : list;\n this.items = [];\n\n this.eventWrapper = {};\n\n this.getItems();\n this.initTemplateString();\n this.addEvents();\n\n this.initialState = list.innerHTML;\n};\n\nObject.assign(DropDown.prototype, {\n getItems: function() {\n this.items = [].slice.call(this.list.querySelectorAll('li'));\n return this.items;\n },\n\n initTemplateString: function() {\n var items = this.items || this.getItems();\n\n var templateString = '';\n if (items.length > 0) templateString = items[items.length - 1].outerHTML;\n this.templateString = templateString;\n\n return this.templateString;\n },\n\n clickEvent: function(e) {\n var selected = utils.closest(e.target, 'LI');\n if (!selected) return;\n\n this.addSelectedClass(selected);\n\n e.preventDefault();\n this.hide();\n\n var listEvent = new CustomEvent('click.dl', {\n detail: {\n list: this,\n selected: selected,\n data: e.target.dataset,\n },\n });\n this.list.dispatchEvent(listEvent);\n },\n\n addSelectedClass: function (selected) {\n this.removeSelectedClasses();\n selected.classList.add(constants.SELECTED_CLASS);\n },\n\n removeSelectedClasses: function () {\n const items = this.items || this.getItems();\n\n items.forEach((item) => {\n item.classList.remove(constants.SELECTED_CLASS)\n });\n },\n\n addEvents: function() {\n this.eventWrapper.clickEvent = this.clickEvent.bind(this)\n this.list.addEventListener('click', this.eventWrapper.clickEvent);\n },\n\n toggle: function() {\n this.hidden ? this.show() : this.hide();\n },\n\n setData: function(data) {\n this.data = data;\n this.render(data);\n },\n\n addData: function(data) {\n this.data = (this.data || []).concat(data);\n this.render(this.data);\n },\n\n render: function(data) {\n const children = data ? data.map(this.renderChildren.bind(this)) : [];\n const renderableList = this.list.querySelector('ul[data-dynamic]') || this.list;\n\n renderableList.innerHTML = children.join('');\n },\n\n renderChildren: function(data) {\n var html = utils.t(this.templateString, data);\n var template = document.createElement('div');\n\n template.innerHTML = html;\n this.setImagesSrc(template);\n template.firstChild.style.display = data.droplab_hidden ? 'none' : 'block';\n\n return template.firstChild.outerHTML;\n },\n\n setImagesSrc: function(template) {\n const images = [].slice.call(template.querySelectorAll('img[data-src]'));\n\n images.forEach((image) => {\n image.src = image.getAttribute('data-src');\n image.removeAttribute('data-src');\n });\n },\n\n show: function() {\n if (!this.hidden) return;\n this.list.style.display = 'block';\n this.currentIndex = 0;\n this.hidden = false;\n },\n\n hide: function() {\n if (this.hidden) return;\n this.list.style.display = 'none';\n this.currentIndex = 0;\n this.hidden = true;\n },\n\n toggle: function () {\n this.hidden ? this.show() : this.hide();\n },\n\n destroy: function() {\n this.hide();\n this.list.removeEventListener('click', this.eventWrapper.clickEvent);\n }\n});\n\nexport default DropDown;\n\n\n\n// WEBPACK FOOTER //\n// ./src/dropdown.js","import 'custom-event-polyfill';\nimport Hook from './hook';\n\nvar HookButton = function(trigger, list, plugins, config) {\n Hook.call(this, trigger, list, plugins, config);\n\n this.type = 'button';\n this.event = 'click';\n\n this.eventWrapper = {};\n\n this.addEvents();\n this.addPlugins();\n};\n\nHookButton.prototype = Object.create(Hook.prototype);\n\nObject.assign(HookButton.prototype, {\n addPlugins: function() {\n this.plugins.forEach(plugin => plugin.init(this));\n },\n\n clicked: function(e){\n var buttonEvent = new CustomEvent('click.dl', {\n detail: {\n hook: this,\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(buttonEvent);\n\n this.list.toggle();\n },\n\n addEvents: function(){\n this.eventWrapper.clicked = this.clicked.bind(this);\n this.trigger.addEventListener('click', this.eventWrapper.clicked);\n },\n\n removeEvents: function(){\n this.trigger.removeEventListener('click', this.eventWrapper.clicked);\n },\n\n restoreInitialState: function() {\n this.list.list.innerHTML = this.list.initialState;\n },\n\n removePlugins: function() {\n this.plugins.forEach(plugin => plugin.destroy());\n },\n\n destroy: function() {\n this.restoreInitialState();\n\n this.removeEvents();\n this.removePlugins();\n },\n\n constructor: HookButton,\n});\n\n\nexport default HookButton;\n\n\n\n// WEBPACK FOOTER //\n// ./src/hook_button.js","import 'custom-event-polyfill';\nimport Hook from './hook';\n\nvar HookInput = function(trigger, list, plugins, config) {\n Hook.call(this, trigger, list, plugins, config);\n\n this.type = 'input';\n this.event = 'input';\n\n this.eventWrapper = {};\n\n this.addEvents();\n this.addPlugins();\n};\n\nObject.assign(HookInput.prototype, {\n addPlugins: function() {\n this.plugins.forEach(plugin => plugin.init(this));\n },\n\n addEvents: function(){\n this.eventWrapper.mousedown = this.mousedown.bind(this);\n this.eventWrapper.input = this.input.bind(this);\n this.eventWrapper.keyup = this.keyup.bind(this);\n this.eventWrapper.keydown = this.keydown.bind(this);\n\n this.trigger.addEventListener('mousedown', this.eventWrapper.mousedown);\n this.trigger.addEventListener('input', this.eventWrapper.input);\n this.trigger.addEventListener('keyup', this.eventWrapper.keyup);\n this.trigger.addEventListener('keydown', this.eventWrapper.keydown);\n },\n\n removeEvents: function() {\n this.hasRemovedEvents = true;\n\n this.trigger.removeEventListener('mousedown', this.eventWrapper.mousedown);\n this.trigger.removeEventListener('input', this.eventWrapper.input);\n this.trigger.removeEventListener('keyup', this.eventWrapper.keyup);\n this.trigger.removeEventListener('keydown', this.eventWrapper.keydown);\n },\n\n input: function(e) {\n if(this.hasRemovedEvents) return;\n\n this.list.show();\n\n const inputEvent = new CustomEvent('input.dl', {\n detail: {\n hook: this,\n text: e.target.value,\n },\n bubbles: true,\n cancelable: true\n });\n e.target.dispatchEvent(inputEvent);\n },\n\n mousedown: function(e) {\n if (this.hasRemovedEvents) return;\n\n const mouseEvent = new CustomEvent('mousedown.dl', {\n detail: {\n hook: this,\n text: e.target.value,\n },\n bubbles: true,\n cancelable: true,\n });\n e.target.dispatchEvent(mouseEvent);\n },\n\n keyup: function(e) {\n if (this.hasRemovedEvents) return;\n\n this.keyEvent(e, 'keyup.dl');\n },\n\n keydown: function(e) {\n if (this.hasRemovedEvents) return;\n\n this.keyEvent(e, 'keydown.dl');\n },\n\n keyEvent: function(e, eventName) {\n this.list.show();\n\n const keyEvent = new CustomEvent(eventName, {\n detail: {\n hook: this,\n text: e.target.value,\n which: e.which,\n key: e.key,\n },\n bubbles: true,\n cancelable: true,\n });\n e.target.dispatchEvent(keyEvent);\n },\n\n restoreInitialState: function() {\n this.list.list.innerHTML = this.list.initialState;\n },\n\n removePlugins: function() {\n this.plugins.forEach(plugin => plugin.destroy());\n },\n\n destroy: function() {\n this.restoreInitialState();\n\n this.removeEvents();\n this.removePlugins();\n\n this.list.destroy();\n }\n});\n\nexport default HookInput;\n\n\n\n// WEBPACK FOOTER //\n// ./src/hook_input.js","import DropLab from './droplab';\nimport constants from './constants';\nimport Keyboard from './keyboard';\n\nconst DATA_TRIGGER = constants.DATA_TRIGGER;\nconst keyboard = Keyboard();\n\nconst setup = function () {\n window.DropLab = DropLab();\n};\n\nsetup();\n\nexport default setup\n\n\n\n// WEBPACK FOOTER //\n// ./src/index.js"],"sourceRoot":""} \ No newline at end of file
diff --git a/app/assets/javascripts/droplab/droplab_infinite_scroll.js b/app/assets/javascripts/droplab/droplab_infinite_scroll.js
new file mode 100644
index 00000000000..7e21b580286
--- /dev/null
+++ b/app/assets/javascripts/droplab/droplab_infinite_scroll.js
@@ -0,0 +1,119 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.droplab||(g.droplab = {}));g=(g.infiniteScroll||(g.infiniteScroll = {}));g.js = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+/* global droplab */
+require('../window')(function(w){
+ w.droplabInfiniteScroll = {
+ timeout: 0,
+ isLoading: false,
+ nonCharacterKeys: [16, 17, 18, 20, 37, 38, 39, 40, 91, 93],
+
+ init: function init(hook) {
+ this.hook = hook;
+ this.config = hook.config;
+
+ if (!w.droplabAjax) throw new Error('No droplabAjax plugin found.');
+ if (!this.config || !this.config.droplabInfiniteScroll.paginationKey) {
+ throw new Error('Invalid droplabInfiniteScroll config.');
+ }
+
+ if (!this.config.droplabAjax.params) this.config.droplabAjax.params = {};
+
+ this.bindEvents();
+ },
+
+ bindEvents: function bindEvents() {
+ var trigger = this.hook.trigger;
+ var list = this.hook.list.list;
+
+ list.addEventListener('scroll', this.debounceScroll.bind(this));
+ list.addEventListener('mouseenter', this.disableParentScroll);
+ list.addEventListener('mouseleave', this.enableParentScroll);
+ trigger.addEventListener('keydown.dl', this.reset.bind(this));
+ trigger.addEventListener('blur', this.hook.list.hide.bind(this.hook.list));
+ },
+
+ unbindEvents: function unbindEvents() {
+ var trigger = this.hook.trigger;
+ var list = this.hook.list.list;
+
+ list.removeEventListener('scroll', this.debounceScroll);
+ list.removeEventListener('mouseenter', this.disableParentScroll);
+ list.removeEventListener('mouseleave', this.enableParentScroll);
+ trigger.removeEventListener('keydown.dl', this.reset);
+ trigger.removeEventListener('blur', this.hook.list.hide);
+ },
+
+ destroy: function destroy() {
+ this.unbindEvents();
+ },
+
+ debounceScroll: function debounceScroll(e) {
+ if (this.timeout) clearTimeout(this.timeout);
+ if (this.isLoading) return;
+
+ this.timeout = setTimeout(this.loadNextPage.bind(this, e), 400);
+ },
+
+ debounceReset: function debounceReset(e) {
+ if (this.resetTimeout) clearTimeout(this.resetTimeout);
+ this.resetTimeout = setTimeout(this.reset.bind(this, e), 400);
+ },
+
+ disableParentScroll: function disableParentScroll() {
+ document.body.style.overflow = 'hidden';
+ document.documentElement.style.overflow = 'hidden';
+ },
+
+ enableParentScroll: function enableParentScroll() {
+ document.body.style.overflow = '';
+ document.documentElement.style.overflow = '';
+ },
+
+ reset: function reset(e) {
+ if (this.isNonCharacterKey(e)) return;
+
+ this.config.droplabAjax.params[this.config.droplabInfiniteScroll.paginationKey] = 1;
+
+ this.hook.list.list.scrollTop = 0;
+ },
+
+ loadNextPage: function loadNextPage(e) {
+ this.isLoading = true;
+
+ var target = e.target;
+ var shouldNotLoad = target.scrollTop < target.scrollHeight - target.offsetHeight;
+
+ if (shouldNotLoad) return this.requestCallback();
+
+ var searchValue = this.hook.trigger.value;
+ var params = this.config.droplabAjax.params || (this.config.droplabAjax.params = {});
+ var paginationKey = this.config.droplabInfiniteScroll.paginationKey || (this.config.droplabInfiniteScroll.paginationKey = {});
+
+ params[paginationKey] = parseInt(params[paginationKey]) + 1 || 1;
+ w.droplabAjax.load('addData', this.requestCallback.bind(this));
+ },
+
+ requestCallback: function requestCallback(data, req) {
+ var params = this.config.droplabAjax.params || (this.config.droplabAjax.params = {});
+ var paginationKey = this.config.droplabInfiniteScroll.paginationKey;
+
+ if (data && data.length === 0) params[paginationKey] = parseInt(params[paginationKey]) - 1 || 1;
+
+ this.isLoading = false;
+ },
+
+ isNonCharacterKey: function isNonCharacterKey(e) {
+ var key = e.detail.which || e.detail.keyCode;
+ return this.nonCharacterKeys.indexOf(key) > -1;
+ },
+ };
+});
+
+},{"../window":2}],2:[function(require,module,exports){
+module.exports = function(callback) {
+ return (function() {
+ callback(this);
+ }).call(null);
+};
+
+},{}]},{},[1])(1)
+});
diff --git a/app/assets/javascripts/droplab/droplab_input_setter.js b/app/assets/javascripts/droplab/droplab_input_setter.js
new file mode 100644
index 00000000000..e45b6334819
--- /dev/null
+++ b/app/assets/javascripts/droplab/droplab_input_setter.js
@@ -0,0 +1,41 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.droplab||(g.droplab = {}));g=(g.inputSetter||(g.inputSetter = {}));g.js = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+/* global droplab */
+
+require('../window')(function(w){
+ w.droplabInputSetter = {
+
+ init: function init(hookInput) {
+ this.config = hookInput.config.droplabInputSetter || (hookInput.config.droplabInputSetter = {});
+ this.hookInput = hookInput;
+ this.hookInput.list.list.addEventListener('click.dl', this.setInput.bind(this));
+ },
+
+ setInput: function setInput(e) {
+ var selected = e.detail.selected;
+ var textContent = selected.textContent;
+ if (!Array.isArray(this.config)) this.config = [this.config];
+
+ this.config.forEach(function(config) {
+ var input = config.input || this.hookInput.trigger;
+
+ if (config.valueAttribute) textContent = selected.getAttribute(config.valueAttribute);
+
+ input.value = textContent;
+ }.bind(this));
+ },
+
+ destroy: function destroy() {
+ this.hookInput.list.list.addEventListener('click.dl', this.setInput);
+ }
+ };
+});
+
+},{"../window":2}],2:[function(require,module,exports){
+module.exports = function(callback) {
+ return (function() {
+ callback(this);
+ }).call(null);
+};
+
+},{}]},{},[1])(1)
+});
diff --git a/app/assets/javascripts/droplab/droplab_remote_filter.js b/app/assets/javascripts/droplab/droplab_remote_filter.js
new file mode 100644
index 00000000000..66f4b190fa7
--- /dev/null
+++ b/app/assets/javascripts/droplab/droplab_remote_filter.js
@@ -0,0 +1,85 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g=(g.droplab||(g.droplab = {}));g=(g.remoteFilter||(g.remoteFilter = {}));g.js = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+/* global droplab */
+require('../window')(function(w){
+ w.droplabRemoteFilter = {
+ timeout: 0,
+ nonCharacterKeys: [16, 17, 18, 20, 37, 38, 39, 40, 91, 93],
+
+ init: function init(hook) {
+ this.hook = hook;
+ this.config = hook.config;
+
+ if (!w.droplabAjax) throw new Error('No droplabAjax plugin found.');
+ if (!this.config || !this.config.droplabRemoteFilter.searchKey) {
+ throw new Error('Invalid droplabRemoteFilter config.');
+ }
+
+ if (!this.config.droplabAjax.params) this.config.droplabAjax.params = {};
+
+ this.bindEvents();
+
+ if (!this.config.droplabAjax.deferRequest) this.debounceTriggerRequest();
+ },
+
+ bindEvents: function bindEvents() {
+ var trigger = this.hook.trigger;
+
+ trigger.addEventListener('keydown.dl', this.debounceTriggerRequest.bind(this));
+ trigger.addEventListener('focus', this.debounceTriggerRequest.bind(this));
+ trigger.addEventListener('blur', this.hook.list.hide.bind(this.hook.list));
+ },
+
+ unbindEvents: function unbindEvents() {
+ var trigger = this.hook.trigger;
+
+ trigger.removeEventListener('keydown.dl', this.debounceTriggerRequest);
+ trigger.removeEventListener('focus', this.debounceTriggerRequest);
+ trigger.removeEventListener('blur', this.hook.list.hide);
+ },
+
+ destroy: function destroy() {
+ this.unbindEvents();
+ },
+
+ debounceTriggerRequest: function debounceTriggerRequest(e) {
+ if (this.isNonCharacterKey(e)) return;
+
+ if (this.timeout) clearTimeout(this.timeout);
+ this.timeout = setTimeout(this.triggerRequest.bind(this), 400);
+ },
+
+ triggerRequest: function triggerRequest() {
+ var searchValue = this.formatValue(this.hook.trigger.value);
+ var searchKey = this.config.droplabRemoteFilter.searchKey;
+ var params = this.config.droplabAjax.params;
+
+ if (searchValue === params[searchKey]) return this.hook.list.show();
+ params[searchKey] = searchValue;
+
+ return w.droplabAjax.load('setData');
+ },
+
+ formatValue: function formatValue(value) {
+ if (this.config.droplabRemoteFilter.formatValue) {
+ return this.config.droplabRemoteFilter.formatValue(value);
+ }
+ return value;
+ },
+
+ isNonCharacterKey: function isNonCharacterKey(e) {
+ if (!e) return false;
+ var key = e.detail.which || e.detail.keyCode;
+ return this.nonCharacterKeys.indexOf(key) > -1;
+ },
+ };
+});
+
+},{"../window":2}],2:[function(require,module,exports){
+module.exports = function(callback) {
+ return (function() {
+ callback(this);
+ }).call(null);
+};
+
+},{}]},{},[1])(1)
+});
diff --git a/app/assets/javascripts/droplab/plugins/ajax.js b/app/assets/javascripts/droplab/plugins/ajax.js
index cf30c3b403d..09be0c355c6 100644
--- a/app/assets/javascripts/droplab/plugins/ajax.js
+++ b/app/assets/javascripts/droplab/plugins/ajax.js
@@ -1 +1,2 @@
-!function(n){function e(a){if(t[a])return t[a].exports;var o=t[a]={i:a,l:!1,exports:{}};return n[a].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var t={};e.m=n,e.c=t,e.i=function(n){return n},e.d=function(n,t,a){e.o(n,t)||Object.defineProperty(n,t,{configurable:!1,enumerable:!0,get:a})},e.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(t,"a",t),t},e.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},e.p="",e(e.s=10)}({10:function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nfunction droplabAjaxException(message) {\n this.message = message;\n}\n\nvar droplabAjax = {\n _loadUrlData: function _loadUrlData(url) {\n var self = this;\n return new Promise(function (resolve, reject) {\n var xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.onreadystatechange = function () {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n if (xhr.status === 200) {\n var data = JSON.parse(xhr.responseText);\n self.cache[url] = data;\n return resolve(data);\n } else {\n return reject([xhr.responseText, xhr.status]);\n }\n }\n };\n xhr.send();\n });\n },\n _loadData: function _loadData(data, config, self) {\n if (config.loadingTemplate) {\n var dataLoadingTemplate = self.hook.list.list.querySelector('[data-loading-template]');\n if (dataLoadingTemplate) {\n dataLoadingTemplate.outerHTML = self.listTemplate;\n }\n }\n self.hook.list[config.method].call(self.hook.list, data);\n },\n init: function init(hook) {\n var self = this;\n self.cache = self.cache || {};\n var config = hook.config.droplabAjax;\n this.hook = hook;\n if (!config || !config.endpoint || !config.method) {\n return;\n }\n if (config.method !== 'setData' && config.method !== 'addData') {\n return;\n }\n if (config.loadingTemplate) {\n var dynamicList = hook.list.list.querySelector('[data-dynamic]');\n var loadingTemplate = document.createElement('div');\n loadingTemplate.innerHTML = config.loadingTemplate;\n loadingTemplate.setAttribute('data-loading-template', '');\n this.listTemplate = dynamicList.outerHTML;\n dynamicList.outerHTML = loadingTemplate.outerHTML;\n }\n if (self.cache[config.endpoint]) {\n self._loadData(self.cache[config.endpoint], config, self);\n } else {\n this._loadUrlData(config.endpoint).then(function (d) {\n self._loadData(d, config, self);\n }).catch(function (e) {\n throw new droplabAjaxException(e.message || e);\n });\n }\n },\n destroy: function destroy() {\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n if (this.listTemplate && dynamicList) {\n dynamicList.outerHTML = this.listTemplate;\n }\n }\n};\n\nwindow.droplabAjax = droplabAjax;\n\nexports.default = droplabAjax;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/plugins/ajax.js\n// module id = 10\n// module chunks = 3\n\n//# sourceURL=webpack:///./src/plugins/ajax.js?")}}); \ No newline at end of file
+!function(t){function e(n){if(a[n])return a[n].exports;var o=a[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,e),o.l=!0,o.exports}var a={};e.m=t,e.c=a,e.i=function(t){return t},e.d=function(t,a,n){e.o(t,a)||Object.defineProperty(t,a,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var a=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(a,"a",a),a},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=10)}({10:function(t,e,a){"use strict";function n(t){this.message=t}Object.defineProperty(e,"__esModule",{value:!0});var o={_loadUrlData:function(t){var e=this;return new Promise(function(a,n){var o=new XMLHttpRequest;o.open("GET",t,!0),o.onreadystatechange=function(){if(o.readyState===XMLHttpRequest.DONE){if(200===o.status){var r=JSON.parse(o.responseText);return e.cache[t]=r,a(r)}return n([o.responseText,o.status])}},o.send()})},_loadData:function(t,e,a){if(e.loadingTemplate){var n=a.hook.list.list.querySelector("[data-loading-template]");n&&(n.outerHTML=a.listTemplate)}a.hook.list[e.method].call(a.hook.list,t)},init:function(t){var e=this;e.cache=e.cache||{};var a=t.config.droplabAjax;if(this.hook=t,a&&a.endpoint&&a.method&&("setData"===a.method||"addData"===a.method)){if(a.loadingTemplate){var o=t.list.list.querySelector("[data-dynamic]"),r=document.createElement("div");r.innerHTML=a.loadingTemplate,r.setAttribute("data-loading-template",""),this.listTemplate=o.outerHTML,o.outerHTML=r.outerHTML}e.cache[a.endpoint]?e._loadData(e.cache[a.endpoint],a,e):this._loadUrlData(a.endpoint).then(function(t){e._loadData(t,a,e)}).catch(function(t){throw new n(t.message||t)})}},destroy:function(){var t=this.hook.list.list.querySelector("[data-dynamic]");this.listTemplate&&t&&(t.outerHTML=this.listTemplate)}};window.droplabAjax=o,e.default=o}});
+//# sourceMappingURL=ajax.js.map \ No newline at end of file
diff --git a/app/assets/javascripts/droplab/plugins/ajax.js.map b/app/assets/javascripts/droplab/plugins/ajax.js.map
new file mode 100644
index 00000000000..fd89dfb9cf8
--- /dev/null
+++ b/app/assets/javascripts/droplab/plugins/ajax.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///dist/plugins/ajax.js","webpack:///webpack/bootstrap 595d943f775089263f5d?9279**","webpack:///./src/plugins/ajax.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","value","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","10","droplabAjaxException","message","this","droplabAjax","_loadUrlData","url","self","Promise","resolve","reject","xhr","XMLHttpRequest","open","onreadystatechange","readyState","DONE","status","data","JSON","parse","responseText","cache","send","_loadData","config","loadingTemplate","dataLoadingTemplate","hook","list","querySelector","outerHTML","listTemplate","method","init","endpoint","dynamicList","document","createElement","innerHTML","setAttribute","then","catch","e","destroy","window","default"],"mappings":"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","file":"./dist/plugins/ajax.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 10);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ 10:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nfunction droplabAjaxException(message) {\n this.message = message;\n}\n\nvar droplabAjax = {\n _loadUrlData: function _loadUrlData(url) {\n var self = this;\n return new Promise(function (resolve, reject) {\n var xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.onreadystatechange = function () {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n if (xhr.status === 200) {\n var data = JSON.parse(xhr.responseText);\n self.cache[url] = data;\n return resolve(data);\n } else {\n return reject([xhr.responseText, xhr.status]);\n }\n }\n };\n xhr.send();\n });\n },\n _loadData: function _loadData(data, config, self) {\n if (config.loadingTemplate) {\n var dataLoadingTemplate = self.hook.list.list.querySelector('[data-loading-template]');\n if (dataLoadingTemplate) {\n dataLoadingTemplate.outerHTML = self.listTemplate;\n }\n }\n self.hook.list[config.method].call(self.hook.list, data);\n },\n init: function init(hook) {\n var self = this;\n self.cache = self.cache || {};\n var config = hook.config.droplabAjax;\n this.hook = hook;\n if (!config || !config.endpoint || !config.method) {\n return;\n }\n if (config.method !== 'setData' && config.method !== 'addData') {\n return;\n }\n if (config.loadingTemplate) {\n var dynamicList = hook.list.list.querySelector('[data-dynamic]');\n var loadingTemplate = document.createElement('div');\n loadingTemplate.innerHTML = config.loadingTemplate;\n loadingTemplate.setAttribute('data-loading-template', '');\n this.listTemplate = dynamicList.outerHTML;\n dynamicList.outerHTML = loadingTemplate.outerHTML;\n }\n if (self.cache[config.endpoint]) {\n self._loadData(self.cache[config.endpoint], config, self);\n } else {\n this._loadUrlData(config.endpoint).then(function (d) {\n self._loadData(d, config, self);\n }).catch(function (e) {\n throw new droplabAjaxException(e.message || e);\n });\n }\n },\n destroy: function destroy() {\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n if (this.listTemplate && dynamicList) {\n dynamicList.outerHTML = this.listTemplate;\n }\n }\n};\n\nwindow.droplabAjax = droplabAjax;\n\nexports.default = droplabAjax;\n\n/***/ })\n\n/******/ });\n\n\n// WEBPACK FOOTER //\n// dist/plugins/ajax.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 10);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 595d943f775089263f5d","function droplabAjaxException(message) {\n this.message = message;\n}\n\nconst droplabAjax = {\n _loadUrlData: function _loadUrlData(url) {\n var self = this;\n return new Promise(function(resolve, reject) {\n var xhr = new XMLHttpRequest;\n xhr.open('GET', url, true);\n xhr.onreadystatechange = function () {\n if(xhr.readyState === XMLHttpRequest.DONE) {\n if (xhr.status === 200) {\n var data = JSON.parse(xhr.responseText);\n self.cache[url] = data;\n return resolve(data);\n } else {\n return reject([xhr.responseText, xhr.status]);\n }\n }\n };\n xhr.send();\n });\n },\n _loadData: function _loadData(data, config, self) {\n if (config.loadingTemplate) {\n var dataLoadingTemplate = self.hook.list.list.querySelector('[data-loading-template]');\n if (dataLoadingTemplate) {\n dataLoadingTemplate.outerHTML = self.listTemplate;\n }\n }\n self.hook.list[config.method].call(self.hook.list, data);\n },\n init: function init(hook) {\n var self = this;\n self.cache = self.cache || {};\n var config = hook.config.droplabAjax;\n this.hook = hook;\n if (!config || !config.endpoint || !config.method) {\n return;\n }\n if (config.method !== 'setData' && config.method !== 'addData') {\n return;\n }\n if (config.loadingTemplate) {\n var dynamicList = hook.list.list.querySelector('[data-dynamic]');\n var loadingTemplate = document.createElement('div');\n loadingTemplate.innerHTML = config.loadingTemplate;\n loadingTemplate.setAttribute('data-loading-template', '');\n this.listTemplate = dynamicList.outerHTML;\n dynamicList.outerHTML = loadingTemplate.outerHTML;\n }\n if (self.cache[config.endpoint]) {\n self._loadData(self.cache[config.endpoint], config, self);\n } else {\n this._loadUrlData(config.endpoint)\n .then(function(d) {\n self._loadData(d, config, self);\n }).catch(function(e) {\n throw new droplabAjaxException(e.message || e);\n });\n }\n },\n destroy: function() {\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n if (this.listTemplate && dynamicList) {\n dynamicList.outerHTML = this.listTemplate;\n }\n }\n};\n\nwindow.droplabAjax = droplabAjax;\n\nexport default droplabAjax;\n\n\n\n// WEBPACK FOOTER //\n// ./src/plugins/ajax.js"],"sourceRoot":""} \ No newline at end of file
diff --git a/app/assets/javascripts/droplab/plugins/ajax_filter.js b/app/assets/javascripts/droplab/plugins/ajax_filter.js
index 97be527bb42..ccc8a2afc41 100644
--- a/app/assets/javascripts/droplab/plugins/ajax_filter.js
+++ b/app/assets/javascripts/droplab/plugins/ajax_filter.js
@@ -1 +1,2 @@
-!function(n){function e(a){if(t[a])return t[a].exports;var r=t[a]={i:a,l:!1,exports:{}};return n[a].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var t={};e.m=n,e.c=t,e.i=function(n){return n},e.d=function(n,t,a){e.o(n,t)||Object.defineProperty(n,t,{configurable:!1,enumerable:!0,get:a})},e.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(t,"a",t),t},e.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},e.p="",e(e.s=11)}({11:function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar droplabAjaxFilter = {\n init: function init(hook) {\n this.destroyed = false;\n this.hook = hook;\n this.notLoading();\n\n this.eventWrapper = {};\n this.eventWrapper.debounceTrigger = this.debounceTrigger.bind(this);\n this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceTrigger);\n this.hook.trigger.addEventListener('focus', this.eventWrapper.debounceTrigger);\n\n this.trigger(true);\n },\n\n notLoading: function notLoading() {\n this.loading = false;\n },\n\n debounceTrigger: function debounceTrigger(e) {\n var NON_CHARACTER_KEYS = [16, 17, 18, 20, 37, 38, 39, 40, 91, 93];\n var invalidKeyPressed = NON_CHARACTER_KEYS.indexOf(e.detail.which || e.detail.keyCode) > -1;\n var focusEvent = e.type === 'focus';\n if (invalidKeyPressed || this.loading) {\n return;\n }\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n this.timeout = setTimeout(this.trigger.bind(this, focusEvent), 200);\n },\n\n trigger: function trigger(getEntireList) {\n var config = this.hook.config.droplabAjaxFilter;\n var searchValue = this.trigger.value;\n if (!config || !config.endpoint || !config.searchKey) {\n return;\n }\n if (config.searchValueFunction) {\n searchValue = config.searchValueFunction();\n }\n if (config.loadingTemplate && this.hook.list.data === undefined || this.hook.list.data.length === 0) {\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n var loadingTemplate = document.createElement('div');\n loadingTemplate.innerHTML = config.loadingTemplate;\n loadingTemplate.setAttribute('data-loading-template', true);\n this.listTemplate = dynamicList.outerHTML;\n dynamicList.outerHTML = loadingTemplate.outerHTML;\n }\n if (getEntireList) {\n searchValue = '';\n }\n if (config.searchKey === searchValue) {\n return this.list.show();\n }\n this.loading = true;\n var params = config.params || {};\n params[config.searchKey] = searchValue;\n var self = this;\n self.cache = self.cache || {};\n var url = config.endpoint + this.buildParams(params);\n var urlCachedData = self.cache[url];\n if (urlCachedData) {\n self._loadData(urlCachedData, config, self);\n } else {\n this._loadUrlData(url).then(function (data) {\n self._loadData(data, config, self);\n });\n }\n },\n\n _loadUrlData: function _loadUrlData(url) {\n var self = this;\n return new Promise(function (resolve, reject) {\n var xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.onreadystatechange = function () {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n if (xhr.status === 200) {\n var data = JSON.parse(xhr.responseText);\n self.cache[url] = data;\n return resolve(data);\n } else {\n return reject([xhr.responseText, xhr.status]);\n }\n }\n };\n xhr.send();\n });\n },\n\n _loadData: function _loadData(data, config, self) {\n var list = self.hook.list;\n if (config.loadingTemplate && list.data === undefined || list.data.length === 0) {\n var dataLoadingTemplate = list.list.querySelector('[data-loading-template]');\n if (dataLoadingTemplate) {\n dataLoadingTemplate.outerHTML = self.listTemplate;\n }\n }\n if (!self.destroyed) {\n var hookListChildren = list.list.children;\n var onlyDynamicList = hookListChildren.length === 1 && hookListChildren[0].hasAttribute('data-dynamic');\n if (onlyDynamicList && data.length === 0) {\n list.hide();\n }\n list.setData.call(list, data);\n }\n self.notLoading();\n list.currentIndex = 0;\n },\n\n buildParams: function buildParams(params) {\n if (!params) return '';\n var paramsArray = Object.keys(params).map(function (param) {\n return param + '=' + (params[param] || '');\n });\n return '?' + paramsArray.join('&');\n },\n\n destroy: function destroy() {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n\n this.destroyed = true;\n this.hook.trigger.removeEventListener('keydown.dl', this.eventWrapper.debounceTrigger);\n this.hook.trigger.removeEventListener('focus', this.eventWrapper.debounceTrigger);\n }\n};\n\nwindow.droplabAjaxFilter = droplabAjaxFilter;\n\nexports.default = droplabAjaxFilter;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/plugins/ajax_filter.js\n// module id = 11\n// module chunks = 2\n\n//# sourceURL=webpack:///./src/plugins/ajax_filter.js?")}}); \ No newline at end of file
+!function(e){function t(r){if(i[r])return i[r].exports;var n=i[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,t),n.l=!0,n.exports}var i={};t.m=e,t.c=i,t.i=function(e){return e},t.d=function(e,i,r){t.o(e,i)||Object.defineProperty(e,i,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var i=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(i,"a",i),i},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=11)}({11:function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r={init:function(e){this.destroyed=!1,this.hook=e,this.notLoading(),this.eventWrapper={},this.eventWrapper.debounceTrigger=this.debounceTrigger.bind(this),this.hook.trigger.addEventListener("keydown.dl",this.eventWrapper.debounceTrigger),this.hook.trigger.addEventListener("focus",this.eventWrapper.debounceTrigger),this.trigger(!0)},notLoading:function(){this.loading=!1},debounceTrigger:function(e){var t=[16,17,18,20,37,38,39,40,91,93],i=t.indexOf(e.detail.which||e.detail.keyCode)>-1,r="focus"===e.type;i||this.loading||(this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(this.trigger.bind(this,r),200))},trigger:function(e){var t=this.hook.config.droplabAjaxFilter,i=this.trigger.value;if(t&&t.endpoint&&t.searchKey){if(t.searchValueFunction&&(i=t.searchValueFunction()),t.loadingTemplate&&void 0===this.hook.list.data||0===this.hook.list.data.length){var r=this.hook.list.list.querySelector("[data-dynamic]"),n=document.createElement("div");n.innerHTML=t.loadingTemplate,n.setAttribute("data-loading-template",!0),this.listTemplate=r.outerHTML,r.outerHTML=n.outerHTML}if(e&&(i=""),t.searchKey===i)return this.list.show();this.loading=!0;var o=t.params||{};o[t.searchKey]=i;var a=this;a.cache=a.cache||{};var s=t.endpoint+this.buildParams(o),u=a.cache[s];u?a._loadData(u,t,a):this._loadUrlData(s).then(function(e){a._loadData(e,t,a)})}},_loadUrlData:function(e){var t=this;return new Promise(function(i,r){var n=new XMLHttpRequest;n.open("GET",e,!0),n.onreadystatechange=function(){if(n.readyState===XMLHttpRequest.DONE){if(200===n.status){var o=JSON.parse(n.responseText);return t.cache[e]=o,i(o)}return r([n.responseText,n.status])}},n.send()})},_loadData:function(e,t,i){var r=i.hook.list;if(t.loadingTemplate&&void 0===r.data||0===r.data.length){var n=r.list.querySelector("[data-loading-template]");n&&(n.outerHTML=i.listTemplate)}if(!i.destroyed){var o=r.list.children;1===o.length&&o[0].hasAttribute("data-dynamic")&&0===e.length&&r.hide(),r.setData.call(r,e)}i.notLoading(),r.currentIndex=0},buildParams:function(e){return e?"?"+Object.keys(e).map(function(t){return t+"="+(e[t]||"")}).join("&"):""},destroy:function(){this.timeout&&clearTimeout(this.timeout),this.destroyed=!0,this.hook.trigger.removeEventListener("keydown.dl",this.eventWrapper.debounceTrigger),this.hook.trigger.removeEventListener("focus",this.eventWrapper.debounceTrigger)}};window.droplabAjaxFilter=r,t.default=r}});
+//# sourceMappingURL=ajax_filter.js.map \ No newline at end of file
diff --git a/app/assets/javascripts/droplab/plugins/ajax_filter.js.map b/app/assets/javascripts/droplab/plugins/ajax_filter.js.map
new file mode 100644
index 00000000000..1e1b0003de6
--- /dev/null
+++ b/app/assets/javascripts/droplab/plugins/ajax_filter.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///dist/plugins/ajax_filter.js","webpack:///webpack/bootstrap 595d943f775089263f5d?9279*","webpack:///./src/plugins/ajax_filter.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","value","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","11","droplabAjaxFilter","init","hook","this","destroyed","notLoading","eventWrapper","debounceTrigger","bind","trigger","addEventListener","loading","e","NON_CHARACTER_KEYS","invalidKeyPressed","indexOf","detail","which","keyCode","focusEvent","type","timeout","clearTimeout","setTimeout","getEntireList","config","searchValue","endpoint","searchKey","searchValueFunction","loadingTemplate","undefined","list","data","length","dynamicList","querySelector","document","createElement","innerHTML","setAttribute","listTemplate","outerHTML","show","params","self","cache","url","buildParams","urlCachedData","_loadData","_loadUrlData","then","Promise","resolve","reject","xhr","XMLHttpRequest","open","onreadystatechange","readyState","DONE","status","JSON","parse","responseText","send","dataLoadingTemplate","hookListChildren","children","hasAttribute","hide","setData","currentIndex","keys","map","param","join","destroy","removeEventListener","window","default"],"mappings":"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","file":"./dist/plugins/ajax_filter.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 11);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ 11:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar droplabAjaxFilter = {\n init: function init(hook) {\n this.destroyed = false;\n this.hook = hook;\n this.notLoading();\n\n this.eventWrapper = {};\n this.eventWrapper.debounceTrigger = this.debounceTrigger.bind(this);\n this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceTrigger);\n this.hook.trigger.addEventListener('focus', this.eventWrapper.debounceTrigger);\n\n this.trigger(true);\n },\n\n notLoading: function notLoading() {\n this.loading = false;\n },\n\n debounceTrigger: function debounceTrigger(e) {\n var NON_CHARACTER_KEYS = [16, 17, 18, 20, 37, 38, 39, 40, 91, 93];\n var invalidKeyPressed = NON_CHARACTER_KEYS.indexOf(e.detail.which || e.detail.keyCode) > -1;\n var focusEvent = e.type === 'focus';\n if (invalidKeyPressed || this.loading) {\n return;\n }\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n this.timeout = setTimeout(this.trigger.bind(this, focusEvent), 200);\n },\n\n trigger: function trigger(getEntireList) {\n var config = this.hook.config.droplabAjaxFilter;\n var searchValue = this.trigger.value;\n if (!config || !config.endpoint || !config.searchKey) {\n return;\n }\n if (config.searchValueFunction) {\n searchValue = config.searchValueFunction();\n }\n if (config.loadingTemplate && this.hook.list.data === undefined || this.hook.list.data.length === 0) {\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n var loadingTemplate = document.createElement('div');\n loadingTemplate.innerHTML = config.loadingTemplate;\n loadingTemplate.setAttribute('data-loading-template', true);\n this.listTemplate = dynamicList.outerHTML;\n dynamicList.outerHTML = loadingTemplate.outerHTML;\n }\n if (getEntireList) {\n searchValue = '';\n }\n if (config.searchKey === searchValue) {\n return this.list.show();\n }\n this.loading = true;\n var params = config.params || {};\n params[config.searchKey] = searchValue;\n var self = this;\n self.cache = self.cache || {};\n var url = config.endpoint + this.buildParams(params);\n var urlCachedData = self.cache[url];\n if (urlCachedData) {\n self._loadData(urlCachedData, config, self);\n } else {\n this._loadUrlData(url).then(function (data) {\n self._loadData(data, config, self);\n });\n }\n },\n\n _loadUrlData: function _loadUrlData(url) {\n var self = this;\n return new Promise(function (resolve, reject) {\n var xhr = new XMLHttpRequest();\n xhr.open('GET', url, true);\n xhr.onreadystatechange = function () {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n if (xhr.status === 200) {\n var data = JSON.parse(xhr.responseText);\n self.cache[url] = data;\n return resolve(data);\n } else {\n return reject([xhr.responseText, xhr.status]);\n }\n }\n };\n xhr.send();\n });\n },\n\n _loadData: function _loadData(data, config, self) {\n var list = self.hook.list;\n if (config.loadingTemplate && list.data === undefined || list.data.length === 0) {\n var dataLoadingTemplate = list.list.querySelector('[data-loading-template]');\n if (dataLoadingTemplate) {\n dataLoadingTemplate.outerHTML = self.listTemplate;\n }\n }\n if (!self.destroyed) {\n var hookListChildren = list.list.children;\n var onlyDynamicList = hookListChildren.length === 1 && hookListChildren[0].hasAttribute('data-dynamic');\n if (onlyDynamicList && data.length === 0) {\n list.hide();\n }\n list.setData.call(list, data);\n }\n self.notLoading();\n list.currentIndex = 0;\n },\n\n buildParams: function buildParams(params) {\n if (!params) return '';\n var paramsArray = Object.keys(params).map(function (param) {\n return param + '=' + (params[param] || '');\n });\n return '?' + paramsArray.join('&');\n },\n\n destroy: function destroy() {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n\n this.destroyed = true;\n this.hook.trigger.removeEventListener('keydown.dl', this.eventWrapper.debounceTrigger);\n this.hook.trigger.removeEventListener('focus', this.eventWrapper.debounceTrigger);\n }\n};\n\nwindow.droplabAjaxFilter = droplabAjaxFilter;\n\nexports.default = droplabAjaxFilter;\n\n/***/ })\n\n/******/ });\n\n\n// WEBPACK FOOTER //\n// dist/plugins/ajax_filter.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 11);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 595d943f775089263f5d","const droplabAjaxFilter = {\n init: function(hook) {\n this.destroyed = false;\n this.hook = hook;\n this.notLoading();\n\n this.eventWrapper = {};\n this.eventWrapper.debounceTrigger = this.debounceTrigger.bind(this);\n this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceTrigger);\n this.hook.trigger.addEventListener('focus', this.eventWrapper.debounceTrigger);\n\n this.trigger(true);\n },\n\n notLoading: function notLoading() {\n this.loading = false;\n },\n\n debounceTrigger: function debounceTrigger(e) {\n var NON_CHARACTER_KEYS = [16, 17, 18, 20, 37, 38, 39, 40, 91, 93];\n var invalidKeyPressed = NON_CHARACTER_KEYS.indexOf(e.detail.which || e.detail.keyCode) > -1;\n var focusEvent = e.type === 'focus';\n if (invalidKeyPressed || this.loading) {\n return;\n }\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n this.timeout = setTimeout(this.trigger.bind(this, focusEvent), 200);\n },\n\n trigger: function trigger(getEntireList) {\n var config = this.hook.config.droplabAjaxFilter;\n var searchValue = this.trigger.value;\n if (!config || !config.endpoint || !config.searchKey) {\n return;\n }\n if (config.searchValueFunction) {\n searchValue = config.searchValueFunction();\n }\n if (config.loadingTemplate && this.hook.list.data === undefined ||\n this.hook.list.data.length === 0) {\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n var loadingTemplate = document.createElement('div');\n loadingTemplate.innerHTML = config.loadingTemplate;\n loadingTemplate.setAttribute('data-loading-template', true);\n this.listTemplate = dynamicList.outerHTML;\n dynamicList.outerHTML = loadingTemplate.outerHTML;\n }\n if (getEntireList) {\n searchValue = '';\n }\n if (config.searchKey === searchValue) {\n return this.list.show();\n }\n this.loading = true;\n var params = config.params || {};\n params[config.searchKey] = searchValue;\n var self = this;\n self.cache = self.cache || {};\n var url = config.endpoint + this.buildParams(params);\n var urlCachedData = self.cache[url];\n if (urlCachedData) {\n self._loadData(urlCachedData, config, self);\n } else {\n this._loadUrlData(url)\n .then(function(data) {\n self._loadData(data, config, self);\n });\n }\n },\n\n _loadUrlData: function _loadUrlData(url) {\n var self = this;\n return new Promise(function(resolve, reject) {\n var xhr = new XMLHttpRequest;\n xhr.open('GET', url, true);\n xhr.onreadystatechange = function () {\n if(xhr.readyState === XMLHttpRequest.DONE) {\n if (xhr.status === 200) {\n var data = JSON.parse(xhr.responseText);\n self.cache[url] = data;\n return resolve(data);\n } else {\n return reject([xhr.responseText, xhr.status]);\n }\n }\n };\n xhr.send();\n });\n },\n\n _loadData: function _loadData(data, config, self) {\n const list = self.hook.list;\n if (config.loadingTemplate && list.data === undefined ||\n list.data.length === 0) {\n const dataLoadingTemplate = list.list.querySelector('[data-loading-template]');\n if (dataLoadingTemplate) {\n dataLoadingTemplate.outerHTML = self.listTemplate;\n }\n }\n if (!self.destroyed) {\n var hookListChildren = list.list.children;\n var onlyDynamicList = hookListChildren.length === 1 && hookListChildren[0].hasAttribute('data-dynamic');\n if (onlyDynamicList && data.length === 0) {\n list.hide();\n }\n list.setData.call(list, data);\n }\n self.notLoading();\n list.currentIndex = 0;\n },\n\n buildParams: function(params) {\n if (!params) return '';\n var paramsArray = Object.keys(params).map(function(param) {\n return param + '=' + (params[param] || '');\n });\n return '?' + paramsArray.join('&');\n },\n\n destroy: function destroy() {\n if (this.timeout) {\n clearTimeout(this.timeout);\n }\n\n this.destroyed = true;\n this.hook.trigger.removeEventListener('keydown.dl', this.eventWrapper.debounceTrigger);\n this.hook.trigger.removeEventListener('focus', this.eventWrapper.debounceTrigger);\n }\n};\n\nwindow.droplabAjaxFilter = droplabAjaxFilter;\n\nexport default droplabAjaxFilter;\n\n\n\n// WEBPACK FOOTER //\n// ./src/plugins/ajax_filter.js"],"sourceRoot":""} \ No newline at end of file
diff --git a/app/assets/javascripts/droplab/plugins/filter.js b/app/assets/javascripts/droplab/plugins/filter.js
index f9401c047a8..e485970c4fd 100644
--- a/app/assets/javascripts/droplab/plugins/filter.js
+++ b/app/assets/javascripts/droplab/plugins/filter.js
@@ -1 +1,2 @@
-!function(n){function e(o){if(t[o])return t[o].exports;var i=t[o]={i:o,l:!1,exports:{}};return n[o].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var t={};e.m=n,e.c=t,e.i=function(n){return n},e.d=function(n,t,o){e.o(n,t)||Object.defineProperty(n,t,{configurable:!1,enumerable:!0,get:o})},e.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(t,"a",t),t},e.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},e.p="",e(e.s=12)}({12:function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar droplabFilter = {\n keydown: function keydown(e) {\n var hiddenCount = 0;\n var dataHiddenCount = 0;\n\n var list = e.detail.hook.list;\n var data = list.data;\n var value = e.detail.hook.trigger.value.toLowerCase();\n var config = e.detail.hook.config.droplabFilter;\n var matches = [];\n var filterFunction;\n // will only work on dynamically set data\n if (!data) {\n return;\n }\n\n if (config && config.filterFunction && typeof config.filterFunction === 'function') {\n filterFunction = config.filterFunction;\n } else {\n filterFunction = function filterFunction(o) {\n // cheap string search\n o.droplab_hidden = o[config.template].toLowerCase().indexOf(value) === -1;\n return o;\n };\n }\n\n dataHiddenCount = data.filter(function (o) {\n return !o.droplab_hidden;\n }).length;\n\n matches = data.map(function (o) {\n return filterFunction(o, value);\n });\n\n hiddenCount = matches.filter(function (o) {\n return !o.droplab_hidden;\n }).length;\n\n if (dataHiddenCount !== hiddenCount) {\n list.render(matches);\n list.currentIndex = 0;\n }\n },\n\n debounceKeydown: function debounceKeydown(e) {\n if ([13, // enter\n 16, // shift\n 17, // ctrl\n 18, // alt\n 20, // caps lock\n 37, // left arrow\n 38, // up arrow\n 39, // right arrow\n 40, // down arrow\n 91, // left window\n 92, // right window\n 93].indexOf(e.detail.which || e.detail.keyCode) > -1) return;\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(this.keydown.bind(this, e), 200);\n },\n\n init: function init(hook) {\n var config = hook.config.droplabFilter;\n\n if (!config || !config.template) return;\n\n this.hook = hook;\n\n this.eventWrapper = {};\n this.eventWrapper.debounceKeydown = this.debounceKeydown.bind(this);\n\n this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceKeydown);\n },\n\n destroy: function destroy() {\n this.hook.trigger.removeEventListener('keydown.dl', this.eventWrapper.debounceKeydown);\n\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n if (this.listTemplate && dynamicList) {\n dynamicList.outerHTML = this.listTemplate;\n }\n }\n};\n\nwindow.droplabFilter = droplabFilter;\n\nexports.default = droplabFilter;\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/plugins/filter.js\n// module id = 12\n// module chunks = 1\n\n//# sourceURL=webpack:///./src/plugins/filter.js?")}}); \ No newline at end of file
+!function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=12)}({12:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o={keydown:function(e){var t,n=0,o=0,i=e.detail.hook.list,r=i.data,d=e.detail.hook.trigger.value.toLowerCase(),u=e.detail.hook.config.droplabFilter,l=[];r&&(t=u&&u.filterFunction&&"function"==typeof u.filterFunction?u.filterFunction:function(e){return e.droplab_hidden=e[u.template].toLowerCase().indexOf(d)===-1,e},o=r.filter(function(e){return!e.droplab_hidden}).length,l=r.map(function(e){return t(e,d)}),n=l.filter(function(e){return!e.droplab_hidden}).length,o!==n&&(i.render(l),i.currentIndex=0))},debounceKeydown:function(e){[13,16,17,18,20,37,38,39,40,91,92,93].indexOf(e.detail.which||e.detail.keyCode)>-1||(this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(this.keydown.bind(this,e),200))},init:function(e){var t=e.config.droplabFilter;t&&t.template&&(this.hook=e,this.eventWrapper={},this.eventWrapper.debounceKeydown=this.debounceKeydown.bind(this),this.hook.trigger.addEventListener("keydown.dl",this.eventWrapper.debounceKeydown))},destroy:function(){this.hook.trigger.removeEventListener("keydown.dl",this.eventWrapper.debounceKeydown);var e=this.hook.list.list.querySelector("[data-dynamic]");this.listTemplate&&e&&(e.outerHTML=this.listTemplate)}};window.droplabFilter=o,t.default=o}});
+//# sourceMappingURL=filter.js.map \ No newline at end of file
diff --git a/app/assets/javascripts/droplab/plugins/filter.js.map b/app/assets/javascripts/droplab/plugins/filter.js.map
new file mode 100644
index 00000000000..7f101a64449
--- /dev/null
+++ b/app/assets/javascripts/droplab/plugins/filter.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["webpack:///dist/plugins/filter.js","webpack:///webpack/bootstrap 595d943f775089263f5d?9279","webpack:///./src/plugins/filter.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","value","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","12","droplabFilter","keydown","e","filterFunction","hiddenCount","dataHiddenCount","list","detail","hook","data","trigger","toLowerCase","config","matches","droplab_hidden","template","indexOf","filter","length","map","render","currentIndex","debounceKeydown","which","keyCode","this","timeout","clearTimeout","setTimeout","bind","init","eventWrapper","addEventListener","destroy","removeEventListener","dynamicList","querySelector","listTemplate","outerHTML","window","default"],"mappings":"CAAS,SAAUA,GCInB,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAI,EAAAJ,EACAK,GAAA,EACAH,WAUA,OANAJ,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,GAGAI,EAAAE,GAAA,EAGAF,EAAAD,QAvBA,GAAAD,KA4BAF,GAAAQ,EAAAT,EAGAC,EAAAS,EAAAP,EAGAF,EAAAK,EAAA,SAAAK,GAA2C,MAAAA,IAG3CV,EAAAW,EAAA,SAAAR,EAAAS,EAAAC,GACAb,EAAAc,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,GACAK,cAAA,EACAC,YAAA,EACAC,IAAAN,KAMAb,EAAAoB,EAAA,SAAAhB,GACA,GAAAS,GAAAT,KAAAiB,WACA,WAA2B,MAAAjB,GAAA,SAC3B,WAAiC,MAAAA,GAEjC,OADAJ,GAAAW,EAAAE,EAAA,IAAAA,GACAA,GAIAb,EAAAc,EAAA,SAAAQ,EAAAC,GAAsD,MAAAR,QAAAS,UAAAC,eAAAlB,KAAAe,EAAAC,IAGtDvB,EAAA0B,EAAA,GAGA1B,IAAA2B,EAAA,MDMMC,GACA,SAAUxB,EAAQD,EAASH,GAEjC,YAGAe,QAAOC,eAAeb,EAAS,cAC7BO,OAAO,GE7ET,IAAMmB,IACJC,QAAS,SAASC,GAChB,GAQIC,GARAC,EAAc,EACdC,EAAkB,EAElBC,EAAOJ,EAAEK,OAAOC,KAAKF,KACrBG,EAAOH,EAAKG,KACZ5B,EAAQqB,EAAEK,OAAOC,KAAKE,QAAQ7B,MAAM8B,cACpCC,EAASV,EAAEK,OAAOC,KAAKI,OAAOZ,cAC9Ba,IAGAJ,KAKFN,EADES,GAAUA,EAAOT,gBAAmD,kBAA1BS,GAAOT,eAClCS,EAAOT,eAEP,SAASlB,GAGxB,MADAA,GAAE6B,eAAiB7B,EAAE2B,EAAOG,UAAUJ,cAAcK,QAAQnC,MAAW,EAChEI,GAIXoB,EAAkBI,EAAKQ,OAAO,SAAShC,GACrC,OAAQA,EAAE6B,iBACTI,OAEHL,EAAUJ,EAAKU,IAAI,SAASlC,GAC1B,MAAOkB,GAAelB,EAAGJ,KAG3BuB,EAAcS,EAAQI,OAAO,SAAShC,GACpC,OAAQA,EAAE6B,iBACTI,OAECb,IAAoBD,IACtBE,EAAKc,OAAOP,GACZP,EAAKe,aAAe,KAIxBC,gBAAiB,SAAyBpB,IAEtC,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,GACA,IACAc,QAAQd,EAAEK,OAAOgB,OAASrB,EAAEK,OAAOiB,UAAW,IAE5CC,KAAKC,SAASC,aAAaF,KAAKC,SACpCD,KAAKC,QAAUE,WAAWH,KAAKxB,QAAQ4B,KAAKJ,KAAMvB,GAAI,OAGxD4B,KAAM,SAActB,GAClB,GAAII,GAASJ,EAAKI,OAAOZ,aAEpBY,IAAWA,EAAOG,WAEvBU,KAAKjB,KAAOA,EAEZiB,KAAKM,gBACLN,KAAKM,aAAaT,gBAAkBG,KAAKH,gBAAgBO,KAAKJ,MAE9DA,KAAKjB,KAAKE,QAAQsB,iBAAiB,aAAcP,KAAKM,aAAaT,mBAGrEW,QAAS,WACPR,KAAKjB,KAAKE,QAAQwB,oBAAoB,aAAcT,KAAKM,aAAaT,gBAEtE,IAAIa,GAAcV,KAAKjB,KAAKF,KAAKA,KAAK8B,cAAc,iBAChDX,MAAKY,cAAgBF,IACvBA,EAAYG,UAAYb,KAAKY,eAKnCE,QAAOvC,cAAgBA,EF+EvB1B,EAAQkE,QE7EOxC","file":"./dist/plugins/filter.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 12);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ 12:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nvar droplabFilter = {\n keydown: function keydown(e) {\n var hiddenCount = 0;\n var dataHiddenCount = 0;\n\n var list = e.detail.hook.list;\n var data = list.data;\n var value = e.detail.hook.trigger.value.toLowerCase();\n var config = e.detail.hook.config.droplabFilter;\n var matches = [];\n var filterFunction;\n // will only work on dynamically set data\n if (!data) {\n return;\n }\n\n if (config && config.filterFunction && typeof config.filterFunction === 'function') {\n filterFunction = config.filterFunction;\n } else {\n filterFunction = function filterFunction(o) {\n // cheap string search\n o.droplab_hidden = o[config.template].toLowerCase().indexOf(value) === -1;\n return o;\n };\n }\n\n dataHiddenCount = data.filter(function (o) {\n return !o.droplab_hidden;\n }).length;\n\n matches = data.map(function (o) {\n return filterFunction(o, value);\n });\n\n hiddenCount = matches.filter(function (o) {\n return !o.droplab_hidden;\n }).length;\n\n if (dataHiddenCount !== hiddenCount) {\n list.render(matches);\n list.currentIndex = 0;\n }\n },\n\n debounceKeydown: function debounceKeydown(e) {\n if ([13, // enter\n 16, // shift\n 17, // ctrl\n 18, // alt\n 20, // caps lock\n 37, // left arrow\n 38, // up arrow\n 39, // right arrow\n 40, // down arrow\n 91, // left window\n 92, // right window\n 93].indexOf(e.detail.which || e.detail.keyCode) > -1) return;\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(this.keydown.bind(this, e), 200);\n },\n\n init: function init(hook) {\n var config = hook.config.droplabFilter;\n\n if (!config || !config.template) return;\n\n this.hook = hook;\n\n this.eventWrapper = {};\n this.eventWrapper.debounceKeydown = this.debounceKeydown.bind(this);\n\n this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceKeydown);\n },\n\n destroy: function destroy() {\n this.hook.trigger.removeEventListener('keydown.dl', this.eventWrapper.debounceKeydown);\n\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n if (this.listTemplate && dynamicList) {\n dynamicList.outerHTML = this.listTemplate;\n }\n }\n};\n\nwindow.droplabFilter = droplabFilter;\n\nexports.default = droplabFilter;\n\n/***/ })\n\n/******/ });\n\n\n// WEBPACK FOOTER //\n// dist/plugins/filter.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 12);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 595d943f775089263f5d","const droplabFilter = {\n keydown: function(e){\n var hiddenCount = 0;\n var dataHiddenCount = 0;\n\n var list = e.detail.hook.list;\n var data = list.data;\n var value = e.detail.hook.trigger.value.toLowerCase();\n var config = e.detail.hook.config.droplabFilter;\n var matches = [];\n var filterFunction;\n // will only work on dynamically set data\n if(!data){\n return;\n }\n\n if (config && config.filterFunction && typeof config.filterFunction === 'function') {\n filterFunction = config.filterFunction;\n } else {\n filterFunction = function(o){\n // cheap string search\n o.droplab_hidden = o[config.template].toLowerCase().indexOf(value) === -1;\n return o;\n };\n }\n\n dataHiddenCount = data.filter(function(o) {\n return !o.droplab_hidden;\n }).length;\n\n matches = data.map(function(o) {\n return filterFunction(o, value);\n });\n\n hiddenCount = matches.filter(function(o) {\n return !o.droplab_hidden;\n }).length;\n\n if (dataHiddenCount !== hiddenCount) {\n list.render(matches);\n list.currentIndex = 0;\n }\n },\n\n debounceKeydown: function debounceKeydown(e) {\n if ([\n 13, // enter\n 16, // shift\n 17, // ctrl\n 18, // alt\n 20, // caps lock\n 37, // left arrow\n 38, // up arrow\n 39, // right arrow\n 40, // down arrow\n 91, // left window\n 92, // right window\n 93, // select\n ].indexOf(e.detail.which || e.detail.keyCode) > -1) return;\n\n if (this.timeout) clearTimeout(this.timeout);\n this.timeout = setTimeout(this.keydown.bind(this, e), 200);\n },\n\n init: function init(hook) {\n var config = hook.config.droplabFilter;\n\n if (!config || !config.template) return;\n\n this.hook = hook;\n\n this.eventWrapper = {};\n this.eventWrapper.debounceKeydown = this.debounceKeydown.bind(this);\n\n this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceKeydown);\n },\n\n destroy: function destroy() {\n this.hook.trigger.removeEventListener('keydown.dl', this.eventWrapper.debounceKeydown);\n\n var dynamicList = this.hook.list.list.querySelector('[data-dynamic]');\n if (this.listTemplate && dynamicList) {\n dynamicList.outerHTML = this.listTemplate;\n }\n }\n};\n\nwindow.droplabFilter = droplabFilter;\n\nexport default droplabFilter;\n\n\n\n// WEBPACK FOOTER //\n// ./src/plugins/filter.js"],"sourceRoot":""} \ No newline at end of file
diff --git a/app/assets/javascripts/groups_droplab.js.es6 b/app/assets/javascripts/groups_droplab.js.es6
new file mode 100644
index 00000000000..2420b52db96
--- /dev/null
+++ b/app/assets/javascripts/groups_droplab.js.es6
@@ -0,0 +1,44 @@
+(() => {
+ const global = window.gl || (window.gl = {});
+
+ const GroupsDroplab = {
+ init(trigger, list, input) {
+ if (!trigger || !list) return;
+
+ const droplab = new DropLab();
+
+ droplab.addHook(trigger, list, [
+ droplabRemoteFilter,
+ droplabInfiniteScroll,
+ droplabAjax,
+ droplabInputSetter,
+ ], {
+ droplabAjax: {
+ endpoint: Api.buildUrl(Api.groupsPath),
+ method: 'setData',
+ params: {
+ per_page: 10,
+ page: 1,
+ skip_groups: document.querySelector('#groups-droplab').dataset.skip_groups,
+ },
+ deferRequest: true,
+ loadingTemplate: `<i class="fa fa-spinner fa-spin"></i>`,
+ },
+ droplabRemoteFilter: {
+ searchKey: 'search',
+ },
+ droplabInfiniteScroll: {
+ paginationKey: 'page',
+ },
+ droplabInputSetter: [{
+ input,
+ valueAttribute: 'data-id',
+ }, {
+ valueAttribute: 'data-name',
+ }],
+ });
+ }
+ };
+
+ global.GroupsDroplab = GroupsDroplab;
+})();
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 887ab481de4..03307976307 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -546,3 +546,24 @@
color: $gl-text-color-secondary;
}
}
+
+.droplab ul {
+ overflow-y: scroll;
+
+ #dl-infinite-scroll-loading-element {
+ color: $gray-darkest;
+ text-align: center;
+
+ .loading-more {
+ &> i {
+ display: inline-block;
+ }
+
+ &> small {
+ display: inline-block;
+ padding-left: $gl-padding;
+ padding-right: $gl-padding;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 09b85db7d45..5c34f433daf 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -805,6 +805,10 @@ pre.light-well {
}
}
+.droplab.groups ul {
+ max-height: 200px;
+}
+
.compare-form-group {
.dropdown-menu {
width: 100%;
diff --git a/app/views/projects/group_links/_index.html.haml b/app/views/projects/group_links/_index.html.haml
index b6116dbec41..0d03e640ca6 100644
--- a/app/views/projects/group_links/_index.html.haml
+++ b/app/views/projects/group_links/_index.html.haml
@@ -11,7 +11,7 @@
= form_tag namespace_project_group_links_path(@project.namespace, @project), class: 'js-requires-input', method: :post do
.form-group
= label_tag :link_group_id, "Group", class: "label-light"
- = groups_select_tag(:link_group_id, data: { skip_groups: @skip_groups }, required: true)
+ = render('shared/groups_droplab', input: :link_group_id, required: true, placeholder: 'Search for a group', data: { skip_groups: @skip_groups })
.form-group
= label_tag :link_group_access, "Max access level", class: "label-light"
.select-wrapper
diff --git a/app/views/shared/_groups_droplab.html.haml b/app/views/shared/_groups_droplab.html.haml
new file mode 100644
index 00000000000..1b2de557ade
--- /dev/null
+++ b/app/views/shared/_groups_droplab.html.haml
@@ -0,0 +1,12 @@
+- input = local_assigns.fetch(:input, nil)
+- placeholder = local_assigns.fetch(:placeholder, nil)
+- required = local_assigns.fetch(:required, false)
+- data = local_assigns.fetch(:data, {})
+
+.dropdown.groups.droplab
+ %input.input.form-control{ id: "#{input}_trigger", required: required.to_s, type: 'text', placeholder: placeholder }
+ = hidden_field_tag input
+ %ul#groups-droplab.dropdown-menu.dropdown-menu-full-width{ data: data.merge({ dropdown: 'true', dynamic: 'true' }) }
+ %li
+ %a{ href: '#', data: { id: '{{id}}', name: '{{name}}' } } {{name}}
+ %div{ data: { 'loading-template' => 'true' } }