Skip to content

Commit 8d9abde

Browse files
authored
Merge pull request #1600 from plone/thet/select2/single-select
fix(pat-select2): Show predefined value for single-select widgets.
2 parents 00e0610 + a4b35d6 commit 8d9abde

2 files changed

Lines changed: 53 additions & 2 deletions

File tree

src/pat/select2/select2.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,22 @@ export default Base.extend({
217217
this.options.multiple === undefined ? true : this.options.multiple;
218218
this.options.ajax = this.options.ajax || {};
219219
this.options.ajax.url = this.options.vocabularyUrl;
220-
// XXX removing the following function does'nt break tests. dead code?
221220
this.options.initSelection = ($el, callback) => {
222221
const data = [];
223222
const value = $el.val();
224223
for (const val of value.split(this.options.separator)) {
224+
if (val === "") {
225+
// Skip empty values, e.g. from an empty input.
226+
continue;
227+
}
225228
const _val = utils.removeHTML(val);
226229
data.push({ id: _val, text: _val });
227230
}
228-
callback(data);
231+
// Select2 v3 expects a single object for single-select
232+
// widgets and an array for multi-select widgets. Passing an
233+
// array to a single select leaves `data.text` undefined and
234+
// the pre-set value is not rendered.
235+
callback(this.options.multiple ? data : data[0] || null);
229236
};
230237
}
231238

src/pat/select2/select2.test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,50 @@ describe("Select2", function () {
100100
expect(select2.options.ajax.url).toEqual("select2-users-vocabulary");
101101
});
102102

103+
it("renders the preset value of a single-select input widget", async function () {
104+
document.body.innerHTML = `
105+
<input class="pat-select2"
106+
value="Europe/Vienna"
107+
data-pat-select2='{
108+
"multiple": false,
109+
"allowNewItems": "false",
110+
"vocabularyUrl": "select2-timezone-vocabulary"
111+
}'
112+
/>
113+
`;
114+
115+
registry.scan(document.body);
116+
await utils.timeout(1);
117+
118+
const el = document.querySelector("input.pat-select2");
119+
expect($(el).select2("data")).toEqual({
120+
id: "Europe/Vienna",
121+
text: "Europe/Vienna",
122+
});
123+
expect($(el).parent().find(".select2-chosen").text()).toEqual("Europe/Vienna");
124+
});
125+
126+
it("renders the preset value of a single-select select widget", async function () {
127+
document.body.innerHTML = `
128+
<select class="pat-select2">
129+
<option value="Europe/Paris">Europe/Paris</option>
130+
<option value="Europe/Vienna" selected>Europe/Vienna</option>
131+
</select>
132+
`;
133+
134+
registry.scan(document.body);
135+
await utils.timeout(1);
136+
137+
const el = document.querySelector("select.pat-select2");
138+
// For a native <select>, select2 v3 attaches extra metadata to the
139+
// data object (element, disabled, locked, ...), so match a subset.
140+
expect($(el).select2("data")).toMatchObject({
141+
id: "Europe/Vienna",
142+
text: "Europe/Vienna",
143+
});
144+
expect($(el).parent().find(".select2-chosen").text()).toEqual("Europe/Vienna");
145+
});
146+
103147
it("displays the vocabulary when clicking an empty checkbox", async function () {
104148
document.body.innerHTML = `
105149
<input type="hidden"

0 commit comments

Comments
 (0)