Dropdown refactor. Not ready.
This commit is contained in:
parent
9705606c89
commit
0641519d22
6 changed files with 88 additions and 9 deletions
|
|
@ -90,3 +90,15 @@ const DropdownWidget = (() => {
|
||||||
setButton
|
setButton
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function DropDown(cfg) {
|
||||||
|
return {
|
||||||
|
id: cfg.id,
|
||||||
|
refreshUrl: cfg.refreshUrl,
|
||||||
|
selectUrl: cfg.selectUrl,
|
||||||
|
|
||||||
|
itemSelect(e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,4 +40,55 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
||||||
|
{% macro dynamic_dropdown(id, list = none, label = none, current_item = none, entry_link = none, enabled = true, refresh_url = none, select_url = none) %}
|
||||||
|
<label for="{{ id }}" class="form-label">
|
||||||
|
{{ label or '' }}
|
||||||
|
{% if entry_link %}
|
||||||
|
{{ links.entry_link(entry_link, current_item.id) }}
|
||||||
|
{% endif %}
|
||||||
|
</label>
|
||||||
|
<div class="dropdown" id="{{ id }}-dropdown" x-data='DropDown({
|
||||||
|
id: {{ id|tojson }},
|
||||||
|
refreshUrl: {{ refresh_url|tojson if refresh_url else "null" }},
|
||||||
|
selectUrl: {{ select_url|tojson if select_url else "null" }}
|
||||||
|
})'
|
||||||
|
hx-preserve>
|
||||||
|
<div class="btn-group w-100">
|
||||||
|
<button
|
||||||
|
class="btn btn-outline-dark dropdown-toggle overflow-x-hidden w-100 rounded-end{% if current_item and enabled %}-0 border-end-0{% endif %} dropdown-button"
|
||||||
|
type="button" data-bs-toggle="dropdown" data-inv-value="{{ current_item.id if current_item else '' }}"
|
||||||
|
id="{{ id }}Button" {% if not enabled %} disabled{% endif %}
|
||||||
|
style="border-color: rgb(222, 226, 230);{% if not enabled %} background-color: rgb(233, 236, 239); color: rgb(0, 0, 0);{% endif %}">
|
||||||
|
{{ current_item.identifier if current_item else '-' }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-outline-danger rounded-end font-weight-bold border-start-0{% if not current_item or not enabled %} d-none{% endif %}"
|
||||||
|
type="button" id="{{ id }}ClearButton"
|
||||||
|
style="z-index: 9999; border-color: rgb(222, 226, 230);{% if not enabled %} background-color: rgb(233, 236, 239); color: rgb(0, 0, 0);{% endif %}">
|
||||||
|
{{ icons.render_icon('x-lg', 16) }}
|
||||||
|
</button>
|
||||||
|
<input type="hidden" name="{{ id }}" id="{{ id }}" value="{{ current_item.id if current_item else '' }}">
|
||||||
|
<ul class="dropdown-menu w-100 pt-0" style="max-height: 40vh; z-index: 9999;" id="menu{{ id }}">
|
||||||
|
<input type="text"
|
||||||
|
class="form-control rounded-bottom-0 border-start-0 border-top-0 border-end-0 dropdown-search-input"
|
||||||
|
id="search{{ id }}" placeholder="Search...">
|
||||||
|
<div class="overflow-auto overflow-x-hidden" style="z-index: 9999;" id="{{ id }}DropdownContent">
|
||||||
|
{% if list %}
|
||||||
|
{% for item in list %}
|
||||||
|
<li><a class="dropdown-item" data-inv-value="{{ item.id }}">{{
|
||||||
|
item.identifier }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% if refresh_url %}
|
||||||
|
{% set url = refresh_url ~ ('&' if '?' in refresh_url else '?') ~ 'view=list&limit=0' %}
|
||||||
|
<div id="{{ id }}-htmx-refresh" class="d-none" hx-get="{{ url }}"
|
||||||
|
hx-trigger="revealed, combobox:refresh from:#{{ id }}-dropdown" hx-target="#{{ id }}DropdownContent" hx-swap="innerHTML"></div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
|
||||||
10
inventory/templates/fragments/_list_fragment.html
Normal file
10
inventory/templates/fragments/_list_fragment.html
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{# templates/fragments/_list_fragment.html #}
|
||||||
|
{% for it in options %}
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" data-inv-value="{{ it.id }}"
|
||||||
|
{% for k, v in it.items() if k not in ('id','name') and v is not none %}
|
||||||
|
data-{{ k|e }}="{{ v|e }}"
|
||||||
|
{% endfor %}
|
||||||
|
@click.prevent='itemSelect($event)'>{{ it.name }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{{ combos.render_combobox(
|
{{ combos.render_combobox(
|
||||||
id='play',
|
id='combo',
|
||||||
label='Breakfast!',
|
label='Breakfast!',
|
||||||
create_url=url_for('ui.create_item', model_name='brand'),
|
refresh_url=url_for('ui.list_items', model_name='brand')
|
||||||
edit_url=url_for('ui.update_item', model_name='brand'),
|
) }}
|
||||||
refresh_url=url_for('ui.list_items', model_name='brand'),
|
|
||||||
delete_url=url_for('ui.delete_item', model_name='brand')
|
{{ dropdowns.dynamic_dropdown(
|
||||||
|
id = 'dropdown',
|
||||||
|
refresh_url=url_for('ui.list_items', model_name='user')
|
||||||
) }}
|
) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
@ -55,9 +55,13 @@ def list_items(model_name):
|
||||||
items = [call(Model, 'ui_serialize', r, view=view) or default_serialize(Model, r, view=view)
|
items = [call(Model, 'ui_serialize', r, view=view) or default_serialize(Model, r, view=view)
|
||||||
for r in rows]
|
for r in rows]
|
||||||
|
|
||||||
want_html = (request.args.get("view") == "option") or ("HX-Request" in request.headers)
|
want_option = (request.args.get("view") == "option")
|
||||||
if want_html:
|
want_list = (request.args.get("view") == "list")
|
||||||
|
print(view)
|
||||||
|
if want_option:
|
||||||
return render_template("fragments/_option_fragment.html", options=items)
|
return render_template("fragments/_option_fragment.html", options=items)
|
||||||
|
if want_list:
|
||||||
|
return render_template("fragments/_list_fragment.html", options=items)
|
||||||
return jsonify({"items": items})
|
return jsonify({"items": items})
|
||||||
|
|
||||||
@bp.post("/<model_name>/create")
|
@bp.post("/<model_name>/create")
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ def default_delete(session, Model, ids):
|
||||||
session.commit()
|
session.commit()
|
||||||
return count
|
return count
|
||||||
|
|
||||||
def default_serialize(Model, obj, *, view='option'):
|
def default_serialize(Model, obj, *, view=None):
|
||||||
# 1. Explicit config wins
|
# 1. Explicit config wins
|
||||||
label_attr = getattr(Model, 'ui_label_attr', None)
|
label_attr = getattr(Model, 'ui_label_attr', None)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue