1- import { AlchemyHTMLElement } from "alchemy_admin/components/alchemy_html_element"
21import { setupSelectLocale } from "alchemy_admin/i18n"
32
43export function hightlightTerm ( name , term ) {
54 return name . replace ( new RegExp ( term , "gi" ) , ( match ) => `<em>${ match } </em>` )
65}
76
8- export class RemoteSelect extends AlchemyHTMLElement {
9- static properties = {
10- allowClear : { default : false } ,
11- selection : { default : undefined } ,
12- placeholder : { default : "" } ,
13- queryParams : { default : "{}" } ,
14- url : { default : "" }
15- }
7+ export class RemoteSelect extends HTMLElement {
8+ #select2 = null
169
17- async connected ( ) {
10+ async connectedCallback ( ) {
1811 await setupSelectLocale ( )
12+ // Bail out if the element was disconnected while the locale was loading.
13+ // Otherwise Select2 would leak onto a detached input.
14+ if ( ! this . isConnected ) return
1915
2016 this . input . classList . add ( "alchemy_selectbox" )
2117
22- $ ( this . input )
18+ this . #select2 = $ ( this . input )
2319 . select2 ( this . select2Config )
24- . on ( "select2-open" , ( evt ) => {
25- this . onOpen ( evt )
26- } )
27- . on ( "change" , ( evt ) => {
28- this . onChange ( evt )
29- } )
20+ . on ( "select2-open" , this . #onOpen)
21+ . on ( "change" , this . #onChange)
3022 }
3123
24+ disconnectedCallback ( ) {
25+ if ( this . #select2) {
26+ this . #select2. off ( "select2-open" , this . #onOpen)
27+ this . #select2. off ( "change" , this . #onChange)
28+ this . #select2. select2 ( "destroy" )
29+ this . #select2 = null
30+ }
31+ }
32+
33+ #onOpen = ( evt ) => this . onOpen ( evt )
34+ #onChange = ( evt ) => this . onChange ( evt )
35+
3236 /**
3337 * Optional on change handler called by Select2.
3438 * @param {Event } event
@@ -54,6 +58,38 @@ export class RemoteSelect extends AlchemyHTMLElement {
5458 } , 100 )
5559 }
5660
61+ /**
62+ * Dispatches a custom event with given name, namespaced under `Alchemy.`.
63+ * Subclasses may call this to emit their own events.
64+ * @param {string } name The name of the custom event
65+ * @param {object } detail Optional event details
66+ */
67+ dispatchCustomEvent ( name , detail = { } ) {
68+ this . dispatchEvent (
69+ new CustomEvent ( `Alchemy.${ name } ` , { bubbles : true , detail } )
70+ )
71+ }
72+
73+ get allowClear ( ) {
74+ return this . hasAttribute ( "allow-clear" )
75+ }
76+
77+ get selection ( ) {
78+ return this . getAttribute ( "selection" )
79+ }
80+
81+ get placeholder ( ) {
82+ return this . getAttribute ( "placeholder" ) ?? ""
83+ }
84+
85+ get queryParams ( ) {
86+ return this . getAttribute ( "query-params" ) ?? "{}"
87+ }
88+
89+ get url ( ) {
90+ return this . getAttribute ( "url" ) ?? ""
91+ }
92+
5793 get input ( ) {
5894 return this . getElementsByTagName ( "input" ) [ 0 ]
5995 }
0 commit comments