Index: Dev/trunk/css/visualeditors.css
===================================================================
--- Dev/trunk/css/visualeditors.css	(revision 183)
+++ Dev/trunk/css/visualeditors.css	(revision 184)
@@ -34,4 +34,8 @@
     padding: 2em 0;
 }
+
+/************************/
+/* STANDARD UI ELEMENTS */
+/************************/
 
 .largeFrame {
@@ -68,6 +72,4 @@
     width: auto;
     max-height: 300px;
-    overflow-y: auto;
-    overflow-x: hidden;
     padding: 1em 1em;
     border: 1px solid #FFF;
@@ -94,4 +96,16 @@
 }
 
+.innerLargeFrame.horizontal {
+    height: auto;
+    overflow-x: auto;
+    overflow-y: hidden;
+}
+
+.innerLargeFrame.vertical {
+    overflow-x: hidden;
+    overflow-y: auto;
+    max-height: none;
+}
+
 .smallFrame {
     margin: 0.5em auto;
@@ -193,5 +207,5 @@
 
 .bigButton .buttonIcon {
-    
+
 }
 
@@ -214,4 +228,5 @@
     -o-user-select: none;
     user-select: none;
+    cursor: default;
 }
 
@@ -227,20 +242,14 @@
 }
 
+
 /****************************/
 /* PIPELINE EDITOR SPECIFIC */
 /****************************/
 
-#seqContent {
-    overflow-y: hidden;
-    overflow-x: scroll;
-    width: 800px;
-    height: 9em;
-    float: left;
-}
-
 #seqContentWrapper {
     clear: none;
     float: left;
     margin-right: -32000px;
+    min-height: 9em;
 }
 
Index: Dev/trunk/js/sequencerScripts.js
===================================================================
--- Dev/trunk/js/sequencerScripts.js	(revision 183)
+++ Dev/trunk/js/sequencerScripts.js	(revision 184)
@@ -1,50 +1,13 @@
 /* 
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+ * You can change the type of sequencer by including a hidden input field with id "contentTypeField" in your document.
+ * The initEditor() method will then adjust internal variables in the sequencer object to match that type of content.
  */
 
-var sequencer = {   // GLOBAL VAR TO STORE SEQUENCER SETTINGS!
-    uid: "",                // The unique id of this sequencer (not DB related!). This will help to avoid global var conflicts. Assign this randomly! (STRING)
-    session: {              // Properties of the currently loaded session
-        title: "",              // Title or name (STRING)
-        uid: "",                // Database UID of the current session (STRING)
-        pipeline: {             // Pipeline
-            uids: [],               // Uids of objects in pipeline (STRING)
-            types: [],              // Types of objects in pipeline (STRING)
-            upToDate: []            // Whether or not object displays are up to date (BOOL)
-        }
-    },
-    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!]
-        title: "",              // Title or the name of the survey
-        uid: "",                // Uid of the survey
-        questions: {            // Properties of the questions contained within this survey
-            uids: [],               // An array of uids of the questions, in the order that they appear in the survey
-            upToDate: []            // Whether or not a certain question needs an update
-        }
-    },
-    state: {                // Operating state of the sequencer
-        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.
-        numSteps: 0,            // Number of steps currently drawn in the editor (not necessarily same as number of steps in pipeline!) (INTEGER)
-        loaded: false,          // Whether or not the sequencer content has been updated for the first time (BOOL)
-        selectedStep: {         // Properties of the currently selected step
-            uid: "",                // UID of this step (STRING)
-            index: null             // The 'index' of this step in the current sequencer view (NOT the pipeline!) (INTEGER)
-        }        
-    },
-    settings: {             // Various settings to determine the workings of the sequencer
-        content: {              // Properties related to the content view of the sequencer
-            contentType: "session", // Type of the loaded parent object (STRING)
-            width: null,            // Width of the viewing area (INTEGER)
-            height: null,           // Height of the viewing area (INTEGER)
-            maxObjects: null,       // The maximum number of content elements to be displayed at once time (INTEGER)
-            orientation: "horizontal"        // Whether the editor should be a vertical or horizontal editor (STRING)
-        },
-        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
-    }
-}
-
+var sequencer = createVarArray();
 
 function SubmitToolbox(type) {
-    deselectStep();
+    if (sequencer.state.updating == true) return;
+    sequencer.state.updating = true;
+    deselectStep();    
     var c = "objectToCreate="+type;
     var u = "createObject.php";
@@ -217,14 +180,16 @@
     }
     console.log(sequencer);
