2 .object_class_wrapper {
4 grid-template-columns: 1fr 1fr 1fr;
17 grid-template-columns: 1fr 1fr;
28 box-shadow: 0px 0px 7px 0px rgba(0,0,0,0.75);
29 transition-property: box-shadow, background-color;
30 transition-duration: .2s;
34 box-shadow: 0px 0px 14px 0px rgba(0,0,0,0.75);
35 transition-property: box-shadow;
36 transition-duration: .2s;
41 box-shadow: 0px 0px 14px 0px rgba(0,0,0,0.75);
42 background-color: #CCECD7;
43 transition-property: background-color;
44 transition-duration: .2s;
49 background-color: #EFEFEF;
50 box-shadow: 0px 0px 1px 0px rgba(0,0,0,0.75);
51 transition-property: box-shadow;
52 transition-duration: .2s;
55 .disabled_node:hover {
56 box-shadow: 0px 0px 1px 0px rgba(0,0,0,0.75);
60 background-color: #FFFFFF;
71 <input name="filter_field" id="filter_field" type="hidden"/>
72 <div id="grid_wrapper" class="grid_wrapper">
73 {% for object_class, object_list in filter_objects %}
74 <div class="class_grid_wrapper">
75 <div style="display:inline-block;margin:auto">
76 <h4>{{object_class}}</h4>
78 <div id="{{object_class}}" class="object_class_wrapper">
79 {% for obj in object_list %}
80 <div id="object_parent">
81 <div id="{{ obj.id|default:'not_provided' }}" class="grid-item">
82 <p class="grid-item-header">{{obj.name}}</p>
83 <p class="grid-item-description">{{obj.description}}</p>
84 <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>
86 <input type="hidden" name="{{obj.id}}_selected" value="false"/>
94 <div id="dropdown_wrapper">
98 var initialized = false;
99 var mapping = {{ mapping|safe }};
100 var filter_items = {{ filter_items|safe }};
102 var selection = {{selection_data|default_if_none:"null"|safe}};
103 var dropdown_count = 0;
105 {% if selection_data %}
106 make_selection({{selection_data|safe}});
109 function make_selection( selection_data ){
113 for(var k in selection_data) {
114 selected_items = selection_data[k];
115 for( var selected_item in selected_items ){
116 var node = filter_items[selected_item];
117 if(!node['multiple']){
118 var input_value = selected_items[selected_item];
119 if( input_value != 'false' ) {
123 var div = document.getElementById(selected_item)
124 var inputs = div.parentNode.getElementsByTagName("input")
125 var input = div.parentNode.getElementsByTagName("input")[0]
126 input.value = input_value;
127 updateResult(selected_item);
129 make_multiple_selection(selected_items, selected_item);
135 function make_multiple_selection(data, item_class){
136 var node = filter_items[item_class];
139 prepop_data = data[item_class];
140 for(var i=0; i<prepop_data.length; i++){
141 var div = add_item_prepopulate(node, prepop_data[i]);
142 updateObjectResult(div);
146 function markAndSweep(root){
147 for(var nodeId in filter_items) {
148 node = filter_items[nodeId];
149 node['marked'] = true; //mark all nodes
150 //clears grey background of everything
156 while(toCheck.length > 0){
157 node = toCheck.pop();
158 if(!node['marked']) {
159 //already visited, just continue
162 node['marked'] = false; //mark as visited
163 if(node['follow'] || node == root){ //add neighbors if we want to follow this node (labs)
164 var mappingId = node.id
165 var neighbors = mapping[mappingId];
166 for(var neighId in neighbors) {
167 neighId = neighbors[neighId];
168 var neighbor = filter_items[neighId];
169 toCheck.push(neighbor);
174 //now remove all nodes still marked
175 for(var nodeId in filter_items){
176 node = filter_items[nodeId];
183 function process(node) {
184 if(node['selected']) {
189 //remember the currently selected, then reset everything and reselect one at a time
190 for(var nodeId in filter_items) {
191 node = filter_items[nodeId];
192 if(node['selected']) {
198 for(var i=0; i<selected.length; i++) {
201 markAndSweep(selected[i]);
206 function select(node) {
207 elem = document.getElementById(node['id']);
208 node['selected'] = true;
209 elem.classList.remove('cleared_node');
210 elem.classList.remove('disabled_node');
211 elem.classList.add('selected_node');
212 var input = elem.parentNode.getElementsByTagName("input")[0];
213 input.disabled = false;
217 function clear(node) {
218 elem = document.getElementById(node['id']);
219 node['selected'] = false;
220 node['selectable'] = true;
221 elem.classList.add('cleared_node')
222 elem.classList.remove('disabled_node');
223 elem.classList.remove('selected_node');
224 elem.parentNode.getElementsByTagName("input")[0].disabled = true;
227 function disable_node(node) {
228 elem = document.getElementById(node['id']);
229 node['selected'] = false;
230 node['selectable'] = false;
231 elem.classList.remove('cleared_node');
232 elem.classList.add('disabled_node');
233 elem.classList.remove('selected_node');
234 elem.parentNode.getElementsByTagName("input")[0].disabled = true;
237 function processClick(id, multiple){
241 var element = document.getElementById(id);
242 var node = filter_items[id];
243 if(!node['selectable']){
247 return processClickMultipleObject(node);
249 node['selected'] = !node['selected']; //toggle on click
251 if(node['selected']) {
261 function processClickMultipleObject(node){
267 function add_node(node){
268 return add_item_prepopulate(node, {});
273 function restrictchars(input)
275 if( input.validity.patternMismatch )
277 input.setCustomValidity("Only alphanumeric characters (a-z, A-Z, 0-9), underscore(_), and hyphen (-) are allowed");
278 input.reportValidity();
281 input.value = input.value.replace(/([^A-Za-z0-9-_.])+/g, "");
286 function checkunique(tocheck)
289 for( var i = 0; i < inputs.length; i++ )
291 if( inputs[i].value == val && inputs[i] != tocheck)
293 tocheck.setCustomValidity("All hostnames must be unique");
294 tocheck.reportValidity();
298 tocheck.setCustomValidity("");
301 function add_item_prepopulate(node, prepopulate){
303 var div = document.createElement("DIV");
304 div.class = node['id'];
305 div.id = "dropdown_" + dropdown_count;
307 var label = document.createElement("H5");
308 label.style['display'] = 'inline';
309 label.appendChild(document.createTextNode(node['name']));
310 div.appendChild(label);
311 for(var i=0; i<node['forms'].length; i++){
312 form = node['forms'][i];
313 var input = document.createElement("INPUT");
314 input.type = form['type'];
315 input.name = form['name'];
316 input.pattern = "(?=^.{1,253}$)(^([A-Za-z0-9-_]{1,62}\.)*[A-Za-z0-9-_]{1,63})";
317 input.title = "Only alphanumeric characters (a-z, A-Z, 0-9), underscore(_), and hyphen (-) are allowed"
318 input.placeholder = form['placeholder'];
320 input.onchange = function() { updateObjectResult(div); restrictchars(this); };
321 input.oninput = function() { restrictchars(this); };
322 if(form['name'] in prepopulate){
323 input.value = prepopulate[form['name']];
325 div.appendChild(input);
327 //add class id to dropdown object
328 var hiddenInput = document.createElement("INPUT");
329 hiddenInput.type = "hidden";
330 hiddenInput.name = "class";
331 hiddenInput.value = node['id'];
332 div.appendChild(hiddenInput);
333 button = document.createElement("BUTTON");
334 button.onclick = function(){
335 remove_dropdown(div.id);
337 button.type = "button";
338 button.appendChild(document.createTextNode("Remove"));
339 div.appendChild(button);
340 document.getElementById("dropdown_wrapper").appendChild(div);
341 updateObjectResult(div);
345 function remove_dropdown(id){
346 var div = document.getElementById(id);
347 var parent = div.parentNode;
348 div.parentNode.removeChild(div);
349 //checks if we have removed last item in class
350 var deselect_class = true;
351 var div_inputs = div.getElementsByTagName("input");
352 var div_class = div_inputs[div_inputs.length-1].value;
353 var result_class = document.getElementById(div_class).parentNode.parentNode.id;
354 delete result[result_class][div.id];
355 for(var i=0; i<parent.children.length; i++){
356 var inputs = parent.children[i].getElementsByTagName("input");
357 var object_class = "";
358 for(var k=0; k<inputs.length; k++){
359 if(inputs[k].name == "class"){
360 object_class = inputs[k].value;
363 if(object_class == div_class){
364 deselect_class = false;
368 clear(filter_items[div_class]);
372 function updateResult(nodeId){
376 if(!filter_items[nodeId]['multiple']){
377 var node = document.getElementById(nodeId);
379 value[nodeId] = node.parentNode.getElementsByTagName("input")[0].value;
380 result[node.parentNode.parentNode.id][nodeId] = value;
384 function updateObjectResult(parentElem){
385 node_type = document.getElementById(parentElem.class).parentNode.parentNode.id;
387 inputs = parentElem.getElementsByTagName("input");
388 for(var i in inputs){
390 input[e.name] = e.value;
392 result[node_type][parentElem.id] = input;
395 function filter_field_init() {
396 for(nodeId in filter_items) {
397 element = document.getElementById(nodeId);
398 node = filter_items[nodeId];
399 result[element.parentNode.parentNode.id] = {}