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 flask; from flask import request
|
||||||
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
import etiquette
|
import etiquette
|
||||||
|
|
||||||
|
from .. import caching
|
||||||
from .. import common
|
from .. import common
|
||||||
from .. import decorators
|
from .. import decorators
|
||||||
from .. import jsonify
|
from .. import jsonify
|
||||||
|
@ -154,6 +156,13 @@ def post_album_edit(album_id):
|
||||||
|
|
||||||
# Album listings ###################################################################################
|
# 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():
|
def get_albums_core():
|
||||||
albums = list(common.P.get_root_albums())
|
albums = list(common.P.get_root_albums())
|
||||||
albums.sort(key=lambda x: x.display_name.lower())
|
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);
|
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 =
|
api.albums.edit =
|
||||||
function edit(album_id, title, description, callback)
|
function edit(album_id, title, description, callback)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,26 +4,24 @@ tag_autocomplete.tags = new Set();
|
||||||
tag_autocomplete.synonyms = {};
|
tag_autocomplete.synonyms = {};
|
||||||
|
|
||||||
tag_autocomplete.DATALIST_ID = "tag_autocomplete_datalist";
|
tag_autocomplete.DATALIST_ID = "tag_autocomplete_datalist";
|
||||||
|
tag_autocomplete.datalist = null;
|
||||||
|
tag_autocomplete.on_load_hooks = [];
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
tag_autocomplete.init_datalist =
|
tag_autocomplete.init_datalist =
|
||||||
function init_datalist()
|
function init_datalist()
|
||||||
{
|
{
|
||||||
console.log("Init datalist.");
|
if (tag_autocomplete.datalist)
|
||||||
let datalist;
|
|
||||||
datalist = document.getElementById(tag_autocomplete.DATALIST_ID);
|
|
||||||
if (datalist)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log("Init tag_autocomplete datalist.");
|
||||||
datalist = document.createElement("datalist");
|
const datalist = document.createElement("datalist");
|
||||||
datalist.id = tag_autocomplete.DATALIST_ID;
|
datalist.id = tag_autocomplete.DATALIST_ID;
|
||||||
document.body.appendChild(datalist);
|
document.body.appendChild(datalist);
|
||||||
|
|
||||||
const fragment = document.createDocumentFragment();
|
const fragment = document.createDocumentFragment();
|
||||||
common.delete_all_children(datalist);
|
|
||||||
for (const tag_name of tag_autocomplete.tags)
|
for (const tag_name of tag_autocomplete.tags)
|
||||||
{
|
{
|
||||||
const option = document.createElement("option");
|
const option = document.createElement("option");
|
||||||
|
@ -37,6 +35,12 @@ function init_datalist()
|
||||||
fragment.appendChild(option);
|
fragment.appendChild(option);
|
||||||
}
|
}
|
||||||
datalist.appendChild(fragment);
|
datalist.appendChild(fragment);
|
||||||
|
tag_autocomplete.datalist = datalist;
|
||||||
|
|
||||||
|
for (const hook of tag_autocomplete.on_load_hooks)
|
||||||
|
{
|
||||||
|
hook(datalist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tag_autocomplete.normalize_tagname =
|
tag_autocomplete.normalize_tagname =
|
||||||
|
@ -101,11 +105,7 @@ function resolve(tagname)
|
||||||
tag_autocomplete.get_all_tags_callback =
|
tag_autocomplete.get_all_tags_callback =
|
||||||
function get_all_tags_callback(response)
|
function get_all_tags_callback(response)
|
||||||
{
|
{
|
||||||
if (response["meta"]["status"] == 304)
|
if (response.meta.status !== 200)
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (response["meta"]["status"] != 200)
|
|
||||||
{
|
{
|
||||||
console.error(response);
|
console.error(response);
|
||||||
return;
|
return;
|
||||||
|
@ -113,8 +113,7 @@ function get_all_tags_callback(response)
|
||||||
|
|
||||||
tag_autocomplete.tags = new Set(response.data.tags);
|
tag_autocomplete.tags = new Set(response.data.tags);
|
||||||
tag_autocomplete.synonyms = response.data.synonyms;
|
tag_autocomplete.synonyms = response.data.synonyms;
|
||||||
setTimeout(() => tag_autocomplete.init_datalist(), 0);
|
setTimeout(tag_autocomplete.init_datalist, 0);
|
||||||
return tag_autocomplete.tagset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tag_autocomplete.on_pageload =
|
tag_autocomplete.on_pageload =
|
||||||
|
|
|
@ -141,6 +141,7 @@ const ALBUM_ID = undefined;
|
||||||
{% if theme %}<link rel="stylesheet" href="/static/css/theme_{{theme}}.css">{% endif %}
|
{% if theme %}<link rel="stylesheet" href="/static/css/theme_{{theme}}.css">{% endif %}
|
||||||
<script src="/static/js/common.js"></script>
|
<script src="/static/js/common.js"></script>
|
||||||
<script src="/static/js/api.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/spinner.js"></script>
|
||||||
<script src="/static/js/editor.js"></script>
|
<script src="/static/js/editor.js"></script>
|
||||||
<script src="/static/js/hotkeys.js"></script>
|
<script src="/static/js/hotkeys.js"></script>
|
||||||
|
@ -180,6 +181,7 @@ const ALBUM_ID = undefined;
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="green_button button_with_confirm"
|
class="green_button button_with_confirm"
|
||||||
|
data-holder-id="add_child_holder"
|
||||||
data-is-input="1"
|
data-is-input="1"
|
||||||
data-prompt="Child ID"
|
data-prompt="Child ID"
|
||||||
data-cancel-class="gray_button"
|
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 title_text = document.getElementById("title_text");
|
||||||
const description_text = document.getElementById("description_text");
|
const description_text = document.getElementById("description_text");
|
||||||
const ed = new editor.Editor([title_text, description_text], on_open, on_save, on_cancel);
|
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>
|
</script>
|
||||||
|
|
||||||
{% endif %} {## Shared ############################################################################}
|
{% endif %} {## Shared ############################################################################}
|
||||||
|
|
Loading…
Reference in a new issue