131131 color : var (--crit ); padding : 10px ; border-radius : 6px ;
132132 margin-bottom : 16px ; display : none;
133133 }
134- .isp-dropdown { position : relative; }
135- .isp-selected {
136- display : flex; align-items : center; gap : 8px ;
137- background : var (--input-bg ); border : 1px solid var (--input-border );
138- border-radius : 4px ; padding : 8px 10px ; cursor : pointer;
139- font-size : 0.95em ; font-family : inherit; color : var (--text );
140- }
141- .isp-selected : hover { border-color : var (--accent ); }
142- .isp-selected .isp-arrow { margin-left : auto; font-size : 0.8em ; color : var (--muted ); }
143- .isp-options {
144- display : none; position : absolute; top : 100% ; left : 0 ; right : 0 ;
145- background : var (--input-bg ); border : 1px solid var (--input-border );
146- border-radius : 4px ; margin-top : 2px ; z-index : 50 ;
147- max-height : 240px ; overflow-y : auto;
148- }
149- .isp-options .open { display : block; }
150- .isp-option {
151- display : flex; align-items : center; gap : 8px ;
152- padding : 8px 10px ; cursor : pointer; font-size : 0.95em ;
153- }
154- .isp-option : hover { background : var (--card ); }
155- .isp-badge {
156- display : inline-block; width : 10px ; height : 10px ;
157- border-radius : 3px ; flex-shrink : 0 ;
158- }
159134 @media (max-width : 600px ) { .form-grid { grid-template-columns : 1fr ; } }
160135 </ style >
161136</ head >
@@ -237,29 +212,14 @@ <h2>{{ t.mqtt_broker }} <span style="font-size:0.75em; font-weight:normal; color
237212 < h2 > {{ t.general }}</ h2 >
238213 < div class ="form-grid ">
239214 < div class ="form-row ">
240- < label > {{ t.isp_name }}</ label >
241- < div class ="isp-dropdown " id ="isp-dropdown ">
242- < div class ="isp-selected " id ="isp-selected " onclick ="toggleIspDropdown() ">
243- < span class ="isp-badge " id ="isp-sel-badge "> </ span >
244- < span class ="isp-text " id ="isp-sel-text "> {{ t.isp_select }}</ span >
245- < span class ="isp-arrow "> ▾</ span >
246- </ div >
247- < div class ="isp-options " id ="isp-options ">
248- < div class ="isp-option " data-value ="" onclick ="selectIsp(this) ">
249- < span class ="isp-text "> {{ t.isp_select }}</ span >
250- </ div >
251- {% for isp in t.isp_options %}
252- < div class ="isp-option " data-value ="{{ isp }} " onclick ="selectIsp(this) ">
253- {% if isp in isp_colors %}< span class ="isp-badge " style ="background:{{ isp_colors[isp] }} "> </ span > {% endif %}
254- < span class ="isp-text "> {{ isp }}</ span >
255- </ div >
256- {% endfor %}
257- < div class ="isp-option " data-value ="__other__ " onclick ="selectIsp(this) ">
258- < span class ="isp-text "> {{ t.isp_other }}</ span >
259- </ div >
260- </ div >
261- < input type ="hidden " id ="isp_value " value ="{{ config.isp_name or '' }} ">
262- </ div >
215+ < label for ="isp_select "> {{ t.isp_name }}</ label >
216+ < select id ="isp_select " name ="isp_select " onchange ="onIspChange() ">
217+ < option value =""> {{ t.isp_select }}</ option >
218+ {% for isp in t.isp_options %}
219+ < option value ="{{ isp }} " {% if config.isp_name == isp %}selected{% endif %} > {{ isp }}</ option >
220+ {% endfor %}
221+ < option value ="__other__ " {% if config.isp_name and config.isp_name not in t.isp_options %}selected{% endif %} > {{ t.isp_other }}</ option >
222+ </ select >
263223 < span class ="hint "> {{ t.isp_hint }}</ span >
264224 </ div >
265225 < div class ="form-row " id ="isp-other-row " style ="display:{% if config.isp_name and config.isp_name not in t.isp_options %}flex{% else %}none{% endif %} ">
@@ -319,49 +279,12 @@ <h2>{{ t.general }}</h2>
319279 }
320280} ) ( ) ;
321281
322- var ISP_COLORS = { { isp_colors| tojson } } ;
323- var ispOpen = false ;
324-
325- function toggleIspDropdown ( ) {
326- ispOpen = ! ispOpen ;
327- document . getElementById ( 'isp-options' ) . classList . toggle ( 'open' , ispOpen ) ;
328- }
329-
330- function selectIsp ( el ) {
331- var val = el . getAttribute ( 'data-value' ) ;
332- document . getElementById ( 'isp_value' ) . value = val ;
333- var badge = document . getElementById ( 'isp-sel-badge' ) ;
334- var text = document . getElementById ( 'isp-sel-text' ) ;
335- var color = ISP_COLORS [ val ] ;
336- badge . style . background = color || 'transparent' ;
337- badge . style . display = color ? 'inline-block' : 'none' ;
338- text . textContent = el . querySelector ( '.isp-text' ) . textContent ;
339- ispOpen = false ;
340- document . getElementById ( 'isp-options' ) . classList . remove ( 'open' ) ;
341- document . getElementById ( 'isp-other-row' ) . style . display = val === '__other__' ? 'flex' : 'none' ;
282+ function onIspChange ( ) {
283+ var sel = document . getElementById ( 'isp_select' ) ;
284+ var row = document . getElementById ( 'isp-other-row' ) ;
285+ row . style . display = sel . value === '__other__' ? 'flex' : 'none' ;
342286}
343287
344- document . addEventListener ( 'click' , function ( e ) {
345- if ( ! e . target . closest ( '.isp-dropdown' ) ) {
346- ispOpen = false ;
347- document . getElementById ( 'isp-options' ) . classList . remove ( 'open' ) ;
348- }
349- } ) ;
350-
351- ( function ( ) {
352- var val = document . getElementById ( 'isp_value' ) . value ;
353- if ( ! val ) return ;
354- var opts = document . querySelectorAll ( '#isp-options .isp-option' ) ;
355- var found = false ;
356- for ( var i = 0 ; i < opts . length ; i ++ ) {
357- if ( opts [ i ] . getAttribute ( 'data-value' ) === val ) { selectIsp ( opts [ i ] ) ; found = true ; break ; }
358- }
359- if ( ! found ) {
360- var other = document . querySelector ( '#isp-options .isp-option[data-value="__other__"]' ) ;
361- selectIsp ( other ) ;
362- }
363- } ) ( ) ;
364-
365288function showToast ( msg , ok ) {
366289 var el = document . getElementById ( 'toast' ) ;
367290 el . textContent = msg ;
@@ -376,18 +299,18 @@ <h2>{{ t.general }}</h2>
376299function getFormData ( ) {
377300 var form = document . getElementById ( 'settings-form' ) ;
378301 var data = { } ;
379- form . querySelectorAll ( 'input:not(#theme-check):not(#isp_other_input):not(#isp_value), select ' ) . forEach ( function ( inp ) {
302+ form . querySelectorAll ( 'input:not(#theme-check):not(#isp_other_input), select :not(#isp_select) ' ) . forEach ( function ( inp ) {
380303 if ( SECRET_FIELDS . indexOf ( inp . name ) !== - 1 ) {
381304 data [ inp . name ] = inp . value || MASK ;
382305 } else {
383306 data [ inp . name ] = inp . value ;
384307 }
385308 } ) ;
386- var ispVal = document . getElementById ( 'isp_value' ) . value ;
387- if ( ispVal === '__other__' ) {
309+ var ispSel = document . getElementById ( 'isp_select' ) ;
310+ if ( ispSel . value === '__other__' ) {
388311 data . isp_name = document . getElementById ( 'isp_other_input' ) . value ;
389312 } else {
390- data . isp_name = ispVal ;
313+ data . isp_name = ispSel . value ;
391314 }
392315 data . theme = themeCheck . checked ? 'dark' : 'light' ;
393316 return data ;
0 commit comments