Add album_autocomplete.js, so "Add child" box can autocomplete.
This makes putting albums together a little easier, though datalist performance still leaves a lot to be desired.
This commit is contained in:
		
							parent
							
								
									4e3e2fea12
								
							
						
					
					
						commit
						86c09aedc1
					
				
					 5 changed files with 108 additions and 14 deletions
				
			
		|  | @ -1,8 +1,10 @@ | |||
| import flask; from flask import request | ||||
| import time | ||||
| import urllib.parse | ||||
| 
 | ||||
| import etiquette | ||||
| 
 | ||||
| from .. import caching | ||||
| from .. import common | ||||
| from .. import decorators | ||||
| from .. import jsonify | ||||
|  | @ -154,6 +156,13 @@ def post_album_edit(album_id): | |||
| 
 | ||||
| # Album listings ################################################################################### | ||||
| 
 | ||||
| @site.route('/all_albums.json') | ||||
| @caching.cached_endpoint(max_age=0) | ||||
| def get_all_album_names(): | ||||
|     all_albums = {album.display_name: album.id for album in common.P.get_albums()} | ||||
|     response = {'updated': int(time.time()), 'albums': all_albums} | ||||
|     return jsonify.make_json_response(response) | ||||
| 
 | ||||
| def get_albums_core(): | ||||
|     albums = list(common.P.get_root_albums()) | ||||
|     albums.sort(key=lambda x: x.display_name.lower()) | ||||
|  |  | |||
							
								
								
									
										59
									
								
								frontends/etiquette_flask/static/js/album_autocomplete.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								frontends/etiquette_flask/static/js/album_autocomplete.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| const album_autocomplete = {}; | ||||
| 
 | ||||
| album_autocomplete.albums = {}; | ||||
| 
 | ||||
