summaryrefslogtreecommitdiffstats
path: root/dashboard/src/templates/dashboard/multiple_select_filter_widget.html
diff options
context:
space:
mode:
Diffstat (limited to 'dashboard/src/templates/dashboard/multiple_select_filter_widget.html')
-rw-r--r--dashboard/src/templates/dashboard/multiple_select_filter_widget.html420
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>