{%- set static = static ?? false %} {%- set fullWidth = fullWidth ?? true %} {%- set cols = cols ?? [] %} {%- set rows = rows ?? [] %} {%- set initJs = not static and (initJs ?? true) -%} {%- set minRows = minRows ?? null %} {%- set maxRows = maxRows ?? null %} {%- set describedBy = describedBy ?? null %} {%- set includeRowId = includeRowId ?? false %} {%- set totalRows = rows|length %} {%- set staticRows = static or (staticRows ?? false) or (minRows == 1 and maxRows == 1 and totalRows == 1) %} {%- set allowAdd = (allowAdd ?? false) and not staticRows %} {%- set allowReorder = (allowReorder ?? false) and not staticRows %} {%- set allowDelete = (allowDelete ?? false) and not staticRows %} {% set actionMenuItems = [ { icon: 'arrow-up', label: 'Move up'|t('app'), attributes: { data: {action: 'moveUp'}, }, }, { icon: 'arrow-down', label: 'Move down'|t('app'), attributes: { data: {action: 'moveDown'}, }, }, ] %} {% if not static %} {{ hiddenInput(name, '') }} {% endif %} {% macro cellClass(fullWidth, col, class) %} {{- (class is iterable ? class : [class])|merge([ "#{col.type}-cell", col.type in [ 'autosuggest', 'color', 'date', 'email', 'multiline', 'number', 'singleline', 'template', 'time', 'url', ] ? 'textual' : null, fullWidth and (col.thin ?? false) ? 'thin' : null, col.info is defined ? 'has-info' : null, ]|filter)|join(' ') -}} {% endmacro %} {% set tableAttributes = { id: id, class: [ 'editable', fullWidth ? 'fullwidth', static ? 'static', totalRows == 0 ? 'hidden', ]|filter, } %} {%- if block('attr') is defined %} {%- set tableAttributes = tableAttributes|merge(('
')|parseAttr, recursive=true) %} {% endif %} {% for col in cols %} {%- switch col.type %} {%- case 'time' %} {%- do view.registerAssetBundle('craft\\web\\assets\\timepicker\\TimepickerAsset') %} {%- case 'template' %} {%- do view.registerAssetBundle("craft\\web\\assets\\vue\\VueAsset") %} {%- endswitch %} {% endfor %} {% tag 'table' with tableAttributes %} {% for col in cols %} {% endfor %} {% if (allowDelete and allowReorder) %} {% else %} {% if allowDelete %}{% endif %} {% if allowReorder %}{% endif %} {% endif %} {% if includeRowId %} {# for hidden row ID #} {% endif %} {% if cols|filter(c => (c.headingHtml ?? c.heading ?? c.info ?? '') is not same as(''))|length %} {% for col in cols %} {% set columnHeadingId = "#{id}-heading-#{loop.index}" %} {%- if col.headingHtml is defined %} {{- col.headingHtml|raw }} {%- elseif col.heading ?? false %} {{- col.heading }} {%- else %}   {%- endif %} {%- if col.info is defined -%} {{ col.info|md|raw }} {%- endif -%} {% endfor %} {% if (allowDelete or allowReorder) %} {{ 'Row actions'|t('app') }} {% endif %} {% if includeRowId %} Row ID {% endif %} {% endif %} {% for rowId, row in rows %} {% set rowNumber = loop.index %} {% set rowName = 'Row {index}'|t('app', {index: rowNumber}) %} {% set actionBtnLabel = "#{rowName} #{'Actions'|t('app')}" %} {% for colId, col in cols %} {% set cell = row[colId] is defined ? row[colId] : (defaultValues[colId] ?? null) %} {% set value = cell.value is defined ? cell.value : cell %} {% if col.width ?? false %} {% set width = col.width|trim %} {% set width = width ends with 'px' ? width|slice(0, width|length - 2) : width %} {% set minWidth = width ends with '%' ? col.width : "#{col.width}px" %} {% set widthAttributes = " width=\"#{width}\" style=\"min-width: #{minWidth}\"" %} {% else %} {% set widthAttributes = '' %} {% endif %} {% if col.type == 'heading' %} {{ value|raw }} {% elseif col.type == 'html' %} {{ value|raw }} {% else %} {% set headingId = "#{id}-heading-#{loop.index}" %} {% set hasErrors = cell.hasErrors ?? false %} {% set cellName = name~'['~rowId~']['~colId~']' %} {% set isCode = (col.code ?? false) or col.type == 'color' %} {% block tablecell %} {%- switch col.type -%} {%- case 'checkbox' -%}
{% include "_includes/forms/checkbox" with { name: cellName, value: col.value ?? 1, checked: value is not empty, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %}
{%- case 'icon' -%} {% include '_includes/forms/iconPicker' with { name: cellName, value, small: true, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %} {%- case 'color' -%} {% include "_includes/forms/color" with { name: cellName, value: value, small: true, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %} {%- case 'date' -%} {% include "_includes/forms/date" with { name: cellName, value: value, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %} {%- case 'lightswitch' -%} {% include "_includes/forms/lightswitch" with { name: cellName, on: value, value: col.value ?? 1, small: true, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %} {% case 'select' -%} {% include "_includes/forms/select" with { class: 'small', name: cellName, options: cell.options ?? col.options, value: value, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %} {%- case 'time' -%} {% include "_includes/forms/time" with { name: cellName, value: value, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %} {%- case 'email' or 'url' -%} {% include "_includes/forms/text" with { type: col.type, name: cellName, placeholder: col.placeholder ?? null, value: value, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %} {%- case 'autosuggest' or 'template' -%} {% include "_includes/forms/autosuggest" with { name: cellName, suggestTemplates: col.type == 'template', suggestEnvVars: col.suggestEnvVars ?? false, suggestAliases: col.suggestAliases ?? false, value: value, disabled: static, labelledBy: headingId, describedBy: describedBy, } only %} {%- default -%} {% if col.type == 'number' and col.locale ?? false %} {{ hiddenInput("#{cellName}[locale]", col.locale) }} {% set cellName = "#{cellName}[value]" %} {% set value = value|number(locale=col.locale) %} {% endif %} {% if static %}
{{ value }}
{% else %} {% if value %} {% endif %} {{ tag('textarea', { name: cellName, rows: col.rows ?? 1, placeholder: col.placeholder ?? false, autocomplete: isCode ? 'off' : false, autocorrect: isCode ? 'off' : false, autocapitalize: isCode ? 'off' : false, spellcheck: isCode ? 'false' : false, aria: { labelledby: headingId, describedby: describedBy, }, html: value, }) }} {% endif %} {%- endswitch -%} {% endblock %} {% endif %} {% endfor %} {% if allowReorder -%}
{{~ disclosureMenu(actionMenuItems, { buttonAttributes: { 'aria-label': actionBtnLabel, class: ['action-btn'], title: 'Actions'|t('app'), data: { 'disclosure-trigger': true, }, }, }) }}
{%- endif -%} {%- if allowDelete -%} {{ tag('button', { class: [ 'delete', 'icon', minRows and totalRows <= minRows ? 'disabled' : null, ]|filter, type: 'button', disabled: minRows and totalRows <= minRows, title: 'Delete'|t('app'), aria: { label: 'Delete row {index}'|t('app', { index: rowNumber, }), } }) }} {%- endif -%} {% for inputName, value in row.hiddenInputs ?? [] %} {{ hiddenInput("#{name}[#{rowId}][#{inputName}]", value) }} {% endfor %} {% if includeRowId and (row.rowId ?? false) %} {{ hiddenInput("#{name}[#{rowId}][rowId]", row.rowId) }} {% endif %} {% endfor %} {% endtag %} {% if allowAdd %} {% set buttonText = addRowLabel ?? "Add a row"|t('app') %} {% endif %} {% if initJs %} {% set jsId = id|namespaceInputId|e('js') %} {% set jsName = name|namespaceInputName|e('js') %} {% set jsCols = cols|json_encode %} {% set defaultValues = defaultValues ?? null %} {% js %} new Craft.EditableTable("{{ jsId }}", "{{ jsName }}", {{ jsCols|raw }}, { defaultValues: {{ defaultValues ? defaultValues|json_encode|raw : '{}' }}, allowAdd: {{ allowAdd ? 'true' : 'false' }}, allowDelete: {{ allowDelete ? 'true' : 'false' }}, allowReorder: {{ allowReorder ? 'true' : 'false' }}, minRows: {{ minRows ? minRows : 'null' }}, maxRows: {{ maxRows ? maxRows : 'null' }} }); {% endjs %} {% endif %}