feat: auto-enrich data_filter code fields with valueField/textField/params/dataurl from model codes

When data_filter declares uitype='code' for a search field, xls2crud now
automatically looks up the matching code definition in models/*.json codes
array and populates valueField, textField, params (dbname/table/tblvalue/
tbltext), and dataurl. This prevents UiCode crash (Cannot read properties
of undefined reading 'length') in InlineForm search forms.
This commit is contained in:
Hermes Agent 2026-06-22 11:56:15 +08:00
parent 70b6997fca
commit 5295a1ce8f
5 changed files with 54 additions and 2 deletions

Binary file not shown.

View File

@ -14,9 +14,13 @@ data_browser_tmpl = """
"submit_label":"搜索",
"submit_css":"primary",
"fields":[
{% for f in data_filter.fields %}
{%- for f in data_filter.fields %}
{%- if f.uitype == 'code' %}
{{json.dumps(filter_fields[loop.index0], ensure_ascii=False)}}{% if not loop.last %},{% endif %}
{%- else %}
{"name":"{{f.field}}","uitype":"{{f.uitype}}","placeholder":"{{f.title}}","cwidth":15}{% if not loop.last %},{% endif %}
{% endfor %}
{%- endif %}
{%- endfor %}
]
},
"binds":[{

View File

@ -255,9 +255,57 @@ def filter_backslash(s):
ls = s.split('\\/')
return '/'.join(ls)
def build_filter_field_list(desc) -> list:
"""Build enriched filter field list for InlineForm search form.
When a data_filter field has uitype='code', auto-populate
valueField/textField/params/dataurl from the model's codes definition."""
if not desc.data_filter or not desc.data_filter.get('fields'):
return []
codes_map = {}
if desc.codes:
for c in desc.codes:
cfield = c.field if isinstance(c, dict) else getattr(c, 'field', None)
if cfield:
codes_map[cfield] = c
modulename = getattr(desc, 'modulename', '')
result = []
for f in desc.data_filter.fields:
field_name = f.field if isinstance(f, dict) else getattr(f, 'field', '')
field_title = f.title if isinstance(f, dict) else getattr(f, 'title', '')
field_uitype = f.uitype if isinstance(f, dict) else getattr(f, 'uitype', 'str')
field_def = {
'name': field_name,
'uitype': field_uitype,
'placeholder': field_title,
'cwidth': 15
}
if field_uitype == 'code' and field_name in codes_map:
c = codes_map[field_name]
ctable = c.table if isinstance(c, dict) else getattr(c, 'table', '')
cvaluefield = c.valuefield if isinstance(c, dict) else getattr(c, 'valuefield', '')
ctextfield = c.textfield if isinstance(c, dict) else getattr(c, 'textfield', '')
ccond = (c.cond if isinstance(c, dict) else getattr(c, 'cond', None))
field_def['valueField'] = field_name
field_def['textField'] = field_name + '_text'
field_def['params'] = {
'dbname': "{{get_module_dbname('" + modulename + "')}}",
'table': ctable,
'tblvalue': cvaluefield,
'tbltext': ctextfield,
'valueField': field_name,
'textField': field_name + '_text'
}
if ccond:
field_def['params']['cond'] = ccond
field_def['dataurl'] = "{{entire_url('/appbase/get_code.dspy')}}"
result.append(field_def)
return result
def build_data_browser(pat: str, desc: dict):
desc = desc.copy()
desc.fieldliststr = json.dumps(field_list(desc), ensure_ascii=False, indent=4)
desc.filter_fields = build_filter_field_list(desc)
desc.filterfieldstr = json.dumps(desc.filter_fields, ensure_ascii=False, indent=4)
e = MyTemplateEngine([])
s = e.renders(data_browser_tmpl, desc)
with codecs.open(os.path.join(pat, f'index.ui'), 'w', "utf-8") as f: