Skip to content

Commit 903f220

Browse files
committed
Fix combobox field attribute not sending values to form params
Fixed #440 - Remove `default: nil` from `attr :name` to match Phoenix core_components pattern, allowing `assign_new` to properly set name from form field - Add `assign_new(:name, fn -> nil end)` in non-field function heads for standalone usage without form - Fix JS createNewOption reply callback to update label and value independently instead of skipping when only label changes - Fix `_target: ["undefined"]` in phx-change by stopping search input event propagation to parent form - Extract `refreshSelectedDisplay` and `handleCreateReply` in JS hook
1 parent 930f91c commit 903f220

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

priv/assets/js/combobox.js

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ let Combobox = {
330330
},
331331

332332
handleSearch(e) {
333+
e.stopPropagation();
333334
this.clearCreateError();
334335
const query = e.target.value.toLowerCase();
335336
this.dropdownOptions = this.getDropdownOptions();
@@ -755,15 +756,40 @@ let Combobox = {
755756
}
756757
},
757758

758-
removeCreatedOption(selectOpt, optionEl, errorMsg) {
759-
selectOpt.remove();
760-
optionEl.remove();
761-
this.setupOptionListeners();
759+
refreshSelectedDisplay() {
762760
if (this.select.multiple) {
763761
this.updateMultipleSelectedDisplay();
764762
} else {
765763
this.updateSingleSelectedDisplay();
766764
}
765+
},
766+
767+
handleCreateReply(reply, selectOpt, optionEl) {
768+
if (reply.error) {
769+
this.removeCreatedOption(selectOpt, optionEl, reply.error);
770+
return;
771+
}
772+
773+
if (reply.value) {
774+
selectOpt.value = reply.value;
775+
optionEl.setAttribute("data-combobox-value", reply.value);
776+
}
777+
778+
if (reply.label) {
779+
selectOpt.textContent = reply.label;
780+
optionEl.querySelector("span").textContent = reply.label;
781+
}
782+
783+
if (reply.value || reply.label) {
784+
this.refreshSelectedDisplay();
785+
}
786+
},
787+
788+
removeCreatedOption(selectOpt, optionEl, errorMsg) {
789+
selectOpt.remove();
790+
optionEl.remove();
791+
this.setupOptionListeners();
792+
this.refreshSelectedDisplay();
767793
this.dispatchChangeEvent();
768794

769795
if (errorMsg) {
@@ -835,24 +861,7 @@ let Combobox = {
835861
this.pushEvent(
836862
this.onCreateEvent,
837863
{ id: this.el.id.replace(/-combo$/, ""), value: trimmed },
838-
(reply) => {
839-
if (reply.error) {
840-
this.removeCreatedOption(selectOpt, optionEl, reply.error);
841-
return;
842-
}
843-
if (reply.value && reply.value !== trimmed) {
844-
selectOpt.value = reply.value;
845-
selectOpt.textContent = reply.label || reply.value;
846-
optionEl.setAttribute("data-combobox-value", reply.value);
847-
optionEl.querySelector("span").textContent =
848-
reply.label || reply.value;
849-
if (this.select.multiple) {
850-
this.updateMultipleSelectedDisplay();
851-
} else {
852-
this.updateSingleSelectedDisplay();
853-
}
854-
}
855-
},
864+
(reply) => this.handleCreateReply(reply, selectOpt, optionEl),
856865
);
857866
}
858867
},

priv/components/combobox.eex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ defmodule <%= @module %> do
8686

8787
@doc type: :component
8888
attr :id, :any, default: nil, doc: "A unique identifier is used to manage state and interaction"
89-
attr :name, :any, default: nil, doc: "Name of input"
89+
attr :name, :any, doc: "Name of input"
9090
attr :label, :string, default: nil
9191
attr :value, :any, doc: "Value of input"
9292
attr :field, Phoenix.HTML.FormField, doc: "a form field struct retrieved from the form"
@@ -164,6 +164,7 @@ defmodule <%= @module %> do
164164
assigns =
165165
assigns
166166
|> assign_new(:id, fn -> "combo-#{random_id()}" end)
167+
|> assign_new(:name, fn -> nil end)
167168
|> assign_new(:options, fn -> [] end)
168169
|> assign_new(:option, fn -> [] end)
169170
|> assign_new(:value, fn -> Map.get(assigns, :value, []) end)
@@ -386,6 +387,7 @@ defmodule <%= @module %> do
386387
assigns =
387388
assigns
388389
|> assign_new(:id, fn -> "combo-#{random_id()}" end)
390+
|> assign_new(:name, fn -> nil end)
389391
|> assign_new(:options, fn -> [] end)
390392
|> assign_new(:option, fn -> [] end)
391393
|> assign_new(:value, fn -> Map.get(assigns, :value) end)

0 commit comments

Comments
 (0)