Skip to content

Commit f53c36d

Browse files
authored
Merge pull request #1603 from plone/querystring-select2-fix
`pat-querystring`: fix issue with the new select2 native events
2 parents 8c201cf + cb83396 commit f53c36d

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

src/pat/querystring/querystring.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,15 @@ Criteria.prototype = {
111111
width: self.options.indexWidth,
112112
placeholder: _t("Select criteria"),
113113
});
114-
self.$index.on("change", function (e) {
114+
self.$index.on("change", function () {
115+
// Read the value from the element rather than from the event's
116+
// `val` property. Select2 v3 fires a jQuery `change` event carrying
117+
// a `val` property, but pat-select2 also re-dispatches a native
118+
// `change` event (for native listeners), which jQuery's `change`
119+
// handler catches as well. On that second invocation `e.val` would
120+
// be undefined. Reading `self.$index.val()` is correct in both cases.
115121
self.removeValue();
116-
self.createOperator(e.val);
122+
self.createOperator(self.$index.val());
117123
self.createClear();
118124
self.trigger("index-changed");
119125
});

src/pat/querystring/querystring.test.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,41 @@ describe("Querystring", function () {
169169
global.fetch.mockClear();
170170
delete global.fetch;
171171
});
172+
173+
it("handles a native change event on the index select", async function () {
174+
// Regression test: pat-select2 re-dispatches a native `change` event in
175+
// addition to the Select2 v3 jQuery `change` event. jQuery's `change`
176+
// handler catches both, so the index handler fires twice — once with
177+
// `e.val` set (Select2) and once with `e.val` undefined (native event).
178+
// The handler must read the value from the element, not from `e.val`,
179+
// otherwise the native invocation passes `undefined` to createOperator
180+
// and throws.
181+
const criterias = await import("./test-querystringcriteria.json");
182+
global.fetch = jest.fn().mockImplementation(mockFetch(criterias));
183+
184+
registry.scan(document.body);
185+
await utils.timeout(1);
186+
187+
// The last criteria row is the empty one a user fills in.
188+
const indexSelects = document.querySelectorAll(
189+
".querystring-criteria-index select"
190+
);
191+
const $index = $(indexSelects[indexSelects.length - 1]);
192+
const wrapper = $index.parents(".querystring-criteria-wrapper")[0];
193+
194+
// Pick a value and fire ONLY a native change event (no Select2 `val`).
195+
$index.val("Title");
196+
$index[0].dispatchEvent(new Event("change", { bubbles: true }));
197+
await utils.timeout(1);
198+
199+
// The operator select must have been built for the selected index.
200+
const operator = wrapper.querySelector(
201+
".querystring-criteria-operator select"
202+
);
203+
expect(operator).not.toBeNull();
204+
expect(operator.options.length).toBeGreaterThan(0);
205+
206+
global.fetch.mockClear();
207+
delete global.fetch;
208+
});
172209
});

0 commit comments

Comments
 (0)