Skip to content

Commit a832b46

Browse files
Merge pull request #152 from lionel-bijaoui/lb_better_behavior_for_radios_and_checklist
Better behavior for radios and checklist
2 parents f4bd438 + 1f6150f commit a832b46

File tree

4 files changed

+330
-57
lines changed

4 files changed

+330
-57
lines changed

src/fields/core/fieldChecklist.vue

+35-18
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<template lang="pug">
22
.wrapper
33
.listbox.form-control(v-if="schema.listBox", :disabled="disabled")
4-
.list-row(v-for="item in items", :class="{'is-checked': getItemIsChecked(item)}")
4+
.list-row(v-for="item in items", :class="{'is-checked': isItemChecked(item)}")
55
label
6-
input(type="checkbox", :checked="getItemIsChecked(item)", :disabled="disabled", @input="onChanged($event, item)")
6+
input(type="checkbox", :checked="isItemChecked(item)", :disabled="disabled", @input="onChanged($event, item)")
77
| {{ getItemName(item) }}
88

99
.combobox.form-control(v-if="!schema.listBox", :disabled="disabled")
@@ -12,9 +12,9 @@
1212
.arrow
1313

1414
.dropList
15-
.list-row(v-if="comboExpanded", v-for="item in items", :class="{'is-checked': getItemIsChecked(item)}")
15+
.list-row(v-if="comboExpanded", v-for="item in items", :class="{'is-checked': isItemChecked(item)}")
1616
label
17-
input(type="checkbox", :checked="getItemIsChecked(item)", :disabled="disabled", @input="onChanged($event, item)")
17+
input(type="checkbox", :checked="isItemChecked(item)", :disabled="disabled", @input="onChanged($event, item)")
1818
| {{ getItemName(item) }}
1919
</template>
2020

