Browse Source

Improvements to RuleBuilder, including HTML output for preview

Nathan Schneider 4 years ago
parent
commit
7ef547252c
3 changed files with 86 additions and 45 deletions
  1. 2 0
      _data/modules.csv
  2. 81 20
      _layouts/rule.html
  3. 3 25
      _sass/communityrule.scss

+ 2 - 0
_data/modules.csv

@@ -1,8 +1,10 @@
 name,id,description,url,source,type
 Board,board,,https://democraticmediums.info/mediums/board/,Democratic Mediums,structure
 Bureaucracy,bureaucracy,,https://democraticmediums.info/mediums/bureaucracy/,Democratic Mediums,structure
+Executive,executive,,,,structure
 Federation,federation,,https://democraticmediums.info/mediums/federation/,Democratic Mediums,structure
 Judiciary,judiciary,,https://democraticmediums.info/mediums/judiciary/,Democratic Mediums,structure
+Legislative,legislative,,,,structure
 Multicameralism,multicameralism,,https://democraticmediums.info/mediums/multicameralism/,Democratic Mediums,structure
 Platform,platform,,https://democraticmediums.info/mediums/platform/,Democratic Mediums,structure
 Separation of powers,separation_of_powers,,https://democraticmediums.info/mediums/separation_of_powers/,Democratic Mediums,structure

+ 81 - 20
_layouts/rule.html

@@ -19,16 +19,26 @@ layout: default
   function drop(ev) {
       ev.preventDefault();
       var target = ev.target;
-      if (target.id != "module-input") { // First, confirm location is valid
-          // Prevents dropping into dummy text field
-          if (target.id == "drag-directions") {
-              target = target.parentElement;
-          } else if (!document.getElementById("module-input").contains(target) ||
-                     document.getElementById("module-menu").contains(target)) {
+      // First, confirm target location is valid
+      function targetCheck () {
+          if (target.id == "module-input") { 
+              return true;
+          } else if (!document.getElementById("module-input").contains(target)) {
               // Ignore destinations not in the correct area
-              return;
+              return false;
+          } else if (target.id == "drag-directions") {
+              // Prevents dropping into dummy text field
+              target = target.parentElement;
+              return true;
+          } else if (target.classList[0] == "module") {
+              return true;
+          } else {
+              // be sure we're adding to module, not its children              
+              target = target.parentElement;
+              return targetCheck();
           }
       }
+      if (!targetCheck()) { return; } 
       // Set up transfer
       var data = ev.dataTransfer.getData("text");
       // Iff module is from the menu clone it
@@ -65,7 +75,8 @@ layout: default
   // Edits the title field of a given module based on #custom-field
   function moduleTitleEdit(moduleID) {
       var module = document.getElementById(moduleID).children[0];
-      var content = document.getElementById("custom-field").innerHTML.replace(/(<([^>]+)>)/ig,'');
+      var content =
+          stripHTML(document.getElementById("custom-field").innerHTML);
       module.title = content;
   }
   
@@ -104,14 +115,63 @@ layout: default
       }
   }
 
-  // Turns RuleBuilder contents into a nested array
-  // TKTK to do
+  // Turns RuleBuilder contents into an output-ready nested array
+  // Returns empty array if no modules
   function builderArray() {
-      var modulesDOM = "";
-      var modulesArray = [];
-          
+      var modules = document.getElementById("module-input").children;
+      // takes an array of children
+      // returns an array with all modules in the array, recursively nested
+      function iterateArray (childs) {
+          var moduleArray = [];
+          if (childs.length > 0) {
+              for (var i = 0; i < childs.length; i++) {
+                  module = childs[i];
+                  if (module.classList[0] == "module") {
+                      var moduleName = module.children.item("module-name");
+                      var moduleData = moduleName.title;
+                      var moduleChilds = module.children;
+                      moduleArray.push(
+                          [stripHTML(moduleName.innerHTML),
+                           stripHTML(moduleData),
+                           iterateArray(moduleChilds)]);
+                  }
+              }
+          }
+          return moduleArray;
+      } // end function
+      return iterateArray(modules);
   }
+
+  function displayBuilderHTML() {
+      var output = "";
+      var mainArray = builderArray();
+      function arrayHTML(thisArray) {
+          var thisOutput = "";
+          if (thisArray.length > 0) {
+              thisOutput += "<ul>\n";
+              for (var i = 0; i < thisArray.length; i++) {
+                  var item = thisArray[i];
+                  thisOutput += "<li><strong>" + item[0] + "</strong> ";
+                  thisOutput += item[1] + "</li>\n";
+                  if (item[2].length > 0) {
+                      thisOutput += arrayHTML(item[2]);
+                  }
+              }
+              thisOutput += "</ul>\n";
+          }
+          return thisOutput
+      }
+      return arrayHTML(mainArray);
+  }
+  
+  
   // end RuleBuilder functions
+
+  // Removes all HTML content
+  function stripHTML(input) {
+      input = input.replace(/(<([^>]+)>)/ig,'');
+      return input;
+  }
   
   // toggleVisible(id)
   // Toggles the visibility of a given element by given ID
@@ -151,20 +211,21 @@ layout: default
               editableFields[i].style.borderStyle = "none";
               // Remove empty fields entirely
               var content = editableFields[i].innerHTML;
-              content = content.replace(/(<([^>]+)>)/ig,''); // strips stray tags
+              content = stripHTML(content);
               if (content === "") {
                   editableFields[i].style.display = "none";
               }   
           }
