@@ -30,7 +30,7 @@ function getLabelNode(el: SelectHTMLElement): JQuery<HTMLElement> {
3030 . find ( 'label[for="' + escapedId + '"]' ) ;
3131}
3232
33- function getConfigScript ( el : SelectHTMLElement ) : JQuery < HTMLElement > {
33+ function getConfigScript ( el : SelectHTMLElement ) : JQuery < HTMLScriptElement > {
3434 return $ ( el )
3535 . parent ( )
3636 . find ( 'script[data-for="' + $escape ( el . id ) + '"]' ) ;
@@ -125,21 +125,24 @@ class SelectInputBinding extends InputBinding {
125125 this . _selectize ( el ) ;
126126 }
127127
128- // re-initialize selectize
129128 if ( hasDefinedProperty ( data , "config" ) ) {
130- const config = getConfigScript ( el ) ;
129+ const oldConfig = getConfigScript ( el ) ;
131130
132- // Before replacing, remember the default-plugins (for py-shiny)
133- const plugins = config . attr ( "data-default-plugins" ) ;
134- config . replaceWith ( data . config ! ) ;
131+ // Before replacing the config, remember the remove-button (for py-shiny)
132+ const oldRemoveButton = oldConfig [ 0 ] . getAttribute ( "data-remove-button" ) ;
135133
136- // If plugins were present in the old but not the new config,
137- // keep them since default plugins should be sticky across updates
134+ // Replace the old config with the new one
135+ oldConfig . replaceWith ( data . config ! ) ;
136+
137+ // If remove-button was present in the old but not the new config,
138+ // keep it since it should be sticky across updates
138139 const newConfig = getConfigScript ( el ) ;
139- if ( plugins && ! newConfig . attr ( "data-default-plugins" ) ) {
140- newConfig . attr ( "data-default-plugins" , plugins ) ;
140+ const newRemoveButton = newConfig [ 0 ] . getAttribute ( "data-remove-button" ) ;
141+ if ( oldRemoveButton !== null && newRemoveButton === null ) {
142+ newConfig [ 0 ] . setAttribute ( "data-remove-button" , oldRemoveButton ) ;
141143 }
142144
145+ // re-initialize selectize (with the new config)
143146 this . _selectize ( el , true ) ;
144147 }
145148
@@ -256,7 +259,7 @@ class SelectInputBinding extends InputBinding {
256259
257260 if ( config . length === 0 ) return undefined ;
258261
259- this . _supplyDefaultPlugins ( config ) ;
262+ this . _addRemoveButtonPlugins ( el , config [ 0 ] ) ;
260263
261264 let options : SelectizeOptions & {
262265 labelField : "label" ;
@@ -320,15 +323,26 @@ class SelectInputBinding extends InputBinding {
320323 return control ;
321324 }
322325
323- // py-shiny may include a data-default-plugins attribute, requesting
326+ // py-shiny may include a data-remove-button attribute, requesting
324327 // "default" plugins (i.e., plugins not specified by the user).
325328 // If present, update the config (i.e., the <script> tag's JSON object)
326329 // to include them.
327- private _supplyDefaultPlugins ( config : JQuery < HTMLElement > ) : void {
328- const plugins = config . data ( "default-plugins" ) ;
329- if ( ! Array . isArray ( plugins ) ) return ;
330+ private _addRemoveButtonPlugins (
331+ el : SelectHTMLElement ,
332+ config : HTMLScriptElement ,
333+ ) : void {
334+ if ( ! config . hasAttribute ( "data-remove-button" ) ) return ;
335+
336+ const removeButton = config . getAttribute ( "data-remove-button" ) ;
337+
338+ const plugins = [ ] ;
339+ if ( removeButton == "both" ) {
340+ plugins . push ( "remove_button" , "clear_button" ) ;
341+ } else if ( removeButton == "true" ) {
342+ plugins . push ( el . multiple ? "remove_button" : "clear_button" ) ;
343+ }
330344
331- const configJSON : SelectizeOptions = JSON . parse ( config . html ( ) ) ;
345+ const configJSON : SelectizeOptions = JSON . parse ( config . innerHTML ) ;
332346 const pluginsJSON = configJSON . plugins || [ ] ;
333347
334348 plugins . forEach ( ( plugin ) => {
@@ -338,7 +352,7 @@ class SelectInputBinding extends InputBinding {
338352 } ) ;
339353
340354 configJSON . plugins = pluginsJSON ;
341- config . html ( JSON . stringify ( configJSON ) ) ;
355+ config . innerHTML = JSON . stringify ( configJSON ) ;
342356 }
343357}
344358
0 commit comments