Removed Double onclick
[pharos-tools.git] / dashboard / src / templates / dashboard / multiple_select_filter_widget.html
index d794b73..4302543 100644 (file)
@@ -1,9 +1,13 @@
+<script src="/static/js/dashboard.js">
+</script>
+
 <style>
 .object_class_wrapper {
     display: grid;
     grid-template-columns: 1fr 1fr 1fr;
     border: 0px;
 }
+
 .class_grid_wrapper {
     border: 0px;
     text-align: center;
     display: grid;
     grid-template-columns: 1fr 1fr;
 }
+
 .grid-item {
     cursor: pointer;
-    border:1px solid #cccccc;
+    border: 1px solid #cccccc;
     border-radius: 5px;
-    margin:20px;
+    margin: 20px;
     height: 200px;
     padding: 7px;
-    transition-property: box-shadow, background-color;
-    transition-duration: .2s;
+    transition: border-color ease-in-out .1s,box-shadow ease-in-out .1s;
+    box-shadow: 0 1px 1px rgba(0,0,0,.075);
+
+    display: flex;
+    flex-direction: column;
 }
 
-.grid-item:hover {
-    box-shadow: 0px 0px 7px 0px rgba(0,0,0,0.45);
-    transition-property: box-shadow;
-    transition-duration: .2s;
+.grid-item > .btn:active, .grid-item > .btn:focus {
+    outline: none; !important;
+    box-shadow: none;
+}
 
+.grid-item-description {
+    flex: 1;
 }
 
 .selected_node {
-    box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.45);
-    background-color: #fff;
-    transition-property: background-color;
-    transition-duration: .2s;
+    border-color: #40c640;
+    box-shadow: 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(109, 243, 76, 0.6);
+    transition: border-color ease-in-out .1s,box-shadow ease-in-out .1s;
+}
+
+.grid-item:hover:not(.selected_node):not(.disabled_node) {
+    box-shadow: 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(100, 100, 100, 0.3);
+    transition: border-color ease-in-out .1s,box-shadow ease-in-out .1s;
 }
 
 .disabled_node {
     cursor: not-allowed;
     background-color: #EFEFEF;
-    transition-property: box-shadow;
-    transition-duration: .2s;
-    border: 1px solid #ccc;
 }
 
-.disabled_node:hover {
-}
+.disabled_node:hover {}
 
 .cleared_node {
     background-color: #FFFFFF;
 }
 
-.grid-item-header
-{
+.grid-item-header {
     font-weight: bold;
     font-size: 20px;
     margin-top: 10px;
 }
 
-#dropdown_wrapper > div > h5 {
-    margin: 12px;
-    display: inline-block;
-    vertical-align: middle;
+.dropdown_item {
+    border: 1px;
+    border-style: solid;
+    border-color: lightgray;
+    border-radius: 5px;
+    margin: 20px;
+    padding: 2px;
+    grid-column: 1;
+    display: grid;
+    grid-template-columns: 1fr 3fr 1fr;
+    justify-items: center;
 }
 
-#dropdown_wrapper > div > button {
-    padding: 7px;
+.dropdown_item > button {
     margin: 2px;
-    float: right;
-    width: 80px;
+    justify-self: end;
 }
-#dropdown_wrapper > div > input {
-    padding: 7px;
-    margin: 2px;
-    float: right;
-    width: 300px;
-    width: calc(100% - 240px);
+
+.dropdown_item > h5 {
+    margin: auto;
 }
 
-#dropdown_wrapper > div {
-    border:2px;
-    border-style:none;
-    border-color:black;
-    border-radius: 5px;
-    margin:20px;
-    padding: 2px;
-    box-shadow: 0px 0px 7px 0px rgba(0,0,0,0.75);
-    transition-property: box-shadow, background-color;
-    transition-duration: .2s;
-    display: inline-block;
-    vertical-align: middle;
+.dropdown_item > input {
+    padding: 7px;
+    margin: 2px;
+    width: 90%;
 }
 
 #dropdown_wrapper {
     display: grid;
-    grid-template-columns: 3fr 5fr;
+    grid-template-columns: 4fr 5fr;
 }
