{% comment %} Renders each option (search result) in the dropdown. If is_tabular is true, renders a row of columns. If not, checks for custom rendering templates. {% endcomment %} {% load i18n %} option: function(data, escape) { {% include "django_tomselect/helpers/decode_if_needed.html" %} {% if 'data_template_option' in widget.attrs.keys and widget.attrs.data_template_option %} {# SECURITY: |safe is required here to emit the JS template string without double-escaping. #} {# The value is developer-provided via TomSelectConfig(attrs={"render": {"option": ...}}) #} {# and JSON-encoded server-side in widgets.py build_attrs() via json.dumps(). #} {# User data interpolated into the template is escaped by Tom Select's escape() function. #} var template = {{ widget.attrs.data_template_option|safe }}; var result = template.replace(/\$\{data\.(\w+)\}/g, function(match, fieldName) { var value = data[fieldName]; if (value === undefined || value === null) return ''; return escape(String(value)); }); // Also support ${escape(data.fieldName)} pattern for explicit escaping result = result.replace(/\$\{escape\(data\.(\w+)\)\}/g, function(match, fieldName) { var value = data[fieldName]; if (value === undefined || value === null) return ''; return escape(String(value)); }); return result; {% elif widget.is_tabular %} // For tabular display, show in rows and columns let columns = ''; {% if widget.plugins.dropdown_header.show_value_field %} columns += ` `; {% else %} columns += ``; {% endif %} {% for item in widget.plugins.dropdown_header.extra_values %} columns += ``; {% endfor %} return `
${columns}
`; {% else %} const safeValue = escape(decodeIfNeeded(data['{{ widget.label_field|escapejs }}'])); return `
${safeValue}
`; {% endif %} },