Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 1 | "use strict"; |
| 2 | |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 3 | define( |
Akron | 0b489ad | 2018-02-02 16:49:32 +0100 | [diff] [blame] | 4 | ['menu', 'selectMenu/item', 'util'], |
Akron | c82513b | 2016-06-11 11:22:36 +0200 | [diff] [blame] | 5 | function (menuClass, selectMenuItemClass) { |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 6 | |
| 7 | return { |
| 8 | create : function (element) { |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 9 | |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 10 | const select = element.getElementsByTagName('select')[0]; |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 11 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 12 | if (select === null) |
| 13 | return; |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 14 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 15 | // Prepare list before object upgras |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 16 | const list = []; |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 17 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 18 | // Iterate through options list |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 19 | // Get option item and add to list |
Akron | b50964a | 2020-10-12 11:44:37 +0200 | [diff] [blame] | 20 | Array.from( |
| 21 | select.getElementsByTagName('option') |
Akron | b50964a | 2020-10-12 11:44:37 +0200 | [diff] [blame] | 22 | ).forEach(function(item) { |
| 23 | |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 24 | const opt = [ |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 25 | item.textContent, |
| 26 | item.getAttribute('value') |
| 27 | ]; |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 28 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 29 | // If the item has an attribute - list |
| 30 | if (item.hasAttribute('desc')) |
| 31 | opt.push(item.getAttribute('desc')); |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 32 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 33 | list.push(opt); |
Akron | b50964a | 2020-10-12 11:44:37 +0200 | [diff] [blame] | 34 | }); |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 35 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 36 | // Create object with list |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 37 | const obj = Object.create(menuClass).upgradeTo(this) |
| 38 | ._init( |
| 39 | list, { |
| 40 | itemClass : selectMenuItemClass |
| 41 | } |
| 42 | ); |
Akron | 7f613e0 | 2016-11-07 02:50:44 +0100 | [diff] [blame] | 43 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 44 | obj._container = element; |
| 45 | obj._select = select; |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 46 | select.style.display = 'none'; |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 47 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 48 | // Create title |
Akron | 0b489ad | 2018-02-02 16:49:32 +0100 | [diff] [blame] | 49 | obj._title = obj._container.addE('span'); |
| 50 | obj._title.addT(''); |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 51 | |
| 52 | obj._container.appendChild(obj.element()); |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 53 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 54 | // Show the menu |
| 55 | obj._container.addEventListener('click', obj.showSelected.bind(obj)); |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 56 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 57 | // Add index information to each item |
Akron | 678c26f | 2020-10-09 08:52:50 +0200 | [diff] [blame] | 58 | obj._items.forEach((e,i) => e._index = i); |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 59 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 60 | // This is only domspecific |
| 61 | obj.element().addEventListener('blur', function (e) { |
| 62 | this.menu.hide(); |
| 63 | this.menu.showTitle(); |
| 64 | }); |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 65 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 66 | // In case another tool changes |
| 67 | // the option via JS - this needs |
| 68 | // to be reflected! |
| 69 | select.addEventListener('change', function (e) { |
| 70 | this.showTitle(); |
| 71 | }.bind(obj)); |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 72 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 73 | obj.showTitle(); |
| 74 | return obj; |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 75 | }, |
| 76 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 77 | /** |
| 78 | * Get or set the selection index |
| 79 | */ |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 80 | select : function (index) { |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 81 | const t = this; |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 82 | if (arguments.length > 0) { |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 83 | t._selected = index; |
| 84 | t._select.selectedIndex = index; |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 85 | }; |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 86 | |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 87 | return t._selected || t._select.selectedIndex || 0; |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 88 | }, |
| 89 | |
Akron | 086fe5d | 2017-11-13 14:01:45 +0100 | [diff] [blame] | 90 | |
| 91 | /** |
| 92 | * Set the select value |
| 93 | */ |
| 94 | selectValue : function (vParam) { |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 95 | const t = this; |
| 96 | const qlf = t._select.options; |
Akron | 678c26f | 2020-10-09 08:52:50 +0200 | [diff] [blame] | 97 | for (let i = 0; i < qlf.length; i++) { |
Akron | 086fe5d | 2017-11-13 14:01:45 +0100 | [diff] [blame] | 98 | if (qlf[i].value == vParam) { |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 99 | t.hide(); |
| 100 | t.select(i); |
| 101 | t.showTitle(); |
Akron | 086fe5d | 2017-11-13 14:01:45 +0100 | [diff] [blame] | 102 | break; |
| 103 | }; |
| 104 | }; |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 105 | return t; |
Akron | 086fe5d | 2017-11-13 14:01:45 +0100 | [diff] [blame] | 106 | }, |
| 107 | |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 108 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 109 | /** |
| 110 | * Show the select menu |
| 111 | */ |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 112 | showSelected : function () { |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 113 | const t = this; |
| 114 | t._title.style.display = 'none'; |
| 115 | t.show(t._selected = t._select.selectedIndex); |
| 116 | t.focus(); |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 117 | }, |
| 118 | |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 119 | |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 120 | /** |
| 121 | * Show the title |
| 122 | */ |
Akron | 6bb7158 | 2016-06-10 20:41:08 +0200 | [diff] [blame] | 123 | showTitle : function () { |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 124 | |
| 125 | // Get the selection context |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 126 | const t = this; |
| 127 | const s = t.select(); |
| 128 | t._title.textContent = t.item( |
| 129 | t.select() |
Akron | aba7a5a | 2016-08-15 21:58:33 +0200 | [diff] [blame] | 130 | ).title(); |
Akron | 5de8c7d | 2020-10-19 14:15:11 +0200 | [diff] [blame] | 131 | t._title.style.display = 'inline'; |
Akron | ad89483 | 2016-06-08 18:24:48 +0200 | [diff] [blame] | 132 | } |
| 133 | } |
| 134 | } |
| 135 | ); |