source: Dev/trunk/js/questionEditorScripts.js @ 221

Last change on this file since 221 was 218, checked in by fpvanagthoven, 13 years ago

Laatste versies van alles!

File size: 18.2 KB
Line 
1//////////////////////
2/* HELPER FUNCTIONS */
3//////////////////////
4
5function hasClass(ele,cls) {
6    if (ele.className)
7        return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
8}
9 
10function addClass(ele,cls) {
11    if (!this.hasClass(ele,cls)) ele.className += " "+cls;
12}
13 
14function removeClass(ele,cls) {
15    if (hasClass(ele,cls)) {
16        var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
17        ele.className=ele.className.replace(reg,' ');
18    }
19}
20
21//////////////////////////
22/* END HELPER FUNCTIONS */
23//////////////////////////
24
25//////////////////////
26/* CREATE FUNCTIONS */
27//////////////////////
28
29function createQuestionEditor() {
30    // Outer div
31    var editorElement = ce("div");
32    this.className = "smallFrame questionEditor";
33    editorElement.id = sequencer.state.selectedObject.uid;
34    // Header
35    var titleDiv = ce("div");
36    titleDiv.className = "smallTitle";
37    var numberDiv = ce("div");
38    numberDiv.className = "listNumber";
39    numberDiv.innerHTML = "4";
40    var nameSpan = ce("span");
41    nameSpan.innerHTML = "New question";
42    titleDiv.appendChild(numberDiv);
43    titleDiv.innerHTML += "Editing: ";
44    titleDiv.appendChild(nameSpan);
45    editorElement.appendChild(titleDiv);
46   
47    //Content area
48    var contentDiv = ce("div");
49    contentDiv.className = "content";
50    var bodyText = createNewElement("textarea", null, "qBodyTextField", "qBodyTextField", null);
51    bodyText.value = "Question body text goes here";
52   
53   
54    // The dynamic questionParams div, where all the control elements and inputs will be located
55    var questionParams = ce("div");
56    questionParams.className = "questionParams";
57    contentDiv.appendChild(bodyText);
58    var qIdentField = createNewElement("input", "text", "qIdentField", "questionParamField", null);
59    var qIdentField_lbl = createNewInputLabel("Question code:","qIdentField", "l");
60    questionParams.appendChild(qIdentField_lbl);
61    questionParams.appendChild(qIdentField);
62   
63    var qTypeField = createNewElement("select", null, "qTypeField", "questionParamField", null);
64    var qTypeField_lbl = createNewInputLabel("Answer type:","qTypeField", "l");
65    questionParams.appendChild(qTypeField_lbl);
66    questionParams.appendChild(qTypeField);
67    qTypeField.addEventListener("change", function(){
68        debugger;
69        selectAnswerType();
70    }, false);
71    // Add the select options. Do this in a block scope to prevent the o1 var from messing things up.
72    // Also helps in structuring code.
73    {
74        var o1 = ce("option");
75        o1.value = null;
76        o1.text = "";
77        qTypeField.appendChild(o1);
78       
79        o1 = ce("option");
80        o1.value = "int";
81        o1.text = "Integer";
82        qTypeField.appendChild(o1);
83       
84        o1 = ce("option");
85        o1.value = "scale";
86        o1.text = "Scale";
87        qTypeField.appendChild(o1);
88       
89        o1 = ce("option");
90        o1.value = "choice";
91        o1.text = "Multiple choice";
92        qTypeField.appendChild(o1);
93       
94        o1 = ce("option");
95        o1.value = "text";
96        o1.text = "Text";
97        qTypeField.appendChild(o1);
98    }
99   
100    contentDiv.appendChild(questionParams);
101    editorElement.appendChild(contentDiv);
102   
103    // Controls bar
104    var controlsDiv = ce("div");
105    controlsDiv.className = "controls";
106    var btnDiscard = createNewElement("input", "button", "btnDiscard", null, "Discard");
107    var btnSave = createNewElement("input", "button", "btnSave", null, "Save");
108    controlsDiv.appendChild(btnDiscard);
109    controlsDiv.appendChild(btnSave);
110    btnSave.addEventListener("click", function(){
111        swapQuestionState(true);
112    }, false);
113    btnDiscard.addEventListener("click", function(){
114        swapQuestionState(false);
115    }, false);
116    editorElement.appendChild(controlsDiv);
117   
118    return editorElement;
119}
120
121function swapQuestionState(save) {
122    // Function that replaces a question display with the question editor, or vice versa.
123    if (sequencer.state.editing == false) {
124        // Start editing
125        sequencer.state.editing = true;
126        var questionElement = ge(sequencer.state.selectedObject.uid);
127        // test
128        var editor = new QuestionEditor();
129        editor.init();
130        // end test
131        //var editorElement = createQuestionEditor();
132        var content = ge("seqContentWrapper");
133        content.replaceChild(editor.element, questionElement);
134    }
135    else {
136       
137        if (save) {
138            if (save == true) {
139                alert("Saving shit yo!");
140            // User is done editing
141            // 1. Create the edited question in db (createObject.php), then set the proper properties (saveObject.php)
142            // 2. Revert back to question display
143            }
144            else {
145                // Anders discard gewoon alles en haal de question display weg.
146                ge("seqContentWrapper").removeChild(ge(sequencer.state.selectedObject.uid));
147            }
148        }
149   
150    }
151}
152
153
154//////////////////////////
155/* END CREATE FUNCTIONS */
156//////////////////////////
157
158var qUID, parentObjectUID, qName, qTag, qType, qAnswerLength;
159
160function selectAnswerType(){
161    var selectBox = document.getElementById("qTypeField");
162    if (selectBox.value != undefined && selectBox.value != "") {
163        qType = selectBox.value;
164    }
165    else {
166        return;
167    }
168    removeWrongAnswerFields(selectBox);
169    switch (qType) {
170        case "int":
171            selectIntType();
172            break;
173        case "scale":
174            selectScaleType();
175            break;
176        case "choice":
177            //selectChoiceType();
178            break;
179        case "text":
180            //selectTextType();
181            break;
182        default:
183            alert("Invalid answer type selected!");
184            break;
185    }
186   
187}
188
189function createNewElement(tag, type, id, cl, value) {
190    // This is a double of the ce() alias function in generalScripts.js.
191    // It allows for more specific creation of elements on one line,
192    // instead of 5 subsequent lines of code defining tag, id, class, value, etc...
193    // This is handy when doing creation-heavy operations such as adding inputs
194    //!!! Since this is defined in questionEditorScripts.js, it should only be used in this context.
195    //!!! Use ce() whenever possible, since it's included on every page and works faster.
196   
197    var newElement = document.createElement(tag);
198    if (type != undefined) newElement.type = type;
199    if (id != undefined) newElement.id = id;
200    if (cl != undefined) newElement.className = cl;
201    if (value != undefined) {
202        newElement.value = value;
203        newElement.text = value;
204    }
205    return newElement;
206}
207
208function createNewInputLabel(text, target, align) {
209    var newLabel = document.createElement("label");
210    if (target) newLabel.setAttribute("for",target);
211    if (align) newLabel.className = "questionParamLabel "+align+"Align"; else newLabel.className="questionParamLabel";
212    newLabel.innerHTML = text;
213    return newLabel;
214}
215
216function removeWrongAnswerFields(el) {
217    while (el.nextSibling) {
218        el.parentNode.removeChild(el.nextSibling);
219    }
220}
221
222function updateIdentifier() {
223    var identField = document.getElementById("questionIdentifierField");
224    if (identField.value == undefined && identField.value == "") {
225        return;
226    }
227    var headerField = document.getElementById("header_identifier");
228    headerField.innerHTML = identField.value;
229}
230
231
232///////////////////
233/* INT SELECTION */
234///////////////////
235
236function selectIntType() {
237    var selectBox = document.getElementById("questionType");
238    var content = document.getElementById("questionEditor_questionParams");
239    // Add minimum value input
240    var minValueBox = createNewElement("input","text","minValueBox", "questionParamField", null);
241    var minValueBoxLabel = createNewInputLabel("Minimum value:", "minValueBox");
242    addClass(minValueBoxLabel, "formLineBreak");
243    content.appendChild(minValueBoxLabel);
244    content.appendChild(minValueBox);
245    // Add maximum value input
246    var maxValueBox = createNewElement("input", "text", "maxValueBox", "questionParamField", null);
247    var maxValueBoxLabel = createNewInputLabel("Maximum value:","maxValueBox");
248    addClass(maxValueBoxLabel, "formLineBreak");
249    content.appendChild(maxValueBoxLabel);
250    content.appendChild(maxValueBox);
251}
252
253/////////////////////
254/* SCALE SELECTION */
255/////////////////////
256
257function selectScaleType() {
258    // I heard you like walls of text!
259    var content = document.getElementById("questionEditor_questionParams");
260    // Add number of choices input
261    var numChoicesBox = createNewElement("select", null, "numChoicesBox","questionParamField",null);
262    var numChoicesBoxLabel = createNewInputLabel("Scale size:","numChoicesBox");
263    for (var i = 0; i < 10; i++) {
264        var option = createNewElement("option");
265        option.text = i+1;
266        option.value = i+1;
267        numChoicesBox.appendChild(option);
268    }
269    addClass(numChoicesBoxLabel, "formLineBreak");
270    content.appendChild(numChoicesBoxLabel);
271    content.appendChild(numChoicesBox);
272    // Add legends enabled input
273    var legendsEnabledCheckBox = createNewElement("input","checkbox","legendsEnabledCheckbox","questionParamField",null);
274    var legendsEnabledCheckBoxLabel = createNewInputLabel("Enable legends","legendsEnabledCheckBox");
275    addClass(legendsEnabledCheckBoxLabel, "formLineBreak");
276    content.appendChild(legendsEnabledCheckBoxLabel);
277    content.appendChild(legendsEnabledCheckBox);
278    // Add legend labels boxes
279    var upperLegendBox = createNewElement("input","text","upperLegendBox","questionParamField");
280    var lowerLegendBox = createNewElement("input","text","lowerLegendBox","questionParamField");
281    var lowerLegendBoxLabel = createNewInputLabel("Lower legend","lowerLegendBox");
282    var upperLegendBoxLabel = createNewInputLabel("Upper legend","upperLegendBox");
283    addClass(lowerLegendBoxLabel,"formLineBreak");
284    content.appendChild(lowerLegendBoxLabel);
285    content.appendChild(lowerLegendBox);
286    addClass(upperLegendBoxLabel,"formLineBreak");
287    content.appendChild(upperLegendBoxLabel);
288    content.appendChild(upperLegendBox);
289    // Disable these boxes, since the checkbox is unchecked by default
290    lowerLegendBox.disabled = true;
291    upperLegendBox.disabled = true;
292    if (legendsEnabledCheckBox.addEventListener) {
293        legendsEnabledCheckBox.addEventListener("click", toggleScaleLegends, true);
294    }
295}
296
297function toggleScaleLegends() {
298    var content = document.getElementById("questionEditor_questionParams");
299    var checkbox = document.getElementById("legendsEnabledCheckbox");
300    var upperLegendBox = document.getElementById("upperLegendBox");
301    var lowerLegendBox = document.getElementById("lowerLegendBox");
302    if (checkbox.checked == true) {
303        upperLegendBox.disabled = false;
304        lowerLegendBox.disabled = false;
305    }
306    else {
307        upperLegendBox.disabled = true;
308        lowerLegendBox.disabled = true;
309    }
310}
311
312///////////////////////////////
313/* MULTIPLE CHOICE SELECTION */
314///////////////////////////////
315
316function selectChoiceType() {
317    var selectionBox = document.getElementById("questionType");
318    var content = document.getElementById("questionEditor_questionParams");
319}
320
321function resizeTextArea() {
322    var textArea = document.getElementById("questionEditor_bodyText");
323    if (document.getElementById("hiddenScalingDiv")) {
324        var hiddenDiv = document.getElementById("hiddenScalingDiv");
325    }
326    else {
327        var hiddenDiv = document.createElement("div");
328        hiddenDiv.style.visibility = "hidden";
329        textArea.appendChild(hiddenDiv);
330    }
331   
332    debugger;
333    hiddenDiv.innerHTML = "";
334    var userText = textArea.firstChild;
335    alert(userText);
336}
337
338
339//TEST FUNCTIONS
340
341/*
342 * These functions are an attempt at making editors class based, for easier organisation and parameter storage and access.
343 * It prevents having to add more question-specific clutter to the sequencer object
344 */
345
346function QuestionEditor() {
347    // Properties   
348    this.uid = null;
349    this.element = null;
350    this.paramsElement = null;
351   
352    // Basic functionality
353    this.setValues = function(arguments) {
354        // Query question information from database, then fill element fields with correct information.
355       
356    }
357    this.init = function() {
358        // Outer div
359        this.element = ce("div");
360        this.element.className = "smallFrame questionEditor";
361        this.element.id = sequencer.state.selectedObject.uid;
362        this.uid = sequencer.state.selectedObject.uid;
363        // Header
364        var titleDiv = ce("div");
365        titleDiv.className = "smallTitle";
366        var numberDiv = ce("div");
367        numberDiv.className = "listNumber";
368        numberDiv.innerHTML = "4";
369        var nameSpan = ce("span");
370        nameSpan.id = "qTitleField";
371        nameSpan.innerHTML = "New question";
372        titleDiv.appendChild(numberDiv);
373        titleDiv.innerHTML += "Editing: ";
374        titleDiv.appendChild(nameSpan);
375        this.element.appendChild(titleDiv);
376   
377        //Content area
378        var contentDiv = ce("div");
379        contentDiv.className = "content";
380        var bodyText = createNewElement("textarea", null, "qBodyTextField", "qBodyTextField", null);
381        bodyText.value = "Question body text goes here";
382   
383   
384        // The dynamic questionParams div, where all the control elements and inputs will be located
385        var questionParams = ce("div");
386        this.paramsElement = questionParams;
387        questionParams.className = "questionParams";
388        contentDiv.appendChild(bodyText);
389        var qIdentField = createNewElement("input", "text", "qIdentField", "questionParamField", null);
390        var qIdentField_lbl = createNewInputLabel("Question code:","qIdentField", "l");
391        questionParams.appendChild(qIdentField_lbl);
392        questionParams.appendChild(qIdentField);
393   
394        var qTypeField = createNewElement("select", null, "qTypeField", "questionParamField", null);
395        var qTypeField_lbl = createNewInputLabel("Answer type:","qTypeField", "l");
396        questionParams.appendChild(qTypeField_lbl);
397        questionParams.appendChild(qTypeField);
398        qTypeField.addEventListener("change", function(){
399            debugger;
400            selectAnswerType();
401        }, false);
402        // Add the select options. Do this in a block scope to prevent the o1 var from messing things up.
403        // Also helps in structuring code.
404        {
405            var o1 = ce("option");
406            o1.value = null;
407            o1.text = "";
408            qTypeField.appendChild(o1);
409       
410            o1 = ce("option");
411            o1.value = "int";
412            o1.text = "Integer";
413            qTypeField.appendChild(o1);
414       
415            o1 = ce("option");
416            o1.value = "scale";
417            o1.text = "Scale";
418            qTypeField.appendChild(o1);
419       
420            o1 = ce("option");
421            o1.value = "choice";
422            o1.text = "Multiple choice";
423            qTypeField.appendChild(o1);
424       
425            o1 = ce("option");
426            o1.value = "text";
427            o1.text = "Text";
428            qTypeField.appendChild(o1);
429        }
430   
431        contentDiv.appendChild(questionParams);
432        this.element.appendChild(contentDiv);
433   
434        // Controls bar
435        var controlsDiv = ce("div");
436        controlsDiv.className = "controls";
437        var btnDiscard = createNewElement("input", "button", "btnDiscard", null, "Discard");
438        var btnSave = createNewElement("input", "button", "btnSave", null, "Save");
439        controlsDiv.appendChild(btnDiscard);
440        controlsDiv.appendChild(btnSave);
441        btnSave.addEventListener("click", function(){
442            swapQuestionState(true);
443        }, false);
444        btnDiscard.addEventListener("click", function(){
445            swapQuestionState(false);
446        }, false);
447        this.element.appendChild(controlsDiv);
448        var request = {
449            "uid": this.uid,
450            "type": "Question"
451        }
452        var requestString = "args="+JSON.stringify(request);
453        newAjaxRequest(requestString, "returnObjectDisplay.php", function(result){
454            // Fill in the element with the correct values
455            // Result is sent to setValues in object form already, perhaps better idea to send in string format and parse within the target method?
456            this.setValues(JSON.parse(result.responseText));
457        }, true);
458    }
459    this.submit = function() {
460        var request = {
461            "title": ge("qTitleField").value,
462            "type": ge("qTypeField").value
463        }
464       
465        newAjaxRequest(requestString, "createObject.php", function(result){
466            // Display a success message, or throw an error.
467        }, true);
468    }
469   
470    // Updating input fields
471    this.selectAnswertype = function () {
472        // Switch statement, call this.type_x where x is the relevant answer type.
473        // For all this.type_X funtions:
474        // Use the createNewElement and createNewInputLabel methods to add controls or input fields.
475        // Input field convention:  class = questionParamField, id = qTypeField / qScaleSize, etc...
476        // Input label class: "l" or "r" depending on alignment with respect to parent ("for") input element.
477        // Important: use the this.paramsElement to access the questionParams div!
478        // 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!
479    }
480    this.type_Scale = function () {
481       
482    }
483    this.type_Integer = function () {
484       
485    }
486    this.type_Text = function () {
487       
488    }
489    this.type_Choice = function() {
490       
491    }
492   
493}
494
495function newEditor() {
496    // Get variables, ofc not null...
497    var arguments = null;
498    var editor = new QuestionEditor(arguments);
499    editor.setValues(arguments);
500    ge("seqContentWrapper").appendChild(editor.element);
501// Etc. We can put the switchModes() command in here as well, I'd say...
502// Or should that be in the QuestionEditor class? That's probably better, since it has direct access to all the internal variables.
503}
504
505function startEditingQuestion(uid) {
506    if (sequencer.state.editing == true) return;
507   
508    var element = ge(uid);
509    var editor = new QuestionEditor();
510    var newElement = editor.createElement();
511    // Query parameters
512    editor.setValues(parameters);
513    element.parentNode.replaceChild(newElement, element);
514    sequencer.state.editing = true;
515}
Note: See TracBrowser for help on using the repository browser.