diff options
Diffstat (limited to 'dashboard/src/templates/dashboard/multiple_select_filter_widget.html')
-rw-r--r-- | dashboard/src/templates/dashboard/multiple_select_filter_widget.html | 420 |
1 files changed, 63 insertions, 357 deletions
diff --git a/dashboard/src/templates/dashboard/multiple_select_filter_widget.html b/dashboard/src/templates/dashboard/multiple_select_filter_widget.html index 536fdcc..4302543 100644 --- a/dashboard/src/templates/dashboard/multiple_select_filter_widget.html +++ b/dashboard/src/templates/dashboard/multiple_select_filter_widget.html @@ -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; @@ -20,112 +24,109 @@ 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> @@ -134,310 +135,15 @@ <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.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> |