Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/pat/select2/select2.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,22 @@ export default Base.extend({
this.options.multiple === undefined ? true : this.options.multiple;
this.options.ajax = this.options.ajax || {};
this.options.ajax.url = this.options.vocabularyUrl;
// XXX removing the following function does'nt break tests. dead code?
this.options.initSelection = ($el, callback) => {
const data = [];
const value = $el.val();
for (const val of value.split(this.options.separator)) {
if (val === "") {
// Skip empty values, e.g. from an empty input.
continue;
}
const _val = utils.removeHTML(val);
data.push({ id: _val, text: _val });
}
callback(data);
// Select2 v3 expects a single object for single-select
// widgets and an array for multi-select widgets. Passing an
// array to a single select leaves `data.text` undefined and
// the pre-set value is not rendered.
callback(this.options.multiple ? data : data[0] || null);
};
}

Expand Down
44 changes: 44 additions & 0 deletions src/pat/select2/select2.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,50 @@ describe("Select2", function () {
expect(select2.options.ajax.url).toEqual("select2-users-vocabulary");
});

it("renders the preset value of a single-select input widget", async function () {
document.body.innerHTML = `
<input class="pat-select2"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't that be a <select> if its not multiple values ?

I wonder why this is needed, because the language field actually works with predefined values: https://github.com/plone/plone.app.dexterity/blob/master/src/plone/app/dexterity/behaviors/metadata.py#L110

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A‌ <select> field cannot use AJAX‌ remote data.

And for the timezone selection fields I do not want to use pre-populated list of options - because it can be huge - but a text field where you can enter manually (if JS is off) or search/select via AJAX.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that makes totally sense

value="Europe/Vienna"
data-pat-select2='{
"multiple": false,
"allowNewItems": "false",
"vocabularyUrl": "select2-timezone-vocabulary"
}'
/>
`;

registry.scan(document.body);
await utils.timeout(1);

const el = document.querySelector("input.pat-select2");
expect($(el).select2("data")).toEqual({
id: "Europe/Vienna",
text: "Europe/Vienna",
});
expect($(el).parent().find(".select2-chosen").text()).toEqual("Europe/Vienna");
});

it("renders the preset value of a single-select select widget", async function () {
document.body.innerHTML = `
<select class="pat-select2">
<option value="Europe/Paris">Europe/Paris</option>
<option value="Europe/Vienna" selected>Europe/Vienna</option>
</select>
`;

registry.scan(document.body);
await utils.timeout(1);

const el = document.querySelector("select.pat-select2");
// For a native <select>, select2 v3 attaches extra metadata to the
// data object (element, disabled, locked, ...), so match a subset.
expect($(el).select2("data")).toMatchObject({
id: "Europe/Vienna",
text: "Europe/Vienna",
});
expect($(el).parent().find(".select2-chosen").text()).toEqual("Europe/Vienna");
});

it("displays the vocabulary when clicking an empty checkbox", async function () {
document.body.innerHTML = `
<input type="hidden"
Expand Down
Loading