Skip to content

Commit d756963

Browse files
committed
Add support isReadOnly(readOnlyChangedCallback) for pretty-checkbox, surveyjs/survey-library#1195
1 parent 4424869 commit d756963

File tree

1 file changed

+190
-175
lines changed

1 file changed

+190
-175
lines changed

src/pretty-checkbox.js

Lines changed: 190 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -1,186 +1,201 @@
11
function init(Survey) {
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-
]
26-
}
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-
});
59-
}
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;
2+
const widget = {
3+
settings: {
4+
supportedTypes: ["radiogroup", "checkbox", "boolean"],
5+
radiogroup: {
6+
rootClass: "pretty p-default p-round",
7+
inputType: "radio",
8+
states: [{ stateClass: "state p-success", addOn: "" }]
9+
},
10+
checkbox: {
11+
rootClass: "pretty p-default",
12+
inputType: "checkbox",
13+
states: [{ stateClass: "state p-success", addOn: "" }]
14+
},
15+
boolean: {
16+
rootClass: "pretty p-icon p-default p-has-indeterminate",
17+
inputType: "checkbox",
18+
states: [
19+
{ stateClass: "state p-success", addOn: "" },
20+
{
21+
stateClass: "state p-success p-is-indeterminate",
22+
iconClass: "icon mdi mdi-minus",
23+
addOn: ""
24+
}
25+
]
26+
}
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 =
36+
widget.settings.supportedTypes.indexOf(question.getType()) !== -1;
37+
38+
if (widget.activatedBy === "property") {
39+
return question["renderAs"] === "prettycheckbox" && isFitByType;
40+
} else if (widget.activatedBy === "type") {
41+
return isFitByType;
42+
}
43+
44+
return false;
45+
},
46+
activatedByChanged: function(value) {
47+
if (this.widgetIsLoaded()) {
48+
widget.activatedBy = value;
49+
widget.settings.supportedTypes.forEach(function(supportedType) {
50+
Survey.JsonObject.metaData.removeProperty(supportedType, "renderAs");
51+
52+
if (value === "property") {
53+
Survey.JsonObject.metaData.addProperty(supportedType, {
54+
name: "renderAs",
55+
default: "standard",
56+
choices: ["standard", "prettycheckbox"]
15257
});
58+
}
59+
});
60+
}
61+
},
62+
isDefaultRender: false,
63+
afterRender: function(question, element) {
64+
const itemInputs = {};
65+
const questionType = question.getType();
66+
const options = this.settings[questionType];
67+
const checkboxType = questionType === "checkbox";
68+
const radiogroupType = questionType === "radiogroup";
69+
const booleanType = questionType === "boolean";
70+
71+
var inChangeHandler = false;
72+
const changeHandler = function(event) {
73+
inChangeHandler = true;
74+
try {
75+
const target = arguments[0].target;
76+
const targetValue = target.value;
77+
const targetChecked = target.checked;
78+
79+
if (checkboxType) {
80+
const questionValue = question.value || [];
81+
const valueIndex = questionValue.indexOf(targetValue);
82+
if (targetChecked) {
83+
if (valueIndex === -1) {
84+
questionValue.push(targetValue);
85+
}
86+
} else {
87+
if (valueIndex !== -1) {
88+
questionValue.splice(valueIndex, 1);
89+
}
90+
}
15391

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;
92+
question.value = questionValue;
93+
} else if (radiogroupType) {
94+
question.value = targetValue;
95+
} else {
96+
question.value = targetChecked;
97+
}
98+
} finally {
99+
inChangeHandler = false;
100+
}
101+
};
102+
103+
const itemWidth =
104+
question.colCount > 0 ? 100 / question.colCount + "%" : "";
105+
106+
const choices = booleanType
107+
? [{ locText: question.locTitle, value: !!question.value }]
108+
: question.choices;
109+
choices.forEach(function(choiceItem, index) {
110+
const input = document.createElement("input");
111+
input.type = options.inputType;
112+
input.name = question.name + (checkboxType ? "" + index : "");
113+
input.onchange = changeHandler;
114+
input.value = choiceItem.value;
115+
116+
if (booleanType) {
117+
input.indeterminate = question.defaultValue === "indeterminate";
176118
}
177-
};
178119

179-
Survey.CustomWidgetCollection.Instance.addCustomWidget(widget, "property");
120+
const controlRoot = document.createElement("div");
121+
controlRoot.className = options.rootClass;
122+
controlRoot.appendChild(input);
123+
124+
options.states.forEach(function(state) {
125+
const stateRoot = document.createElement("div");
126+
stateRoot.className = state.stateClass;
127+
if (!!state.iconClass) {
128+
const icon = document.createElement("i");
129+
icon.className = state.iconClass;
130+
stateRoot.appendChild(icon);
131+
}
132+
133+
const label = document.createElement("label");
134+
if (choiceItem.locText.hasHtml) {
135+
label.innerHTML = choiceItem.locText.html;
136+
} else {
137+
label.textContent = choiceItem.locText.text;
138+
}
139+
stateRoot.appendChild(label);
140+
141+
controlRoot.appendChild(stateRoot);
142+
if (!!state.addOn) {
143+
stateRoot.insertAdjacentHTML("afterbegin", state.addOn);
144+
}
145+
});
146+
147+
const itemRoot = document.createElement("div");
148+
itemRoot.className = "sv_cw_pretty_checkbox_" + questionType;
149+
itemRoot.style.display = "inline-block";
150+
itemRoot.style.width = itemWidth;
151+
itemRoot.appendChild(controlRoot);
152+
153+
element.appendChild(itemRoot);
154+
155+
itemInputs[choiceItem.value] = input;
156+
});
157+
158+
const updateValueHandler = function(newValue) {
159+
if (!inChangeHandler) {
160+
var checkedItems = newValue || [];
161+
if (radiogroupType) {
162+
checkedItems = [newValue];
163+
}
164+
165+
Object.values(itemInputs).forEach(function(inputItem) {
166+
if (checkedItems.indexOf(inputItem.value) !== -1) {
167+
inputItem.setAttribute("checked", undefined);
168+
} else {
169+
inputItem.removeAttribute("checked");
170+
}
171+
});
172+
}
173+
};
174+
const readOnlyHandler = function() {
175+
Object.values(itemInputs).forEach(function(inputItem) {
176+
if (question.isReadOnly) {
177+
inputItem.setAttribute("disabled", true);
178+
} else {
179+
inputItem.removeAttribute("disabled");
180+
}
181+
});
182+
};
183+
184+
question.valueChangedCallback = updateValueHandler;
185+
question.readOnlyChangedCallback = readOnlyHandler;
186+
updateValueHandler(question.value);
187+
readOnlyHandler();
188+
},
189+
willUnmount: function(question, el) {
190+
question.valueChangedCallback = undefined;
191+
}
192+
};
193+
194+
Survey.CustomWidgetCollection.Instance.addCustomWidget(widget, "property");
180195
}
181196

182197
if (typeof Survey !== "undefined") {
183-
init(Survey);
198+
init(Survey);
184199
}
185200

186201
export default init;

0 commit comments

Comments
 (0)