Changeset 237 for Dev/branches


Ignore:
Timestamp:
01/17/12 18:17:51 (13 years ago)
Author:
fpvanagthoven
Message:
  • Faal met perongeluk de database committen-_- Maar is weer deleted, zou nu weer moeten werken.
  • QuestionEditor? werkt nu grotendeels, paar kleine afwerkingsfoutjes (en data die nog niet in de DB passen)
  • selectQuestion scherm gemaakt, is nog niet zo multifunctioneel als je zou hopen. Ideaal gezien zou dit ipv een statische PHP pagina, een JS driven widget worden die je bijvoorbeeld kan gebruiken voor "Add existing question" in de surveyEditor.
  • Zelfde voor selectApplication.php en selectSurvey.php.
  • objectSelectionWidget class maken voor dit doeleind? (Na demo!)
Location:
Dev/branches/jos-branch
Files:
3 added
6 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • Dev/branches/jos-branch/css/visualeditors.css

    r236 r237  
    3434    width: 100%;
    3535    position: relative;
    36     padding: 2em 0;
     36    padding: 1em 0;
    3737}
    3838
     
    123123.innerLargeFrame {
    124124    width: auto;
    125     max-height: 300px;
    126     padding: 1em 1em;
     125    /*padding: 1em 1em;*/
    127126    border: 1px solid #FFF;
    128127    border-radius: 0.5em;
     
    156155.innerLargeFrame.vertical {
    157156    overflow-x: hidden;
    158     overflow-y: auto;
    159     max-height: none;
     157    overflow-y: scroll;
    160158}
    161159
     
    179177    box-shadow: 2px 2px 1px #888;
    180178    border: 1px solid #FFF;
    181     margin: 0;
    182179}
    183180
     
    326323    float: left;
    327324    margin-right: -32000px;
     325    padding: 1em;
    328326    min-height: 9em;
    329327}
  • Dev/branches/jos-branch/getObject.php

    r235 r237  
    44
    55//Get post variables
    6 if (!isset($_POST['args']) || empty($_POST['args'])) {
    7     $requestArray = JSON_deode($_POST['args']);
     6if (isset($_POST['args']) || !empty($_POST['args'])) {
     7    $requestArray = JSON_decode($_POST['args']);
    88} else {
    99    die("No input passed!");
     
    1818    if (isset($results) && !empty($results) && count($results) > 0) {
    1919        // Add type property for easier identification in JS.
    20         $results[0]->objectType = type;
     20        $results[0]->objectType = $type;
    2121        $resultArray[] = $results[0];
    2222    }
     
    2626}
    2727
    28 $output = JSON.encode($resultArray);
     28$output = JSON_encode($resultArray);
    2929echo $output;
    3030?>
  • Dev/branches/jos-branch/js/generalScripts.js

    r233 r237  
    163163            posX += element.offsetLeft;
    164164            posY += element.offsetTop;
     165        } while (element = element.offsetParent);
     166    }
     167   
     168    var result = {
     169        X: posX,
     170        Y: posY
     171    }
     172    return result;
     173}
     174
     175// TODO: this is a broken version of the above function, to be used during the demo ONLY! (Else the dropdown menu does not work correctly...
     176// Fix/remove as soon as possible
     177function getWrongPos(element) {
     178    var posX = posY = 0;
     179    if (element.offsetParent) {
     180        do {
     181            posX += element.offsetLeft;
     182            posY += element.offsetTop;
    165183        } while (element = element.offSetParent);
    166184    }
     
    184202
    185203// Drop down menu implementation. Supports three levels: Base button, 1st level categories, and 2nd level links
     204// TODO: getPos functie werkte eerst niet goed, menu offset is nog beetje whack. Betere manier van dropdown menu vinden en voor nu even de getPos functie stuk laten?
    186205function DDMenu() {
    187206    // Initialize function, setting all needed variables.
     
    227246        instance.ddMenuItem = ge(id);
    228247        instance.ddMenuItem.style.visibility = "visible";
    229         var parentPos = getPos(instance.ddMenuItem.parentNode);
     248        var parentPos = getWrongPos(instance.ddMenuItem.parentNode);
    230249        var parentWidth = getWidth(instance.ddMenuItem.parentNode);
    231250        instance.ddMenuItem.style.left = (parentPos.X + parentWidth)+"px";
     
    252271    }
    253272}
     273
     274function manualEventFire(element, rawEvent) {
     275    // Attempts to fire a raw DOM event on an element
     276   
     277    try {
     278        element = document.getElementById(element);
     279        if (element.fireEvent) {
     280            element.fireEvent("on"+rawEvent.type, rawEvent);
     281            return true;
     282        }
     283        else if (element.dispatchEvent) {
     284            element.dispatchEvent(rawEvent);
     285            return true;
     286        }
     287    } catch (e) {
     288    }
     289    return false;
     290}
  • Dev/branches/jos-branch/js/questionEditorScripts.js

    r236 r237  
    2121}
    2222
    23 function updateIdentifier() {
    24     var identField = document.getElementById("questionIdentifierField");
    25     if (identField.value == undefined && identField.value == "") {
    26         return;
    27     }
    28     var headerField = document.getElementById("header_identifier");
    29     headerField.innerHTML = identField.value;
    30 }
    31 
    32 
    33 //////////////////////////////////////////
    34 /* QUESTION EDITOR CLASS BASED APPROACH */
    35 //////////////////////////////////////////
    36 
    3723function QuestionEditor() {
    3824    // Properties   
     
    4733    // Basic functionality
    4834    this.setValues = function(arguments) {
    49         var question = JSON.parse(arguments);       
     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        }
    5072    }
    5173    this.init = function() {
     
    150172    this.save = function() {
    151173        var request = {
    152             "title": ge("qeTitleField").value,
    153             "type": ge("qeTypeField").value
     174            "title": ge("qeTitleField").innerHTML,
     175            "code": ge("qeCodeField").value,
     176            "description": ge("qeBodyTextField").value
    154177        }
    155178       
     
    158181                request.answerType = "int";
    159182                request.minValue = parseInt(ge("qeMinValueField").value);
     183                if (request.minValue == "NaN") request.minValue = -1;   // Is this the correct way to do this?
    160184                request.maxValue = parseInt(ge("qeMaxValueField").value);
     185                if (request.maxValue == "NaN") request.maxValue = -1;
     186                // Include error checking and form validation!!
    161187                break;
    162188            case "scale":
     
    166192                request.lowerLegend = ge("qeLowerLegendField").value;
    167193                request.upperLegend = ge("qeUpperLegendField").value;
     194                // Include error checking and form validation!!
    168195                break;
    169196            case "choice":
    170197                request.answerType = "choice";
     198                request.multipleAnswers = ge("qeMultipleAnswersField").checked;
     199                request.possibleAnswers = array();
     200                var answerFieldset = ge("qeParamsAnswerFieldset");
     201                var count = ge("qeNumOptionsField").value;
     202               
     203                for (var i = 0; i < count; i++) {
     204                    var el = ge("qeAnswerField"+i);
     205                    request.possibleAnswers.push(el.value);
     206                }
     207                // Include error checking and form validation!!
    171208                break;
    172209            case "text":
    173210                request.answerType = "text";
    174                 break;
    175         }
    176        
    177         newAjaxRequest(requestString, "createObject.php", function(result){
    178             // Display a success message, or throw an error.
    179             }, true);
     211                request.maxTextLength = ge("qeTextMaxLength").value;
     212                // Include error checking and form validation!!
     213                break;
     214        }
     215       
     216        requestString = "args="+JSON.stringify(request);
     217       
     218        newAjaxRequest(requestString, "setQuestion.php", function(result){
     219            // Then add the returned uid, if existing, to the sequencer.survey.questions array and set it for update
     220            debugger;
     221            var response = JSON.parse(result.responseText);
     222            console.log(response);
     223            if (response.created == true) {
     224                if (response.uid) {
     225                    // Created a new question, add it to the sequencer content array and set it for an update
     226                    sequencer.survey.questions.uids.push(response.uid);
     227                    sequencer.survey.questions.upToDate.push(false);
     228                }
     229                else {
     230                    alert("ERROR!");
     231                }
     232            } else {
     233                if (response.uid){
     234                    // Edited an existing question that was already in the sequencer content. Set it for an update
     235                    sequencer.survey.questions.upToDate[sequencer.survey.questions.uids.indexOf(response.uid)] = false;
     236                }
     237                else {
     238                    alert("ERROR!");
     239                }
     240            }
     241           
     242           
     243            // Then remove the editor from the sequencer content, so that it can be replaced with the correct question view.
     244            me.element.parentNode.removeChild(me.element);
     245            sequencer.state.editing = false;
     246            updateSequencer();
     247        }, true);
     248    }
     249    this.discard = function() {
     250        me.element.parentNode.removeChild(me.element);
     251        me.init();
     252        sequencer.state.loaded = true;
     253        sequencer.state.editing = false;
    180254    }
    181255    this.reset = function() {
     
    340414    }
    341415    this.type_Choice_CheckAnswerFields = function() {
    342         debugger;
    343416        var container = ge("qeParamsAnswerFieldset");
    344417        var numAnswers = parseInt(document.getElementById("qeNumOptionsField").value, 10);
     
    358431            // Extra inputs need to be added
    359432            var n = numAnswers - numAnswerFields;
    360             for (var x = 0; x < n; x++) {
     433            for (var x = 1; x < n+1; x++) {
    361434                var group = ce("div");
    362435                group.className = "qeChoiceAnswerGroup";
     
    387460    // Editing
    388461    this.editQuestion = function(uid) {
     462        debugger;
    389463        if (sequencer.state.editing == true) return;
    390464        if (sequencer.state.loaded == false) return;
    391465        sequencer.state.editing = true;
    392        
    393         var request = {
    394             "type": "Question",
    395             "uid": uid
    396         }
    397        
     466        sequencer.state.loaded = false;
     467       
     468        var request = new Array({
     469            type: "Question",
     470            uid: uid
     471        });
     472        me.init();
     473        var oldElement = ge(uid);
     474        if (oldElement) {
     475            // There really should be.... I don't know why I am doing this check...
     476            oldElement.parentNode.replaceChild(me.element, oldElement);
     477        }
    398478        var requestString = "args="+JSON.stringify(request);
    399         sequencer.state.loaded = false;
    400         newAjaxRequest(requestString, getObject.php, function(result){
     479        newAjaxRequest(requestString, "getObject.php", function(result){
    401480            // Once results are in
    402             questionEditor.setValues(result.responseText);
     481            me.setValues(result.responseText);
    403482            sequencer.state.loaded = true;
    404483        }, true);
     
    406485    this.createNewQuestion = function() {
    407486        if (sequencer.state.editing == true) return;
    408         if (sequencer.state.loading == true) return;
     487        if (sequencer.state.loading == false) return;
    409488        sequencer.state.editing = true;
    410489   
     
    414493    }
    415494}
     495
     496// IT LIIIIIIVESSSSS
     497// 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?
     498// Why have a question Description? Is this even necessary?
     499// Needed properties:
     500// Also not exactly sure what "question->category" is for. Is this one of those questionSet things that Julia was talking about?
     501//
  • Dev/branches/jos-branch/js/sequencerScripts.js

    r233 r237  
    123123}
    124124
     125function setSequencerSize() {
     126    var seqContent = ge("seqContent");
     127    switch (sequencer.settings.content.orientation.toLowerCase()) {
     128        case "vertical":
     129            var availHeight = window.innerHeight;
     130            var yOffset = getPos(seqContent).Y;
     131            var bottomControlsHeight = 36;
     132            var bottomMargin = 12;
     133            sequencer.settings.content.height = (availHeight - yOffset - bottomControlsHeight - bottomMargin);
     134            sequencer.settings.content.width = 665;
     135            seqContent.style.height = sequencer.settings.content.height+"px";
     136            seqContent.style.width = sequencer.settings.content.width+"px";
     137            addClass(seqContent, "vertical");
     138            break;
     139        case "horizontal":
     140            sequencer.settings.content.width = 800;
     141            sequencer.settings.content.height = 125;
     142            seqContent.style.height = sequencer.settings.content.height+"px";
     143            seqContent.style.width = sequencer.settings.content.width+"px";
     144            addClass(seqContent, "horizontal");
     145            break;
     146        default:
     147            break;
     148    }
     149}
     150
    125151function initSequencer() {
    126152    // Called from loadSequencer(). Sets sequencer.settings properties depending on content type and values passed by PHP in hidden fields (currently only one), then removes these fields.
     
    129155    // load settings fields first
    130156    var fContentType = ge("sContentTypeField");
    131     var content = ge("seqContent");
    132     //sequencer.settings.content.contentType = fContentType.value.toLowerCase();
    133157    sequencer.settings.content.contentType = fContentType.value;
    134158    //Then select settings from a few presets
    135    
    136159    switch (sequencer.settings.content.contentType.toLowerCase()) {
    137160        case "session":
    138161            sequencer.settings.content.orientation = "horizontal";
    139             sequencer.settings.content.width = 800;
    140             sequencer.settings.content.height = 125;
    141             content.style.width = sequencer.settings.content.width+"px";
    142             content.style.height = sequencer.settings.content.height+"px";
    143             addClass(content, "horizontal");
    144162            break;
    145163        case "survey":
    146164            sequencer.settings.content.orientation = "vertical";
    147             sequencer.settings.content.width = 650;     //guesstimated
    148             var roomH = screen.availHeight;
    149             sequencer.settings.content.height = roomH - 200;
    150             content.style.width = sequencer.settings.content.width+"px";
    151             content.style.height = sequencer.settings.content.height+"px";
    152             addClass(content, "vertical");
    153165            break;
    154166        default:
     
    156168    }
    157169    fContentType.parentNode.parentNode.removeChild(fContentType.parentNode);
     170   
     171    window.addEventListener("load", setSequencerSize, true);
    158172}
    159173
     
    230244        requestString = "args="+JSON.stringify(args);
    231245        newAjaxRequest(requestString, "returnObjectDisplay.php", function(result){
    232             console.log(result.responseText);
     246            //console.log(result.responseText);
    233247            insertNewObjects(result.responseText, needsUpdating);
    234248        }, true);
     
    279293        requestString = "args="+JSON.stringify(args);
    280294        newAjaxRequest(requestString, "returnObjectDisplay.php", function(result){
    281             console.log(result.responseText);
     295            //console.log(result.responseText);
    282296            content.removeChild(loadingGif);
    283297            insertNewObjects(result.responseText, needsUpdating);
     
    392406    //console.log(responseText);
    393407    // Container function that calls different insertNewX() functions depending on content type. Called from updateSequencer().
    394     console.log(responseText);
     408    //console.log(responseText);
    395409    var response = JSON.parse(responseText);
    396410    // For now I assume that only one type of element can be displayed in the editor at one time. Therefore, the type of response[0] is the type of all elements of response.
     
    416430       
    417431    newAjaxRequest(c, u, function(result) {
    418         console.log(result.responseText);
     432        //console.log(result.responseText);
    419433        sequencer.survey.questions.uids.push(removeNL(result.responseText));
    420434        sequencer.survey.questions.upToDate.push(false);
     
    434448         */
    435449    if (!response || !response.length > 0) return;
    436     console.log(response);
     450    //console.log(response);
    437451   
    438452    var content = ge("seqContentWrapper");
     
    524538
    525539function insertNewQuestions(response, needsUpdating) {
     540    //TODO: QuestionDisplay ook classbased maken zoals de questionEditor?
     541   
    526542    //Code that inserts or replaces new object displays in the sequencer. Question version.
    527543    var content = ge("seqContentWrapper");
     
    571587        removeButton.className = "smallButton";
    572588        editButton.addEventListener("click", function(e){
    573             alert('Editing not yet supported!');
     589            var targ;
     590            if (!e) e = window.event;
     591            if (e.target) targ = e.target;
     592            else if (e.srcElement) targ = e.srcElement;
     593           
     594            do {
     595                targ = targ.parentNode;
     596            } while (!hasClass(targ, "question"));
     597           
     598            questionEditor.editQuestion(targ.id);
     599            e.stopPropagation();
    574600        }, false);
    575601        removeButton.addEventListener("click", function(e){
    576602            alert('Removing not yet supported!');
     603            e.stopPropagation();
    577604        }, false);
    578605        controlsDiv.appendChild(editButton);
     
    596623            }
    597624            else {
    598                 content.replaceChild(frameDiv, content.childNodes[needsUpdating[j][0]*2]);
     625                if (content.childNodes[needsUpdating[j][0]*2]) {
     626                    content.replaceChild(frameDiv, content.childNodes[needsUpdating[j][0]*2]);
     627                }
     628                else {
     629                    content.appendChild(frameDiv);
     630                    // HACK TIME!
     631                    for (var s = 0; s < content.childNodes.length; s++) {
     632                        if (hasClass(content.childNodes[s], "loading")) {
     633                            content.childNodes[s].parentNode.removeChild(content.childNodes[s]);
     634                        }
     635                    }
     636                    // Serieus, dit moet beter...
     637                }
    599638            }
    600639            sequencer.survey.questions.upToDate[needsUpdating[j][0]] = true;
     
    622661            request.questions.uids = sequencer.survey.questions.uids;
    623662            requestString = "args="+JSON.stringify(request);
    624             console.log(request);
     663            //console.log(request);
    625664            newAjaxRequest(requestString, url, function(result){
    626665                console.log(result.responseText);
     
    658697function selectStep(uid) {
    659698    // Called from clickStep(), manages CSS class assignment and updating of state variables. Also calls for info panel update.
    660    
     699    debugger;
    661700    var element = ge(uid);
    662701    if (element) {
     
    674713                break;
    675714        }
    676         (type != "survey") ? ajaxInfoRequest(uid, ge("infoPanelContent"), type) : type=type /*This does nothing*/;
     715        (type != "Question") ? ajaxInfoRequest(uid, ge("infoPanelContent"), type) : type=type /*This does nothing*/;
    677716        sequencer.state.selectedObject.uid = uid;
    678717        sequencer.state.selectedObject.index = null;  //Don't know how to do this yet.
     
    718757    requestString += "&sessionUid=";
    719758    requestString += sequencer.session.uid;
    720     console.log(requestString);
     759    //console.log(requestString);
    721760    newAjaxRequest(requestString, "savesession.php", function(result){
    722         console.log(result.responseText);
    723     }, true);
     761        //console.log(result.responseText);
     762        }, true);
    724763}
    725764
  • Dev/branches/jos-branch/questionEditor.php

    r208 r237  
    11<?php
    22require 'classes/master.php'; //should be at top of every page
     3
     4if (!isset($_SESSION['userUid'])) {
     5    redirect("index.php");
     6}
     7
     8if (!isset($_POST['questionUid']) || empty($_POST['questionUid'])) {
     9    redirect("index.php");
     10} else {
     11    $questionUid = $_POST['questionUid'];
     12}
     13
     14$questions = Question::get(array());    //Get all questions
    315?>
    416
    5 <!--
    6 To change this template, choose Tools | Templates
    7 and open the template in the editor.
    8 -->
    917<!DOCTYPE html>
    1018<html>
    1119    <head>
    1220        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    13         <title></title>
     21        <title>Research tool</title>
     22        <script type="text/javascript" src="js/generalScripts.js"></script>
     23        <script type="text/javascript" src="js/sequencerScripts.js"></script>
    1424        <script type="text/javascript" src="js/questionEditorScripts.js"></script>
    15         <?php new StyleSheet("awesome"); ?>
     25        <script type="text/javascript">
     26            window.onload = loadfn;
     27
     28            function saveAndReturn_override() {
     29                // This should be the override function for the save button on the questionEditor (smallFrame).
     30                // It should redirect back to the selectQuestion.php page after the standard questionEditor script saves the changes (or not).
     31                alert("DUH!");
     32                window.location = "selectQuestion.php";
     33            }
     34
     35            function loadfn() {
     36                questionEditor.init();
     37                ge("questionEditor_innerFrame").appendChild(questionEditor.element);
     38                ge("btnSave").addEventListener("mouseup", saveAndReturn_override, true);
     39                request = new Array({
     40                  type: "Question",
     41                  uid: "<?php echo $questionUid ?>"
     42                });
     43               
     44                var requestString = "args="+JSON.stringify(request);
     45                newAjaxRequest(requestString, "getObject.php", function(result){
     46                    questionEditor.setValues(result.responseText);
     47                }, true);
     48               
     49            }
     50        </script>
     51
     52        <?php new Stylesheet('visualEditors'); ?>
    1653    </head>
    1754    <body>
    18         <div id="wrapper">
    19             <div id="content">
    20                 <div id="questionEditor">
    21                     <div id="questionEditor_header">
    22                         Editing: <span id="header_identifier">#QUESTION-IDENT-NO</span>
     55        <div id="header">
     56            <?php new Logo(); ?>
     57        </div>
     58       
     59        <div id="content">
     60            <div id="wrapper">
     61                <div id="questionEditor_outer" class="largeFrame">
     62                    <div class="largeTitle">Edit Question</div>
     63                    <div class="innerLargeFrame" id="questionEditor_innerFrame">
    2364                    </div>
    24                     <div id="questionEditor_content">
    25                         <h2>Question text:</h2>
    26                         <div id="questionEditor_bodyText">
    27                             <textarea id="questionEditor_bodyText_textArea" onKeyUp="resizeTextArea();">THIS IS THE QUESTION BODY TEXT. CLICK HERE TO EDIT!</textarea>
    28                         </div>
    29                         <div id="questionEditor_questionParams" >
    30                             <label for="questionIdentifierField" class="formLineBreak">Question tag:</label> <input type="text" id="questionIdentifierField" class="questionParamField" onChange="updateIdentifier();" />
    31 
    32                             <label for="questionType" class="formLineBreak">Answer type:</label>
    33                             <select id="questionType" onChange="selectAnswerType();" class="questionParamField">
    34                                 <option value=""></option>
    35                                 <option value="int">Integer</option>
    36                                 <option value="scale">Scale</option>
    37                                 <option value="choice">Multiple choice</option>
    38                                 <option value="text">Text</option>
    39                             </select>
    40 
    41 
    42 
    43                         </div>
    44                     </div>
    45                     <div id="questionEditor_controls">
    46                         <input type="button" id="discard" value="Discard" />
    47                         <input type="button" value="Save" />
     65                    <div class="controls">
     66                        <input type="button" value="???" id="btnSaveQuestion" class="smallButton" onclick="" />
    4867                    </div>
    4968                </div>
Note: See TracChangeset for help on using the changeset viewer.