+    sequencer.state.updating = false;   // Re-enable new actions
 }
 
 function loadSequencer() {
     /* 
- * Description:
- * Load data from hidden fields (put there by PHP), store them in the global var "sequencer" (as well as several initialization properties),
- * then remove the hidden fields from the HTML document tree.
- */
+     * Description:
+     * Load data from hidden fields (put there by PHP), store them in the global var "sequencer" (as well as several initialization properties),
+     * then remove the hidden fields from the HTML document tree.
+     */
     
     // Load hidden fields and set required properties in global object var.
+    
     try {
         // settings fields first
@@ -236,5 +201,5 @@
         var fSessionUid = document.getElementById("sessionField");
         var fSessionTitle = document.getElementById("sessionTitleField");
-    
+        debugger;
         sequencer.session.title = fSessionTitle.value;
         sequencer.session.uid = fSessionUid.value;
@@ -248,5 +213,4 @@
         sequencer.state.numSteps = 0;
         sequencer.state.loaded = false;
-        sequencer.settings.content.orientation = "h";
         sequencer.settings.efficientUpdating = true;
     }
@@ -257,4 +221,10 @@
     
     // Then remove the hidden fields from the HTML document
+    // First reset the values to prevent them from being cached.
+    fPipelineString.value = "blaat";
+    fPipelineTypes.value = "blaat2";
+    fSessionUid.value = "blaat3";
+    fSessionTitle.value = "blaat4";
+    
     var hiddenInputs = document.getElementById("hiddenInputs");
     hiddenInputs.parentNode.removeChild(hiddenInputs);
@@ -268,6 +238,6 @@
     var response = JSON.parse(responseText);
     // 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.
-    switch (response[0].type.toLowerCase()) {
-        case "survey": case "application": case "dashboard":
+    switch (sequencer.settings.content.contentType.toLowerCase()) {
+        case "session":
             insertNewSteps(response, needsUpdating);
             break;
@@ -283,10 +253,10 @@
 function insertNewSteps(response, needsUpdating) {
     /*
- * This is a test function displaying how to handle the visual object representation in solely javascript.
- * Communication of relevant variables between PHP and JS happens in JSON format.
- * PHP returns a JSON array of objects to be created by JS
- * JS then loops through this array and creates DIVS to be inserted into the sequencer.
- * These are inserted at the position needsUpdating gives us.
- */
+     * This is a test function displaying how to handle the visual object representation in solely javascript.
+     * Communication of relevant variables between PHP and JS happens in JSON format.
+     * PHP returns a JSON array of objects to be created by JS
+     * JS then loops through this array and creates DIVS to be inserted into the sequencer.
+     * These are inserted at the position needsUpdating gives us.
+     */
     var content = document.getElementById("seqContentWrapper");
     // Remove optional loading images
@@ -332,10 +302,10 @@
 
 function insertNewQuestions(response, needsUpdating) {
-    var content = document.getElementById("seqcContentWrapper");
+    var content = document.getElementById("seqContentWrapper");
     // Loop through returned question objects
     for (var i = 0; i < response.length; i++) {
         // Define the outer frame
         var frameDiv = document.createElement("div");
-        frameDiv.classname = "smallFrame question";
+        frameDiv.className = "smallFrame question";
         frameDiv.id = response[i].uid;
         var titleDiv = document.createElement("div");
@@ -382,6 +352,15 @@
         frameDiv.appendChild(controlsDiv);
         
-    // We now have a full question display DIV contained in the frameDiv variable. We should now add this to the sequencer content.
-        
+        // We now have a full question display DIV contained in the frameDiv variable. We should now add this to the sequencer content.
+        for (var j = needsUpdating.length - 1; j >= 0; j--) {
+            if (needsUpdating[j][1] != response[i].uid) continue;
+            if (needsUpdating[j][0] > sequencer.state.numSteps-1) {
+                content.appendChild(frameDiv);
+            }
+            else {
+                content.replaceChild(frameDiv, content.childNodes[needsUpdating[j][0]*2]);
+            }
+            sequencer.state.numSteps++;
+        }
     }
 }
@@ -418,5 +397,5 @@
 
 function savePipeline (confirmSave) {
-    debugger;
+    
     var answer;
     if (confirmSave == true) {
@@ -461,8 +440,8 @@
 function moveStep (direction) {
     // Check if a step is selected
-    
     if (sequencer.state.selectedStep.uid == null || direction == null) return;
     // Check if the step is not at either end of the pipeline
     var index = sequencer.session.pipeline.uids.indexOf(sequencer.state.selectedStep.uid);
+    if (index == -1) return;
     if ((index < 0) || (index >= sequencer.session.pipeline.uids.length) || (index == 0 && direction == -1) || (index == sequencer.session.pipeline.uids.length - 1 && direction == 1)) {
         alert("Cannot move out of bounds!");
@@ -492,34 +471,144 @@
     sequencer.session.pipeline.uids[index] = sequencer.session.pipeline.uids.splice(index+direction, 1, sequencer.session.pipeline.uids[index])[0];
     sequencer.session.pipeline.types[index] = sequencer.session.pipeline.types.splice(index+direction, 1, sequencer.session.pipeline.types[index])[0];
+    
+    // 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.
+    for (var i = 0; i < tempOtherElement.childNodes.length; i++){
+        var childNode = tempOtherElement.childNodes[i];
+        if (hasClass(childNode, "displayStepIcon")) {
+            childNode.addEventListener("click", function() {
+                clickStep(this.parentNode.id);
+            }, false);
+        }
+    }
+    for (var i = 0; i < tempElement.childNodes.length; i++){
+        var childNode = tempElement.childNodes[i];
+        if (hasClass(childNode, "displayStepIcon")) {
+            childNode.addEventListener("click", function() {
+                clickStep(this.parentNode.id);
+            }, false);
+        }
+    }
+    
+    
+    
      
+// The alternative is to use event bubbling to capture the event on a higher level.
+// Basically, we bind a super-structure onclick event that uses e.target|| event.srcElement to determine which element to move and select.
+// http://stackoverflow.com/questions/29624/how-to-maintain-correct-javascript-event-after-using-clonenodetrue
+// Pro: clean implementation, less events binded.
+// Con: Difficult, this already works fine, probably tougher to use in conjunction with multifunctionality (sessions, surveys, questionsets, etc in one kind of editor)
+     
 }
 
 function initEditor() {
+    // Reset the editor if the 
+    
     // load settings fields first
     var fContentType = document.getElementById("sContentTypeField");
     var content = document.getElementById("seqContent");
     //sequencer.settings.content.contentType = fContentType.value.toLowerCase();
-    sequencer.settings.content.contentType = "survey";
-    
-    var desiredWidth, desiredHeight;
-    
+    sequencer.settings.content.contentType = fContentType.value;
     //Then select settings from a few presets
+    
     switch (sequencer.settings.content.contentType) {
         case "session":
-            sequencer.settings.content.orientation = "h";
+            sequencer.settings.content.orientation = "horizontal";
             sequencer.settings.content.width = 800;
             sequencer.settings.content.height = 125;
             content.style.width = sequencer.settings.content.width+"px";
             content.style.height = sequencer.settings.content.height+"px";
+            addClass(content, "horizontal");
             break;
         case "survey":
-            sequencer.settings.content.orientation = "v";
-            sequencer.settings.content.width = 600;
+            sequencer.settings.content.orientation = "vertical";
+            sequencer.settings.content.width = 800;
             sequencer.settings.content.height = "auto";
             content.style.width = sequencer.settings.content.width+"px";
             content.style.height = sequencer.settings.content.height+"px";
+            addClass(content, "vertical");
             break;
         default:
             break;
     }
-}
+    fContentType.parentNode.parentNode.removeChild(fContentType.parentNode);
+}
+
+function debug_addQuestion() {
+    // 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!
+    var response = [{
+        uid: "1234567890testuid",
+        title: "dummyQuestion",
+        description: "This is a dummy question, not a real one!",
+        type: "question"
+    }];
+    
+    var needsUpdating = [[
+    0,
+    "1234567890testuid",
+    "question"
+    ]];
+    
+    insertNewQuestions(response, needsUpdating);
+}
+
+function debug_switchType() {
+    var content = ge("seqContent");
+    if (sequencer.settings.content.contentType == "session") {
+        // Set to survey
+        sequencer.settings.content.contentType = "survey";
+        sequencer.settings.content.orientation = "vertical";
+        removeClass(content, "horizontal");
+        addClass(content, "vertical");
+    }
+    else {
+        // Set to session
+        sequencer.settings.content.contentType = "session";
+        sequencer.settings.content.orientation = "horizontal";
+        removeClass(content, "vertical");
+        addClass(content, "horizontal");
+    }
+}
+
+function createVarArray() {
+    if (sequencer) delete window.sequencer;
+    return {   // GLOBAL VAR TO STORE SEQUENCER SETTINGS!
+        uid: "",                // The unique id of this sequencer (not DB related!). This will help to avoid global var conflicts. Assign this randomly! (STRING)
+        session: {              // Properties of the currently loaded session
+            title: "",              // Title or name (STRING)
+            uid: "",                // Database UID of the current session (STRING)
+            pipeline: {             // Pipeline
+                uids: [],               // Uids of objects in pipeline (STRING)
+                types: [],              // Types of objects in pipeline (STRING)
+                upToDate: []            // Whether or not object displays are up to date (BOOL)
+            }
+        },
+        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!]
+            title: "",              // Title or the name of the survey
+            uid: "",                // Uid of the survey
+            questions: {            // Properties of the questions contained within this survey
+                uids: [],               // An array of uids of the questions, in the order that they appear in the survey
+                upToDate: []            // Whether or not a certain question needs an update
+            }
+        },
+        state: {                // Operating state of the sequencer
+            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.
+            updating: false,        // Whether or not new steps are currently being queried (to disable any further actions)
+            numSteps: 0,            // Number of steps currently drawn in the editor (not necessarily same as number of steps in pipeline!) (INTEGER)
+            loaded: false,          // Whether or not the sequencer content has been updated for the first time (BOOL)
+            selectedStep: {         // Properties of the currently selected step
+                uid: "",                // UID of this step (STRING)
+                index: null             // The 'index' of this step in the current sequencer view (NOT the pipeline!) (INTEGER)
+            }        
+        },
+        settings: {             // Various settings to determine the workings of the sequencer
+            content: {              // Properties related to the content view of the sequencer
+                contentType: null,      // Type of the loaded parent object (STRING)
+                width: null,            // Width of the viewing area (INTEGER)
+                height: null,           // Height of the viewing area (INTEGER)
+                maxObjects: null,       // The maximum number of content elements to be displayed at once time (INTEGER)
+                orientation: null       // Whether the editor should be a vertical or horizontal editor (STRING)
+            },
+            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
+        }
+    };
+}
Index: Dev/trunk/pipelineEditor.php
===================================================================
--- Dev/trunk/pipelineEditor.php	(revision 183)
+++ Dev/trunk/pipelineEditor.php	(revision 184)
@@ -21,13 +21,15 @@
         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
         <title></title>
-        <?php new StyleSheet("visualeditors"); 
+        <?php
+        new StyleSheet("visualeditors");
         $sequencer->Javascript();
         ?>
-        
+
     </head>
     <body>
         <div id="header">
             <?php new Logo(); ?>
-            <input type="button" onClick="resizeEditor();" value="debug_resize()" />
+            <input type="button" onClick="debug_switchType();" value="debug_switchType()" />
+            <input type="button" onClick="debug_addQuestion();" value="debug_addQuestion()" />
         </div>
 
@@ -38,5 +40,9 @@
                 <?php new PipelineInfoPanel(); ?>
             </div>
-    
+        </div>
+        <div id="settingsFields">
+            <input type="hidden" id="sContentTypeField" value="session" />
+        </div>
+
     </body>
 </html>
