[235] | 1 | var questionEditor = new QuestionEditor(); |
---|
| 2 | |
---|
[233] | 3 | function createNewElement(tag, type, id, cl, value) { |
---|
| 4 | var newElement = document.createElement(tag); |
---|
| 5 | if (type != undefined) newElement.type = type; |
---|
| 6 | if (id != undefined) newElement.id = id; |
---|
| 7 | if (cl != undefined) newElement.className = cl; |
---|
| 8 | if (value != undefined) { |
---|
| 9 | newElement.value = value; |
---|
| 10 | newElement.text = value; |
---|
| 11 | } |
---|
| 12 | return newElement; |
---|
| 13 | } |
---|
| 14 | |
---|
[235] | 15 | function createNewInputLabel(text, target, side) { |
---|
[233] | 16 | var newLabel = document.createElement("label"); |
---|
| 17 | if (target) newLabel.setAttribute("for",target); |
---|
| 18 | newLabel.innerHTML = text; |
---|
[235] | 19 | if (side) newLabel.className = side; |
---|
[233] | 20 | return newLabel; |
---|
| 21 | } |
---|
| 22 | |
---|
| 23 | function QuestionEditor() { |
---|
| 24 | // Properties |
---|
[235] | 25 | this.uid = null; // The uid of the question contained in this editor |
---|
| 26 | var me = this; // Retarded self-reference because: Javascript |
---|
| 27 | this.element = null; // The parent div element containing the questionEditor |
---|
| 28 | this.paramsElement = null; // The parent parameters element where all the input sets will be located |
---|
[236] | 29 | this.paramSets = null; // The currently enabled input sets to be displayed in the paramsElement. |
---|
| 30 | //Currently only supports a single param set (based on answer type), but functionality will scale to multiple sets as needed. |
---|
[233] | 31 | |
---|
[235] | 32 | // Methods |
---|
[233] | 33 | // Basic functionality |
---|
| 34 | this.setValues = function(arguments) { |
---|
[237] | 35 | debugger; |
---|
| 36 | var question = JSON.parse(arguments)[0]; |
---|
| 37 | var qeTypeField = ge("qeTypeField"); |
---|
| 38 | ge("qeCodeField").value = question.code; |
---|
| 39 | ge("qeBodyTextField").value = question.description; |
---|
| 40 | switch (question.type.toLowerCase()) { |
---|
| 41 | case "int": |
---|
| 42 | // First make sure all the necessary fields are present |
---|
| 43 | me.type_Integer(); |
---|
| 44 | // Then fill them in using the available data |
---|
| 45 | qeTypeField.value = "int"; |
---|
| 46 | ge("qeMinValueField").value = question.minValue; |
---|
| 47 | ge("qeMaxValueField").value = question.maxValue; |
---|
| 48 | break; |
---|
| 49 | case "scale": |
---|
| 50 | me.type_Scale(); |
---|
| 51 | qeTypeField.value = "scale"; |
---|
| 52 | ge("qeNumChoicesField").value = question.numChoices; |
---|
| 53 | ge("qeLegendsEnabledField").checked = question.legendsEnabled; |
---|
| 54 | ge("qeLowerLegendField").value = question.lowerLegend; |
---|
| 55 | ge("qeUpperLegendField").value = question.upperLegend; |
---|
| 56 | break; |
---|
| 57 | case "choice": |
---|
| 58 | me.type_Choice(); |
---|
| 59 | qeTypeField.value = "choice"; |
---|
| 60 | ge("qeNumOptionsFIeld").value = question.numOptions; |
---|
| 61 | ge("qeMultipleAnswersField").value = question.multipleAnswers; |
---|
| 62 | // then some more to add textboxes (qeParamAnswerGroup) for all the possble choices. |
---|
| 63 | // Maybe a central version that appends these groups/textinputs? Maybe not, though. Don't want stuff too abstracted... |
---|
| 64 | break; |
---|
| 65 | case "text": |
---|
| 66 | me.type_Text(); |
---|
| 67 | qeTypeField.value = "text"; |
---|
| 68 | ge("qeTextMaxLengthField").value = question.maxTextLength; |
---|
| 69 | break; |
---|
| 70 | |
---|
| 71 | } |
---|
[233] | 72 | } |
---|
[240] | 73 | this.init = function(uid) { |
---|
[233] | 74 | // Outer div |
---|
[238] | 75 | this.saved = false; |
---|
[235] | 76 | me.element = ce("div"); |
---|
| 77 | me.element.className = "smallFrame questionEditor"; |
---|
| 78 | me.element.id = sequencer.state.selectedObject.uid; |
---|
[240] | 79 | me.uid = uid; |
---|
[233] | 80 | // Header |
---|
| 81 | var titleDiv = ce("div"); |
---|
| 82 | titleDiv.className = "smallTitle"; |
---|
| 83 | var numberDiv = ce("div"); |
---|
| 84 | numberDiv.className = "listNumber"; |
---|
[235] | 85 | numberDiv.innerHTML = "4"; //TODO |
---|
[233] | 86 | var nameSpan = ce("span"); |
---|
[235] | 87 | nameSpan.id = "qeTitleField"; |
---|
[233] | 88 | nameSpan.innerHTML = "New question"; |
---|
| 89 | titleDiv.appendChild(numberDiv); |
---|
| 90 | titleDiv.innerHTML += "Editing: "; |
---|
| 91 | titleDiv.appendChild(nameSpan); |
---|
[235] | 92 | me.element.appendChild(titleDiv); |
---|
[233] | 93 | |
---|
| 94 | //Content area |
---|
| 95 | var contentDiv = ce("div"); |
---|
| 96 | contentDiv.className = "content"; |
---|
[235] | 97 | var bodyText = createNewElement("textarea", null, "qeBodyTextField", "qeBodyTextField", null); |
---|
[233] | 98 | bodyText.value = "Question body text goes here"; |
---|
[235] | 99 | contentDiv.appendChild(bodyText); |
---|
| 100 | |
---|
[233] | 101 | // The dynamic questionParams div, where all the control elements and inputs will be located |
---|
| 102 | var questionParams = ce("div"); |
---|
[235] | 103 | me.paramsElement = questionParams; |
---|
[233] | 104 | questionParams.className = "questionParams"; |
---|
[235] | 105 | questionParams.id = "qeQuestionParamsDiv"; |
---|
| 106 | |
---|
| 107 | var basicContainer = ce("div"); |
---|
[236] | 108 | basicContainer.id = "basicInputs"; |
---|
[235] | 109 | |
---|
| 110 | var qeCodeField = createNewElement("input", "text", "qeCodeField", "qeParamField", null); |
---|
| 111 | var qeCodeField_lbl = createNewInputLabel("Question code:","qeCodeField", "l"); |
---|
| 112 | basicContainer.appendChild(qeCodeField_lbl); |
---|
| 113 | basicContainer.appendChild(qeCodeField); |
---|
[233] | 114 | |
---|
[235] | 115 | var qeTypeField = createNewElement("select", null, "qeTypeField", "qeParamField", null); |
---|
| 116 | var qeTypeField_lbl = createNewInputLabel("Answer type:","qeTypeField", "l"); |
---|
| 117 | basicContainer.appendChild(qeTypeField_lbl); |
---|
| 118 | basicContainer.appendChild(qeTypeField); |
---|
| 119 | questionParams.appendChild(basicContainer); |
---|
| 120 | qeTypeField.addEventListener("change", function(){ |
---|
| 121 | //debugger; |
---|
| 122 | me.selectAnswerType(); |
---|
[233] | 123 | }, false); |
---|
| 124 | // Add the select options. Do this in a block scope to prevent the o1 var from messing things up. |
---|
| 125 | // Also helps in structuring code. |
---|
| 126 | { |
---|
| 127 | var o1 = ce("option"); |
---|
| 128 | o1.value = null; |
---|
| 129 | o1.text = ""; |
---|
[235] | 130 | qeTypeField.appendChild(o1); |
---|
[233] | 131 | |
---|
| 132 | o1 = ce("option"); |
---|
| 133 | o1.value = "int"; |
---|
| 134 | o1.text = "Integer"; |
---|
[235] | 135 | qeTypeField.appendChild(o1); |
---|
[233] | 136 | |
---|
| 137 | o1 = ce("option"); |
---|
| 138 | o1.value = "scale"; |
---|
| 139 | o1.text = "Scale"; |
---|
[235] | 140 | qeTypeField.appendChild(o1); |
---|
[233] | 141 | |
---|
| 142 | o1 = ce("option"); |
---|
| 143 | o1.value = "choice"; |
---|
| 144 | o1.text = "Multiple choice"; |
---|
[235] | 145 | qeTypeField.appendChild(o1); |
---|
[233] | 146 | |
---|
| 147 | o1 = ce("option"); |
---|
| 148 | o1.value = "text"; |
---|
| 149 | o1.text = "Text"; |
---|
[235] | 150 | qeTypeField.appendChild(o1); |
---|
[233] | 151 | } |
---|
| 152 | |
---|
| 153 | contentDiv.appendChild(questionParams); |
---|
[235] | 154 | me.element.appendChild(contentDiv); |
---|
[233] | 155 | |
---|
| 156 | // Controls bar |
---|
| 157 | var controlsDiv = ce("div"); |
---|
| 158 | controlsDiv.className = "controls"; |
---|
| 159 | var btnDiscard = createNewElement("input", "button", "btnDiscard", null, "Discard"); |
---|
| 160 | var btnSave = createNewElement("input", "button", "btnSave", null, "Save"); |
---|
| 161 | controlsDiv.appendChild(btnDiscard); |
---|
| 162 | controlsDiv.appendChild(btnSave); |
---|
| 163 | btnSave.addEventListener("click", function(){ |
---|
[235] | 164 | me.save(); |
---|
[233] | 165 | }, false); |
---|
| 166 | btnDiscard.addEventListener("click", function(){ |
---|
[235] | 167 | me.discard(); |
---|
[233] | 168 | }, false); |
---|
[235] | 169 | me.element.appendChild(controlsDiv); |
---|
| 170 | me.paramSets = new Array(); |
---|
| 171 | me.paramSets.push("basic"); |
---|
[233] | 172 | } |
---|
[235] | 173 | this.save = function() { |
---|
[233] | 174 | var request = { |
---|
[237] | 175 | "title": ge("qeTitleField").innerHTML, |
---|
| 176 | "code": ge("qeCodeField").value, |
---|
[240] | 177 | "description": ge("qeBodyTextField").value, |
---|
| 178 | "uid": me.uid |
---|
[233] | 179 | } |
---|
| 180 | |
---|
[236] | 181 | switch (ge("qeTypeField").value) { |
---|
| 182 | case "int": |
---|
| 183 | request.answerType = "int"; |
---|
| 184 | request.minValue = parseInt(ge("qeMinValueField").value); |
---|
[237] | 185 | if (request.minValue == "NaN") request.minValue = -1; // Is this the correct way to do this? |
---|
[236] | 186 | request.maxValue = parseInt(ge("qeMaxValueField").value); |
---|
[237] | 187 | if (request.maxValue == "NaN") request.maxValue = -1; |
---|
| 188 | // Include error checking and form validation!! |
---|
[236] | 189 | break; |
---|
| 190 | case "scale": |
---|
| 191 | request.answerType = "scale"; |
---|
| 192 | request.numChoices = parseInt(ge("qeNumChoicesField").value); |
---|
| 193 | request.legendsEnabled = ge("qeLegendsEnabledField").checked; |
---|
| 194 | request.lowerLegend = ge("qeLowerLegendField").value; |
---|
| 195 | request.upperLegend = ge("qeUpperLegendField").value; |
---|
[237] | 196 | // Include error checking and form validation!! |
---|
[236] | 197 | break; |
---|
| 198 | case "choice": |
---|
| 199 | request.answerType = "choice"; |
---|
[237] | 200 | request.multipleAnswers = ge("qeMultipleAnswersField").checked; |
---|
| 201 | request.possibleAnswers = array(); |
---|
| 202 | var answerFieldset = ge("qeParamsAnswerFieldset"); |
---|
| 203 | var count = ge("qeNumOptionsField").value; |
---|
| 204 | |
---|
| 205 | for (var i = 0; i < count; i++) { |
---|
| 206 | var el = ge("qeAnswerField"+i); |
---|
| 207 | request.possibleAnswers.push(el.value); |
---|
| 208 | } |
---|
| 209 | // Include error checking and form validation!! |
---|
[236] | 210 | break; |
---|
| 211 | case "text": |
---|
| 212 | request.answerType = "text"; |
---|
[237] | 213 | request.maxTextLength = ge("qeTextMaxLength").value; |
---|
| 214 | // Include error checking and form validation!! |
---|
[236] | 215 | break; |
---|
| 216 | } |
---|
| 217 | |
---|
[237] | 218 | requestString = "args="+JSON.stringify(request); |
---|
| 219 | |
---|
| 220 | newAjaxRequest(requestString, "setQuestion.php", function(result){ |
---|
| 221 | // Then add the returned uid, if existing, to the sequencer.survey.questions array and set it for update |
---|
| 222 | debugger; |
---|
[240] | 223 | console.log(result.responseText); |
---|
[237] | 224 | var response = JSON.parse(result.responseText); |
---|
| 225 | console.log(response); |
---|
| 226 | if (response.created == true) { |
---|
| 227 | if (response.uid) { |
---|
| 228 | // Created a new question, add it to the sequencer content array and set it for an update |
---|
| 229 | sequencer.survey.questions.uids.push(response.uid); |
---|
| 230 | sequencer.survey.questions.upToDate.push(false); |
---|
| 231 | } |
---|
| 232 | else { |
---|
| 233 | alert("ERROR!"); |
---|
| 234 | } |
---|
| 235 | } else { |
---|
| 236 | if (response.uid){ |
---|
| 237 | // Edited an existing question that was already in the sequencer content. Set it for an update |
---|
| 238 | sequencer.survey.questions.upToDate[sequencer.survey.questions.uids.indexOf(response.uid)] = false; |
---|
| 239 | } |
---|
| 240 | else { |
---|
| 241 | alert("ERROR!"); |
---|
| 242 | } |
---|
| 243 | } |
---|
| 244 | |
---|
| 245 | |
---|
| 246 | // Then remove the editor from the sequencer content, so that it can be replaced with the correct question view. |
---|
| 247 | me.element.parentNode.removeChild(me.element); |
---|
| 248 | sequencer.state.editing = false; |
---|
| 249 | updateSequencer(); |
---|
| 250 | }, true); |
---|
[233] | 251 | } |
---|
[237] | 252 | this.discard = function() { |
---|
[240] | 253 | debugger; |
---|
| 254 | me.element.parentNode.removeChild(me.element); |
---|
| 255 | sequencer.state.loaded = true; |
---|
| 256 | sequencer.state.editing = false; |
---|
| 257 | sequencer.survey.questions.upToDate[sequencer.survey.questions.uids.indexOf(me.uid)] = false; |
---|
| 258 | updateSequencer(); |
---|
[238] | 259 | |
---|
[237] | 260 | } |
---|
[235] | 261 | this.reset = function() { |
---|
| 262 | me.init(); |
---|
| 263 | } |
---|
[233] | 264 | |
---|
| 265 | // Updating input fields |
---|
[235] | 266 | this.selectAnswerType = function () { |
---|
[233] | 267 | // Switch statement, call this.type_x where x is the relevant answer type. |
---|
| 268 | // For all this.type_X funtions: |
---|
| 269 | // Use the createNewElement and createNewInputLabel methods to add controls or input fields. |
---|
| 270 | // Input field convention: class = questionParamField, id = qTypeField / qScaleSize, etc... |
---|
| 271 | // Input label class: "l" or "r" depending on alignment with respect to parent ("for") input element. |
---|
| 272 | // Important: use the this.paramsElement to access the questionParams div! |
---|
| 273 | // To fully make use of this class-based approach, the editor should be added to a global variable. This global variable should be removed on page unload! |
---|
[235] | 274 | |
---|
| 275 | var type = ge("qeTypeField").value; |
---|
| 276 | switch (type) { |
---|
| 277 | case "int": |
---|
| 278 | me.type_Integer(); |
---|
| 279 | break; |
---|
| 280 | case "scale": |
---|
| 281 | me.type_Scale(); |
---|
| 282 | break; |
---|
| 283 | case "choice": |
---|
| 284 | me.type_Choice(); |
---|
| 285 | break; |
---|
| 286 | case "text": |
---|
| 287 | me.type_Text(); |
---|
| 288 | break; |
---|
| 289 | default: |
---|
| 290 | //Do nothing |
---|
| 291 | break; |
---|
| 292 | |
---|
| 293 | } |
---|
| 294 | |
---|
[233] | 295 | } |
---|
[235] | 296 | this.checkInputSets = function () { |
---|
| 297 | // Loop through all input containers in the paramsField |
---|
| 298 | for (var n = 0; n < me.paramsElement.childNodes.length; n++) { |
---|
[236] | 299 | if (me.paramsElement.childNodes[n].id == "basicInputs") continue; |
---|
| 300 | // Check if the id (inputSet) is currently in paramSets |
---|
| 301 | if (me.paramSets.indexOf(me.paramsElement.childNodes[n].id) < 0) { |
---|
[235] | 302 | me.paramsElement.childNodes[n].parentNode.removeChild(me.paramsElement.childNodes[n]); |
---|
| 303 | n--; |
---|
| 304 | } |
---|
| 305 | |
---|
| 306 | } |
---|
[233] | 307 | } |
---|
[235] | 308 | |
---|
[233] | 309 | this.type_Integer = function () { |
---|
[235] | 310 | if (me.paramSets.indexOf("int_basic") < 0) { |
---|
| 311 | me.paramSets = new Array("int_basic"); |
---|
| 312 | } |
---|
| 313 | else return; |
---|
[233] | 314 | |
---|
[235] | 315 | me.checkInputSets(); |
---|
[236] | 316 | |
---|
| 317 | var container = ce("div"); |
---|
| 318 | container.id = "int_basic"; |
---|
| 319 | |
---|
[235] | 320 | var qeMinValueField = createNewElement("input", "text", "qeMinValueField", "qeParamField", null); |
---|
| 321 | var qeMinValueField_lbl = createNewInputLabel("Minimum value: ", "qeMinValueField", "l"); |
---|
| 322 | var qeMaxValueField = createNewElement("input", "text", "qeMaxValueField", "qeParamField", null); |
---|
| 323 | var qeMaxValueField_lbl = createNewInputLabel("Maximum value: ", "qeMaxValueField", "l"); |
---|
[236] | 324 | |
---|
[235] | 325 | container.appendChild(qeMinValueField_lbl); |
---|
| 326 | container.appendChild(qeMinValueField); |
---|
| 327 | container.appendChild(qeMaxValueField_lbl); |
---|
| 328 | container.appendChild(qeMaxValueField); |
---|
| 329 | me.paramsElement.appendChild(container); |
---|
| 330 | |
---|
[233] | 331 | } |
---|
[235] | 332 | this.type_Scale = function () { |
---|
| 333 | if (me.paramSets.indexOf("scale_basic") < 0) { |
---|
| 334 | me.paramSets = new Array("scale_basic"); |
---|
| 335 | } |
---|
| 336 | else return; |
---|
| 337 | // Clear any input sets that should not be there |
---|
| 338 | me.checkInputSets(); |
---|
| 339 | |
---|
| 340 | var container = ce("div"); |
---|
[236] | 341 | container.id = "scale_basic"; |
---|
[235] | 342 | |
---|
| 343 | // Number of choices SELECT |
---|
| 344 | var numChoicesField = createNewElement("select", null, "qeNumChoicesField", "qeParamField", null); |
---|
| 345 | var numChoicesField_lbl = createNewInputLabel("Number of choices", "qeNumChoicesField", "l"); |
---|
| 346 | // SELECT options |
---|
| 347 | for (var n = 2; n < 11; n++) { |
---|
| 348 | var o = ce("option"); |
---|
[236] | 349 | o.value = n; |
---|
| 350 | o.text = n; |
---|
[235] | 351 | numChoicesField.appendChild(o); |
---|
| 352 | } |
---|
| 353 | container.appendChild(numChoicesField_lbl); |
---|
| 354 | container.appendChild(numChoicesField); |
---|
| 355 | |
---|
| 356 | // Scale labels CHECKBOX and TEXTs |
---|
| 357 | var legendsEnabledField = createNewElement("input", "checkbox", "qeLegendsEnabledField", "qeParamField", null); |
---|
| 358 | var legendsEnabledField_lbl = createNewInputLabel("Enable legends", "qeLegendsEnabledField", "l"); |
---|
| 359 | container.appendChild(legendsEnabledField_lbl); |
---|
| 360 | container.appendChild(legendsEnabledField); |
---|
| 361 | |
---|
| 362 | var upperLegendText = createNewElement("input", "text", "qeUpperLegendField", "qeParamField", null); |
---|
| 363 | var lowerLegendText = createNewElement("input", "text", "qeLowerLegendField", "qeParamField", null); |
---|
| 364 | var upperLegendText_lbl = createNewInputLabel("Upper legend", "qeUpperLegendField", "l"); |
---|
| 365 | var lowerLegendText_lbl = createNewInputLabel("Lower legend", "qeLowerLegendField", "l"); |
---|
| 366 | container.appendChild(lowerLegendText_lbl); |
---|
| 367 | container.appendChild(lowerLegendText); |
---|
| 368 | container.appendChild(upperLegendText_lbl); |
---|
| 369 | container.appendChild(upperLegendText); |
---|
| 370 | |
---|
| 371 | me.paramsElement.appendChild(container); |
---|
| 372 | } |
---|
[233] | 373 | this.type_Text = function () { |
---|
[236] | 374 | if (me.paramSets.indexOf("text_basic") < 0) { |
---|
| 375 | me.paramSets = new Array("text_basic"); |
---|
| 376 | } |
---|
| 377 | else return; |
---|
[233] | 378 | |
---|
[236] | 379 | me.checkInputSets(); |
---|
| 380 | |
---|
| 381 | var container = ce("div"); |
---|
| 382 | container.id="text_basic"; |
---|
[233] | 383 | } |
---|
| 384 | this.type_Choice = function() { |
---|
[236] | 385 | //debugger; |
---|
| 386 | if (me.paramSets.indexOf("choice_basic") < 0) { |
---|
[235] | 387 | me.paramSets = new Array("choice_basic"); |
---|
| 388 | } |
---|
| 389 | else return; |
---|
[233] | 390 | |
---|
[235] | 391 | me.checkInputSets(); |
---|
| 392 | |
---|
| 393 | var container = ce("div"); |
---|
[236] | 394 | container.id = "choice_basic"; |
---|
[235] | 395 | // num options SELECT |
---|
| 396 | var numOptionsSelect = createNewElement("select", null, "qeNumOptionsField", "qeParamField", null); |
---|
| 397 | var numOptionsSelect_lbl = createNewInputLabel("Number of options", "qeNumOptionsField", "l"); |
---|
| 398 | for (var n = 2; n < 11; n++) { |
---|
| 399 | var o = ce("option"); |
---|
[236] | 400 | o.value = n; |
---|
| 401 | o.text = n; |
---|
[235] | 402 | numOptionsSelect.appendChild(o); |
---|
| 403 | } |
---|
| 404 | container.appendChild(numOptionsSelect_lbl); |
---|
| 405 | container.appendChild(numOptionsSelect); |
---|
[236] | 406 | numOptionsSelect.addEventListener("change", me.type_Choice_CheckAnswerFields, true); |
---|
[235] | 407 | |
---|
[236] | 408 | var allowMultiple = createNewElement("input", "checkbox", "qeMultipleAnswersField", "qeParamField", null); |
---|
| 409 | var allowMultiple_lbl = createNewInputLabel("Allow multiple answers", "qeMultipleAnswersField", "l"); |
---|
| 410 | container.appendChild(allowMultiple_lbl); |
---|
| 411 | container.appendChild(allowMultiple); |
---|
| 412 | |
---|
| 413 | var answersField = ce("div"); |
---|
| 414 | answersField.className = "qeParamFieldset"; |
---|
| 415 | answersField.id = "qeParamsAnswerFieldset" |
---|
| 416 | container.appendChild(answersField); |
---|
| 417 | |
---|
[235] | 418 | me.paramsElement.appendChild(container); |
---|
[236] | 419 | me.type_Choice_CheckAnswerFields(); |
---|
[233] | 420 | } |
---|
[236] | 421 | this.type_Choice_CheckAnswerFields = function() { |
---|
| 422 | var container = ge("qeParamsAnswerFieldset"); |
---|
| 423 | var numAnswers = parseInt(document.getElementById("qeNumOptionsField").value, 10); |
---|
| 424 | var numAnswerFields = 0; |
---|
| 425 | { |
---|
| 426 | for (var i = container.childNodes.length-1; i >= 0; i--) { |
---|
| 427 | if (container.childNodes[i].className = "qeChoiceAnswerGroup") { |
---|
| 428 | numAnswerFields++; |
---|
| 429 | } |
---|
| 430 | } |
---|
| 431 | |
---|
| 432 | } |
---|
[235] | 433 | |
---|
[236] | 434 | // If there already are the correct number of answer fields, exit the function |
---|
| 435 | if (numAnswers == numAnswerFields) return; |
---|
| 436 | else if (numAnswers > numAnswerFields) { |
---|
| 437 | // Extra inputs need to be added |
---|
| 438 | var n = numAnswers - numAnswerFields; |
---|
[237] | 439 | for (var x = 1; x < n+1; x++) { |
---|
[236] | 440 | var group = ce("div"); |
---|
| 441 | group.className = "qeChoiceAnswerGroup"; |
---|
| 442 | var field = createNewElement("input", "text", "qeAnswerField"+(numAnswerFields+x), "qeParamField", null); |
---|
| 443 | var field_lbl = createNewInputLabel((numAnswerFields+x), "qeAnswerField"+(numAnswerFields+x), "l"); |
---|
| 444 | |
---|
| 445 | group.appendChild(field_lbl); |
---|
| 446 | group.appendChild(field); |
---|
| 447 | container.appendChild(group); |
---|
| 448 | } |
---|
| 449 | } |
---|
| 450 | else if (numAnswers < numAnswerFields) { |
---|
| 451 | // There are too many inputs and some need to be removed. Start at the end! |
---|
| 452 | // TODO: This is SO inefficient. There has to be a better way, perhaps adding elements to an array? |
---|
| 453 | // TODO: Another approach would be to use the previousSibling property as a way to prevent having to loop through the entire container tree every time an object needs to be removed. |
---|
| 454 | var n = numAnswerFields-numAnswers; |
---|
| 455 | for (var x = 0; x < n; x++) { |
---|
| 456 | for (var y = container.childNodes.length-1; y >= 0; y--) { |
---|
| 457 | if (container.childNodes[y].className == "qeChoiceAnswerGroup") { |
---|
| 458 | container.removeChild(container.childNodes[y]); |
---|
| 459 | break; |
---|
| 460 | } |
---|
| 461 | } |
---|
| 462 | } |
---|
| 463 | } |
---|
| 464 | } |
---|
| 465 | |
---|
[235] | 466 | // Editing |
---|
| 467 | this.editQuestion = function(uid) { |
---|
[237] | 468 | debugger; |
---|
[235] | 469 | if (sequencer.state.editing == true) return; |
---|
| 470 | if (sequencer.state.loaded == false) return; |
---|
| 471 | sequencer.state.editing = true; |
---|
[237] | 472 | sequencer.state.loaded = false; |
---|
[235] | 473 | |
---|
[237] | 474 | var request = new Array({ |
---|
| 475 | type: "Question", |
---|
| 476 | uid: uid |
---|
| 477 | }); |
---|
[240] | 478 | me.init(uid); |
---|
[237] | 479 | var oldElement = ge(uid); |
---|
| 480 | if (oldElement) { |
---|
| 481 | // There really should be.... I don't know why I am doing this check... |
---|
| 482 | oldElement.parentNode.replaceChild(me.element, oldElement); |
---|
[235] | 483 | } |
---|
| 484 | var requestString = "args="+JSON.stringify(request); |
---|
[237] | 485 | newAjaxRequest(requestString, "getObject.php", function(result){ |
---|
[235] | 486 | // Once results are in |
---|
[237] | 487 | me.setValues(result.responseText); |
---|
[235] | 488 | sequencer.state.loaded = true; |
---|
| 489 | }, true); |
---|
| 490 | } |
---|
| 491 | this.createNewQuestion = function() { |
---|
| 492 | if (sequencer.state.editing == true) return; |
---|
[237] | 493 | if (sequencer.state.loading == false) return; |
---|
[235] | 494 | sequencer.state.editing = true; |
---|
[233] | 495 | |
---|
[240] | 496 | me.init(null); |
---|
[235] | 497 | var container = ge("seqContentWrapper"); |
---|
| 498 | container.appendChild(me.element); |
---|
| 499 | } |
---|
[237] | 500 | } |
---|
| 501 | |
---|
| 502 | // IT LIIIIIIVESSSSS |
---|
| 503 | // TODO: Add database fields for all the necessary question parameters. Maybe only one question parameter property that holds all the settings, then read it out in javascript? |
---|
| 504 | // Why have a question Description? Is this even necessary? |
---|
| 505 | // Needed properties: |
---|
| 506 | // Also not exactly sure what "question->category" is for. Is this one of those questionSet things that Julia was talking about? |
---|
| 507 | // |
---|