diff options
Diffstat (limited to 'src/templates/dashboard/searchable_select_multiple.html')
-rw-r--r-- | src/templates/dashboard/searchable_select_multiple.html | 246 |
1 files changed, 161 insertions, 85 deletions
diff --git a/src/templates/dashboard/searchable_select_multiple.html b/src/templates/dashboard/searchable_select_multiple.html index c08fbe5..91ed09c 100644 --- a/src/templates/dashboard/searchable_select_multiple.html +++ b/src/templates/dashboard/searchable_select_multiple.html @@ -1,41 +1,57 @@ <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> -<div class="autocomplete" style="width:400px;"> +<div id="search_select_outer" class="autocomplete"> <div id="warning_pane" style="background: #FFFFFF; color: #CC0000;"> {% if incompatible == "true" %} <h3>Warning: Incompatible Configuration</h3> <p>Please make a different selection, as the current config conflicts with the selected pod</p> {% endif %} </div> - <input id="user_field" name="ignore_this" class="form-control" autocomplete="off" type="text" placeholder="{{placeholder}}" value="{{initial.name}}" oninput="search(this.value)" + <div id="added_counter"> + <p id="added_number">0</p> + <p id="addable_limit">/ {% if selectable_limit > -1 %} {{ selectable_limit }} {% else %} ∞ {% endif %}added</p> + </div> + + <div id="added_list"> + + </div> + + <input id="user_field" name="ignore_this" class="form-control" autocomplete="off" type="text" placeholder="{{placeholder}}" value="" oninput="search(this.value)" {% if disabled %} disabled {% endif %} > + </input> <input type="hidden" id="selector" name="{{ name }}" class="form-control" style="display: none;" {% if disabled %} disabled {% endif %} > </input> - <ul id="drop_results"></ul> - - - <div id="default_entry_wrap" style="display: none;"> - <div class="list_entry unremovable_list_entry"> - <p id="default_text" class="full_name"></p> - <button class="btn-remove btn disabled">remove</button> - </div> + <div id="scroll_restrictor"> + <ul id="drop_results"></ul> </div> + <style> + #scroll_restrictor { + flex: 1; + position: relative; + overflow-y: auto; + padding-bottom: 10px; + } - <div id="added_list"> + #added_list { + margin-bottom: 5px; + } - </div> - <div id="added_counter" style="text-align: center; margin: 10px;"><p id="added_number" style="display: inline;">0</p><p style="display: inline;">/ - {% if selectable_limit > -1 %} {{ selectable_limit }} {% else %} ∞ {% endif %}added</p></div> - <style> + .autocomplete { + display: flex; + flex: 1; + flex-direction: column; + } #user_field { font-size: 14pt; - width: 400px; padding: 5px; + height: 40px; + border: 1px solid #ccc; + border-radius: 5px; } @@ -43,69 +59,135 @@ list-style-type: none; padding: 0; margin: 0; - max-height: 300px; min-height: 0; - overflow-y: scroll; - overflow-x: hidden; border: solid 1px #ddd; - display: none; + border-top: none; + border-bottom: none; + visibility: inherit; + flex: 1; + + position: absolute; + width: 100%; } #drop_results li a{ font-size: 14pt; - border: 1px solid #ddd; background-color: #f6f6f6; - padding: 12px; + padding: 7px; text-decoration: none; display: block; - width: 400px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } - .btn-remove { - float: right; - height: 30px; - margin: 4px; + #drop_results li a { + border-bottom: 1px solid #ddd; } .list_entry { - width: 400px; - border: 1px solid #ddd; - border-radius: 3px; + border: 1px solid #ccc; + border-radius: 5px; margin-top: 5px; vertical-align: middle; line-height: 40px; height: 40px; padding-left: 12px; + width: 100%; + display: flex; } #drop_results li a:hover{ background-color: #ffffff; } - .small_name { - display: inline-block; + .added_entry_text { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline; + width: 100%; + } + + .btn-remove { + float: right; + height: 30px; + margin: 4px; + padding: 1px; + max-width: 20%; + width: 15%; + min-width: 70px; + overflow: hidden; + text-overflow: ellipsis; + } + + .entry_tooltip { + display: none; + } + + #drop_results li a:hover .entry_tooltip { + position: absolute; + background: #444; + color: #ddd; + text-align: center; + font-size: 12pt; + border-radius: 3px; + } - .full_name { + #drop_results { + max-width: 100%; display: inline-block; + list-style-type: none; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + #drop_results li { + overflow: hidden; + text-overflow: ellipsis; } + #added_counter { + text-align: center; + } + + #added_number, #addable_limit { + display: inline; + } </style> </div> <script type="text/javascript"> //flags - var show_from_noentry = {{show_from_noentry|default:"false"}}; - var show_x_results = {{show_x_results|default:-1}}; - var results_scrollable = {{results_scrollable|default:"false"}}; - var selectable_limit = {{selectable_limit|default:-1}}; - var field_name = "{{name|default:"users"}}"; - var placeholder = "{{placeholder|default:"begin typing"}}"; - var default_entry = "{{default_entry}}"; + var show_from_noentry = {{show_from_noentry|yesno:"true,false"}}; // whether to show any results before user starts typing + var show_x_results = {{show_x_results|default:-1}}; // how many results to show at a time, -1 shows all results + var results_scrollable = {{results_scrollable|yesno:"true,false"}}; // whether list should be scrollable + var selectable_limit = {{selectable_limit|default:-1}}; // how many selections can be made, -1 allows infinitely many + var placeholder = "{{placeholder|default:"begin typing"}}"; // placeholder that goes in text box //needed info - var items = {{items|safe}} + var items = {{items|safe}} // items to add to trie. Type is a dictionary of dictionaries with structure: + /* + { + id# : { + "id": any, identifiable on backend + "small_name": string, displayed first (before separator), searchable (use for e.g. username) + "expanded_name": string, displayed second (after separator), searchable (use for e.g. email address) + "string": string, not displayed, still searchable + } + } + */ + + /* used later: + {{ selectable_limit }}: changes what number displays for field + {{ name }}: form identifiable name, relevant for backend + // when submitted, form will contain field data in post with name as the key + {{ placeholder }}: "greyed out" contents put into search field initially to guide user as to what they're searching for + {{ initial }}: in search_field_init(), marked safe, an array of id's each referring to an id from items + */ //tries var expanded_name_trie = {} @@ -116,18 +198,6 @@ string_trie.isComplete = false; var added_items = []; - var initial_log = {{ initial|safe }}; - - var added_template = {{ added_list|default:"{}" }}; - - if( default_entry ) - { - var default_entry_div = document.getElementById("default_entry_wrap"); - default_entry_div.style.display = "inherit"; - - var entry_p = document.getElementById("default_text"); - entry_p.innerText = default_entry; - } search_field_init(); @@ -200,7 +270,11 @@ if( str.length == 1 ) { new_trie.isComplete = true; - new_trie.itemID = id; + if( !new_trie.ids ) + { + new_trie.ids = []; + } + new_trie.ids.push(id); } inner_trie = new_trie; str = str.substring(1); @@ -274,7 +348,7 @@ } if ( trie.isComplete ) { - itemIDs.push( trie.itemID ); + itemIDs.push(...trie.ids); } return itemIDs; @@ -298,6 +372,14 @@ return results; } + function generate_element_text(obj) + { + var content_strings = [obj['expanded_name'], obj['small_name'], obj['string']].filter(x => Boolean(x)); + var result = content_strings.shift(); + if( result == null || content_strings.length < 1) return result; + return result + " (" + content_strings.join(", ") + ")"; + } + function dropdown(ids) { /* @@ -315,27 +397,34 @@ var result_entry = document.createElement("li"); var result_button = document.createElement("a"); var obj = items[id]; - var result_text = document.createTextNode(obj['small_name'] + " : " + obj['expanded_name']); - result_button.appendChild(result_text); + var result_text = generate_element_text(obj); + result_button.appendChild(document.createTextNode(result_text)); result_button.setAttribute('onclick', 'select_item("' + obj['id'] + '")'); + var tooltip = document.createElement("span"); + var tooltiptext = document.createTextNode(result_text); + tooltip.appendChild(tooltiptext); + tooltip.setAttribute('class', 'entry_tooltip'); + result_button.appendChild(tooltip); result_entry.appendChild(result_button); drop.appendChild(result_entry); } + var scroll_restrictor = document.getElementById("scroll_restrictor"); + if( !drop.firstChild ) { - drop.style.display = 'none'; + scroll_restrictor.style.visibility = 'hidden'; } else { - drop.style.display = 'inherit'; + scroll_restrictor.style.visibility = 'inherit'; } } function select_item(item_id) { //TODO make faster - var item = items[item_id]; + var item = items[item_id]['id']; if( (selectable_limit > -1 && added_items.length < selectable_limit) || selectable_limit < 0 ) { if( added_items.indexOf(item) == -1 ) @@ -344,7 +433,10 @@ } } update_selected_list(); + // clear search bar contents + document.getElementById("user_field").value = ""; document.getElementById("user_field").focus(); + search(""); } function remove_item(item_ref) @@ -357,11 +449,6 @@ document.getElementById("user_field").focus(); } - function edit_item(item_id){ - var wf_type = "{{wf_type}}"; - parent.add_edit_wf(wf_type, item_id); - } - function update_selected_list() { document.getElementById("added_number").innerText = added_items.length; @@ -382,32 +469,21 @@ for( var key in added_items ) { - item = added_items[key]; + item_id = added_items[key]; + item = items[item_id]; - list_html += '<div class="list_entry"><p class="full_name">' - + item["expanded_name"] - + '</p><p class="small_name">, ' - + item["small_name"] - + '</p><button onclick="remove_item(' + var element_entry_text = generate_element_text(item); + + list_html += '<div class="list_entry">' + + '<p class="added_entry_text">' + + element_entry_text + + '</p>' + + '<button onclick="remove_item(' + Object.values(items).indexOf(item) + ')" class="btn-remove btn">remove</button>'; - {% if edit %} - list_html += '<button onclick="edit_item(' - + item['id'] - + ')" class="btn-remove btn">edit</button>'; - {% endif %} list_html += '</div>'; } added_list.innerHTML = list_html; } - </script> -<style> - .full_name { - display: inline-block; - } - .small_name { - display: inline-block; - } -</style> |