Skip to content

Commit 1235911

Browse files
authored
Merge pull request #40 from halexiev-hedgeserv/boolean-question-support
Boolean question type support for pretty checkbox widget
2 parents 9377f15 + a90ade1 commit 1235911

File tree

1 file changed

+176
-128
lines changed

1 file changed

+176
-128
lines changed

src/pretty-checkbox.js

Lines changed: 176 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,138 +1,186 @@
11
function init(Survey) {
2-
var widget = {
3-
settings: {
4-
radiogroup: {
5-
rootClass: "pretty p-default p-round",
6-
inputType: "radio",
7-
addOn: "",
8-
titleClass: "state p-success"
9-
},
10-
checkbox: {
11-
rootClass: "pretty p-default",
12-
inputType: "checkbox",
13-
addOn: "",
14-
titleClass: "state p-success"
15-
}
16-
},
17-
name: "pretty-checkbox",
18-
activatedBy: "property",
19-
widgetIsLoaded: function() {
20-
return true;
21-
},
22-
htmlTemplate: "<fieldset></fieldset>",
23-
isFit: function(question) {
24-
var isFitByType =
25-
question.getType() === "radiogroup" ||
26-
question.getType() === "checkbox";
27-
if (widget.activatedBy === "property")
28-
return question["renderAs"] === "prettycheckbox" && isFitByType;
29-
if (widget.activatedBy === "type") return isFitByType;
30-
return false;
31-
},
32-
activatedByChanged: function(activatedBy) {
33-
if (!this.widgetIsLoaded()) return;
34-
widget.activatedBy = activatedBy;
35-
Survey.JsonObject.metaData.removeProperty("radiogroup", "renderAs");
36-
Survey.JsonObject.metaData.removeProperty("checkbox", "renderAs");
37-
if (activatedBy === "property") {
38-
Survey.JsonObject.metaData.addProperty("radiogroup", {
39-
name: "renderAs",
40-
default: "standard",
41-
choices: ["standard", "prettycheckbox"]
42-
});
43-
Survey.JsonObject.metaData.addProperty("checkbox", {
44-
name: "renderAs",
45-
default: "standard",
46-
choices: ["standard", "prettycheckbox"]
47-
});
48-
}
49-
},
50-
isDefaultRender: false,
51-
afterRender: function(question, el) {
52-
var itemInputs = {};
53-
var options = this.settings[question.getType()];
54-
var inChangeHandler = false;
55-
var changeHandler = function(event) {
56-
inChangeHandler = true;
57-
try {
58-
var value = arguments[0].target.value;
59-
if (question.getType() === "checkbox") {
60-
var qValue = question.value || [];
61-
if (arguments[0].target.checked) {
62-
if (qValue.indexOf(value) === -1) {
63-
qValue.push(value);
64-
}
65-
} else {
66-
if (qValue.indexOf(value) !== -1) {
67-
qValue.splice(qValue.indexOf(value), 1);
68-
}
2+
const widget = {
3+
settings: {
4+
supportedTypes: ["radiogroup", "checkbox", "boolean"],
5+
radiogroup: {
6+
rootClass: "pretty p-default p-round",
7+
inputType: "radio",
8+
states: [
9+
{stateClass: "state p-success", addOn: ""}
10+
]
11+
},
12+
checkbox: {
13+
rootClass: "pretty p-default",
14+
inputType: "checkbox",
15+
states: [
16+
{stateClass: "state p-success", addOn: ""}
17+
]
18+
},
19+
boolean: {
20+
rootClass: "pretty p-icon p-default p-has-indeterminate",
21+
inputType: "checkbox",
22+
states: [
23+
{stateClass: "state p-success", addOn: ""},
24+
{stateClass: "state p-success p-is-indeterminate", iconClass: "icon mdi mdi-minus", addOn: ""}
25+
]
6926
}
70-
question.value = qValue;
71-
} else {
72-
question.value = value;
73-
}
74-
} finally {
75-
inChangeHandler = false;
76-
}
77-
};
78-
var itemWidth =
79-
question.colCount > 0 ? 100 / question.colCount + "%" : "";
80-
question.choices.forEach(function(choiceItem, index) {
81-
var itemRoot = document.createElement("div");
82-
itemRoot.className = "sv_cw_pretty_checkbox_" + question.getType();
83-
itemRoot.style.display = "inline-block";
84-
itemRoot.style.width = itemWidth;
85-
var controlRoot = document.createElement("div");
86-
controlRoot.className = options.rootClass;
87-
var input = document.createElement("input");
88-
input.type = options.inputType;
89-
input.name =
90-
question.name + (question.getType() === "checkbox" ? "" + index : "");
91-
input.onchange = changeHandler;
92-
input.value = choiceItem.value;
93-
var titleRoot = document.createElement("div");
94-
titleRoot.className = options.titleClass;
95-
var label = document.createElement("label");
96-
label.textContent = choiceItem.text;
97-
titleRoot.appendChild(label);
98-
controlRoot.appendChild(input);
99-
controlRoot.appendChild(titleRoot);
100-
if (!!options.addOn) {
101-
titleRoot.insertAdjacentHTML("afterbegin", options.addOn);
102-
}
103-
itemRoot.appendChild(controlRoot);
104-
el.appendChild(itemRoot);
105-
106-
itemInputs[choiceItem.value] = input;
107-
});
108-
var updateValueHandler = function(newValue) {
109-
if (!inChangeHandler) {
110-
var checkedItems = newValue || [];
111-
if (question.getType() === "radiogroup") {
112-
checkedItems = [newValue];
113-
}
114-
Object.values(itemInputs).forEach(function(inputItem) {
115-
if (checkedItems.indexOf(inputItem.value) !== -1) {
116-
inputItem.setAttribute("checked", undefined);
117-
} else {
118-
inputItem.removeAttribute("checked");
27+
},
28+
name: "pretty-checkbox",
29+
activatedBy: "property",
30+
widgetIsLoaded: function () {
31+
return true;
32+
},
33+
htmlTemplate: "<fieldset></fieldset>",
34+
isFit: function (question) {
35+
const isFitByType = widget.settings.supportedTypes.indexOf(question.getType()) !== -1;
36+
37+
if (widget.activatedBy === "property") {
38+
return question["renderAs"] === "prettycheckbox" && isFitByType;
39+
} else if (widget.activatedBy === "type") {
40+
return isFitByType;
41+
}
42+
43+
return false;
44+
},
45+
activatedByChanged: function (value) {
46+
if (this.widgetIsLoaded()) {
47+
widget.activatedBy = value;
48+
widget.settings.supportedTypes.forEach(function(supportedType) {
49+
Survey.JsonObject.metaData.removeProperty(supportedType, "renderAs");
50+
51+
if (value === "property") {
52+
Survey.JsonObject.metaData.addProperty(supportedType, {
53+
name: "renderAs",
54+
default: "standard",
55+
choices: ["standard", "prettycheckbox"]
56+
});
57+
}
58+
});
11959
}
120-
});
60+
},
61+
isDefaultRender: false,
62+
afterRender: function (question, element) {
63+
const itemInputs = {};
64+
const questionType = question.getType();
65+
const options = this.settings[questionType];
66+
const checkboxType = questionType === "checkbox";
67+
const radiogroupType = questionType === "radiogroup";
68+
const booleanType = questionType === "boolean";
69+
70+
var inChangeHandler = false;
71+
const changeHandler = function (event) {
72+
inChangeHandler = true;
73+
try {
74+
const target = arguments[0].target;
75+
const targetValue = target.value;
76+
const targetChecked = target.checked;
77+
78+
if (checkboxType) {
79+
const questionValue = question.value || [];
80+
const valueIndex = questionValue.indexOf(targetValue);
81+
if (targetChecked) {
82+
if (valueIndex === -1) {
83+
questionValue.push(targetValue);
84+
}
85+
} else {
86+
if (valueIndex !== -1) {
87+
questionValue.splice(valueIndex, 1);
88+
}
89+
}
90+
91+
question.value = questionValue;
92+
} else if (radiogroupType) {
93+
question.value = targetValue;
94+
} else {
95+
question.value = targetChecked;
96+
}
97+
} finally {
98+
inChangeHandler = false;
99+
}
100+
};
101+
102+
const itemWidth = question.colCount > 0 ? 100 / question.colCount + "%" : "";
103+
104+
const choices = booleanType ? [{locText: question.locTitle, value: !!question.value}] : question.choices;
105+
choices.forEach(function (choiceItem, index) {
106+
const input = document.createElement("input");
107+
input.type = options.inputType;
108+
input.name = question.name + (checkboxType ? "" + index : "");
109+
input.onchange = changeHandler;
110+
input.value = choiceItem.value;
111+
112+
if (booleanType) {
113+
input.indeterminate = (question.defaultValue === 'indeterminate');
114+
}
115+
116+
const controlRoot = document.createElement("div");
117+
controlRoot.className = options.rootClass;
118+
controlRoot.appendChild(input);
119+
120+
options.states.forEach(function(state) {
121+
const stateRoot = document.createElement("div");
122+
stateRoot.className = state.stateClass;
123+
if (!!state.iconClass) {
124+
const icon = document.createElement("i");
125+
icon.className = state.iconClass;
126+
stateRoot.appendChild(icon);
127+
}
128+
129+
const label = document.createElement("label");
130+
if (choiceItem.locText.hasHtml) {
131+
label.innerHTML = choiceItem.locText.html;
132+
} else {
133+
label.textContent = choiceItem.locText.text;
134+
}
135+
stateRoot.appendChild(label);
136+
137+
controlRoot.appendChild(stateRoot);
138+
if (!!state.addOn) {
139+
stateRoot.insertAdjacentHTML("afterbegin", state.addOn);
140+
}
141+
});
142+
143+
const itemRoot = document.createElement("div");
144+
itemRoot.className = "sv_cw_pretty_checkbox_" + questionType;
145+
itemRoot.style.display = "inline-block";
146+
itemRoot.style.width = itemWidth;
147+
itemRoot.appendChild(controlRoot);
148+
149+
element.appendChild(itemRoot);
150+
151+
itemInputs[choiceItem.value] = input;
152+
});
153+
154+
const updateValueHandler = function (newValue) {
155+
if (!inChangeHandler) {
156+
var checkedItems = newValue || [];
157+
if (radiogroupType) {
158+
checkedItems = [newValue];
159+
}
160+
161+
Object.values(itemInputs).forEach(function (inputItem) {
162+
if (checkedItems.indexOf(inputItem.value) !== -1) {
163+
inputItem.setAttribute("checked", undefined);
164+
} else {
165+
inputItem.removeAttribute("checked");
166+
}
167+
});
168+
}
169+
};
170+
171+
question.valueChangedCallback = updateValueHandler;
172+
updateValueHandler(question.value);
173+
},
174+
willUnmount: function (question, el) {
175+
question.valueChangedCallback = undefined;
121176
}
122-
};
123-
question.valueChangedCallback = updateValueHandler;
124-
updateValueHandler(question.value);
125-
},
126-
willUnmount: function(question, el) {
127-
question.valueChangedCallback = undefined;
128-
}
129-
};
130-
131-
Survey.CustomWidgetCollection.Instance.addCustomWidget(widget, "property");
177+
};
178+
179+
Survey.CustomWidgetCollection.Instance.addCustomWidget(widget, "property");
132180
}
133181

134182
if (typeof Survey !== "undefined") {
135-
init(Survey);
183+
init(Survey);
136184
}
137185

138186
export default init;

0 commit comments

Comments
 (0)