// Old, should not be used anymore after class-based QuestionEditor() is finished!!!!! var qUID, parentObjectUID, qName, qTag, qType, qAnswerLength; var questionEditor = new QuestionEditor(); function selectAnswerType(){ var selectBox = document.getElementById("questionType"); if (selectBox.value != undefined && selectBox.value != "") { qType = selectBox.value; } else { return; } removeWrongAnswerFields(selectBox); switch (qType) { case "int": selectIntType(); break; case "scale": selectScaleType(); break; case "choice": //selectChoiceType(); break; case "text": //selectTextType(); break; default: alert("Invalid answer type selected!"); break; } } function createNewElement(tag, type, id, cl, value) { var newElement = document.createElement(tag); if (type != undefined) newElement.type = type; if (id != undefined) newElement.id = id; if (cl != undefined) newElement.className = cl; if (value != undefined) { newElement.value = value; newElement.text = value; } return newElement; } function createNewInputLabel(text, target, side) { var newLabel = document.createElement("label"); if (target) newLabel.setAttribute("for",target); newLabel.innerHTML = text; if (side) newLabel.className = side; return newLabel; } function removeWrongAnswerFields(el) { while (el.nextSibling) { el.parentNode.removeChild(el.nextSibling); } } function updateIdentifier() { var identField = document.getElementById("questionIdentifierField"); if (identField.value == undefined && identField.value == "") { return; } var headerField = document.getElementById("header_identifier"); headerField.innerHTML = identField.value; } ///////////////////// /* SCALE SELECTION */ ///////////////////// function selectScaleType() { // I heard you like walls of text! var content = document.getElementById("questionEditor_questionParams"); // Add number of choices input var numChoicesBox = createNewElement("select", null, "numChoicesBox","questionParamField",null); var numChoicesBoxLabel = createNewInputLabel("Scale size:","numChoicesBox"); for (var i = 0; i < 10; i++) { var option = createNewElement("option"); option.text = i+1; option.value = i+1; numChoicesBox.appendChild(option); } addClass(numChoicesBoxLabel, "formLineBreak"); content.appendChild(numChoicesBoxLabel); content.appendChild(numChoicesBox); // Add legends enabled input var legendsEnabledCheckBox = createNewElement("input","checkbox","legendsEnabledCheckbox","questionParamField",null); var legendsEnabledCheckBoxLabel = createNewInputLabel("Enable legends","legendsEnabledCheckBox"); addClass(legendsEnabledCheckBoxLabel, "formLineBreak"); content.appendChild(legendsEnabledCheckBoxLabel); content.appendChild(legendsEnabledCheckBox); // Add legend labels boxes var upperLegendBox = createNewElement("input","text","upperLegendBox","questionParamField"); var lowerLegendBox = createNewElement("input","text","lowerLegendBox","questionParamField"); var lowerLegendBoxLabel = createNewInputLabel("Lower legend","lowerLegendBox"); var upperLegendBoxLabel = createNewInputLabel("Upper legend","upperLegendBox"); addClass(lowerLegendBoxLabel,"formLineBreak"); content.appendChild(lowerLegendBoxLabel); content.appendChild(lowerLegendBox); addClass(upperLegendBoxLabel,"formLineBreak"); content.appendChild(upperLegendBoxLabel); content.appendChild(upperLegendBox); // Disable these boxes, since the checkbox is unchecked by default lowerLegendBox.disabled = true; upperLegendBox.disabled = true; if (legendsEnabledCheckBox.addEventListener) { legendsEnabledCheckBox.addEventListener("click", toggleScaleLegends, true); } } function toggleScaleLegends() { var content = document.getElementById("questionEditor_questionParams"); var checkbox = document.getElementById("legendsEnabledCheckbox"); var upperLegendBox = document.getElementById("upperLegendBox"); var lowerLegendBox = document.getElementById("lowerLegendBox"); if (checkbox.checked == true) { upperLegendBox.disabled = false; lowerLegendBox.disabled = false; } else { upperLegendBox.disabled = true; lowerLegendBox.disabled = true; } } /////////////////////////////// /* MULTIPLE CHOICE SELECTION */ /////////////////////////////// function selectChoiceType() { var selectionBox = document.getElementById("questionType"); var content = document.getElementById("questionEditor_questionParams"); } function resizeTextArea() { var textArea = document.getElementById("questionEditor_bodyText"); if (document.getElementById("hiddenScalingDiv")) { var hiddenDiv = document.getElementById("hiddenScalingDiv"); } else { var hiddenDiv = document.createElement("div"); hiddenDiv.style.visibility = "hidden"; textArea.appendChild(hiddenDiv); } debugger; hiddenDiv.innerHTML = ""; var userText = textArea.firstChild; alert(userText); } ////////////////////////////////////////// /* QUESTION EDITOR CLASS BASED APPROACH */ ////////////////////////////////////////// function QuestionEditor() { // Properties this.uid = null; // The uid of the question contained in this editor var me = this; // Retarded self-reference because: Javascript this.element = null; // The parent div element containing the questionEditor this.paramsElement = null; // The parent parameters element where all the input sets will be located this.paramSets = null; // The currently enabled input sets to be displayed in the paramsElement // Methods // Basic functionality this.setValues = function(arguments) { var question = JSON.parse(arguments); } this.init = function() { // Outer div me.element = ce("div"); me.element.className = "smallFrame questionEditor"; me.element.id = sequencer.state.selectedObject.uid; me.uid = sequencer.state.selectedObject.uid; // Header var titleDiv = ce("div"); titleDiv.className = "smallTitle"; var numberDiv = ce("div"); numberDiv.className = "listNumber"; numberDiv.innerHTML = "4"; //TODO var nameSpan = ce("span"); nameSpan.id = "qeTitleField"; nameSpan.innerHTML = "New question"; titleDiv.appendChild(numberDiv); titleDiv.innerHTML += "Editing: "; titleDiv.appendChild(nameSpan); me.element.appendChild(titleDiv); //Content area var contentDiv = ce("div"); contentDiv.className = "content"; var bodyText = createNewElement("textarea", null, "qeBodyTextField", "qeBodyTextField", null); bodyText.value = "Question body text goes here"; contentDiv.appendChild(bodyText); // The dynamic questionParams div, where all the control elements and inputs will be located var questionParams = ce("div"); me.paramsElement = questionParams; questionParams.className = "questionParams"; questionParams.id = "qeQuestionParamsDiv"; var basicContainer = ce("div"); basicContainer.className = "basicInputs"; var qeCodeField = createNewElement("input", "text", "qeCodeField", "qeParamField", null); var qeCodeField_lbl = createNewInputLabel("Question code:","qeCodeField", "l"); basicContainer.appendChild(qeCodeField_lbl); basicContainer.appendChild(qeCodeField); var qeTypeField = createNewElement("select", null, "qeTypeField", "qeParamField", null); var qeTypeField_lbl = createNewInputLabel("Answer type:","qeTypeField", "l"); basicContainer.appendChild(qeTypeField_lbl); basicContainer.appendChild(qeTypeField); questionParams.appendChild(basicContainer); qeTypeField.addEventListener("change", function(){ //debugger; me.selectAnswerType(); }, false); // Add the select options. Do this in a block scope to prevent the o1 var from messing things up. // Also helps in structuring code. { var o1 = ce("option"); o1.value = null; o1.text = ""; qeTypeField.appendChild(o1); o1 = ce("option"); o1.value = "int"; o1.text = "Integer"; qeTypeField.appendChild(o1); o1 = ce("option"); o1.value = "scale"; o1.text = "Scale"; qeTypeField.appendChild(o1); o1 = ce("option"); o1.value = "choice"; o1.text = "Multiple choice"; qeTypeField.appendChild(o1); o1 = ce("option"); o1.value = "text"; o1.text = "Text"; qeTypeField.appendChild(o1); } contentDiv.appendChild(questionParams); me.element.appendChild(contentDiv); // Controls bar var controlsDiv = ce("div"); controlsDiv.className = "controls"; var btnDiscard = createNewElement("input", "button", "btnDiscard", null, "Discard"); var btnSave = createNewElement("input", "button", "btnSave", null, "Save"); controlsDiv.appendChild(btnDiscard); controlsDiv.appendChild(btnSave); btnSave.addEventListener("click", function(){ me.save(); }, false); btnDiscard.addEventListener("click", function(){ me.discard(); }, false); me.element.appendChild(controlsDiv); me.paramSets = new Array(); me.paramSets.push("basic"); } this.save = function() { var request = { "title": ge("qeTitleField").value, "type": ge("qeTypeField").value } newAjaxRequest(requestString, "createObject.php", function(result){ // Display a success message, or throw an error. }, true); } this.reset = function() { me.init(); } // Updating input fields this.selectAnswerType = function () { // Switch statement, call this.type_x where x is the relevant answer type. // For all this.type_X funtions: // Use the createNewElement and createNewInputLabel methods to add controls or input fields. // Input field convention: class = questionParamField, id = qTypeField / qScaleSize, etc... // Input label class: "l" or "r" depending on alignment with respect to parent ("for") input element. // Important: use the this.paramsElement to access the questionParams div! // 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! var type = ge("qeTypeField").value; switch (type) { case "int": me.type_Integer(); break; case "scale": me.type_Scale(); break; case "choice": me.type_Choice(); break; case "text": me.type_Text(); break; default: //Do nothing break; } } this.checkInputSets = function () { // Loop through all input containers in the paramsField for (var n = 0; n < me.paramsElement.childNodes.length; n++) { if (me.paramsElement.childNodes[n].className == "basicInputs") continue; // Check if the class (inputSet) is currently in paramSets if (me.paramSets.indexOf(me.paramsElement.childNodes[n].className) < 0) { me.paramsElement.childNodes[n].parentNode.removeChild(me.paramsElement.childNodes[n]); n--; } } } this.type_Integer = function () { if (me.paramSets.indexOf("int_basic") < 0) { me.paramSets = new Array("int_basic"); } else return; me.checkInputSets(); var qeMinValueField = createNewElement("input", "text", "qeMinValueField", "qeParamField", null); var qeMinValueField_lbl = createNewInputLabel("Minimum value: ", "qeMinValueField", "l"); var qeMaxValueField = createNewElement("input", "text", "qeMaxValueField", "qeParamField", null); var qeMaxValueField_lbl = createNewInputLabel("Maximum value: ", "qeMaxValueField", "l"); var container = ce("div"); container.className = "int_basic"; container.appendChild(qeMinValueField_lbl); container.appendChild(qeMinValueField); container.appendChild(qeMaxValueField_lbl); container.appendChild(qeMaxValueField); me.paramsElement.appendChild(container); } this.type_Scale = function () { if (me.paramSets.indexOf("scale_basic") < 0) { me.paramSets = new Array("scale_basic"); } else return; // Clear any input sets that should not be there me.checkInputSets(); var container = ce("div"); container.className = "scale_basic"; // Number of choices SELECT var numChoicesField = createNewElement("select", null, "qeNumChoicesField", "qeParamField", null); var numChoicesField_lbl = createNewInputLabel("Number of choices", "qeNumChoicesField", "l"); // SELECT options for (var n = 2; n < 11; n++) { var o = ce("option"); o.value = n-1; o.text = n-1; numChoicesField.appendChild(o); } container.appendChild(numChoicesField_lbl); container.appendChild(numChoicesField); // Scale labels CHECKBOX and TEXTs var legendsEnabledField = createNewElement("input", "checkbox", "qeLegendsEnabledField", "qeParamField", null); var legendsEnabledField_lbl = createNewInputLabel("Enable legends", "qeLegendsEnabledField", "l"); container.appendChild(legendsEnabledField_lbl); container.appendChild(legendsEnabledField); var upperLegendText = createNewElement("input", "text", "qeUpperLegendField", "qeParamField", null); var lowerLegendText = createNewElement("input", "text", "qeLowerLegendField", "qeParamField", null); var upperLegendText_lbl = createNewInputLabel("Upper legend", "qeUpperLegendField", "l"); var lowerLegendText_lbl = createNewInputLabel("Lower legend", "qeLowerLegendField", "l"); container.appendChild(lowerLegendText_lbl); container.appendChild(lowerLegendText); container.appendChild(upperLegendText_lbl); container.appendChild(upperLegendText); me.paramsElement.appendChild(container); } this.type_Text = function () { } this.type_Choice = function() { debugger; if (me.paramSets.indexOf("choice_basic")) { me.paramSets = new Array("choice_basic"); } else return; me.checkInputSets(); var container = ce("div"); container.className = "choice_basic"; // num options SELECT var numOptionsSelect = createNewElement("select", null, "qeNumOptionsField", "qeParamField", null); var numOptionsSelect_lbl = createNewInputLabel("Number of options", "qeNumOptionsField", "l"); for (var n = 2; n < 11; n++) { var o = ce("option"); o.value = n-1; o.text = n-1; numOptionsSelect.appendChild(o); } container.appendChild(numOptionsSelect_lbl); container.appendChild(numOptionsSelect); me.paramsElement.appendChild(container); } // Editing this.editQuestion = function(uid) { if (sequencer.state.editing == true) return; if (sequencer.state.loaded == false) return; sequencer.state.editing = true; var request = { "type": "Question", "uid": uid } var requestString = "args="+JSON.stringify(request); sequencer.state.loaded = false; newAjaxRequest(requestString, getObject.php, function(result){ // Once results are in questionEditor.setValues(result.responseText); sequencer.state.loaded = true; }, true); } this.createNewQuestion = function() { if (sequencer.state.editing == true) return; if (sequencer.state.loading == true) return; sequencer.state.editing = true; me.reset(); var container = ge("seqContentWrapper"); container.appendChild(me.element); } }