-
+
{% endmacro %}
{% macro dynamic_combobox(
- id, options, label = none, placeholder = none, data_attributes = none,
- create_url = none, edit_url = none, delete_url = none, refresh_url = none
+id, options, label = none, placeholder = none, data_attributes = none,
+create_url = none, edit_url = none, delete_url = none, refresh_url = none
) %}
- {% if label %}
-
-
+{% endmacro %}
\ No newline at end of file
diff --git a/inventory/templates/fragments/_option_fragment.html b/inventory/templates/fragments/_option_fragment.html
new file mode 100644
index 0000000..600edc5
--- /dev/null
+++ b/inventory/templates/fragments/_option_fragment.html
@@ -0,0 +1,6 @@
+{% for option in options %}
+
+{% endfor %}
\ No newline at end of file
diff --git a/inventory/templates/playground.html b/inventory/templates/playground.html
index af7322e..af45727 100644
--- a/inventory/templates/playground.html
+++ b/inventory/templates/playground.html
@@ -2,17 +2,8 @@
{% block content %}
{{ combos.dynamic_combobox(
- 'play',
- [
- {
- 'id': 1,
- 'name': 'Beans'
- },
- {
- 'id': 2,
- 'name': 'Toast'
- },
- ],
- 'Breakfast!'
+ id='play',
+ label='Breakfast!',
+ refresh_url=url_for('ui.list_items', model_name='brand', view='option')
) }}
{% endblock %}
\ No newline at end of file
diff --git a/inventory/ui/blueprint.py b/inventory/ui/blueprint.py
index 160f9a5..74b0df9 100644
--- a/inventory/ui/blueprint.py
+++ b/inventory/ui/blueprint.py
@@ -50,7 +50,9 @@ def list_items(model_name):
rows = call(Model, "ui_query", db.session, text=text, limit=limit, offset=offset) \
or default_query(db.session, Model, text=text, limit=limit, offset=offset)
+ items = [call(Model, 'ui_serialize', r, view=view) or default_serialize(Model, r, view=view)
+ for r in rows]
- data = [ (call(Model, "ui_serialize", r, view=view) or default_serialize(Model, r, view=view))
- for r in rows ]
- return jsonify({"items": data})
+ if view=="option":
+ return render_template('fragments/_option_fragment.html', options=items)
+ return jsonify({"items": items})
diff --git a/inventory/ui/defaults.py b/inventory/ui/defaults.py
index 16d8d16..5212156 100644
--- a/inventory/ui/defaults.py
+++ b/inventory/ui/defaults.py
@@ -89,9 +89,30 @@ def default_delete(session, Model, ids):
return count
def default_serialize(Model, obj, *, view='option'):
- label = infer_label_attr(Model)
- data = {'id': obj.id, 'name': getattr(obj, label)}
+ # 1. Explicit config wins
+ label_attr = getattr(Model, 'ui_label_attr', None)
+
+ # 2. Otherwise, pick the first PREFERRED_LABELS that exists (can be @property or real column)
+ if not label_attr:
+ for candidate in PREFERRED_LABELS:
+ if hasattr(obj, candidate):
+ label_attr = candidate
+ break
+
+ # 3. Fallback to str(obj) if literally nothing found
+ if not label_attr:
+ name_val = str(obj)
+ else:
+ try:
+ name_val = getattr(obj, label_attr)
+ except Exception:
+ name_val = str(obj)
+
+ data = {'id': obj.id, 'name': name_val}
+
+ # Include extra attrs if defined
for attr in getattr(Model, 'ui_extra_attrs', ()):
if hasattr(obj, attr):
data[attr] = getattr(obj, attr)
+
return data