2020-08-01 03:43:15 +02:00
|
|
|
"use strict";
|
|
|
|
|
2020-04-14 10:43:30 +02:00
|
|
|
const DropdownListWidget = function (opts) {
|
2020-05-19 00:16:34 +02:00
|
|
|
const init = () => {
|
|
|
|
// Run basic sanity checks on opts, and set up sane defaults.
|
2020-07-15 00:34:28 +02:00
|
|
|
opts = Object.assign(
|
|
|
|
{
|
|
|
|
null_value: null,
|
|
|
|
render_text: (item_name) => item_name,
|
|
|
|
on_update: () => {},
|
|
|
|
},
|
|
|
|
opts,
|
|
|
|
);
|
2020-05-19 00:16:34 +02:00
|
|
|
opts.container_id = `${opts.widget_name}_widget`;
|
|
|
|
opts.value_id = `id_${opts.widget_name}`;
|
|
|
|
if (opts.value === undefined) {
|
|
|
|
opts.value = opts.null_value;
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.warn("dropdown-list-widget: Called without a default value; using null value");
|
2020-05-19 00:16:34 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
init();
|
2020-04-14 10:43:30 +02:00
|
|
|
|
|
|
|
const render_dropdown_list = require("../templates/settings/dropdown_list.hbs");
|
|
|
|
|
|
|
|
const render = (value) => {
|
|
|
|
$(`#${opts.container_id} #${opts.value_id}`).data("value", value);
|
|
|
|
|
2020-05-18 23:08:30 +02:00
|
|
|
const elem = $(`#${opts.container_id} #${opts.widget_name}_name`);
|
2020-04-14 10:43:30 +02:00
|
|
|
|
|
|
|
if (!value || value === opts.null_value) {
|
|
|
|
elem.text(opts.default_text);
|
|
|
|
elem.addClass("text-warning");
|
2020-07-15 01:29:15 +02:00
|
|
|
elem.closest(".input-group").find(".dropdown_list_reset_button:not([disabled])").hide();
|
2020-04-14 10:43:30 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Happy path
|
2020-07-02 01:39:34 +02:00
|
|
|
const item = opts.data.find((x) => x.value === value.toString());
|
2020-04-14 10:43:30 +02:00
|
|
|
const text = opts.render_text(item.name);
|
|
|
|
elem.text(text);
|
2020-07-15 01:29:15 +02:00
|
|
|
elem.removeClass("text-warning");
|
|
|
|
elem.closest(".input-group").find(".dropdown_list_reset_button:not([disabled])").show();
|
2020-04-14 10:43:30 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const update = (value) => {
|
|
|
|
render(value);
|
2020-04-30 13:09:48 +02:00
|
|
|
opts.on_update(value);
|
2020-04-14 10:43:30 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const register_event_handlers = () => {
|
2020-07-15 00:34:28 +02:00
|
|
|
$(`#${opts.container_id} .dropdown-list-body`).on("click keypress", ".list_item", function (
|
|
|
|
e,
|
|
|
|
) {
|
2020-05-18 23:08:30 +02:00
|
|
|
const setting_elem = $(this).closest(`.${opts.widget_name}_setting`);
|
2020-04-14 10:43:30 +02:00
|
|
|
if (e.type === "keypress") {
|
|
|
|
if (e.which === 13) {
|
|
|
|
setting_elem.find(".dropdown-menu").dropdown("toggle");
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2020-07-15 01:29:15 +02:00
|
|
|
const value = $(this).attr("data-value");
|
2020-04-14 10:43:30 +02:00
|
|
|
update(value);
|
|
|
|
});
|
2020-07-20 21:26:58 +02:00
|
|
|
$(`#${opts.container_id} .dropdown_list_reset_button`).on("click", (e) => {
|
2020-04-14 10:43:30 +02:00
|
|
|
update(opts.null_value);
|
2020-05-19 07:01:53 +02:00
|
|
|
e.preventDefault();
|
2020-04-14 10:43:30 +02:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-04-15 04:29:15 +02:00
|
|
|
const setup = () => {
|
|
|
|
// populate the dropdown
|
|
|
|
const dropdown_list_body = $(`#${opts.container_id} .dropdown-list-body`).expectOne();
|
|
|
|
const search_input = $(`#${opts.container_id} .dropdown-search > input[type=text]`);
|
2020-04-15 22:55:05 +02:00
|
|
|
const dropdown_toggle = $(`#${opts.container_id} .dropdown-toggle`);
|
2020-04-15 04:29:15 +02:00
|
|
|
|
|
|
|
list_render.create(dropdown_list_body, opts.data, {
|
2020-05-18 23:08:30 +02:00
|
|
|
name: `${opts.widget_name}_list`,
|
2020-07-20 22:18:43 +02:00
|
|
|
modifier(item) {
|
|
|
|
return render_dropdown_list({item});
|
2020-04-15 04:29:15 +02:00
|
|
|
},
|
|
|
|
filter: {
|
|
|
|
element: search_input,
|
2020-07-20 22:18:43 +02:00
|
|
|
predicate(item, value) {
|
2020-04-15 04:29:15 +02:00
|
|
|
return item.name.toLowerCase().includes(value);
|
|
|
|
},
|
|
|
|
},
|
2020-07-04 10:07:43 +02:00
|
|
|
simplebar_container: $(`#${opts.container_id} .dropdown-list-wrapper`),
|
2020-04-15 04:29:15 +02:00
|
|
|
});
|
2020-07-20 21:26:58 +02:00
|
|
|
$(`#${opts.container_id} .dropdown-search`).on("click", (e) => {
|
2020-04-15 04:29:15 +02:00
|
|
|
e.stopPropagation();
|
|
|
|
});
|
|
|
|
|
2020-07-20 21:26:58 +02:00
|
|
|
dropdown_toggle.on("click", () => {
|
2020-04-15 04:29:15 +02:00
|
|
|
search_input.val("").trigger("input");
|
|
|
|
});
|
|
|
|
|
2020-07-20 21:26:58 +02:00
|
|
|
dropdown_toggle.on("focus", (e) => {
|
2020-04-15 22:55:05 +02:00
|
|
|
// On opening a Bootstrap Dropdown, the parent element recieves focus.
|
|
|
|
// Here, we want our search input to have focus instead.
|
|
|
|
e.preventDefault();
|
2020-07-20 21:24:26 +02:00
|
|
|
search_input.trigger("focus");
|
2020-04-15 22:55:05 +02:00
|
|
|
});
|
|
|
|
|
2020-07-20 21:26:58 +02:00
|
|
|
search_input.on("keydown", (e) => {
|
2020-04-15 22:55:05 +02:00
|
|
|
if (!/(38|40|27)/.test(e.keyCode)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
e.preventDefault();
|
|
|
|
const custom_event = jQuery.Event("keydown.dropdown.data-api", {
|
|
|
|
keyCode: e.keyCode,
|
|
|
|
which: e.keyCode,
|
|
|
|
});
|
|
|
|
dropdown_toggle.trigger(custom_event);
|
|
|
|
});
|
|
|
|
|
2020-04-30 13:09:48 +02:00
|
|
|
render(opts.value);
|
2020-04-15 04:29:15 +02:00
|
|
|
register_event_handlers();
|
|
|
|
};
|
|
|
|
|
2020-04-14 10:43:30 +02:00
|
|
|
const value = () => {
|
2020-07-15 01:29:15 +02:00
|
|
|
let val = $(`#${opts.container_id} #${opts.value_id}`).data("value");
|
2020-04-14 10:43:30 +02:00
|
|
|
if (val === null) {
|
2020-07-15 01:29:15 +02:00
|
|
|
val = "";
|
2020-04-14 10:43:30 +02:00
|
|
|
}
|
|
|
|
return val;
|
|
|
|
};
|
|
|
|
|
2020-04-15 04:29:15 +02:00
|
|
|
// Run setup() automatically on initialization.
|
|
|
|
setup();
|
|
|
|
|
2020-04-14 10:43:30 +02:00
|
|
|
return {
|
|
|
|
render,
|
|
|
|
value,
|
2020-04-30 16:27:42 +02:00
|
|
|
update,
|
2020-04-14 10:43:30 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-05-12 20:44:05 +02:00
|
|
|
window.dropdown_list_widget = DropdownListWidget;
|