Changeset 184 for Dev


Ignore:
Timestamp:
12/13/11 17:42:11 (13 years ago)
Author:
fpvanagthoven
Message:
 
Location:
Dev/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • Dev/trunk/css/visualeditors.css

    r182 r184  
    3434    padding: 2em 0;
    3535}
     36
     37/************************/
     38/* STANDARD UI ELEMENTS */
     39/************************/
    3640
    3741.largeFrame {
     
    6872    width: auto;
    6973    max-height: 300px;
    70     overflow-y: auto;
    71     overflow-x: hidden;
    7274    padding: 1em 1em;
    7375    border: 1px solid #FFF;
     
    9496}
    9597
     98.innerLargeFrame.horizontal {
     99    height: auto;
     100    overflow-x: auto;
     101    overflow-y: hidden;
     102}
     103
     104.innerLargeFrame.vertical {
     105    overflow-x: hidden;
     106    overflow-y: auto;
     107    max-height: none;
     108}
     109
    96110.smallFrame {
    97111    margin: 0.5em auto;
     
    193207
    194208.bigButton .buttonIcon {
    195    
     209
    196210}
    197211
     
    214228    -o-user-select: none;
    215229    user-select: none;
     230    cursor: default;
    216231}
    217232
     
    227242}
    228243
     244
    229245/****************************/
    230246/* PIPELINE EDITOR SPECIFIC */
    231247/****************************/
    232248
    233 #seqContent {
    234     overflow-y: hidden;
    235     overflow-x: scroll;
    236     width: 800px;
    237     height: 9em;
    238     float: left;
    239 }
    240 
    241249#seqContentWrapper {
    242250    clear: none;
    243251    float: left;
    244252    margin-right: -32000px;
     253    min-height: 9em;
    245254}
    246255
  • Dev/trunk/js/sequencerScripts.js

    r183 r184  
    11/*
    2  * To change this template, choose Tools | Templates
    3  * and open the template in the editor.
     2 * You can change the type of sequencer by including a hidden input field with id "contentTypeField" in your document.
     3 * The initEditor() method will then adjust internal variables in the sequencer object to match that type of content.
    44 */
    55
    6 var sequencer = {   // GLOBAL VAR TO STORE SEQUENCER SETTINGS!
    7     uid: "",                // The unique id of this sequencer (not DB related!). This will help to avoid global var conflicts. Assign this randomly! (STRING)
    8     session: {              // Properties of the currently loaded session
    9         title: "",              // Title or name (STRING)
    10         uid: "",                // Database UID of the current session (STRING)
    11         pipeline: {             // Pipeline
    12             uids: [],               // Uids of objects in pipeline (STRING)
    13             types: [],              // Types of objects in pipeline (STRING)
    14             upToDate: []            // Whether or not object displays are up to date (BOOL)
    15         }
    16     },
    17     survey: {               // Properties of the loaded survey, if applicable (either this or the session tree above is filled in!) [THIS IS NOT CURRENTLY USED AND I SHOULD DELIBERATE ON WHAT VARIABLES TO PUT IN THIS TREE TO MAKE A FUNCTIONAL EDITOR THAT ALSO MATCHES THE DB FORMAT!]
    18         title: "",              // Title or the name of the survey
    19         uid: "",                // Uid of the survey
    20         questions: {            // Properties of the questions contained within this survey
    21             uids: [],               // An array of uids of the questions, in the order that they appear in the survey
    22             upToDate: []            // Whether or not a certain question needs an update
    23         }
    24     },
    25     state: {                // Operating state of the sequencer
    26         editing: false,         // Whether or not one of the contained child objects is currently being edited or in edit mode. Which one can be determined from the selectedStep property.
    27         numSteps: 0,            // Number of steps currently drawn in the editor (not necessarily same as number of steps in pipeline!) (INTEGER)
    28         loaded: false,          // Whether or not the sequencer content has been updated for the first time (BOOL)
    29         selectedStep: {         // Properties of the currently selected step
    30             uid: "",                // UID of this step (STRING)
    31             index: null             // The 'index' of this step in the current sequencer view (NOT the pipeline!) (INTEGER)
    32         }       
    33     },
    34     settings: {             // Various settings to determine the workings of the sequencer
    35         content: {              // Properties related to the content view of the sequencer
    36             contentType: "session", // Type of the loaded parent object (STRING)
    37             width: null,            // Width of the viewing area (INTEGER)
    38             height: null,           // Height of the viewing area (INTEGER)
    39             maxObjects: null,       // The maximum number of content elements to be displayed at once time (INTEGER)
    40             orientation: "horizontal"        // Whether the editor should be a vertical or horizontal editor (STRING)
    41         },
    42         efficientUpdating: true // Whether or not to use selective querying of the database for new step objects. True will only refresh out-of-date steps, False will refresh the whole pipeline
    43     }
    44 }
    45 
     6var sequencer = createVarArray();
    467
    478function SubmitToolbox(type) {
    48     deselectStep();
     9    if (sequencer.state.updating == true) return;
     10    sequencer.state.updating = true;
     11    deselectStep();   
    4912    var c = "objectToCreate="+type;
    5013    var u = "createObject.php";
     
    217180    }
    218181    console.log(sequencer);
     182    sequencer.state.updating = false;   // Re-enable new actions
    219183}
    220184
    221185function loadSequencer() {
    222186    /*
    223  * Description:
    224  * Load data from hidden fields (put there by PHP), store them in the global var "sequencer" (as well as several initialization properties),
    225  * then remove the hidden fields from the HTML document tree.
    226  */
     187     * Description:
     188     * Load data from hidden fields (put there by PHP), store them in the global var "sequencer" (as well as several initialization properties),
     189     * then remove the hidden fields from the HTML document tree.
     190     */
    227191   
    228192    // Load hidden fields and set required properties in global object var.
     193   
    229194    try {
    230195        // settings fields first
     
    236201        var fSessionUid = document.getElementById("sessionField");
    237202        var fSessionTitle = document.getElementById("sessionTitleField");
    238    
     203        debugger;
    239204        sequencer.session.title = fSessionTitle.value;
    240205        sequencer.session.uid = fSessionUid.value;
     
    248213        sequencer.state.numSteps = 0;
    249214        sequencer.state.loaded = false;
    250         sequencer.settings.content.orientation = "h";
    251215        sequencer.settings.efficientUpdating = true;
    252216    }
     
    257221   
    258222    // Then remove the hidden fields from the HTML document
     223    // First reset the values to prevent them from being cached.
     224    fPipelineString.value = "blaat";
     225    fPipelineTypes.value = "blaat2";
     226    fSessionUid.value = "blaat3";
     227    fSessionTitle.value = "blaat4";
     228   
    259229    var hiddenInputs = document.getElementById("hiddenInputs");
    260230    hiddenInputs.parentNode.removeChild(hiddenInputs);
     
    268238    var response = JSON.parse(responseText);
    269239    // 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.
    270     switch (response[0].type.toLowerCase()) {
    271         case "survey": case "application": case "dashboard":
     240    switch (sequencer.settings.content.contentType.toLowerCase()) {
     241        case "session":
    272242            insertNewSteps(response, needsUpdating);
    273243            break;
     
    283253function insertNewSteps(response, needsUpdating) {
    284254    /*
    285  * This is a test function displaying how to handle the visual object representation in solely javascript.
    286  * Communication of relevant variables between PHP and JS happens in JSON format.
    287  * PHP returns a JSON array of objects to be created by JS
    288  * JS then loops through this array and creates DIVS to be inserted into the sequencer.
    289  * These are inserted at the position needsUpdating gives us.
    290  */
     255     * This is a test function displaying how to handle the visual object representation in solely javascript.
     256     * Communication of relevant variables between PHP and JS happens in JSON format.
     257     * PHP returns a JSON array of objects to be created by JS
     258     * JS then loops through this array and creates DIVS to be inserted into the sequencer.
     259     * These are inserted at the position needsUpdating gives us.
     260     */
    291261    var content = document.getElementById("seqContentWrapper");
    292262    // Remove optional loading images
     
    332302
    333303function insertNewQuestions(response, needsUpdating) {
    334     var content = document.getElementById("seqcContentWrapper");
     304    var content = document.getElementById("seqContentWrapper");
    335305    // Loop through returned question objects
    336306    for (var i = 0; i < response.length; i++) {
    337307        // Define the outer frame
    338308        var frameDiv = document.createElement("div");
    339         frameDiv.classname = "smallFrame question";
     309        frameDiv.className = "smallFrame question";
    340310        frameDiv.id = response[i].uid;
    341311        var titleDiv = document.createElement("div");
     
    382352        frameDiv.appendChild(controlsDiv);
    383353       
    384     // We now have a full question display DIV contained in the frameDiv variable. We should now add this to the sequencer content.
    385        
     354        // We now have a full question display DIV contained in the frameDiv variable. We should now add this to the sequencer content.
     355        for (var j = needsUpdating.length - 1; j >= 0; j--) {
     356            if (needsUpdating[j][1] != response[i].uid) continue;
     357            if (needsUpdating[j][0] > sequencer.state.numSteps-1) {
     358                content.appendChild(frameDiv);
     359            }
     360            else {
     361                content.replaceChild(frameDiv, content.childNodes[needsUpdating[j][0]*2]);
     362            }
     363            sequencer.state.numSteps++;
     364        }
    386365    }
    387366}
     
    418397
    419398function savePipeline (confirmSave) {
    420     debugger;
     399   
    421400    var answer;
    422401    if (confirmSave == true) {
     
    461440function moveStep (direction) {
    462441    // Check if a step is selected
    463    
    464442    if (sequencer.state.selectedStep.uid == null || direction == null) return;
    465443    // Check if the step is not at either end of the pipeline
    466444    var index = sequencer.session.pipeline.uids.indexOf(sequencer.state.selectedStep.uid);
     445    if (index == -1) return;
    467446    if ((index < 0) || (index >= sequencer.session.pipeline.uids.length) || (index == 0 && direction == -1) || (index == sequencer.session.pipeline.uids.length - 1 && direction == 1)) {
    468447        alert("Cannot move out of bounds!");
     
    492471    sequencer.session.pipeline.uids[index] = sequencer.session.pipeline.uids.splice(index+direction, 1, sequencer.session.pipeline.uids[index])[0];
    493472    sequencer.session.pipeline.types[index] = sequencer.session.pipeline.types.splice(index+direction, 1, sequencer.session.pipeline.types[index])[0];
     473   
     474    // Finally, rebind the onCLick events to work properly again. I don't know if this 'clones' the event as well (therefore re-adding them casuses memory bloat...) or not.
     475    for (var i = 0; i < tempOtherElement.childNodes.length; i++){
     476        var childNode = tempOtherElement.childNodes[i];
     477        if (hasClass(childNode, "displayStepIcon")) {
     478            childNode.addEventListener("click", function() {
     479                clickStep(this.parentNode.id);
     480            }, false);
     481        }
     482    }
     483    for (var i = 0; i < tempElement.childNodes.length; i++){
     484        var childNode = tempElement.childNodes[i];
     485        if (hasClass(childNode, "displayStepIcon")) {
     486            childNode.addEventListener("click", function() {
     487                clickStep(this.parentNode.id);
     488            }, false);
     489        }
     490    }
     491   
     492   
     493   
    494494     
     495// The alternative is to use event bubbling to capture the event on a higher level.
     496// Basically, we bind a super-structure onclick event that uses e.target|| event.srcElement to determine which element to move and select.
     497// http://stackoverflow.com/questions/29624/how-to-maintain-correct-javascript-event-after-using-clonenodetrue
     498// Pro: clean implementation, less events binded.
     499// Con: Difficult, this already works fine, probably tougher to use in conjunction with multifunctionality (sessions, surveys, questionsets, etc in one kind of editor)
     500     
    495501}
    496502
    497503function initEditor() {
     504    // Reset the editor if the
     505   
    498506    // load settings fields first
    499507    var fContentType = document.getElementById("sContentTypeField");
    500508    var content = document.getElementById("seqContent");
    501509    //sequencer.settings.content.contentType = fContentType.value.toLowerCase();
    502     sequencer.settings.content.contentType = "survey";
    503    
    504     var desiredWidth, desiredHeight;
    505    
     510    sequencer.settings.content.contentType = fContentType.value;
    506511    //Then select settings from a few presets
     512   
    507513    switch (sequencer.settings.content.contentType) {
    508514        case "session":
    509             sequencer.settings.content.orientation = "h";
     515            sequencer.settings.content.orientation = "horizontal";
    510516            sequencer.settings.content.width = 800;
    511517            sequencer.settings.content.height = 125;
    512518            content.style.width = sequencer.settings.content.width+"px";
    513519            content.style.height = sequencer.settings.content.height+"px";
     520            addClass(content, "horizontal");
    514521            break;
    515522        case "survey":
    516             sequencer.settings.content.orientation = "v";
    517             sequencer.settings.content.width = 600;
     523            sequencer.settings.content.orientation = "vertical";
     524            sequencer.settings.content.width = 800;
    518525            sequencer.settings.content.height = "auto";
    519526            content.style.width = sequencer.settings.content.width+"px";
    520527            content.style.height = sequencer.settings.content.height+"px";
     528            addClass(content, "vertical");
    521529            break;
    522530        default:
    523531            break;
    524532    }
    525 }
     533    fContentType.parentNode.parentNode.removeChild(fContentType.parentNode);
     534}
     535
     536function debug_addQuestion() {
     537    // Derp, natuurlijk werkt de addQuestion call niet twee keer. Hij creeert twee keer exact hetzelfde object. Bottom line: het werkt. Nu de editing code voor deze questions gaan schrijven!
     538    var response = [{
     539        uid: "1234567890testuid",
     540        title: "dummyQuestion",
     541        description: "This is a dummy question, not a real one!",
     542        type: "question"
     543    }];
     544   
     545    var needsUpdating = [[
     546    0,
     547    "1234567890testuid",
     548    "question"
     549    ]];
     550   
     551    insertNewQuestions(response, needsUpdating);
     552}
     553
     554function debug_switchType() {
     555    var content = ge("seqContent");
     556    if (sequencer.settings.content.contentType == "session") {
     557        // Set to survey
     558        sequencer.settings.content.contentType = "survey";
     559        sequencer.settings.content.orientation = "vertical";
     560        removeClass(content, "horizontal");
     561        addClass(content, "vertical");
     562    }
     563    else {
     564        // Set to session
     565        sequencer.settings.content.contentType = "session";
     566        sequencer.settings.content.orientation = "horizontal";
     567        removeClass(content, "vertical");
     568        addClass(content, "horizontal");
     569    }
     570}
     571
     572function createVarArray() {
     573    if (sequencer) delete window.sequencer;
     574    return {   // GLOBAL VAR TO STORE SEQUENCER SETTINGS!
     575        uid: "",                // The unique id of this sequencer (not DB related!). This will help to avoid global var conflicts. Assign this randomly! (STRING)
     576        session: {              // Properties of the currently loaded session
     577            title: "",              // Title or name (STRING)
     578            uid: "",                // Database UID of the current session (STRING)
     579            pipeline: {             // Pipeline
     580                uids: [],               // Uids of objects in pipeline (STRING)
     581                types: [],              // Types of objects in pipeline (STRING)
     582                upToDate: []            // Whether or not object displays are up to date (BOOL)
     583            }
     584        },
     585        survey: {               // Properties of the loaded survey, if applicable (either this or the session tree above is filled in!) [THIS IS NOT CURRENTLY USED AND I SHOULD DELIBERATE ON WHAT VARIABLES TO PUT IN THIS TREE TO MAKE A FUNCTIONAL EDITOR THAT ALSO MATCHES THE DB FORMAT!]
     586            title: "",              // Title or the name of the survey
     587            uid: "",                // Uid of the survey
     588            questions: {            // Properties of the questions contained within this survey
     589                uids: [],               // An array of uids of the questions, in the order that they appear in the survey
     590                upToDate: []            // Whether or not a certain question needs an update
     591            }
     592        },
     593        state: {                // Operating state of the sequencer
     594            editing: false,         // Whether or not one of the contained child objects is currently being edited or in edit mode. Which one can be determined from the selectedStep property.
     595            updating: false,        // Whether or not new steps are currently being queried (to disable any further actions)
     596            numSteps: 0,            // Number of steps currently drawn in the editor (not necessarily same as number of steps in pipeline!) (INTEGER)
     597            loaded: false,          // Whether or not the sequencer content has been updated for the first time (BOOL)
     598            selectedStep: {         // Properties of the currently selected step
     599                uid: "",                // UID of this step (STRING)
     600                index: null             // The 'index' of this step in the current sequencer view (NOT the pipeline!) (INTEGER)
     601            }       
     602        },
     603        settings: {             // Various settings to determine the workings of the sequencer
     604            content: {              // Properties related to the content view of the sequencer
     605                contentType: null,      // Type of the loaded parent object (STRING)
     606                width: null,            // Width of the viewing area (INTEGER)
     607                height: null,           // Height of the viewing area (INTEGER)
     608                maxObjects: null,       // The maximum number of content elements to be displayed at once time (INTEGER)
     609                orientation: null       // Whether the editor should be a vertical or horizontal editor (STRING)
     610            },
     611            efficientUpdating: true // Whether or not to use selective querying of the database for new step objects. True will only refresh out-of-date steps, False will refresh the whole pipeline
     612        }
     613    };
     614}
  • Dev/trunk/pipelineEditor.php

    r183 r184  
    2121        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    2222        <title></title>
    23         <?php new StyleSheet("visualeditors");
     23        <?php
     24        new StyleSheet("visualeditors");
    2425        $sequencer->Javascript();
    2526        ?>
    26        
     27
    2728    </head>
    2829    <body>
    2930        <div id="header">
    3031            <?php new Logo(); ?>
    31             <input type="button" onClick="resizeEditor();" value="debug_resize()" />
     32            <input type="button" onClick="debug_switchType();" value="debug_switchType()" />
     33            <input type="button" onClick="debug_addQuestion();" value="debug_addQuestion()" />
    3234        </div>
    3335
     
    3840                <?php new PipelineInfoPanel(); ?>
    3941            </div>
    40    
     42        </div>
     43        <div id="settingsFields">
     44            <input type="hidden" id="sContentTypeField" value="session" />
     45        </div>
     46
    4147    </body>
    4248</html>
Note: See TracChangeset for help on using the changeset viewer.