advanced_select 0.1.10 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3268b609f1b4c08af63c6bc791459345dbbdfb1afa3a1e9974569392e27b417a
4
- data.tar.gz: 525a23db2449fd8867d83fb7b1647d75d6d194a4791971fec0cb55de48a2d1c8
3
+ metadata.gz: be334c14eaabfa7e2d3685deb4f1404b7187cb51c94d8a8dcb17b17e70bc5435
4
+ data.tar.gz: b9a676e2e4a64345631612285e8a362034b4efaaf60650cd201eadb2fa41b5a0
5
5
  SHA512:
6
- metadata.gz: f66187ab2d1914f3de4c933fecbf3b9237684b4c8d911de1582426002f6d099820181401137d6c0896d3cdb99b1af38ecf12acbdd8dd29ff7aac6af965e2c587
7
- data.tar.gz: 3a240d713742fcd791541b4272e499d6036d8ada44eb8697529628d9b1ceb9092678362bf435bcd25bc8b33d95e6f9a95d4a752e23b9b587fe814b738ddb9cd6
6
+ metadata.gz: be666dac14558aa5437cdf536c4bac3e8b392c61694904794a9d935de038152d6852c19e1d537a833f80836ae1101671890b707ea17732773905f185a81bc007
7
+ data.tar.gz: 5ac9dd843c6e837480dbc2fd6a00ecb6013e150a4c278e46ad75dafa1d8476973ac3e081125cd5ef678f5ba5fa5c6d2eb54676fc30fa258c870cd72833aa8a0d
data/README.md CHANGED
@@ -23,6 +23,8 @@ AdvancedSelect is a small Rails engine for rendering an advanced select input wi
23
23
  - [Custom Option Content](#custom-option-content)
24
24
  - [Option Contract](#option-contract)
25
25
  - [Events](#events)
26
+ - [Reading And Writing The Value](#reading-and-writing-the-value)
27
+ - [Driving The Option List](#driving-the-option-list)
26
28
  - [Disabled State](#disabled-state)
27
29
  - [API Reference](#api-reference)
28
30
  - [Local Development](#local-development)
@@ -205,6 +207,30 @@ application.register("advanced-select", AdvancedSelectController)
205
207
 
206
208
  This keeps local custom behavior small while allowing future gem fixes to flow through the base controller.
207
209
 
210
+ Two methods exist as extension points for host apps whose options endpoint does not speak Turbo
211
+ Streams. `readOptionsResponse(response)` turns the `fetch` response into a payload and defaults to
212
+ `response.text()`; `renderOptionsResponse(payload)` puts that payload on the page and defaults to
213
+ `Turbo.renderStreamMessage(payload)`. Overriding them keeps the request sequencing, the stale
214
+ response guard, and the post-render bookkeeping in the base controller:
215
+
216
+ ```js
217
+ export default class extends AdvancedSelectController {
218
+ readOptionsResponse(response) {
219
+ return response.headers.get("content-type")?.includes("application/json")
220
+ ? response.json()
221
+ : super.readOptionsResponse(response)
222
+ }
223
+
224
+ renderOptionsResponse(payload) {
225
+ if (Array.isArray(payload)) {
226
+ this.replaceOptions(payload)
227
+ } else {
228
+ super.renderOptionsResponse(payload)
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
208
234
  For `jsbundling-rails` and other bundlers, the installer copies the full controller because bundlers do not resolve Rails engine JavaScript assets automatically. In that setup the copied file is host-owned.
209
235
 
210
236
  ### jsbundling/Propshaft Example
@@ -756,6 +782,22 @@ Every value change dispatches two events:
756
782
  | `change` | the first hidden input | native form behaviour and [dependent fields](#dependent-fields) |
757
783
  | `advanced-select:change` | the root element | application listeners that need the whole selection |
758
784
 
785
+ A remote field also announces when its options finish rendering:
786
+
787
+ | Event | Target | Purpose |
788
+ | --- | --- | --- |
789
+ | `advanced-select:options-loaded` | the root element | application listeners that react to the option list itself |
790
+
791
+ It fires after every successful [remote](#remote-search) load — including eager
792
+ [dependent](#dependent-fields) loads — once the options are in the DOM and any single-option
793
+ auto-selection has been applied. Its `detail` carries the field `name`, the resulting `value`, and
794
+ the `count` of selectable options, which is enough to react to an empty or single-option result
795
+ without reading the DOM:
796
+
797
+ ```erb
798
+ data-action="advanced-select:options-loaded->my-controller#optionsChanged"
799
+ ```
800
+
759
801
  Both bubble. `advanced-select:change` carries a `detail` payload:
760
802
 
761
803
  ```js
@@ -784,14 +826,70 @@ Prefer it over `change` on multiple selects. `change` is dispatched from the fir
784
826
  it does not fire at all once the last value is cleared from a field rendered with
785
827
  `include_hidden: false` — at that point the field has no inputs left.
786
828
 
787
- The current value is also readable from the controller:
829
+ The current value is also readable from the controller — see [Reading And Writing The Value](#reading-and-writing-the-value).
830
+
831
+ ### Reading And Writing The Value
832
+
833
+ The controller exposes the selection as a small programmatic API, so host code can drive a field
834
+ without reaching into its markup:
788
835
 
789
836
  ```js
790
837
  const select = application.getControllerForElementAndIdentifier(element, "advanced-select")
791
838
 
792
- select.currentValue // => ["3", "7"]
839
+ select.getValue() // => "7", or ["3", "7"] on a multiple select
840
+ select.setValue("7")
841
+ select.setValue(["3", "7"]) // multiple selects also accept a single value
842
+ select.setValue("7", { silent: true }) // assign without broadcasting a change
843
+ select.refresh() // re-render from the current selection
844
+ ```
845
+
846
+ `getValue` returns the submit value — the option's `value` when it defines one, otherwise its `id`.
847
+ It is a string for single selects, an array for multiple selects, and empty when nothing is
848
+ selected.
849
+
850
+ `setValue` resolves each value against the options currently in the list, matching either the
851
+ option's id or its submit value, so `setValue("identity-7")` and `setValue("submit-7")` select the
852
+ same row. A value that matches no option is still assigned and submitted, using the value itself as
853
+ the label — this keeps a server-assigned value from being silently dropped. Passing `""`, `null`, or
854
+ `[]` clears the field. On a single select only the first value of an array is kept.
855
+
856
+ `silent: true` suppresses the `change` and `advanced-select:change` events for that one assignment.
857
+ Use it when the value is being restored rather than chosen — replacing options after a Turbo Stream
858
+ update, for example — so dependent fields do not cascade off a change the user did not make. The
859
+ suppression lasts for a single render; the next assignment broadcasts normally.
860
+
861
+ ### Driving The Option List
862
+
863
+ The option list can be driven from the browser as well, for host apps that load options from
864
+ somewhere the Turbo Stream flow does not cover:
865
+
866
+ ```js
867
+ select.appendOption({ id: "9", label: "Item C" })
868
+
869
+ select.replaceOptions([
870
+ { id: "3", label: "Item A" },
871
+ { id: "7", label: "Item B" }
872
+ ])
873
+
874
+ select.replaceOptions(options, { selected: "7" }) // replace the list and set the value
875
+ select.replaceOptions(options, { selected: null }) // replace the list and clear the value
876
+ select.replaceOptions(options, { silent: false }) // broadcast the resulting value
793
877
  ```
794
878
 
879
+ Both take options in the [option contract](#option-contract) shape and render them through
880
+ `optionElement`, so they carry the host's class map.
881
+
882
+ `appendOption` adds one option to the end of the list and does nothing if an option with that id is
883
+ already there. It does not select the option — that is `addOption`, which exists for
884
+ [Add Mode](#add-mode), where the user creates a value that was not in the list.
885
+
886
+ `replaceOptions` swaps the whole list. Leaving `selected` out keeps the current selection, even when
887
+ the new list no longer contains it — the common case after a search, where the selected record may
888
+ have fallen outside the page of results. Passing `selected` assigns it with `setValue` semantics.
889
+
890
+ Unlike `setValue`, `replaceOptions` is silent by default: replacing a list is not a value change, so
891
+ it should not cascade to dependent fields on its own. Pass `silent: false` when it should.
892
+
795
893
  ### Disabled State
796
894
 
797
895
  Pass `disabled: true` to lock a field. It still renders its current selection —
@@ -1013,6 +1111,16 @@ Tailwind content scanning can usually see class strings when they are written li
1013
1111
 
1014
1112
  The host app can still load the gem CSS through `application.css`. `classes:` entries replace the mapped default classes for that helper call; unmapped keys keep the gem defaults. `append_classes:` entries keep the resolved class and append host classes after it.
1015
1113
 
1114
+ The resolved `option`, `option_check`, `option_content`, and `option_description` classes are also published on the root element as data attributes, so options the controller builds in the browser carry the same classes as the ones the server renders. `optionElement(option)` returns such an element:
1115
+
1116
+ ```js
1117
+ const select = application.getControllerForElementAndIdentifier(element, "advanced-select")
1118
+
1119
+ select.currentOptionsTarget.appendChild(select.optionElement({ id: "7", label: "Item B" }))
1120
+ ```
1121
+
1122
+ It produces the same markup as `advanced_select_option_tag`: the option contract's `id`, `value`, `label`, `display_label`, and `description` are all honored, and the resulting element is fully interactive — hovering activates it and clicking selects it.
1123
+
1016
1124
  ### CSS Overrides
1017
1125
 
1018
1126
  Importmap/Sprockets host applications can put app-specific styling in a host-owned file such as:
@@ -30,6 +30,7 @@ export default class extends Controller {
30
30
  this.timer = null
31
31
  this.requestSequence = 0
32
32
  this.activeIndex = -1
33
+ this.suppressChange = false
33
34
  this.placeholderClass = this.element.dataset.advancedSelectPlaceholderClass || "ui-advanced-select-placeholder"
34
35
  this.valueClass = this.element.dataset.advancedSelectValueClass || "ui-advanced-select-value"
35
36
  this.tokenClass = this.element.dataset.advancedSelectTokenClass || "ui-advanced-select-token"
@@ -40,6 +41,10 @@ export default class extends Controller {
40
41
  this.optionActiveClasses = this.classList(this.element.dataset.advancedSelectOptionActiveClass || "ui-advanced-select-option-active")
41
42
  this.addOptionActiveClasses = this.classList(this.element.dataset.advancedSelectAddOptionActiveClass || "")
42
43
  this.optionSelectedClasses = this.classList(this.element.dataset.advancedSelectOptionSelectedClass || "")
44
+ this.optionClass = this.element.dataset.advancedSelectOptionClass || "ui-advanced-select-option"
45
+ this.optionCheckClass = this.element.dataset.advancedSelectOptionCheckClass || "ui-advanced-select-option-check"
46
+ this.optionContentClass = this.element.dataset.advancedSelectOptionContentClass || "ui-advanced-select-option-content"
47
+ this.optionDescriptionClass = this.element.dataset.advancedSelectOptionDescriptionClass || "ui-advanced-select-option-description"
43
48
  this.selectedValue = this.selectedValue.map((option) => this.normalizeSelectedOption(option))
44
49
  this.close = this.close.bind(this)
45
50
  this.renderOptionsState()
@@ -164,6 +169,55 @@ export default class extends Controller {
164
169
  this.close()
165
170
  }
166
171
 
172
+ getValue() {
173
+ return this.currentValue
174
+ }
175
+
176
+ setValue(value, { silent = false } = {}) {
177
+ const requested = (Array.isArray(value) ? value : [value])
178
+ .filter((item) => item !== "" && item != null)
179
+ .map(String)
180
+ const values = this.multipleValue ? requested : requested.slice(0, 1)
181
+ const options = this.optionElements.map((element) => this.optionData(element))
182
+
183
+ this.selectedValue = values.map((item) => {
184
+ const option = options.find((candidate) => candidate.id === item || candidate.value === item)
185
+
186
+ return this.normalizeSelectedOption(option || { id: item, value: item, label: item })
187
+ })
188
+
189
+ this.suppressChange = silent
190
+ this.renderSelection()
191
+ }
192
+
193
+ appendOption(option) {
194
+ const normalized = this.normalizeSelectedOption(option)
195
+ const present = this.optionElements.some((element) => element.dataset.advancedSelectValueParam === normalized.id)
196
+
197
+ if (present) {
198
+ return
199
+ }
200
+
201
+ this.currentOptionsTarget.appendChild(this.optionElement(normalized))
202
+ this.renderOptionsState()
203
+ }
204
+
205
+ replaceOptions(options, { selected, silent = true } = {}) {
206
+ this.currentOptionsTarget.replaceChildren(...options.map((option) => this.optionElement(option)))
207
+
208
+ if (selected === undefined) {
209
+ this.suppressChange = silent
210
+ this.renderSelection()
211
+ return
212
+ }
213
+
214
+ this.setValue(selected, { silent })
215
+ }
216
+
217
+ refresh() {
218
+ this.renderSelection()
219
+ }
220
+
167
221
  keydown(event) {
168
222
  if (event.key === "ArrowDown") {
169
223
  event.preventDefault()
@@ -265,14 +319,14 @@ export default class extends Controller {
265
319
  throw new Error("Advanced select options request failed")
266
320
  }
267
321
 
268
- return response.text()
322
+ return this.readOptionsResponse(response)
269
323
  })
270
- .then((html) => {
324
+ .then((payload) => {
271
325
  if (!(eager || this.expanded) || requestSequence !== this.requestSequence) {
272
326
  return
273
327
  }
274
328
 
275
- Turbo.renderStreamMessage(html)
329
+ this.renderOptionsResponse(payload)
276
330
  requestAnimationFrame(() => {
277
331
  if (!(eager || this.expanded) || requestSequence !== this.requestSequence) {
278
332
  return
@@ -285,6 +339,8 @@ export default class extends Controller {
285
339
  if (autoSelect) {
286
340
  this.autoSelectSingle()
287
341
  }
342
+
343
+ this.dispatchOptionsLoaded()
288
344
  })
289
345
  })
290
346
  .catch(() => {
@@ -350,6 +406,37 @@ export default class extends Controller {
350
406
  }
351
407
  }
352
408
 
409
+ optionElement(option) {
410
+ const normalized = this.normalizeSelectedOption(option)
411
+ const button = document.createElement("button")
412
+
413
+ button.type = "button"
414
+ button.className = this.optionClass
415
+ button.setAttribute("role", "option")
416
+ button.setAttribute("aria-selected", "false")
417
+ button.dataset.advancedSelectOption = ""
418
+ button.dataset.action = "mouseenter->advanced-select#activateOption mousedown->advanced-select#choose"
419
+ button.dataset.advancedSelectValueParam = normalized.id
420
+ button.dataset.advancedSelectSubmitValueParam = normalized.value
421
+ button.dataset.advancedSelectLabelParam = normalized.label
422
+ button.dataset.advancedSelectDisplayLabelParam = normalized.displayLabel
423
+ button.dataset.advancedSelectOptionParam = JSON.stringify(normalized)
424
+
425
+ const check = this.textElement("span", this.optionCheckClass, "")
426
+ check.dataset.advancedSelectOptionCheck = ""
427
+
428
+ const content = this.textElement("span", this.optionContentClass, "")
429
+ content.appendChild(this.textElement("span", "", normalized.label))
430
+
431
+ if (normalized.description) {
432
+ content.appendChild(this.textElement("span", this.optionDescriptionClass, normalized.description))
433
+ }
434
+
435
+ button.append(check, content)
436
+
437
+ return button
438
+ }
439
+
353
440
  optionData(element) {
354
441
  const data = this.parseOptionData(element.dataset.advancedSelectOptionParam)
355
442
  const value = element.dataset.advancedSelectValueParam
@@ -402,7 +489,31 @@ export default class extends Controller {
402
489
  this.renderOptionsState()
403
490
  this.caretTarget.classList.toggle("hidden", this.selectedValue.length > 0)
404
491
  this.clearTarget.classList.toggle("hidden", this.disabledValue || this.selectedValue.length === 0)
405
- this.dispatchValueChange()
492
+
493
+ if (this.suppressChange) {
494
+ this.suppressChange = false
495
+ } else {
496
+ this.dispatchValueChange()
497
+ }
498
+ }
499
+
500
+ readOptionsResponse(response) {
501
+ return response.text()
502
+ }
503
+
504
+ renderOptionsResponse(payload) {
505
+ Turbo.renderStreamMessage(payload)
506
+ }
507
+
508
+ dispatchOptionsLoaded() {
509
+ this.element.dispatchEvent(new CustomEvent("advanced-select:options-loaded", {
510
+ bubbles: true,
511
+ detail: {
512
+ name: this.nameValue,
513
+ value: this.currentValue,
514
+ count: this.selectableOptionElements.length
515
+ }
516
+ }))
406
517
  }
407
518
 
408
519
  dispatchValueChange() {
@@ -29,6 +29,10 @@
29
29
  data-advanced-select-option-active-class="<%= advanced_select_state_class(class_map, :option_active) %>"
30
30
  data-advanced-select-add-option-active-class="<%= advanced_select_state_class(class_map, :add_option_active) %>"
31
31
  data-advanced-select-option-selected-class="<%= advanced_select_state_class(class_map, :option_selected) %>"
32
+ data-advanced-select-option-class="<%= advanced_select_class(class_map, :option) %>"
33
+ data-advanced-select-option-check-class="<%= advanced_select_class(class_map, :option_check) %>"
34
+ data-advanced-select-option-content-class="<%= advanced_select_class(class_map, :option_content) %>"
35
+ data-advanced-select-option-description-class="<%= advanced_select_class(class_map, :option_description) %>"
32
36
  data-advanced-select-selected-value="<%= advanced_select_selected_value(selected_options) %>">
33
37
  <div data-advanced-select-target="hiddenFields">
34
38
  <% if multiple %>
@@ -1,3 +1,3 @@
1
1
  module AdvancedSelect
2
- VERSION = "0.1.10"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -30,6 +30,7 @@ export default class extends Controller {
30
30
  this.timer = null
31
31
  this.requestSequence = 0
32
32
  this.activeIndex = -1
33
+ this.suppressChange = false
33
34
  this.placeholderClass = this.element.dataset.advancedSelectPlaceholderClass || "ui-advanced-select-placeholder"
34
35
  this.valueClass = this.element.dataset.advancedSelectValueClass || "ui-advanced-select-value"
35
36
  this.tokenClass = this.element.dataset.advancedSelectTokenClass || "ui-advanced-select-token"
@@ -40,6 +41,10 @@ export default class extends Controller {
40
41
  this.optionActiveClasses = this.classList(this.element.dataset.advancedSelectOptionActiveClass || "ui-advanced-select-option-active")
41
42
  this.addOptionActiveClasses = this.classList(this.element.dataset.advancedSelectAddOptionActiveClass || "")
42
43
  this.optionSelectedClasses = this.classList(this.element.dataset.advancedSelectOptionSelectedClass || "")
44
+ this.optionClass = this.element.dataset.advancedSelectOptionClass || "ui-advanced-select-option"
45
+ this.optionCheckClass = this.element.dataset.advancedSelectOptionCheckClass || "ui-advanced-select-option-check"
46
+ this.optionContentClass = this.element.dataset.advancedSelectOptionContentClass || "ui-advanced-select-option-content"
47
+ this.optionDescriptionClass = this.element.dataset.advancedSelectOptionDescriptionClass || "ui-advanced-select-option-description"
43
48
  this.selectedValue = this.selectedValue.map((option) => this.normalizeSelectedOption(option))
44
49
  this.close = this.close.bind(this)
45
50
  this.renderOptionsState()
@@ -164,6 +169,55 @@ export default class extends Controller {
164
169
  this.close()
165
170
  }
166
171
 
172
+ getValue() {
173
+ return this.currentValue
174
+ }
175
+
176
+ setValue(value, { silent = false } = {}) {
177
+ const requested = (Array.isArray(value) ? value : [value])
178
+ .filter((item) => item !== "" && item != null)
179
+ .map(String)
180
+ const values = this.multipleValue ? requested : requested.slice(0, 1)
181
+ const options = this.optionElements.map((element) => this.optionData(element))
182
+
183
+ this.selectedValue = values.map((item) => {
184
+ const option = options.find((candidate) => candidate.id === item || candidate.value === item)
185
+
186
+ return this.normalizeSelectedOption(option || { id: item, value: item, label: item })
187
+ })
188
+
189
+ this.suppressChange = silent
190
+ this.renderSelection()
191
+ }
192
+
193
+ appendOption(option) {
194
+ const normalized = this.normalizeSelectedOption(option)
195
+ const present = this.optionElements.some((element) => element.dataset.advancedSelectValueParam === normalized.id)
196
+
197
+ if (present) {
198
+ return
199
+ }
200
+
201
+ this.currentOptionsTarget.appendChild(this.optionElement(normalized))
202
+ this.renderOptionsState()
203
+ }
204
+
205
+ replaceOptions(options, { selected, silent = true } = {}) {
206
+ this.currentOptionsTarget.replaceChildren(...options.map((option) => this.optionElement(option)))
207
+
208
+ if (selected === undefined) {
209
+ this.suppressChange = silent
210
+ this.renderSelection()
211
+ return
212
+ }
213
+
214
+ this.setValue(selected, { silent })
215
+ }
216
+
217
+ refresh() {
218
+ this.renderSelection()
219
+ }
220
+
167
221
  keydown(event) {
168
222
  if (event.key === "ArrowDown") {
169
223
  event.preventDefault()
@@ -265,14 +319,14 @@ export default class extends Controller {
265
319
  throw new Error("Advanced select options request failed")
266
320
  }
267
321
 
268
- return response.text()
322
+ return this.readOptionsResponse(response)
269
323
  })
270
- .then((html) => {
324
+ .then((payload) => {
271
325
  if (!(eager || this.expanded) || requestSequence !== this.requestSequence) {
272
326
  return
273
327
  }
274
328
 
275
- Turbo.renderStreamMessage(html)
329
+ this.renderOptionsResponse(payload)
276
330
  requestAnimationFrame(() => {
277
331
  if (!(eager || this.expanded) || requestSequence !== this.requestSequence) {
278
332
  return
@@ -285,6 +339,8 @@ export default class extends Controller {
285
339
  if (autoSelect) {
286
340
  this.autoSelectSingle()
287
341
  }
342
+
343
+ this.dispatchOptionsLoaded()
288
344
  })
289
345
  })
290
346
  .catch(() => {
@@ -350,6 +406,37 @@ export default class extends Controller {
350
406
  }
351
407
  }
352
408
 
409
+ optionElement(option) {
410
+ const normalized = this.normalizeSelectedOption(option)
411
+ const button = document.createElement("button")
412
+
413
+ button.type = "button"
414
+ button.className = this.optionClass
415
+ button.setAttribute("role", "option")
416
+ button.setAttribute("aria-selected", "false")
417
+ button.dataset.advancedSelectOption = ""
418
+ button.dataset.action = "mouseenter->advanced-select#activateOption mousedown->advanced-select#choose"
419
+ button.dataset.advancedSelectValueParam = normalized.id
420
+ button.dataset.advancedSelectSubmitValueParam = normalized.value
421
+ button.dataset.advancedSelectLabelParam = normalized.label
422
+ button.dataset.advancedSelectDisplayLabelParam = normalized.displayLabel
423
+ button.dataset.advancedSelectOptionParam = JSON.stringify(normalized)
424
+
425
+ const check = this.textElement("span", this.optionCheckClass, "")
426
+ check.dataset.advancedSelectOptionCheck = ""
427
+
428
+ const content = this.textElement("span", this.optionContentClass, "")
429
+ content.appendChild(this.textElement("span", "", normalized.label))
430
+
431
+ if (normalized.description) {
432
+ content.appendChild(this.textElement("span", this.optionDescriptionClass, normalized.description))
433
+ }
434
+
435
+ button.append(check, content)
436
+
437
+ return button
438
+ }
439
+
353
440
  optionData(element) {
354
441
  const data = this.parseOptionData(element.dataset.advancedSelectOptionParam)
355
442
  const value = element.dataset.advancedSelectValueParam
@@ -402,7 +489,31 @@ export default class extends Controller {
402
489
  this.renderOptionsState()
403
490
  this.caretTarget.classList.toggle("hidden", this.selectedValue.length > 0)
404
491
  this.clearTarget.classList.toggle("hidden", this.disabledValue || this.selectedValue.length === 0)
405
- this.dispatchValueChange()
492
+
493
+ if (this.suppressChange) {
494
+ this.suppressChange = false
495
+ } else {
496
+ this.dispatchValueChange()
497
+ }
498
+ }
499
+
500
+ readOptionsResponse(response) {
501
+ return response.text()
502
+ }
503
+
504
+ renderOptionsResponse(payload) {
505
+ Turbo.renderStreamMessage(payload)
506
+ }
507
+
508
+ dispatchOptionsLoaded() {
509
+ this.element.dispatchEvent(new CustomEvent("advanced-select:options-loaded", {
510
+ bubbles: true,
511
+ detail: {
512
+ name: this.nameValue,
513
+ value: this.currentValue,
514
+ count: this.selectableOptionElements.length
515
+ }
516
+ }))
406
517
  }
407
518
 
408
519
  dispatchValueChange() {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: advanced_select
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mehmet Celik