Skip to content

Commit 7cbc8f6

Browse files
committed
Functional stateless comp for multiple checkboxes.
1 parent 0bdaa89 commit 7cbc8f6

File tree

2 files changed

+39
-44
lines changed

2 files changed

+39
-44
lines changed

playground/samples/arrays.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module.exports = {
1515
title: "A multiple choices list",
1616
items: {
1717
type: "string",
18-
enum: ["foo", "bar", "fuzz"],
18+
enum: ["foo", "bar", "fuzz", "qux"],
1919
},
2020
uniqueItems: true
2121
},

src/components/widgets/CheckboxesWidget.js

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,50 @@
1-
import React, { Component, PropTypes } from "react";
1+
import React, { PropTypes } from "react";
22

3-
class CheckboxesWidget extends Component {
4-
constructor(props) {
5-
super(props);
6-
this.state = this.getStateFromProps(props);
7-
}
83

9-
getStateFromProps(props) {
10-
const selected = props.options.reduce((o, {label}) => {
11-
o[label] = props.value.indexOf(label) !== -1;
12-
return o;
13-
}, {});
14-
console.log(selected);
15-
return {selected};
16-
}
4+
function selectValue(value, selected, all) {
5+
const at = all.indexOf(value);
6+
const updated = selected.slice(0, at).concat(value, selected.slice(at));
7+
// As inserting values at predefined index positions doesn't work we empty
8+
// arrays, we need to reorder the updated selection to match the initial order
9+
return updated.sort((a, b) => {
10+
const ai = all.findIndex(x => x === a);
11+
const bi = all.findIndex(x => x === b);
12+
return ai > bi;
13+
});
14+
}
1715

18-
render() {
19-
const {
20-
options,
21-
value,
22-
onChange
23-
} = this.props;
16+
function deselectValue(value, selected) {
17+
return selected.filter(v => v !== value);
18+
}
2419

25-
return (
26-
<div>{
27-
options.map(({label}, i) => {
28-
return (
29-
<div className="checkbox">
20+
function CheckboxesWidget(props) {
21+
const {id, disabled, options, value, onChange} = props;
22+
return (
23+
<div id={id}>{
24+
options.map((option, index) => {
25+
const checked = value.indexOf(option.value) !== -1;
26+
return (
27+
<div key={index} className="checkbox">
3028
<label>
3129
<input type="checkbox"
32-
key={i}
33-
id={label}
34-
title={label}
35-
checked={value.indexOf(label) !== -1}
30+
id={`${id}_${option.label}`}
31+
checked={checked}
32+
disabled={disabled}
3633
onChange={(event) => {
37-
this.state.selected[event.target.id] = event.target.checked;
38-
this.setState(this.state);
39-
40-
const selectedKeys = Object.keys(this.state.selected).filter((key) => {
41-
return this.state.selected[key];
42-
});
43-
onChange(selectedKeys);
34+
const all = options.map(({value}) => value);
35+
if (event.target.checked) {
36+
onChange(selectValue(option.value, value, all));
37+
} else {
38+
onChange(deselectValue(option.value, value));
39+
}
4440
}} />
45-
<strong>{label}</strong>
41+
<strong>{option.label}</strong>
4642
</label>
47-
</div>
48-
);
49-
})
50-
}</div>
51-
);
52-
}
43+
</div>
44+
);
45+
})
46+
}</div>
47+
);
5348
}
5449

5550
if (process.env.NODE_ENV !== "production") {

0 commit comments

Comments
 (0)