1const plugin = document.getElementById('plugin_info'); 2const component = document.getElementById('plugin_components'); 3const output = document.getElementById('output'); 4updatePluginNameStatus(); 5 6/** 7 * disable the plugin name field when a component has been added 8 */ 9function updatePluginNameStatus() { 10 plugin.querySelector('input').readOnly = output.children.length > 0; 11 document.querySelector('button[type=submit]').disabled = output.children.length === 0; 12} 13 14/** 15 * Create the HTML element for a component 16 * 17 * @param {string} plugin The plugin base name 18 * @param {string} type The component type 19 * @param {string} name The component name 20 * @returns {HTMLLIElement|null} null if the component already exists 21 */ 22function createComponentElement(plugin, type, name) { 23 let id = `${type}_plugin_${plugin}`; 24 if (name !== '') { 25 id += `_${name}`; 26 } 27 28 if (document.getElementById(`component-${id}`)) { 29 return null; 30 } 31 32 const li = document.createElement('li'); 33 li.id = `component-${id}`; 34 li.dataset.type = type; 35 li.dataset.name = name; 36 37 const hidden = document.createElement('input'); 38 hidden.type = 'hidden'; 39 hidden.name = 'components[]'; 40 hidden.value = id; 41 li.append(hidden); 42 43 const remove = document.createElement('button'); 44 remove.type = 'button'; 45 remove.innerText = 'X'; 46 remove.title = 'Remove this component'; 47 remove.addEventListener('click', function (event) { 48 li.remove(); 49 updatePluginNameStatus(); 50 }); 51 li.append(remove); 52 53 const label = document.createElement('span'); 54 label.innerText = id; 55 li.append(label); 56 57 58 // add auto completion for events 59 if (type === 'action') { 60 const events = document.createElement('input'); 61 events.type = 'text'; 62 events.name = `options[${id}]`; 63 events.placeholder = 'EVENTS_TO_HANDLE, ...'; 64 li.append(events); 65 new Awesomplete(events, { 66 list: ACTION_EVENTS, 67 filter: function (text, input) { 68 return Awesomplete.FILTER_CONTAINS(text, input.match(/[^,]*$/)[0]); 69 }, 70 71 item: function (text, input) { 72 return Awesomplete.ITEM(text, input.match(/[^,]*$/)[0]); 73 }, 74 75 replace: function (text) { 76 var before = this.input.value.match(/^.+,\s*|/)[0]; 77 this.input.value = before + text + ", "; 78 } 79 }); 80 } 81 82 83 return li; 84} 85 86 87/** 88 * Add a component to the output list 89 */ 90component.querySelector('button').addEventListener('click', function (event) { 91 const plugin_base = plugin.querySelector('input'); // first input field is plugin base name 92 const component_type = component.querySelector('select'); 93 const component_name = component.querySelector('input'); 94 95 if (!plugin_base.validity.valid) { 96 plugin_base.reportValidity(); 97 plugin_base.focus(); 98 return; 99 } 100 101 if (!component_name.validity.valid) { 102 component_name.reportValidity(); 103 component_name.focus(); 104 return; 105 } 106 107 const li = createComponentElement(plugin_base.value, component_type.value, component_name.value); 108 if (!li) return; 109 110 output.appendChild(li); 111 updatePluginNameStatus(); 112}); 113