| album_autocomplete.DATALIST_ID = "album_autocomplete_datalist"; | ||||
| album_autocomplete.datalist = null; | ||||
| album_autocomplete.on_load_hooks = []; | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| album_autocomplete.init_datalist = | ||||
| function init_datalist() | ||||
| { | ||||
|     if (album_autocomplete.datalist) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|     console.log("Init album_autocomplete datalist."); | ||||
|     const datalist = document.createElement("datalist"); | ||||
|     datalist.id = album_autocomplete.DATALIST_ID; | ||||
|     document.body.appendChild(datalist); | ||||
| 
 | ||||
|     const fragment = document.createDocumentFragment(); | ||||
|     for (const album_name in album_autocomplete.albums) | ||||
|     { | ||||
|         const album_id = album_autocomplete.albums[album_name]; | ||||
|         const option = document.createElement("option"); | ||||
|         option.value = album_id; | ||||
|         option.innerText = album_name; | ||||
|         fragment.appendChild(option); | ||||
|     } | ||||
|     datalist.appendChild(fragment); | ||||
|     album_autocomplete.datalist = datalist; | ||||
| 
 | ||||
|     for (const hook of album_autocomplete.on_load_hooks) | ||||
|     { | ||||
|         hook(datalist); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| album_autocomplete.get_all_albums_callback = | ||||
| function get_all_albums_callback(response) | ||||
| { | ||||
|     if (response.meta.status !== 200) | ||||
|     { | ||||
|         console.error(response); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     album_autocomplete.albums = response.data.albums; | ||||
|     setTimeout(album_autocomplete.init_datalist, 0); | ||||
| } | ||||
| 
 | ||||
| album_autocomplete.on_pageload = | ||||
| function on_pageload() | ||||
| { | ||||
|     setTimeout(api.albums.get_all_albums(album_autocomplete.get_all_albums_callback), 0); | ||||
| } | ||||
| document.addEventListener("DOMContentLoaded", album_autocomplete.on_pageload); | ||||
|  | @ -61,6 +61,13 @@ function _delete(album_id, callback) | |||
|     common.post(url, null, callback); | ||||
| } | ||||
| 
 | ||||
| api.albums.get_all_albums = | ||||
| function get_all_albums(callback) | ||||
| { | ||||
|     const url = "/all_albums.json"; | ||||
|     common.get(url, callback); | ||||
| } | ||||
| 
 | ||||
| api.albums.edit = | ||||
| function edit(album_id, title, description, callback) | ||||
| { | ||||
|  |  | |||
|  | @ -4,26 +4,24 @@ tag_autocomplete.tags = new Set(); | |||
| tag_autocomplete.synonyms = {}; | ||||
| 
 | ||||
| tag_autocomplete.DATALIST_ID = "tag_autocomplete_datalist"; | ||||
| tag_autocomplete.datalist = null; | ||||
| tag_autocomplete.on_load_hooks = []; | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| tag_autocomplete.init_datalist = | ||||
| function init_datalist() | ||||
| { | ||||
|     console.log("Init datalist."); | ||||
|     let datalist; | ||||
|     datalist = document.getElementById(tag_autocomplete.DATALIST_ID); | ||||
|     if (datalist) | ||||
|     if (tag_autocomplete.datalist) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     datalist = document.createElement("datalist"); | ||||
|     console.log("Init tag_autocomplete datalist."); | ||||
|     const datalist = document.createElement("datalist"); | ||||
|     datalist.id = tag_autocomplete.DATALIST_ID; | ||||
|     document.body.appendChild(datalist); | ||||
| 
 | ||||
|     const fragment = document.createDocumentFragment(); | ||||
|     common.delete_all_children(datalist); | ||||
|     for (const tag_name of tag_autocomplete.tags) | ||||
|     { | ||||
|         const option = document.createElement("option"); | ||||
|  | @ -37,6 +35,12 @@ function init_datalist() | |||
|         fragment.appendChild(option); | ||||
|     } | ||||
|     datalist.appendChild(fragment); | ||||
|     tag_autocomplete.datalist = datalist; | ||||
| 
 | ||||
|     for (const hook of tag_autocomplete.on_load_hooks) | ||||
|     { | ||||
|         hook(datalist); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| tag_autocomplete.normalize_tagname = | ||||
|  | @ -101,11 +105,7 @@ function resolve(tagname) | |||
| tag_autocomplete.get_all_tags_callback = | ||||
| function get_all_tags_callback(response) | ||||
| { | ||||
|     if (response["meta"]["status"] == 304) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|     if (response["meta"]["status"] != 200) | ||||
|     if (response.meta.status !== 200) | ||||
|     { | ||||
|         console.error(response); | ||||
|         return; | ||||
|  | @ -113,8 +113,7 @@ function get_all_tags_callback(response) | |||
| 
 | ||||
|     tag_autocomplete.tags = new Set(response.data.tags); | ||||
|     tag_autocomplete.synonyms = response.data.synonyms; | ||||
|     setTimeout(() => tag_autocomplete.init_datalist(), 0); | ||||
|     return tag_autocomplete.tagset; | ||||
|     setTimeout(tag_autocomplete.init_datalist, 0); | ||||
| } | ||||
| 
 | ||||
| tag_autocomplete.on_pageload = | ||||
|  |  | |||
|  | @ -141,6 +141,7 @@ const ALBUM_ID = undefined; | |||
|     {% if theme %}<link rel="stylesheet" href="/static/css/theme_{{theme}}.css">{% endif %} | ||||
|     <script src="/static/js/common.js"></script> | ||||
|     <script src="/static/js/api.js"></script> | ||||
|     <script src="/static/js/album_autocomplete.js"></script> | ||||
|     <script src="/static/js/spinner.js"></script> | ||||
|     <script src="/static/js/editor.js"></script> | ||||
|     <script src="/static/js/hotkeys.js"></script> | ||||
|  | @ -180,6 +181,7 @@ const ALBUM_ID = undefined; | |||
| 
 | ||||
|         <button | ||||
|         class="green_button button_with_confirm" | ||||
|         data-holder-id="add_child_holder" | ||||
|         data-is-input="1" | ||||
|         data-prompt="Child ID" | ||||
|         data-cancel-class="gray_button" | ||||
|  | @ -368,6 +370,24 @@ function on_cancel(ed, edit_element_map, display_element_map) | |||
| const title_text = document.getElementById("title_text"); | ||||
| const description_text = document.getElementById("description_text"); | ||||
| const ed = new editor.Editor([title_text, description_text], on_open, on_save, on_cancel); | ||||
| 
 | ||||
| function add_album_datalist_on_load(datalist) | ||||
| { | ||||
|     /* | ||||
|     I found that the `list` property must be set by setAttribute, not | ||||
|     regular assignment, and it must be provided the ID of the datalist, not | ||||
|     the datalist object itself. Furthermore, it cannot be done until the | ||||
|     datalist is ready -- I tried adjusting the button_with_confirm | ||||
|     initializer to let me set the datalist during the input's construction, | ||||
|     but at that point the datalist prep usually / certainly hasn't run yet | ||||
|     and it didn't work. All that is to say I had to add this on_load hook | ||||
|     function to only call setAttribute after the datalist has been prepared. | ||||
|     */ | ||||
|     const holder = document.getElementById("add_child_holder"); | ||||
|     const input = holder.getElementsByTagName("input")[0]; | ||||
|     input.setAttribute("list", "album_autocomplete_datalist"); | ||||
| } | ||||
| album_autocomplete.on_load_hooks.push(add_album_datalist_on_load); | ||||
| </script> | ||||
| 
 | ||||
| {% endif %} {## Shared ############################################################################} | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue