Skip to content

Commit d2c0960

Browse files
committed
dependshandler: ok, we need to support multiple inputs, not just one. Alone because of the radio buttons, where many are named the same. Done.
pick bc255bfb6 fixup dependshandler modernize fixup
1 parent ce5afaa commit d2c0960

File tree

2 files changed

+84
-22
lines changed

2 files changed

+84
-22
lines changed

src/lib/dependshandler.js

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,51 +7,60 @@ class DependsHandler {
77
this.ast = parser.parse(expression); // TODO: handle parse exceptions here
88
}
99

10-
_findInput(name) {
10+
_findInputs(name) {
11+
// In case of radio buttons, there might be multiple inputs.
1112
// "name" in parentheses, because it can be any value. Common is:
1213
// `somename:list` for a radio input list.
13-
const input = this.context.querySelector(`
14+
let inputs = this.context.querySelectorAll(`
1415
input[name="${name}"],
1516
select[name="${name}"],
1617
textarea[name="${name}"],
1718
button[name="${name}"]
1819
`);
19-
return input || document.querySelector(`#${name}`) || null;
20+
if (!inputs.length) {
21+
// This should really only find one instance.
22+
inputs = document.querySelectorAll(`#${name}`);
23+
}
24+
return inputs;
2025
}
2126

2227
_getValue(name) {
23-
const input = this._findInput(name);
24-
if (!input) {
25-
return null;
26-
}
28+
let inputs = this._findInputs(name);
29+
30+
inputs = [...inputs].filter((input) => {
31+
if (input.type === "radio" && input.checked === false) {
32+
return false;
33+
}
34+
if (input.type === "checkbox" && input.checked === false) {
35+
return false;
36+
}
37+
return true;
38+
});
2739

28-
if (
29-
(input.type === "radio" || input.type === "checkbox") &&
30-
input.checked === false
31-
) {
40+
if (inputs.length === 0) {
3241
return null;
3342
}
3443

35-
return input.value;
44+
return inputs[0].value;
3645
}
3746

3847
getAllInputs() {
3948
const todo = [this.ast];
40-
const inputs = new Set();
49+
const all_inputs = new Set();
4150

4251
while (todo.length) {
4352
const node = todo.shift();
4453
if (node.input) {
45-
const input = this._findInput(node.input);
46-
if (input) {
47-
inputs.add(input);
54+
const inputs = this._findInputs(node.input);
55+
for (const input of inputs) {
56+
all_inputs.add(input);
4857
}
4958
}
5059
if (node.children && node.children.length) {
5160
todo.push.apply(todo, node.children);
5261
}
5362
}
54-
return [...inputs];
63+
return [...all_inputs];
5564
}
5665

5766
_evaluate(node) {

src/lib/dependshandler.test.js

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ describe("pat-dependshandler", function () {
2929
});
3030
});
3131

32-
describe("_findInput", function () {
32+
describe("_findInputs", function () {
3333
it("no input, nothing found", function () {
3434
document.body.innerHTML = `
3535
<div id="lab"></div>
3636
`;
3737
const lab = document.getElementById("lab");
3838
const handler = new DependsHandler(lab, "foo");
39-
expect(handler._findInput("foo")).toBe(null);
39+
40+
expect(handler._findInputs("foo").length).toBe(0);
4041
});
4142

4243
it("find input by name", function () {
@@ -48,7 +49,9 @@ describe("pat-dependshandler", function () {
4849
const lab = document.getElementById("lab");
4950
const foo = document.querySelector("[name=foo]");
5051
const handler = new DependsHandler(lab, "foo");
51-
expect(handler._findInput("foo")).toBe(foo);
52+
53+
expect(handler._findInputs("foo").length).toBe(1);
54+
expect(handler._findInputs("foo")[0]).toBe(foo);
5255
});
5356

5457
it("find input by id", function () {
@@ -61,7 +64,8 @@ describe("pat-dependshandler", function () {
6164
const bar = document.getElementById("bar");
6265
const handler = new DependsHandler(lab, "bar");
6366

64-
expect(handler._findInput("bar")).toBe(bar);
67+
expect(handler._findInputs("bar").length).toBe(1);
68+
expect(handler._findInputs("bar")[0]).toBe(bar);
6569
});
6670

6771
it("Restrict searches to current form", function () {
@@ -76,7 +80,25 @@ describe("pat-dependshandler", function () {
7680
const foo1 = document.getElementById("foo1");
7781
const handler = new DependsHandler(lab, "foo");
7882

79-
expect(handler._findInput("foo")).toBe(foo1);
83+
expect(handler._findInputs("foo").length).toBe(1);
84+
expect(handler._findInputs("foo")[0]).toBe(foo1);
85+
});
86+
87+
it("find multiple inputs of the same name, e.g. for radio buttons", function () {
88+
document.body.innerHTML = `
89+
<div id="lab">
90+
<input type="radio" name="foo:list"/>
91+
<input type="radio" name="foo:list"/>
92+
<input type="radio" name="foo:list"/>
93+
</div>
94+
`;
95+
const lab = document.getElementById("lab");
96+
const foos = document.querySelectorAll("[name='foo:list']");
97+
const handler = new DependsHandler(lab, "foo:list");
98+
expect(handler._findInputs("foo:list").length).toBe(3);
99+
expect(handler._findInputs("foo:list")[0]).toBe(foos[0]);
100+
expect(handler._findInputs("foo:list")[1]).toBe(foos[1]);
101+
expect(handler._findInputs("foo:list")[2]).toBe(foos[2]);
80102
});
81103
});
82104

@@ -128,6 +150,37 @@ describe("pat-dependshandler", function () {
128150

129151
expect(handler._getValue("foo")).toBe("bar");
130152
});
153+
154+
it("Returns the value of the checked radio buttons in a list of multiple radio buttons.", function () {
155+
document.body.innerHTML = `
156+
<div id="lab">
157+
<input type="radio" name="foo:list" value="bar"/>
158+
<input type="radio" name="foo:list" value="baz"/>
159+
<input type="radio" name="foo:list" value="fuzz" checked/>
160+
<input type="radio" name="foo:list" value="nuzz"/>
161+
</div>
162+
`;
163+
const lab = document.getElementById("lab");
164+
const handler = new DependsHandler(lab, "foo:list");
165+
166+
expect(handler._getValue("foo:list")).toBe("fuzz");
167+
});
168+
169+
it("Returns no value in a list of multiple radio buttons of no one is checked.", function () {
170+
document.body.innerHTML = `
171+
<div id="lab">
172+
<input type="radio" name="foo:list" value="bar"/>
173+
<input type="radio" name="foo:list" value="baz"/>
174+
<input type="radio" name="foo:list" value="fuzz"/>
175+
<input type="radio" name="foo:list" value="nuzz"/>
176+
</div>
177+
`;
178+
const lab = document.getElementById("lab");
179+
const handler = new DependsHandler(lab, "foo:list");
180+
181+
expect(handler._getValue("foo:list")).toBe(null);
182+
});
183+
131184
});
132185

133186
describe("getAllInputs", function () {

0 commit comments

Comments
 (0)