source: Dev/trunk/classes/QuestionCreationTool.php @ 117

Last change on this file since 117 was 117, checked in by fpvanagthoven, 14 years ago

Start on php to js loading questions.

File size: 22.6 KB
RevLine 
[102]1<?php
2
3/**
4 * Tool that displays a list and an edit panel
5 *
6 * @author fpvanagthoven
7 */
8class QuestionCreationTool {
[115]9
[114]10    private $questions;
[102]11
[114]12    public function __construct($questions) {
13        $this->questions = $questions;
[116]14
15        $this->loadQuestionsToJavascript();
[103]16        $this->javascript();
[102]17        $this->displayList();
18        $this->displayEditPanel();
19    }
[116]20   
21    /**
22     * Loads the questions that PHP retrieved from database
23     * into javascript. This is done so that the page does not need
24     * to refresh in order to load an entire question in to the form.
[117]25     *
26     * The javascript array will have question codes as keys.
27     * The value is a javascript Question object that gets created from
28     * the PHP object.
[116]29     */
30    private function loadQuestionsToJavascript()
31    {
[117]32//        ?><script type="text/javascript">
33        document.questions = array();
[116]34       
[117]35        //<?php
36//        foreach ($this->questions as $question) {
37//            ?>
38           
39           
40           
41            //<?php
42//        }
43//        ?></script><?php
[116]44    }
[102]45
[103]46    private function javascript() {
47        ?>
48        <script type="text/javascript">
49            function handleType(select)
50            {
51                var type = select.valueOf().value;
52                clearSpecifications();
[116]53                                                                                                       
[103]54                /* set answerCount for options */
55                document.getElementById("answerSpecifications").answerCount = 1;
[116]56                                                                                                       
[103]57                switch (type) {
58                    case "text":
59                        break;
60                    case "mc":
61                        addOption();
62                        break;
63                    case "int":
64                        minMax();
65                        break;
66                    case "checkboxes":
67                        addOption();
68                        break;
69                    case "scale":
70                        minMaxIncr();
71                        break;
72                    default:
[116]73                                                                                                               
[103]74                        break;
75                }
76
77            }
[116]78                                                                                                   
[103]79            function clearSpecifications()
80            {
81                var specs = document.getElementById("answerSpecifications");
82                specs.innerHTML = "";
83                specs.clicked = null;
84                specs.lastAnswer = null;
[116]85                                                                                       
[103]86                var questionType = document.getElementById("questionType");
87                var buttons = document.getElementById("questionButtons");
88                if(buttons != null)
89                    questionType.removeChild(buttons);
90            }
[116]91                                                                                                   
[103]92            function addOption()
93            {                       
94                var specs = document.getElementById("answerSpecifications");
[116]95                                                                                                       
[103]96                addAddRemoveOptionButtonsOnce(specs);
97                addAnswerInput(specs);
[116]98                                                                                                       
[103]99            }
[116]100                                                                                                   
[103]101            function removeOption()
102            {
103                var specs = document.getElementById("answerSpecifications");
[116]104                                                                                                       
[103]105                if(specs.lastAnswer.prev != null)
106                {
107                    specs.removeChild(specs.lastAnswer);
108                    specs.lastAnswer = specs.lastAnswer.prev;
109                    specs.answerCount--;
110                }
111            }
[116]112                                                                                                   
[103]113            function addAnswerInput(specs)
114            {
115                var answerCount = specs.answerCount;
[116]116                                                                                                       
[103]117                /* set value for option textbox */
118                var optionStr = "Option " + answerCount;
[116]119                                                                                                       
[103]120                /* the input textbox */
121                var answerInput = document.createElement("input");
122                answerInput.setAttribute("type", "text");
123                answerInput.setAttribute("name", "ans" + answerCount);
124                answerInput.setAttribute("value", optionStr);
125                answerInput.className = "answerInput";
[116]126                                                                                                       
[103]127                specs.appendChild(answerInput);
[116]128                                                                                                       
[103]129                /* Singly linked list */
130                answerInput.prev = specs.lastAnswer; // remember last one
131                specs.lastAnswer = answerInput; // new lastAnswer
[116]132                                                                                                       
[103]133                specs.answerCount++;               
134            }
[116]135                                                                                                   
[103]136            function addAddRemoveOptionButtonsOnce(specs)
137            {
138                if (specs.clicked == null)
139                {
140                    var buttonsDiv = document.createElement("div");
141                    buttonsDiv.id = "questionButtons";
142                    buttonsDiv.style.display = "inline";
143                    var typeBox = document.getElementById("questionType");
144                    typeBox.appendChild(buttonsDiv);
[116]145                                                                                           
[103]146                    addAddOptionButton(buttonsDiv);                                 
147                    addRemoveOptionButton(buttonsDiv);
[116]148                                                                                                           
[103]149                    specs.clicked = true;
150                }
151            }
[116]152                                                                                                   
[103]153            function addAddOptionButton(buttonsDiv)
154            {   
155                var addOpt = document.createElement("input");
156                addOpt.setAttribute("type", "button");
157                addOpt.setAttribute("id", "addOpt");
158                addOpt.setAttribute("class", "surveyButton");
159                addOpt.setAttribute("onclick", "addOption()");
160                addOpt.setAttribute("value", "Add Option");
161                buttonsDiv.appendChild(addOpt);                                 
162            }
[116]163                                                                                                   
[103]164            function addRemoveOptionButton(buttonsDiv)
165            {
166                var removeOpt = document.createElement("input");
167                removeOpt.setAttribute("type", "button");
168                removeOpt.className = "surveyButton";
169                removeOpt.setAttribute("onclick", "removeOption()");
170                removeOpt.setAttribute("value", "x");
171                buttonsDiv.appendChild(removeOpt);
172            }
[116]173                                                                                                   
[103]174            function minMax(min, max)
175            {
176                if (min == null)
177                    var min = '';
178                if (max == null)
179                    var max = '';
[116]180                                                                                                                                                                                                                                                                                                                               
[103]181                var specs = document.getElementById("answerSpecifications");
[116]182                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
[103]183                var answerDiv = document.createElement("div");
[116]184                                                                                                                                                                                                                                                                                                                                                                                                                                       
[103]185                answerDiv.className = "answerDiv";
186                answerDiv.innerHTML = "<label for='min'>Min</label><input type='text' class='intBox' onchange='checkInt(this)' value='" + min + "' name='ans1' />" +
187                    "<label for='max'>Max</label><input type='text' class='intBox' onchange='checkInt(this)' value='" + max + "' name='ans2' />";
[116]188                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
[103]189                specs.appendChild(answerDiv);
190            }     
[116]191                                                                           
[103]192            function checkInt(input)
193            {
194                input.style.borderWidth = '1px' ;
195                var value = input.value;
196                if (isNaN(value))
197                {
198                    input.style.borderColor = 'red';
199                    input.checkPassed = 'no';
200                }
201                else
202                {
203                    input.style.border = '1px solid #888;';
204                    input.checkPassed = null;
205                }
206            }
[116]207                                                           
[103]208            function minMaxIncr(left, right, incr)
209            {
210                if (left == null)
211                    var left = '';
212                else
213                    left.replace("'", "&#39;");
214                if (right == null)
215                    var right = '';
216                else
217                    right.replace("'", "&#39;");
218                if (incr == null)
219                    var incr = '';
[116]220                                                                                                                                                                                                                                                       
[103]221                var specs = document.getElementById("answerSpecifications");
[116]222                                                                                                                                                                                                                                                                                                                                                                                                                                               
[103]223                var answerDiv = document.createElement("div");
224                answerDiv.className = "answerDiv";
[116]225                                                                                                                                                                               
[103]226                var leftLabel = document.createElement("label");
227                var rightLabel = document.createElement("label");
228                var scaleLabel = document.createElement("label");
229                leftLabel.innerHTML = "Left label";
230                rightLabel.innerHTML = "Right label";
231                scaleLabel.innerHTML = "Scale count";
[116]232                                                                                                                                                                               
[103]233                var leftInput = document.createElement("input");
234                leftInput.type = "text";
235                leftInput.value = left;
236                leftInput.name= "ans1";
237                leftInput.setAttribute("onchange", "handleAnswerChange()");
[116]238                                                                                                                                                                               
[103]239                var rightInput = document.createElement("input");
240                rightInput.type = "text";
241                rightInput.value = right;
242                rightInput.name = "ans2";
243                rightInput.setAttribute("onchange", "handleAnswerChange()");
[116]244                                                                                                                                                                               
[103]245                var scaleInput = document.createElement("input");
246                scaleInput.type = "text";
247                scaleInput.className = "intBox";
248                scaleInput.value = incr;
249                scaleInput.setAttribute("onblur", "checkInt(this)");
250                scaleInput.setAttribute("onchange", "");
251                scaleInput.name = "ans3";
[116]252                                                                                                                                                                               
[103]253                answerDiv.appendChild(leftLabel);
254                answerDiv.appendChild(leftInput);
255                answerDiv.appendChild(rightLabel);
256                answerDiv.appendChild(rightInput);
257                answerDiv.appendChild(scaleLabel);
258                answerDiv.appendChild(scaleInput);
[116]259                                                                                                                                                                                                                                                                                                                                                                                                                           
[103]260                specs.appendChild(answerDiv);
[108]261            }   
[116]262                                           
[108]263            function newCategory()
264            {
265                var categoryBox = document.getElementById("categoryBox");
266                categoryBox.innerHTML = "";
[116]267                                               
[108]268                var categoryInput = document.createElement("input");
269                categoryInput.name = "questionCategory";
[116]270                                               
[108]271                categoryBox.appendChild(categoryInput);
272            }
[116]273                                                       
[112]274            function clearFields()
275            {
276                clearCategory();
277                clearCode();
278                clearTitle();
279                clearDescription();
280                clearType();
281            }
[116]282                                           
[112]283            function clearCategory()
284            {
285                var categoryBox = document.getElementById("categoryBox");
286                categoryBox.innerHTML = "";
[116]287                                               
[112]288                var questionCategorySelect = document.createElement("select");
289                questionCategorySelect.setAttribute("name", "questionCategory");
290                questionCategorySelect.id = "questionCategorySelect";
[116]291                                               
[112]292                var newCategoryButton = document.createElement("input");
293                newCategoryButton.setAttribute("type", "button");
294                newCategoryButton.setAttribute("onclick", "newCategory()");
295                newCategoryButton.setAttribute("value", "New Category");
296                newCategoryButton.className = "surveyButton";
[116]297                                               
[112]298                categoryBox.appendChild(questionCategorySelect);
299                categoryBox.appendChild(newCategoryButton);
300            }
[116]301                                           
[112]302            function clearCode()
303            {
304                var codeInput = document.getElementById("questionCode");
305                codeInput.value = "";
306            }
[116]307                                           
[112]308            function clearTitle()
309            {
310                var titleInput = document.getElementById("questionTitle");
311                titleInput.value ="";
312            }
[116]313                                           
[112]314            function clearDescription()
315            {
316                var descriptionInput = document.getElementById("questionDescription");
317                descriptionInput.value = "";
318            }
[116]319                                           
[112]320            function clearType()
321            {
322                var typeSelect = document.getElementById("questionTypeSelect");
323                typeSelect.selectedIndex = 0;
[114]324                clearSpecifications();
[112]325            }
[116]326                                           
[103]327        </script>
328        <?php
329    }
330
[102]331    private function displayList() {
332        ?>
333        <div id="questionListWrapper">
[103]334            <select id="questionsList" size="9999">
[116]335                <?php $this->populateList(); ?>
[102]336            </select>
337        </div>
338        <?php
339    }
340
341    private function displayEditPanel() {
342        ?>
[104]343        <div id="questionCreation" class="floatLeft">
[116]344            <?php $this->displayForm(); ?>
[102]345        </div>
346        <?php
347    }
348
[104]349    private function displayForm() {
350        ?>
351        <form id="questionEditForm" method="post" action="" onsubmit="">
352            <table class="questionTable">
353                <tr>
[108]354                    <td><label for="questionCategory">Category</label></td>
355                    <td id="categoryBox"><!-- Select should be filled with existing categories-->
[116]356                        <?php $this->questionCategorySelect(); ?>
[108]357                    </td>
358                </tr>
359                <tr>
[104]360                    <td><label for="questionCode">Code</label></td>
361                    <td><input id="questionCode" name="questionCode" size="5" /></td>
362                </tr>
363                <tr>
364                    <td><label for="questionTitle">Title</label></td>
[108]365                    <td><input id="questionTitle" name="questionTitle" size="60" /></td>
[104]366                </tr>
367                <tr>
368                    <td><label for="questionDescription">Description</label></td>
369                    <td><input id="questionDescription" name="questionDescription" size="60" /></td>
370                </tr>
371                <tr>
372                    <td><label for="questionType">Type answer</label></td>
373                    <td id="questionType">
[112]374                        <select id="questionTypeSelect" name="questionType" onchange="handleType(this)">
[104]375                            <option value='text' selected='selected'>Text</option>
376                            <option value='int'>Integer</option>
377                            <option value='mc'>Multiple choice</option>
378                            <option value='checkboxes'>Checkboxes</option>
379                            <option value='scale'>Scale</option>
380                        </select>
381                    </td>
382                </tr>
383            </table>
384            <div id="answerSpecifications"></div>
[112]385            <input id="clearQuestionFields" type="button" onclick="clearFields()" class="surveyButton" value="Clear" />
[104]386            <input id="saveQuestion" type="submit" class="surveyButton" value="Save" />
387        </form>
388        <?php
389    }
[115]390
391    private function questionCategorySelect() {
392        ?>
393        <select id="questionCategorySelect" name="questionCategory">
394            <option value='Uncategorized' selected='selected'>Uncategorized</option>
395            <?php $this->generateCategoryOptions(); ?>
396        </select>
397        <!-- New category button -->
398        <input type="button" class="surveyButton" onclick="newCategory()" value="New Category" />
399        <?php
400    }
[116]401
402    private function generateCategoryOptions() {
[115]403        $categories = array();
[116]404
[115]405        foreach ($this->questions as $question) {
406            $category = $question->category;
[116]407            array_push($categories, $category);
[115]408        }
[116]409        $categories = array_unique($categories);
410
[115]411        // You might want to escape quotes and stuff here
412        foreach ($categories as $category) {
[114]413            ?>
[116]414            <option value="<?php echo $category; ?>"><?php echo $category; ?></option>
415            <?php
[114]416        }
417    }
[104]418
[116]419    /**
420     * Populates the question list. Sorts the list first by question category.
421     */
[115]422    private function populateList() {
[116]423
424        $this->questions = $this->sortByCategory($this->questions);
425
426        $currentCategory = null;
427
[115]428        foreach ($this->questions as $question) {
[116]429            if (is_null($currentCategory)) {
430                ?> <optgroup label="<?php echo $question->category; ?>"><?php
431                $currentCategory = $question->category;
432            } else if ($currentCategory != $question->category) {
433                /* Next category */
434                ?></optgroup><?php
435                $currentCategory = $question->category;
436                ?> <optgroup label="<?php echo $question->category; ?>"><?php
437            }
[115]438            ?>
[116]439                /* function loadQuestionIn() should still be made */
440                <option value="<?php echo $question->code; ?>" onfocus="loadQuestionIn()">
441                    <?php echo "[" . $question->code . "] " . $question->title; ?>
442                </option>
443
[115]444                <?php
445            }
[116]446            ?></optgroup><?php
447    }
[115]448
[116]449    /**
450     *
451     * @param type $questions
452     */
453    private function sortByCategory($questions) {
454        usort($questions, "cmp");
455        return $questions;
[115]456    }
[116]457
458}
459
460/* This function is placed outside the class on purpose.
461 * It's only used as callback function.
462 */
463
464function cmp($q1, $q2) {
465    if ($q1->category == $q2->category) {
466        if($q1->code < $q2->code)
467            return -1;
468        else
469            return 1;
470    }
471    return ($q1->category < $q2->category) ? -1 : 1;
472}
[115]473    ?>
Note: See TracBrowser for help on using the repository browser.