-          // Remove headers of empty sections (Inefficient! Might be merged with the above iteration)
-          // First, RuleBuilder
+          // RuleBuilder sections
           if (builderEmpty()) {
               document.getElementById("rule-builder").style.display = "none";
           }
           if (document.contains(document.getElementById("custom-field-container"))) {
               document.getElementById("custom-field-container").remove();
           }
-          // Now, RuleWriter sections
+          document.getElementById("module-menu").style.display = "none";
+          document.getElementById("builder-field").innerHTML = displayBuilderHTML();
+          // RuleWriter: Remove headers of empty sections
           var sections = document.getElementsByClassName("section");
           for (var i = 0; i < sections.length; i++) {
               var sectionQuestions = sections[i].getElementsByClassName("editable");
@@ -211,6 +272,7 @@ layout: default
           classDisplayAll("delete-module","inline");
           // builder handling
           document.getElementById("rule-builder").style.display = "block";
+          document.getElementById("builder-field").innerHTML = "";          
           // author handling
           document.getElementById("authorship-result").style.display = "none";
           document.getElementById("authorship-words").style.display = "none";
@@ -467,7 +529,7 @@ layout: default
       <div id="builder-field">
       </div>
       
-      <div id="module-menu">
+      <div id="module-menu" style="display:none;">
         <!-- Customizable module -->
         <span class="module" id="module-custom"
               draggable="true" ondragstart="drag(event)">
@@ -483,8 +545,7 @@ layout: default
 		<span class="module" id="module-{{ module.id }}"
 			  draggable="true" ondragstart="drag(event)">
 		  <span id="module-name"
-                onclick="moduleEditField(this.parentNode.id)">
-            {{ module.name }}</span>
+                onclick="moduleEditField(this.parentNode.id)">{{ module.name }}</span>
           <a target="_blank" href="{{ module.url }}" class="module-link">
             <img title="{{ module.type }}" draggable="false" 
                  {% if module.type == "structure" %}

+ 3 - 25
_sass/communityrule.scss

@@ -37,10 +37,8 @@
     border-bottom: 1px solid lightgray;
 }
 
+/* Modules */
 
-/* Tooltip for Modules
-   https://www.w3schools.com/css/tryit.asp?filename=trycss_tooltip_right 
-   This could bear substantial improvement. */
 #module-toggle {
     float: right;
     position: relative;
@@ -50,33 +48,13 @@
 #module-menu {
     display: none;
     max-height: 200px;
-    overflow: scroll;
+    overflow-y: scroll;
     margin: 0 0 10px 0;
-}
-.button .tooltiptext {
-    visibility: hidden;
-    width: 400px;
-    overflow:scroll;
-    height:400px;
-    border: 1px solid black;
-    background-color: white;
-    text-align: center;
-    border-radius: 6px;
-    padding: 10px;
-    /* Position the tooltip */
-    position: absolute;
-    z-index: 1;
-    top: -5px;
-    right: 100%;
+    border: 1px solid lightgray;
 }
 .button:hover {
     background-color: lightgray;
 }
-.button:hover .tooltiptext {
-    visibility: visible;
-}
-
-/* Modules */
 
 #module-input {
     overflow: hidden;