1 <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
3 <div class="autocomplete" style="width:400px;">
4 <div id="warning_pane" style="background: #FFFFFF; color: #CC0000;">
5 {% if incompatible == "true" %}
6 <h3>Warning: Incompatible Configuration</h3>
7 <p>Please make a different selection, as the current config conflicts with the selected pod</p>
10 <input id="user_field" name="ignore_this" class="form-control" autocomplete="off" type="text" placeholder="{{placeholder}}" value="{{initial.name}}" oninput="search(this.value)"
11 {% if disabled %} disabled {% endif %}
14 <input type="hidden" id="selector" name="{{ name }}" class="form-control" style="display: none;"
15 {% if disabled %} disabled {% endif %}
19 <ul id="drop_results"></ul>
22 <div id="default_entry_wrap" style="display: none;">
23 <div class="list_entry unremovable_list_entry">
24 <p id="default_text" class="full_name"></p>
25 <button class="btn-remove btn disabled">remove</button>
32 <div id="added_counter" style="text-align: center; margin: 10px;"><p id="added_number" style="display: inline;">0</p><p style="display: inline;">/
33 {% if selectable_limit > -1 %} {{ selectable_limit }} {% else %} ∞ {% endif %}added</p></div>
43 list-style-type: none;
50 border: solid 1px #ddd;
57 border: 1px solid #ddd;
58 background-color: #f6f6f6;
60 text-decoration: none;
73 border: 1px solid #ddd;
76 vertical-align: middle;
82 #drop_results li a:hover{
83 background-color: #ffffff;
87 display: inline-block;
91 display: inline-block;
97 <script type="text/javascript">
99 var show_from_noentry = {{show_from_noentry|default:"false"}};
100 var show_x_results = {{show_x_results|default:-1}};
101 var results_scrollable = {{results_scrollable|default:"false"}};
102 var selectable_limit = {{selectable_limit|default:-1}};
103 var field_name = "{{name|default:"users"}}";
104 var placeholder = "{{placeholder|default:"begin typing"}}";
105 var default_entry = "{{default_entry}}";
108 var items = {{items|safe}}
111 var expanded_name_trie = {}
112 expanded_name_trie.isComplete = false;
113 var small_name_trie = {}
114 small_name_trie.isComplete = false;
116 string_trie.isComplete = false;
118 var added_items = [];
119 var initial_log = {{ initial|safe }};
121 var added_template = {{ added_list|default:"{}" }};
125 var default_entry_div = document.getElementById("default_entry_wrap");
126 default_entry_div.style.display = "inherit";
128 var entry_p = document.getElementById("default_text");
129 entry_p.innerText = default_entry;
134 if( show_from_noentry )
140 var textfield = document.getElementById("user_field");
141 var drop = document.getElementById("drop_results");
143 textfield.disabled = "True";
144 drop.style.display = "none";
146 var btns = document.getElementsByClassName("btn-remove");
147 for( var i = 0; i < btns.length; i++ )
149 btns[i].classList.add("disabled");
153 function search_field_init() {
154 build_all_tries(items);
156 var initial = {{ initial|safe }};
158 for( var i = 0; i < initial.length; i++)
160 select_item(String(initial[i]));
162 if(initial.length == 1)
164 search(items[initial[0]]["small_name"]);
165 document.getElementById("user_field").value = items[initial[0]]["small_name"];
169 function build_all_tries(dict)
177 function add_item(item)
180 add_to_tree(item['expanded_name'], id, expanded_name_trie);
181 add_to_tree(item['small_name'], id, small_name_trie);
182 add_to_tree(item['string'], id, string_trie);
185 function add_to_tree(str, id, trie)
190 if( !inner_trie[str.charAt(0)] )
193 inner_trie[str.charAt(0)] = new_trie;
197 new_trie = inner_trie[str.charAt(0)];
200 if( str.length == 1 )
202 new_trie.isComplete = true;
203 new_trie.itemID = id;
205 inner_trie = new_trie;
206 str = str.substring(1);
210 function search(input)
212 if( input.length == 0 && !show_from_noentry){
216 else if( input.length == 0 && show_from_noentry)
218 dropdown(items); //show all items
223 var tr1 = getSubtree(input, expanded_name_trie);
225 var tr2 = getSubtree(input, small_name_trie);
227 var tr3 = getSubtree(input, string_trie);
229 var results = collate(trees);
234 function getSubtree(input, given_trie)
237 recursive function to return the trie accessed at input
240 if( input.length == 0 ){
245 var substr = input.substring(0, input.length - 1);
246 var last_char = input.charAt(input.length-1);
247 var subtrie = getSubtree(substr, given_trie);
248 if( !subtrie ) //substr not in the trie
252 var indexed_trie = subtrie[last_char];
257 function serialize(trie)
260 takes in a trie and returns a list of its item id's
265 return itemIDs; //empty, base case
267 for( var key in trie )
273 itemIDs = itemIDs.concat(serialize(trie[key]));
275 if ( trie.isComplete )
277 itemIDs.push( trie.itemID );
283 function collate(trees)
286 takes a list of tries
287 returns a list of ids of objects that are available
290 for( var i in trees )
292 var available_IDs = serialize(trees[i]);
293 for( var j=0; j<available_IDs.length; j++){
294 var itemID = available_IDs[j];
295 results[itemID] = items[itemID];
301 function dropdown(ids)
304 takes in a mapping of ids to objects in items
305 and displays them in the dropdown
307 var drop = document.getElementById("drop_results");
308 while(drop.firstChild)
310 drop.removeChild(drop.firstChild);
315 var result_entry = document.createElement("li");
316 var result_button = document.createElement("a");
318 var result_text = document.createTextNode(obj['small_name'] + " : " + obj['expanded_name']);
319 result_button.appendChild(result_text);
320 result_button.setAttribute('onclick', 'select_item("' + obj['id'] + '")');
321 result_entry.appendChild(result_button);
322 drop.appendChild(result_entry);
325 if( !drop.firstChild )
327 drop.style.display = 'none';
331 drop.style.display = 'inherit';
335 function select_item(item_id)
338 var item = items[item_id];
339 if( (selectable_limit > -1 && added_items.length < selectable_limit) || selectable_limit < 0 )
341 if( added_items.indexOf(item) == -1 )
343 added_items.push(item);
346 update_selected_list();
347 document.getElementById("user_field").focus();
350 function remove_item(item_ref)
352 item = Object.values(items)[item_ref];
353 var index = added_items.indexOf(item);
354 added_items.splice(index, 1);
356 update_selected_list()
357 document.getElementById("user_field").focus();
360 function edit_item(item_id){
361 var wf_type = "{{wf_type}}";
362 parent.add_edit_wf(wf_type, item_id);
365 function update_selected_list()
367 document.getElementById("added_number").innerText = added_items.length;
368 selector = document.getElementById('selector');
369 selector.value = JSON.stringify(added_items);
370 added_list = document.getElementById('added_list');
372 while(selector.firstChild)
374 selector.removeChild(selector.firstChild);
376 while(added_list.firstChild)
378 added_list.removeChild(added_list.firstChild);
383 for( var key in added_items )
385 item = added_items[key];
387 list_html += '<div class="list_entry"><p class="full_name">'
388 + item["expanded_name"]
389 + '</p><p class="small_name">, '
391 + '</p><button onclick="remove_item('
392 + Object.values(items).indexOf(item)
393 + ')" class="btn-remove btn">remove</button>';
395 list_html += '<button onclick="edit_item('
397 + ')" class="btn-remove btn">edit</button>';
399 list_html += '</div>';
402 added_list.innerHTML = list_html;
408 display: inline-block;
411 display: inline-block;