summaryrefslogtreecommitdiffstats
path: root/dashboard/src/templates/dashboard/multiple_select_filter_widget.html
diff options
context:
space:
mode:
authorParker Berberian <pberberian@iol.unh.edu>2018-10-10 16:06:47 -0400
committerParker Berberian <pberberian@iol.unh.edu>2018-10-15 13:16:11 -0400
commit25275685e9a735e51fae8b1a936ba5733f6fb770 (patch)
treec3af41d1986c0812ca7ed059c16c7c7c7bd354cf /dashboard/src/templates/dashboard/multiple_select_filter_widget.html
parentf2e83b24260b018bb7cc30421eda6c9a8cebc309 (diff)
Lab as a Service 2.0
See changes here: https://wiki.opnfv.org/display/INF/Pharos+Laas Change-Id: I59ada5f98e70a28d7f8c14eab3239597e236ca26 Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu> Signed-off-by: Parker Berberian <pberberian@iol.unh.edu>
Diffstat (limited to 'dashboard/src/templates/dashboard/multiple_select_filter_widget.html')
-rw-r--r--dashboard/src/templates/dashboard/multiple_select_filter_widget.html402
1 files changed, 402 insertions, 0 deletions
diff --git a/dashboard/src/templates/dashboard/multiple_select_filter_widget.html b/dashboard/src/templates/dashboard/multiple_select_filter_widget.html
new file mode 100644
index 0000000..ed29ed6
--- /dev/null
+++ b/dashboard/src/templates/dashboard/multiple_select_filter_widget.html
@@ -0,0 +1,402 @@
+<style>
+.object_class_wrapper {
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
+ border: 0px;
+}
+.class_grid_wrapper {
+ border: 0px;
+ border-left: 1px;
+ border-right: 1px;
+ border-style: solid;
+ border-color: grey;
+ text-align: center;
+}
+.grid_wrapper {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+}
+.grid-item {
+ cursor: pointer;
+ border:2px;
+ border-style:none;
+ border-color:black;
+ border-radius: 5px;
+ margin:20px;
+ height: 200px;
+ padding: 7px;
+ box-shadow: 0px 0px 7px 0px rgba(0,0,0,0.75);
+ transition-property: box-shadow, background-color;
+ transition-duration: .2s;
+}
+
+.grid-item:hover {
+ box-shadow: 0px 0px 14px 0px rgba(0,0,0,0.75);
+ transition-property: box-shadow;
+ transition-duration: .2s;
+
+}
+
+.selected_node {
+ box-shadow: 0px 0px 14px 0px rgba(0,0,0,0.75);
+ background-color: #CCECD7;
+ transition-property: background-color;
+ transition-duration: .2s;
+}
+
+.disabled_node {
+ cursor: not-allowed;
+ background-color: #EFEFEF;
+ box-shadow: 0px 0px 1px 0px rgba(0,0,0,0.75);
+ transition-property: box-shadow;
+ transition-duration: .2s;
+}
+
+.disabled_node:hover {
+ box-shadow: 0px 0px 1px 0px rgba(0,0,0,0.75);
+}
+
+.cleared_node {
+ background-color: #FFFFFF;
+}
+
+.grid-item-header
+{
+ font-weight: bold;
+ font-size: 20px;
+ margin-top: 10px;
+}
+
+</style>
+<input name="filter_field" id="filter_field" type="hidden"/>
+<div id="grid_wrapper" class="grid_wrapper">
+{% for object_class, object_list in filter_objects %}
+<div class="class_grid_wrapper">
+ <div style="display:inline-block;margin:auto">
+ <h4>{{object_class}}</h4>
+ </div>
+ <div id="{{object_class}}" class="object_class_wrapper">
+ {% for obj in object_list %}
+ <div id="object_parent">
+ <div id="{{ obj.id|default:'not_provided' }}" class="grid-item">
+ <p class="grid-item-header">{{obj.name}}</p>
+ <p class="grid-item-description">{{obj.description}}</p>
+ <button type="button" class="btn btn-success grid-item-select-btn" onclick="processClick('{{obj.id}}', {% if obj.multiple %}true{% else %}false{% endif %});">{% if obj.multiple %}Add{% else %}Select{% endif %}</button>
+ </div>
+ <input type="hidden" name="{{obj.id}}_selected" value="false"/>
+ </div>
+ {% endfor %}
+ </div>
+ </div>
+{% endfor %}
+</div>
+
+<div id="dropdown_wrapper">
+</div>
+
+<script>
+var initialized = false;
+var mapping = {{ mapping|safe }};
+var items = {{ items|safe }};
+var result = {};
+var selection = {{selection_data|default_if_none:"null"|safe}};
+var dropdown_count = 0;
+
+{% if selection_data %}
+make_selection({{selection_data|safe}});
+{% endif %}
+
+function make_selection( selection_data ){
+ if(!initialized) {
+ init();
+ }
+ for(var k in selection_data) {
+ selected_items = selection_data[k];
+ for( var item in selected_items ){
+ var node = items[item];
+ if(!node['multiple']){
+ var input_value = selected_items[item];
+ if( input_value != 'false' ) {
+ select(node);
+ markAndSweep(node);
+ }
+ var div = document.getElementById(item)
+ var input = div.parentNode.getElementsByTagName("input")[0]
+ input.value = input_value;
+ updateResult(item);
+ } else {
+ make_multiple_selection(selected_items, item);
+ }
+ }
+ }
+}
+
+function make_multiple_selection(data, item_class){
+ var node = items[item_class];
+ select(node);
+ markAndSweep(node);
+ prepop_data = data[item_class];
+ for(var i=0; i<prepop_data.length; i++){
+ var div = add_item_prepopulate(node, prepop_data[i]);
+ updateObjectResult(div);
+ }
+}
+
+function markAndSweep(root){
+ for(var nodeId in items) {
+ node = items[nodeId];
+ node['marked'] = true; //mark all nodes
+ //clears grey background of everything
+ }
+
+ toCheck = [];
+ toCheck.push(root);
+
+ while(toCheck.length > 0){
+ node = toCheck.pop();
+ if(!node['marked']) {
+ //already visited, just continue
+ continue;
+ }
+ node['marked'] = false; //mark as visited
+ if(node['follow'] || node == root){ //add neighbors if we want to follow this node (labs)
+ var mappingId = node.id
+ var neighbors = mapping[mappingId];
+ for(var neighId in neighbors) {
+ neighId = neighbors[neighId];
+ var neighbor = items[neighId];
+ toCheck.push(neighbor);
+ }
+ }
+ }
+
+ //now remove all nodes still marked
+ for(var nodeId in items){
+ node = items[nodeId];
+ if(node['marked']){
+ disable(node);
+ }
+ }
+}
+
+function process(node) {
+ if(node['selected']) {
+ markAndSweep(node);
+ }
+ else {
+ var selected = []
+ //remember the currently selected, then reset everything and reselect one at a time
+ for(var nodeId in items) {
+ node = items[nodeId];
+ if(node['selected']) {
+ selected.push(node);
+ }
+ clear(node);
+
+ }
+ for(var i=0; i<selected.length; i++) {
+ node = selected[i];
+ select(node);
+ markAndSweep(selected[i]);
+ }
+ }
+}
+
+function select(node) {
+ elem = document.getElementById(node['id']);
+ node['selected'] = true;
+ elem.classList.remove('cleared_node')
+ elem.classList.remove('disabled_node')
+ elem.classList.add('selected_node')
+ var input = elem.parentNode.getElementsByTagName("input")[0];
+ input.disabled = false;
+ input.value = true;
+}
+
+function clear(node) {
+ elem = document.getElementById(node['id']);
+ node['selected'] = false;
+ node['selectable'] = true;
+ elem.classList.add('cleared_node')
+ elem.classList.remove('disabled_node')
+ elem.classList.remove('selected_node')
+ elem.parentNode.getElementsByTagName("input")[0].disabled = true;
+}
+
+function disable(node) {
+ elem = document.getElementById(node['id']);
+ node['selected'] = false;
+ node['selectable'] = false;
+ elem.classList.remove('cleared_node')
+ elem.classList.add('disabled_node')
+ elem.classList.remove('selected_node')
+ elem.parentNode.getElementsByTagName("input")[0].disabled = true;
+}
+
+function processClick(id, multiple){
+ if(!initialized){
+ init();
+ }
+ var element = document.getElementById(id);
+ var node = items[id];
+ if(!node['selectable']){
+ return;
+ }
+ if(multiple){
+ return processClickMultipleObject(node);
+ }
+ node['selected'] = !node['selected']; //toggle on click
+
+ if(node['selected']) {
+ select(node);
+ }
+ else {
+ clear(node);
+ }
+ process(node);
+ updateResult(id);
+}
+
+function processClickMultipleObject(node){
+ select(node);
+ add_item(node);
+ process(node);
+}
+
+function add_item(node){
+ return add_item_prepopulate(node, {});
+}
+
+inputs = []
+
+function restrictchars(input)
+{
+ if( input.validity.patternMismatch )
+ {
+ input.setCustomValidity("Only alphanumeric characters (a-z, A-Z, 0-9), underscore(_), and hyphen (-) are allowed");
+ input.reportValidity();
+ }
+
+ input.value = input.value.replace(/([^A-Za-z0-9-_.])+/g, "");
+
+ checkunique(input);
+}
+
+function checkunique(tocheck)
+{
+ val = tocheck.value;
+ for( var i = 0; i < inputs.length; i++ )
+ {
+ if( inputs[i].value == val && inputs[i] != tocheck)
+ {
+ tocheck.setCustomValidity("All hostnames must be unique");
+ tocheck.reportValidity();
+ return;
+ }
+ }
+ tocheck.setCustomValidity("");
+}
+
+function add_item_prepopulate(node, prepopulate){
+ inputs = [];
+ var div = document.createElement("DIV");
+ div.class = node['id'];
+ div.id = "dropdown_" + dropdown_count;
+ dropdown_count++;
+ var label = document.createElement("H5");
+ label.style['display'] = 'inline';
+ label.appendChild(document.createTextNode(node['name']));
+ div.appendChild(label);
+ for(var i=0; i<node['forms'].length; i++){
+ form = node['forms'][i];
+ var input = document.createElement("INPUT");
+ input.type = form['type'];
+ input.name = form['name'];
+ input.pattern = "(?=^.{1,253}$)(^([A-Za-z0-9-_]{1,62}\.)*[A-Za-z0-9-_]{1,63})";
+ input.title = "Only alphanumeric characters (a-z, A-Z, 0-9), underscore(_), and hyphen (-) are allowed"
+ input.placeholder = form['placeholder'];
+ inputs.push(input);
+ input.onchange = function() { updateObjectResult(div); restrictchars(this); };
+ input.oninput = function() { restrictchars(this); };
+ if(form['name'] in prepopulate){
+ input.value = prepopulate[form['name']];
+ }
+ div.appendChild(input);
+ }
+ //add class id to dropdown object
+ var hiddenInput = document.createElement("INPUT");
+ hiddenInput.type = "hidden";
+ hiddenInput.name = "class";
+ hiddenInput.value = node['id'];
+ div.appendChild(hiddenInput);
+ button = document.createElement("BUTTON");
+ button.onclick = function(){
+ remove_dropdown(div.id);
+ }
+ button.type = "button";
+ button.appendChild(document.createTextNode("Remove"));
+ div.appendChild(button);
+ document.getElementById("dropdown_wrapper").appendChild(div);
+ return div;
+}
+
+function remove_dropdown(id){
+ var div = document.getElementById(id);
+ var parent = div.parentNode;
+ div.parentNode.removeChild(div);
+ //checks if we have removed last item in class
+ var deselect_class = true;
+ var div_inputs = div.getElementsByTagName("input");
+ var div_class = div_inputs[div_inputs.length-1].value;
+ var result_class = document.getElementById(div_class).parentNode.parentNode.id;
+ delete result[result_class][div.id];
+ for(var i=0; i<parent.children.length; i++){
+ var inputs = parent.children[i].getElementsByTagName("input");
+ var object_class = "";
+ for(var k=0; k<inputs.length; k++){
+ if(inputs[k].name == "class"){
+ object_class = inputs[k].value;
+ }
+ }
+ if(object_class == div_class){
+ deselect_class = false;
+ }
+ }
+ if(deselect_class){
+ clear(items[div_class]);
+ }
+}
+
+function updateResult(nodeId){
+ if(!initialized){
+ init();
+ }
+ if(!items[nodeId]['multiple']){
+ var node = document.getElementById(nodeId);
+ var value = {}
+ value[nodeId] = node.parentNode.getElementsByTagName("input")[0].value;
+ result[node.parentNode.parentNode.id][nodeId] = value;
+ }
+}
+
+function updateObjectResult(parentElem){
+ node_type = document.getElementById(parentElem.class).parentNode.parentNode.id;
+ input = {};
+ inputs = parentElem.getElementsByTagName("input");
+ for(var i in inputs){
+ var e = inputs[i];
+ input[e.name] = e.value;
+ }
+ result[node_type][parentElem.id] = input;
+}
+
+function init() {
+ for(nodeId in items) {
+ element = document.getElementById(nodeId);
+ node = items[nodeId];
+ result[element.parentNode.parentNode.id] = {}
+ }
+ initialized = true;
+}
+
+</script>