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 items = {{ 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 item in selected_items ){
116 var node = items[item];
117 if(!node['multiple']){
118 var input_value = selected_items[item];
119 if( input_value != 'false' ) {
123 var div = document.getElementById(item)
124 var input = div.parentNode.getElementsByTagName("input")[0]
125 input.value = input_value;
128 make_multiple_selection(selected_items, item);
134 function make_multiple_selection(data, item_class){
135 var node = items[item_class];
138 prepop_data = data[item_class];
139 for(var i=0; i<prepop_data.length; i++){
140 var div = add_item_prepopulate(node, prepop_data[i]);
141 updateObjectResult(div);
145 function markAndSweep(root){
146 for(var nodeId in items) {
147 node = items[nodeId];
148 node['marked'] = true; //mark all nodes
149 //clears grey background of everything
155 while(toCheck.length > 0){
156 node = toCheck.pop();
157 if(!node['marked']) {
158 //already visited, just continue
161 node['marked'] = false; //mark as visited
162 if(node['follow'] || node == root){ //add neighbors if we want to follow this node (labs)
163 var mappingId = node.id
164 var neighbors = mapping[mappingId];
165 for(var neighId in neighbors) {
166 neighId = neighbors[neighId];
167 var neighbor = items[neighId];
168 toCheck.push(neighbor);
173 //now remove all nodes still marked
174 for(var nodeId in items){
175 node = items[nodeId];
182 function process(node) {
183 if(node['selected']) {
188 //remember the currently selected, then reset everything and reselect one at a time
189 for(var nodeId in items) {
190 node = items[nodeId];
191 if(node['selected']) {
197 for(var i=0; i<selected.length; i++) {
200 markAndSweep(selected[i]);
205 function select(node) {
206 elem = document.getElementById(node['id']);
207 node['selected'] = true;
208 elem.classList.remove('cleared_node')
209 elem.classList.remove('disabled_node')
210 elem.classList.add('selected_node')
211 var input = elem.parentNode.getElementsByTagName("input")[0];
212 input.disabled = false;
216 function clear(node) {
217 elem = document.getElementById(node['id']);
218 node['selected'] = false;
219 node['selectable'] = true;
220 elem.classList.add('cleared_node')
221 elem.classList.remove('disabled_node')
222 elem.classList.remove('selected_node')
223 elem.parentNode.getElementsByTagName("input")[0].disabled = true;
226 function disable(node) {
227 elem = document.getElementById(node['id']);
228 node['selected'] = false;
229 node['selectable'] = false;
230 elem.classList.remove('cleared_node')
231 elem.classList.add('disabled_node')
232 elem.classList.remove('selected_node')
233 elem.parentNode.getElementsByTagName("input")[0].disabled = true;
236 function processClick(id, multiple){
240 var element = document.getElementById(id);
241 var node = items[id];
242 if(!node['selectable']){
246 return processClickMultipleObject(node);
248 node['selected'] = !node['selected']; //toggle on click
250 if(node['selected']) {
260 function processClickMultipleObject(node){
266 function add_item(node){
267 return add_item_prepopulate(node, {});
272 function restrictchars(input)
274 if( input.validity.patternMismatch )
276 input.setCustomValidity("Only alphanumeric characters (a-z, A-Z, 0-9), underscore(_), and hyphen (-) are allowed");
277 input.reportValidity();
280 input.value = input.value.replace(/([^A-Za-z0-9-_.])+/g, "");
285 function checkunique(tocheck)
288 for( var i = 0; i < inputs.length; i++ )
290 if( inputs[i].value == val && inputs[i] != tocheck)
292 tocheck.setCustomValidity("All hostnames must be unique");
293 tocheck.reportValidity();
297 tocheck.setCustomValidity("");
300 function add_item_prepopulate(node, prepopulate){
302 var div = document.createElement("DIV");
303 div.class = node['id'];
304 div.id = "dropdown_" + dropdown_count;
306 var label = document.createElement("H5");
307 label.style['display'] = 'inline';
308 label.appendChild(document.createTextNode(node['name']));
309 div.appendChild(label);
310 for(var i=0; i<node['forms'].length; i++){
311 form = node['forms'][i];
312 var input = document.createElement("INPUT");
313 input.type = form['type'];
314 input.name = form['name'];
315 input.pattern = "(?=^.{1,253}$)(^([A-Za-z0-9-_]{1,62}\.)*[A-Za-z0-9-_]{1,63})";
316 input.title = "Only alphanumeric characters (a-z, A-Z, 0-9), underscore(_), and hyphen (-) are allowed"
317 input.placeholder = form['placeholder'];
319 input.onchange = function() { updateObjectResult(div); restrictchars(this); };
320 input.oninput = function() { restrictchars(this); };
321 if(form['name'] in prepopulate){
322 input.value = prepopulate[form['name']];
324 div.appendChild(input);
326 //add class id to dropdown object
327 var hiddenInput = document.createElement("INPUT");
328 hiddenInput.type = "hidden";
329 hiddenInput.name = "class";
330 hiddenInput.value = node['id'];
331 div.appendChild(hiddenInput);
332 button = document.createElement("BUTTON");
333 button.onclick = function(){
334 remove_dropdown(div.id);
336 button.type = "button";
337 button.appendChild(document.createTextNode("Remove"));
338 div.appendChild(button);
339 document.getElementById("dropdown_wrapper").appendChild(div);
340 updateObjectResult(div);
344 function remove_dropdown(id){
345 var div = document.getElementById(id);
346 var parent = div.parentNode;
347 div.parentNode.removeChild(div);
348 //checks if we have removed last item in class
349 var deselect_class = true;
350 var div_inputs = div.getElementsByTagName("input");
351 var div_class = div_inputs[div_inputs.length-1].value;
352 var result_class = document.getElementById(div_class).parentNode.parentNode.id;
353 delete result[result_class][div.id];
354 for(var i=0; i<parent.children.length; i++){
355 var inputs = parent.children[i].getElementsByTagName("input");
356 var object_class = "";
357 for(var k=0; k<inputs.length; k++){
358 if(inputs[k].name == "class"){
359 object_class = inputs[k].value;
362 if(object_class == div_class){
363 deselect_class = false;
367 clear(items[div_class]);
371 function updateResult(nodeId){
375 if(!items[nodeId]['multiple']){
376 var node = document.getElementById(nodeId);
378 value[nodeId] = node.parentNode.getElementsByTagName("input")[0].value;
379 result[node.parentNode.parentNode.id][nodeId] = value;
383 function updateObjectResult(parentElem){
384 node_type = document.getElementById(parentElem.class).parentNode.parentNode.id;
386 inputs = parentElem.getElementsByTagName("input");
387 for(var i in inputs){
389 input[e.name] = e.value;
391 result[node_type][parentElem.id] = input;
395 for(nodeId in items) {
396 element = document.getElementById(nodeId);
397 node = items[nodeId];
398 result[element.parentNode.parentNode.id] = {}