@@ -49,22 +49,39 @@
4949
},
5050
5151
methods: {
52-
getItemID(item) {
53-
if (isObject(item) && item.id)
54-
return item.id;
55-
56-
return item;
52+
getItemValue(item) {
53+
if (isObject(item)){
54+
if (typeof this.schema["checklistOptions"] !== "undefined" && typeof this.schema["checklistOptions"]["value"] !== "undefined") {
55+
return item[this.schema.checklistOptions.value];
56+
} else {
57+
if (typeof item["value"] !== "undefined") {
58+
return item.value;
59+
} else {
60+
throw "value is not defined. If you want to use another key name, add a `value` property under `checklistOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/checklist.html#checklist-field-with-object-values";
61+
}
62+
}
63+
} else {
64+
return item;
65+
}
5766
},
58-
5967
getItemName(item) {
60-
if (isObject(item) && item.name)
61-
return item.name;
62-
63-
return item;
68+
if (isObject(item)){
69+
if (typeof this.schema["checklistOptions"] !== "undefined" && typeof this.schema["checklistOptions"]["name"] !== "undefined") {
70+
return item[this.schema.checklistOptions.name];
71+
} else {
72+
if (typeof item["name"] !== "undefined") {
73+
return item.name;
74+
} else {
75+
throw "name is not defined. If you want to use another key name, add a `name` property under `checklistOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/checklist.html#checklist-field-with-object-values";
76+
}
77+
}
78+
} else {
79+
return item;
80+
}
6481
},
6582
66-
getItemIsChecked(item) {
67-
return (this.value && this.value.indexOf(this.getItemID(item)) != -1);
83+
isItemChecked(item) {
84+
return (this.value && this.value.indexOf(this.getItemValue(item)) != -1);
6885
},
6986
7087
onChanged(event, item) {
@@ -73,9 +90,9 @@
7390
}
7491
7592
if (event.target.checked) {
76-
this.value.push(this.getItemID(item));
93+
this.value.push(this.getItemValue(item));
7794
} else {
78-
this.value.splice(this.value.indexOf(this.getItemID(item)), 1);
95+
this.value.splice(this.value.indexOf(this.getItemValue(item)), 1);
7996
}
8097
},
8198

src/fields/core/fieldRadios.vue

+28-21
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,41 @@
2828
},
2929
3030
methods: {
31-
onSelection(item) {
32-
if (isObject(item) && this.schema.radiosOptions.value && item[this.schema.radiosOptions.value]){
33-
this.value = item[this.schema.radiosOptions.value];
34-
} else{
35-
this.value = item;
36-
}
37-
},
3831
getItemValue(item) {
39-
if (isObject(item) && this.schema.radiosOptions.value && item[this.schema.radiosOptions.value]){
40-
return item[this.schema.radiosOptions.value];
32+
if (isObject(item)){
33+
if (typeof this.schema["radiosOptions"] !== "undefined" && typeof this.schema["radiosOptions"]["value"] !== "undefined") {
34+
return item[this.schema.radiosOptions.value];
35+
} else {
36+
if (typeof item["value"] !== "undefined") {
37+
return item.value;
38+
} else {
39+
throw "value is not defined. If you want to use another key name, add a `value` property under `radiosOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/radios.html#radios-field-with-object-values";
40+
}
41+
}
42+
} else {
43+
return item;
4144
}
42-
43-
return item;
4445
},
4546
getItemName(item) {
46-
if (isObject(item) && this.schema.radiosOptions.name && item[this.schema.radiosOptions.name]){
47-
return item[this.schema.radiosOptions.name];
47+
if (isObject(item)){
48+
if (typeof this.schema["radiosOptions"] !== "undefined" && typeof this.schema["radiosOptions"]["name"] !== "undefined") {
49+
return item[this.schema.radiosOptions.name];
50+
} else {
51+
if (typeof item["name"] !== "undefined") {
52+
return item.name;
53+
} else {
54+
throw "name is not defined. If you want to use another key name, add a `name` property under `radiosOptions` in the schema. https://icebob.gitbooks.io/vueformgenerator/content/fields/radios.html#radios-field-with-object-values";
55+
}
56+
}
57+
} else {
58+
return item;
4859
}
49-
50-
return item;
60+
},
61+
onSelection(item) {
62+
this.value = this.getItemValue(item);
5163
},
5264
isItemChecked(item) {
53-
let currentValue;
54-
if (isObject(item) && this.schema.radiosOptions.value && item[this.schema.radiosOptions.value]){
55-
currentValue = item[this.schema.radiosOptions.value];
56-
} else{
57-
currentValue = item;
58-
}
65+
let currentValue = this.getItemValue(item);
5966
return (currentValue === this.value);
6067
},
6168
}

test/unit/specs/fields/fieldChecklist.spec.js

+143-15
Original file line numberDiff line numberDiff line change
@@ -141,20 +141,20 @@ describe("fieldChecklist.vue", function() {
141141

142142
});
143143

144-
describe("check static values with { id, name } objects", () => {
144+
describe("check static values with { value, name } objects (default key name)", () => {
145145
let schema = {
146146
type: "checklist",
147147
label: "Skills",
148148
model: "skills",
149149
listBox: true,
150150
values: [
151-
{ id: 1, name: "HTML5" },
152-
{ id: 2, name: "Javascript" },
153-
{ id: 3, name: "CSS3" },
154-
{ id: 4, name: "CoffeeScript" },
155-
{ id: 5, name: "AngularJS" },
156-
{ id: 6, name: "ReactJS" },
157-
{ id: 7, name: "VueJS" }
151+
{ value: 1, name: "HTML5" },
152+
{ value: 2, name: "Javascript" },
153+
{ value: 3, name: "CSS3" },
154+
{ value: 4, name: "CoffeeScript" },
155+
{ value: 5, name: "AngularJS" },
156+
{ value: 6, name: "ReactJS" },
157+
{ value: 7, name: "VueJS" }
158158
]
159159
};
160160
let model = { skills: [2, 7] };
@@ -265,6 +265,134 @@ describe("fieldChecklist.vue", function() {
265265

266266
});
267267

268+
describe("check static values with { id, label } objects (custom key name with `checklistOptions`)", () => {
269+
let schema = {
270+
type: "checklist",
271+
label: "Skills",
272+
model: "skills",
273+
listBox: true,
274+
values: [
275+
{ id: 1, label: "HTML5" },
276+
{ id: 2, label: "Javascript" },
277+
{ id: 3, label: "CSS3" },
278+
{ id: 4, label: "CoffeeScript" },
279+
{ id: 5, label: "AngularJS" },
280+
{ id: 6, label: "ReactJS" },
281+
{ id: 7, label: "VueJS" }
282+
],
283+
checklistOptions: {
284+
value: "id",
285+
name: "label"
286+
}
287+
};
288+
let model = { skills: [2, 7] };
289+
let listbox;
290+
let checkboxes;
291+
let listRowList;
292+
293+
function isChecked(idx) {
294+
return(checkboxes[idx].checked);
295+
}
296+
297+
before( () => {
298+
createField(this, schema, model, false);
299+
listbox = el.querySelector(".listbox");
300+
checkboxes = listbox.querySelectorAll("input[type=checkbox]");
301+
listRowList = listbox.querySelectorAll(".list-row");
302+
});
303+
304+
it("should contain items", () => {
305+
expect(checkboxes.length).to.be.equal(7);
306+
});
307+
308+
it("should checked the values", () => {
309+
expect(isChecked(0)).to.be.false;
310+
expect(isChecked(1)).to.be.true;
311+
expect(isChecked(2)).to.be.false;
312+
expect(isChecked(3)).to.be.false;
313+
expect(isChecked(4)).to.be.false;
314+
expect(isChecked(5)).to.be.false;
315+
expect(isChecked(6)).to.be.true;
316+
});
317+
318+
describe("test values reactivity to changes", () => {
319+
320+
it("listbox value should be the model value after changed", (done) => {
321+
model.skills = [3];
322+
vm.$nextTick( () => {
323+
expect(isChecked(0)).to.be.false;
324+
expect(isChecked(1)).to.be.false;
325+
expect(isChecked(2)).to.be.true;
326+
expect(isChecked(3)).to.be.false;
327+
expect(isChecked(4)).to.be.false;
328+
expect(isChecked(5)).to.be.false;
329+
expect(isChecked(6)).to.be.false;
330+
done();
331+
});
332+
333+
});
334+
335+
it("model value should be the listbox value if changed", (done) => {
336+
checkboxes[0].checked = true;
337+
trigger(checkboxes[0], "input");
338+
339+
vm.$nextTick( () => {
340+
expect(model.skills).to.be.deep.equal([3, 1]);
341+
done();
342+
});
343+
344+
});
345+
346+
});
347+
348+
describe("test 'is-checked' class attribution reactivity to changes", () => {
349+
350+
it(".list-row with checked input should have a 'is-checked' class", () => {
351+
expect(listRowList[0].classList.contains("is-checked")).to.be.true;
352+
expect(listRowList[1].classList.contains("is-checked")).to.be.false;
353+
expect(listRowList[2].classList.contains("is-checked")).to.be.true;
354+
expect(listRowList[3].classList.contains("is-checked")).to.be.false;
355+
expect(listRowList[4].classList.contains("is-checked")).to.be.false;
356+
expect(listRowList[5].classList.contains("is-checked")).to.be.false;
357+
expect(listRowList[6].classList.contains("is-checked")).to.be.false;
358+
});
359+
360+
it(".list-row with checked input should have a 'is-checked' class after model value is changed", (done) => {
361+
model.skills = [4];
362+
vm.$nextTick( () => {
363+
expect(listRowList[0].classList.contains("is-checked")).to.be.false;
364+
expect(listRowList[1].classList.contains("is-checked")).to.be.false;
365+
expect(listRowList[2].classList.contains("is-checked")).to.be.false;
366+
expect(listRowList[3].classList.contains("is-checked")).to.be.true;
367+
expect(listRowList[4].classList.contains("is-checked")).to.be.false;
368+
expect(listRowList[5].classList.contains("is-checked")).to.be.false;
369+
expect(listRowList[6].classList.contains("is-checked")).to.be.false;
370+
done();
371+
});
372+
373+
});
374+
375+
it(".list-row with checked input should have a 'is-checked' class after listbox value is changed", (done) => {
376+
checkboxes[0].checked = true;
377+
trigger(checkboxes[0], "input");
378+
379+
vm.$nextTick( () => {
380+
expect(listRowList[0].classList.contains("is-checked")).to.be.true;
381+
expect(listRowList[1].classList.contains("is-checked")).to.be.false;
382+
expect(listRowList[2].classList.contains("is-checked")).to.be.false;
383+
expect(listRowList[3].classList.contains("is-checked")).to.be.true;
384+
expect(listRowList[4].classList.contains("is-checked")).to.be.false;
385+
expect(listRowList[5].classList.contains("is-checked")).to.be.false;
386+
expect(listRowList[6].classList.contains("is-checked")).to.be.false;
387+
done();
388+
});
389+
390+
});
391+
392+
});
393+
394+
});
395+
268396
describe("check function values", () => {
269397
let schema = {
270398
type: "checklist",
@@ -273,13 +401,13 @@ describe("fieldChecklist.vue", function() {
273401
listBox: true,
274402
values() {
275403
return [
276-
{ id: 1, name: "HTML5" },
277-
{ id: 2, name: "Javascript" },
278-
{ id: 3, name: "CSS3" },
279-
{ id: 4, name: "CoffeeScript" },
280-
{ id: 5, name: "AngularJS" },
281-
{ id: 6, name: "ReactJS" },
282-
{ id: 7, name: "VueJS" }
404+
{ value: 1, name: "HTML5" },
405+
{ value: 2, name: "Javascript" },
406+
{ value: 3, name: "CSS3" },
407+
{ value: 4, name: "CoffeeScript" },
408+
{ value: 5, name: "AngularJS" },
409+
{ value: 6, name: "ReactJS" },
410+
{ value: 7, name: "VueJS" }
283411
];
284412
}
285413
};

0 commit comments

Comments
 (0)