Skip to content

Commit

Permalink
Adapt to select2 version 4 for :array options of form_configurable
Browse files Browse the repository at this point in the history
- Use the `<select>` tag  as demanded in version 4
- Turn on `tags` to allow for manual input
- Drop complete API response caching and simplify:
  - Use the AjaxAdapter when cache_response is false
  - Use the ArrayAdapter when cache_response is true after calling the API
  • Loading branch information
knu committed Apr 19, 2023
1 parent 6dc9783 commit 4b36537
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 77 deletions.
120 changes: 44 additions & 76 deletions app/assets/javascripts/components/form_configurable.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,6 @@ $(function () {
};

return (window.initializeFormCompletable = function () {
let returnedResults = {};
const completableDefaultOptions = (input) => ({
results: [
returnedResults[$(input).data("attribute")] || {
text: "Options",
children: [{ id: undefined, text: "loading ..." }],
},
{
text: "Current",
children: [{ id: $(input).val(), text: $(input).val() }],
},
{
text: "Custom",
children: [{ id: "manualInput", text: "manual input" }],
},
],
});

$("input[role~=validatable], select[role~=validatable]").on(
"change",
(e) => {
Expand All @@ -38,89 +20,75 @@ $(function () {
form_group.addClass("has-feedback").removeClass("has-error");
form_group.find("span").addClass("hidden");
form_group.find(".glyphicon-ok").removeClass("hidden");
return (returnedResults = {});
},
error: (data) => {
form_group.addClass("has-feedback").addClass("has-error");
form_group.find("span").addClass("hidden");
form_group.find(".glyphicon-remove").removeClass("hidden");
return (returnedResults = {});
},
});
}
);

$("input[role~=validatable], select[role~=validatable]").trigger("change");

$.each($("input[role~=completable]"), (i, input) =>
$(input)
.select2({
data: () => completableDefaultOptions(input),
})
.on("change", function (e) {
if (e.added && e.added.id === "manualInput") {
$(e.currentTarget).select2("destroy");
return $(e.currentTarget).val(e.removed.id);
}
})
);
$.each($("select[role~=completable]"), (i, select) => {
const $select = $(select);
const value = $select.data("value");

const updateDropdownData = function (form_data, element, data) {
returnedResults[form_data.attribute] = {
text: "Options",
children: data,
const setValue = (value) => {
if (
$select
.find("option")
.toArray()
.some((option) => option.value == value)
) {
$select.val(value).trigger("change");
} else {
$select
.append(new Option(value, value, true, true))
.trigger("change");
}
};
$(element).trigger("change");
$("input[role~=completable]").off(
"select2-opening",
select2OpeningCallback
);
$(element).select2("open");
return $("input[role~=completable]").on(
"select2-opening",
select2OpeningCallback
);
};

var select2OpeningCallback = function (e) {
const form_data = getFormData(e.currentTarget);
if (
returnedResults[form_data.attribute] &&
!$(e.currentTarget).data("cacheResponse")
) {
delete returnedResults[form_data.attribute];
}
if (returnedResults[form_data.attribute]) {
return;
}

return $.ajax("/agents/complete", {
type: "POST",
data: form_data,
success: (data) => {
return updateDropdownData(form_data, e.currentTarget, data);
},
error: (data) => {
return updateDropdownData(form_data, e.currentTarget, [
{ id: undefined, text: "Error loading data." },
]);
},
});
};
if ($select.data("cacheResponse")) {
const loadData = (data) => {
$select.select2({ data: data, tags: true });
setValue(value);
};

$("input[role~=completable]").on("select2-opening", select2OpeningCallback);
$.ajax("/agents/complete", {
type: "POST",
data: getFormData(select),
success: (data) => loadData(data),
error: (data) =>
loadData([{ id: undefined, text: "Error loading data." }]),
});
} else {
$select.select2({
ajax: {
url: "/agents/complete",
type: "POST",
data: (params) => getFormData(select),
processResults: (data) => ({ results: data }),
},
tags: true,
});
setValue(value);
}
});

return $("input[type=radio][role~=form-configurable]").change(function (e) {
$("input[type=radio][role~=form-configurable]").change(function (e) {
const input = $(e.currentTarget)
.parents()
.siblings(
`input[data-attribute=${$(e.currentTarget).data("attribute")}]`
);
if ($(e.currentTarget).val() === "manual") {
return input.removeClass("hidden");
input.removeClass("hidden");
} else {
input.val($(e.currentTarget).val());
return input.addClass("hidden");
input.addClass("hidden");
}
});
});
Expand Down
6 changes: 5 additions & 1 deletion app/presenters/form_configurable_agent_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ def option_field_for(attribute)
@view.concat(@view.text_field_tag("agent[options][#{attribute}]", value,
html_options.merge(class: "form-control #{@agent.send(:boolify, value) != nil ? 'hidden' : ''}")))
end
when :array, :string
when :array
@view.select_tag "agent[options][#{attribute}]", nil,
html_options.deep_merge(class: 'form-control',
data: { value:, cache_response: data[:cache_response] != false })
when :string
@view.text_field_tag "agent[options][#{attribute}]", value,
html_options.deep_merge(class: 'form-control', data: { cache_response: data[:cache_response] != false })
end
Expand Down

0 comments on commit 4b36537

Please sign in to comment.