-
 </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 %}
+{% for object_class, object_list in display_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="{{ obj.id|default:'not_provided' }}" class="grid-item">
+            <div id="{{ obj.id|default:'not_provided' }}" class="grid-item" onclick="multi_filter_widget.processClick(
+                    '{{obj.id}}');">
                 <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>
+                <button type="button" class="btn btn-success grid-item-select-btn">
+                    {% if obj.multiple %}Add{% else %}Select{% endif %}
+                </button>
             </div>
-            <input type="hidden" name="{{obj.id}}_selected" value="false"/>
         {% endfor %}
         </div>
     </div>
 
 <div id="dropdown_wrapper">
 </div>
-
 <script>
-var initialized = false;
-var mapping = {{ mapping|safe }};
-var filter_items = {{ filter_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) {
-        filter_field_init();
-    }
-    for(var k in selection_data) {
-        selected_items = selection_data[k];
-        for( var selected_item in selected_items ){
-            var node = filter_items[selected_item];
-            if(!node['multiple']){
-                var input_value = selected_items[selected_item];
-                if( input_value != 'false' ) {
-                    select(node);
-                    markAndSweep(node);
-                }
-                var div = document.getElementById(selected_item)
-                var inputs = div.parentNode.getElementsByTagName("input")
-                var input = div.parentNode.getElementsByTagName("input")[0]
-                input.value = input_value;
-                updateResult(selected_item);
-            } else {
-                make_multiple_selection(selected_items, selected_item);
-            }
-        }
-    }
-}
-
-function make_multiple_selection(data, item_class){
-    var node = filter_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 filter_items) {
-        node = filter_items[nodeId];
-        node['marked'] = true; //mark all nodes
-        //clears grey background of everything
-    }
-
-    toCheck = [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 = filter_items[neighId];
-                toCheck.push(neighbor);
-            }
-        }
-    }
-
-    //now remove all nodes still marked
-    for(var nodeId in filter_items){
-        node = filter_items[nodeId];
-        if(node['marked']){
-            disable_node(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 filter_items) {
-            node = filter_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(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){
-        filter_field_init();
-    }
-    var element = document.getElementById(id);
-    var node = filter_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_node(node);
-    process(node);
-}
-
-function add_node(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.appendChild(document.createTextNode(node['name']));
-    div.appendChild(label);
-    button = document.createElement("BUTTON");
-    button.type = "button";
-    button.appendChild(document.createTextNode("Remove"));
-    button.classList.add("btn-danger");
-    button.classList.add("btn");
-    div.appendChild(button);
-    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.onclick = function(){
-        remove_dropdown(div.id);
-    }
-    document.getElementById("dropdown_wrapper").appendChild(div);
-    var linebreak = document.createElement("BR");
-    document.getElementById("dropdown_wrapper").appendChild(linebreak);
-    updateObjectResult(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(filter_items[div_class]);
-    }
-}
-
-function updateResult(nodeId){
-    if(!initialized){
-        filter_field_init();
-    }
-    if(!filter_items[nodeId]['multiple']){
-        var node = document.getElementById(nodeId);
-        var value = {}
-        value[nodeId] = node.parentNode.getElementsByTagName("input")[0].value;
-        result[node.parentNode.id] = {};
-        result[node.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 multipleSelectFilterWidgetEntry() {
+    const graph_neighbors = {{ neighbors|safe }};
+    const filter_items = {{ filter_items|safe }};
+    const initial_value = {{ initial_value|default_if_none:"{}"|safe }};
 
-function filter_field_init() {
-    for(nodeId in filter_items) {
-        element = document.getElementById(nodeId);
-        node = filter_items[nodeId];
-        result[element.parentNode.id] = {}
-        }
-    initialized = true;
+    //global variable
+    multi_filter_widget = new MultipleSelectFilterWidget(graph_neighbors, filter_items, initial_value);
 }
 
+multipleSelectFilterWidgetEntry();
 </script>