diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java index 5d7c410231..e163ce8f30 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/FormConstants.java @@ -146,4 +146,13 @@ private FormConstants() { /** The resource type for date time input field v1 */ public static final String RT_FD_FORM_DATETIME_V1 = RT_FD_FORM_PREFIX + "datetime/v1/datetime"; + /** The resource type for table v1 */ + public static final String RT_FD_FORM_TABLE_V1 = RT_FD_FORM_PREFIX + "table/v1/table"; + + /** The resource type for table header v1 */ + public static final String RT_FD_FORM_TABLE_HEADER_V1 = RT_FD_FORM_PREFIX + "tableheader/v1/tableheader"; + + /** The resource type for table row v1 */ + public static final String RT_FD_FORM_TABLE_ROW_V1 = RT_FD_FORM_PREFIX + "tablerow/v1/tablerow"; + } diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java index 545b2a6f5c..64b0fad3d4 100644 --- a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/form/ReservedProperties.java @@ -172,6 +172,22 @@ private ReservedProperties() { public static final String FD_DRAFT_ID = "fd:draftId"; + public static final String PN_CQ_ANNOTATIONS = "cq:annotations"; + + /** + * Comma-separated proportional column widths JCR property, also passed into fd:dor for DOR table rendering (matches + * GuideTableElement key). + */ + public static final String PN_DOR_COLUMN_WIDTHS = "columnWidth"; + + /** When true, adaptive form table columns can be sorted at runtime (publish). */ + public static final String PN_ENABLE_SORTING = "enableSorting"; + + /** fd:viewType values for table sub-components — used as :type in exported JSON and matched in AF2→AF1 DOR transformer. */ + public static final String VT_TABLE = "table"; + public static final String VT_TABLE_ROW = "table-row"; + public static final String VT_TABLE_HEADER = "table-header"; + // Begin: Form submission related properties public static final String FD_SUBMIT_PROPERTIES = "fd:submit"; public static final String PN_SUBMIT_ACTION_TYPE = "actionType"; diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableHeaderImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableHeaderImpl.java new file mode 100644 index 0000000000..cec915f247 --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableHeaderImpl.java @@ -0,0 +1,42 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2026 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.jetbrains.annotations.NotNull; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.forms.core.components.internal.form.FormConstants; +import com.adobe.cq.forms.core.components.internal.form.ReservedProperties; +import com.adobe.cq.forms.core.components.models.form.Panel; + +@Model( + adaptables = { SlingHttpServletRequest.class, Resource.class }, + adapters = { Panel.class, ComponentExporter.class }, + resourceType = { FormConstants.RT_FD_FORM_TABLE_HEADER_V1 }) +@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class TableHeaderImpl extends PanelImpl { + + @Override + @NotNull + public String getExportedType() { + return ReservedProperties.VT_TABLE_HEADER; + } +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableImpl.java new file mode 100644 index 0000000000..cf10ec50ca --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableImpl.java @@ -0,0 +1,142 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2026 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nullable; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; +import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; +import org.jetbrains.annotations.NotNull; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.forms.core.components.internal.form.FormConstants; +import com.adobe.cq.forms.core.components.internal.form.ReservedProperties; +import com.adobe.cq.forms.core.components.models.form.Panel; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@Model( + adaptables = { SlingHttpServletRequest.class, Resource.class }, + adapters = { Panel.class, ComponentExporter.class }, + resourceType = { FormConstants.RT_FD_FORM_TABLE_V1 }) +@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class TableImpl extends PanelImpl { + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.PN_DOR_COLUMN_WIDTHS) + @Nullable + protected String columnWidth; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL, name = ReservedProperties.PN_ENABLE_SORTING) + @Nullable + protected Boolean enableSorting; + + /** + * When {@code true}, runtime (publish) enables client-side column sorting. + * Omitted from JSON when {@code false} (see {@link JsonInclude.Include#NON_DEFAULT}). + */ + @JsonProperty("enableSorting") + @JsonInclude(JsonInclude.Include.NON_DEFAULT) + public boolean isEnableSorting() { + return Boolean.TRUE.equals(enableSorting); + } + + /** + * Returns the raw comma-separated column width string from JCR (e.g. "1,1,4"). + * Used in edit mode as the {@code data-column-widths} attribute. + */ + @JsonIgnore + public String getColumnWidth() { + return columnWidth; + } + + /** + * True when {@link #getColumnWidthColStyles()} would return a non-empty list (valid authored widths). + */ + @JsonIgnore + public boolean isColumnWidthsConfigured() { + return !getColumnWidthColStyles().isEmpty(); + } + + @Override + @NotNull + public String getExportedType() { + return ReservedProperties.VT_TABLE; + } + + @Override + @JsonIgnore + @NotNull + public Map getDorProperties() { + Map props = new LinkedHashMap<>(super.getDorProperties()); + if (columnWidth != null && !columnWidth.isEmpty()) { + // Pass authored proportional widths into fd:dor so DoRTableElement can compute + // proportional XFA column widths (e.g. "1,2,1" → relative pixel widths). + props.put(ReservedProperties.PN_DOR_COLUMN_WIDTHS, columnWidth); + } + return props; + } + + /** + * One entry per column for {@code }: {@code width: N%} (no HTL string concatenation). + * For example, proportional {@code "1,1,4"} becomes {@code width: 16%}, {@code width: 16%}, {@code width: 66%}. + * Negative or non-numeric values are treated as 1. The last column absorbs any rounding remainder so widths sum to 100%. + */ + @JsonIgnore + public List getColumnWidthColStyles() { + if (columnWidth == null || columnWidth.isEmpty()) { + return Collections.emptyList(); + } + String[] parts = columnWidth.split(","); + int[] values = new int[parts.length]; + int sum = 0; + for (int i = 0; i < parts.length; i++) { + try { + values[i] = Integer.parseInt(parts[i].trim()); + } catch (NumberFormatException e) { + values[i] = 1; + } + if (values[i] < 0) { + values[i] = 0; + } + sum += values[i]; + } + if (sum == 0) { + return Collections.emptyList(); + } + List result = new ArrayList<>(); + int allocated = 0; + for (int i = 0; i < values.length; i++) { + int pct = (i == values.length - 1) + ? (100 - allocated) + : (int) Math.floor((values[i] * 100.0) / sum); + allocated += pct; + result.add("width: " + pct + "%"); + } + return result; + } +} diff --git a/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableRowImpl.java b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableRowImpl.java new file mode 100644 index 0000000000..5fff674f1d --- /dev/null +++ b/bundles/af-core/src/main/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableRowImpl.java @@ -0,0 +1,42 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2026 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.jetbrains.annotations.NotNull; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.forms.core.components.internal.form.FormConstants; +import com.adobe.cq.forms.core.components.internal.form.ReservedProperties; +import com.adobe.cq.forms.core.components.models.form.Panel; + +@Model( + adaptables = { SlingHttpServletRequest.class, Resource.class }, + adapters = { Panel.class, ComponentExporter.class }, + resourceType = { FormConstants.RT_FD_FORM_TABLE_ROW_V1 }) +@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class TableRowImpl extends PanelImpl { + + @Override + @NotNull + public String getExportedType() { + return ReservedProperties.VT_TABLE_ROW; + } +} diff --git a/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableImplTest.java b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableImplTest.java new file mode 100644 index 0000000000..bc60e470ac --- /dev/null +++ b/bundles/af-core/src/test/java/com/adobe/cq/forms/core/components/internal/models/v1/form/TableImplTest.java @@ -0,0 +1,204 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Copyright 2026 Adobe + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package com.adobe.cq.forms.core.components.internal.models.v1.form; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import org.apache.sling.api.resource.Resource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.adobe.cq.export.json.SlingModelFilter; +import com.adobe.cq.forms.core.Utils; +import com.adobe.cq.forms.core.components.models.form.Panel; +import com.adobe.cq.forms.core.context.FormsCoreComponentTestContext; +import com.day.cq.wcm.api.NameConstants; +import com.day.cq.wcm.msm.api.MSMNameConstants; +import io.wcm.testing.mock.aem.junit5.AemContext; +import io.wcm.testing.mock.aem.junit5.AemContextExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(AemContextExtension.class) +public class TableImplTest { + + private static final String BASE = "/form/table"; + private static final String CONTENT_ROOT = "/content"; + private static final String PATH_TABLE = CONTENT_ROOT + "/table"; + private static final String PATH_TABLE_WITH_COLUMN_WIDTH = CONTENT_ROOT + "/table-with-column-width"; + private static final String PATH_TABLE_WITH_SORTING = CONTENT_ROOT + "/table-with-sorting"; + private static final String PATH_TABLE_WITH_EQUAL_WIDTHS = CONTENT_ROOT + "/table-with-equal-widths"; + private static final String PATH_TABLE_WITH_INVALID_WIDTH = CONTENT_ROOT + "/table-with-invalid-width"; + private static final String PATH_TABLE_WITH_NEGATIVE_WIDTH = CONTENT_ROOT + "/table-with-negative-width"; + private static final String PATH_TABLE_WITH_ZERO_WIDTHS = CONTENT_ROOT + "/table-with-zero-widths"; + private static final String PATH_TABLEHEADER = CONTENT_ROOT + "/tableheader"; + private static final String PATH_TABLEROW = CONTENT_ROOT + "/tablerow"; + + private final AemContext context = FormsCoreComponentTestContext.newAemContext(); + + @BeforeEach + void setUp() { + context.load().json(BASE + FormsCoreComponentTestContext.TEST_CONTENT_JSON, CONTENT_ROOT); + context.registerService(SlingModelFilter.class, new SlingModelFilter() { + private final Set IGNORED_NODE_NAMES = new HashSet() { + { + add(NameConstants.NN_RESPONSIVE_CONFIG); + add(MSMNameConstants.NT_LIVE_SYNC_CONFIG); + add("cq:annotations"); + } + }; + + @Override + public Map filterProperties(Map map) { + return map; + } + + @Override + public Iterable filterChildResources(Iterable childResources) { + return StreamSupport + .stream(childResources.spliterator(), false) + .filter(r -> !IGNORED_NODE_NAMES.contains(r.getName())) + .collect(Collectors.toList()); + } + }); + } + + @Test + void testGetDorProperties_noColumnWidthWhenNotAuthored() throws Exception { + Panel table = Utils.getComponentUnderTest(PATH_TABLE, Panel.class, context); + Map dorProps = table.getDorProperties(); + assertNull(dorProps.get("columnWidth"), + "columnWidth must be absent when no columnWidth is authored"); + } + + @Test + void testGetDorProperties_columnWidthPassedThroughWhenAuthored() throws Exception { + Panel table = Utils.getComponentUnderTest(PATH_TABLE_WITH_COLUMN_WIDTH, Panel.class, context); + Map dorProps = table.getDorProperties(); + assertEquals("1,2,1", dorProps.get("columnWidth"), + "columnWidth must carry the authored proportional value"); + } + + @Test + void testExportedType_table() throws Exception { + Panel table = Utils.getComponentUnderTest(PATH_TABLE, Panel.class, context); + assertEquals("table", table.getExportedType()); + } + + @Test + void testExportedType_tableHeader() throws Exception { + Panel header = Utils.getComponentUnderTest(PATH_TABLEHEADER, Panel.class, context); + assertEquals("table-header", header.getExportedType()); + } + + @Test + void testExportedType_tableRow() throws Exception { + Panel row = Utils.getComponentUnderTest(PATH_TABLEROW, Panel.class, context); + assertEquals("table-row", row.getExportedType()); + } + + @Test + void testIsEnableSorting_falseWhenNotAuthored() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE, Panel.class, context); + assertFalse(table.isEnableSorting(), "enableSorting must be false when not authored"); + } + + @Test + void testIsEnableSorting_trueWhenAuthored() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE_WITH_SORTING, Panel.class, context); + assertTrue(table.isEnableSorting(), "enableSorting must be true when authored"); + } + + @Test + void testGetColumnWidth_nullWhenNotAuthored() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE, Panel.class, context); + assertNull(table.getColumnWidth(), "getColumnWidth must be null when not authored"); + } + + @Test + void testGetColumnWidth_returnedWhenAuthored() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE_WITH_COLUMN_WIDTH, Panel.class, context); + assertEquals("1,2,1", table.getColumnWidth(), "getColumnWidth must return the authored value"); + } + + @Test + void testGetColumnWidthColStyles_emptyWhenNotAuthored() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE, Panel.class, context); + assertTrue(table.getColumnWidthColStyles().isEmpty()); + assertFalse(table.isColumnWidthsConfigured()); + } + + @Test + void testGetColumnWidthColStyles_sumsTo100() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE_WITH_EQUAL_WIDTHS, Panel.class, context); + List styles = table.getColumnWidthColStyles(); + assertEquals(3, styles.size()); + int total = styles.stream() + .mapToInt(s -> Integer.parseInt(s.replace("width: ", "").replace("%", "").trim())) + .sum(); + assertEquals(100, total, "column widths must sum to 100%"); + assertTrue(table.isColumnWidthsConfigured()); + } + + @Test + void testGetColumnWidthColStyles_proportionalWidths() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE_WITH_COLUMN_WIDTH, Panel.class, context); + List styles = table.getColumnWidthColStyles(); + assertEquals(3, styles.size()); + int total = styles.stream() + .mapToInt(s -> Integer.parseInt(s.replace("width: ", "").replace("%", "").trim())) + .sum(); + assertEquals(100, total, "proportional widths must sum to 100%"); + } + + @Test + void testGetColumnWidthColStyles_invalidValueTreatedAs1() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE_WITH_INVALID_WIDTH, Panel.class, context); + List styles = table.getColumnWidthColStyles(); + assertEquals(2, styles.size(), "invalid token should be treated as 1"); + int total = styles.stream() + .mapToInt(s -> Integer.parseInt(s.replace("width: ", "").replace("%", "").trim())) + .sum(); + assertEquals(100, total, "widths must sum to 100% even with invalid token"); + } + + @Test + void testGetColumnWidthColStyles_negativeValueTreatedAs0() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE_WITH_NEGATIVE_WIDTH, Panel.class, context); + List styles = table.getColumnWidthColStyles(); + assertEquals(3, styles.size(), "negative value should be clamped to 0"); + int total = styles.stream() + .mapToInt(s -> Integer.parseInt(s.replace("width: ", "").replace("%", "").trim())) + .sum(); + assertEquals(100, total, "widths must sum to 100% even with negative token"); + } + + @Test + void testGetColumnWidthColStyles_allZeroReturnsEmpty() throws Exception { + TableImpl table = (TableImpl) Utils.getComponentUnderTest(PATH_TABLE_WITH_ZERO_WIDTHS, Panel.class, context); + assertTrue(table.getColumnWidthColStyles().isEmpty(), "all-zero widths must return empty list"); + assertFalse(table.isColumnWidthsConfigured()); + } +} diff --git a/bundles/af-core/src/test/resources/form/table/test-content.json b/bundles/af-core/src/test/resources/form/table/test-content.json new file mode 100644 index 0000000000..b8f78a18b9 --- /dev/null +++ b/bundles/af-core/src/test/resources/form/table/test-content.json @@ -0,0 +1,71 @@ +{ + "table": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/table/v1/table", + "name": "myTable", + "jcr:title": "My Table", + "fieldType": "panel" + }, + "table-with-column-width": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/table/v1/table", + "name": "myTableWithWidths", + "jcr:title": "My Table With Column Widths", + "fieldType": "panel", + "columnWidth": "1,2,1" + }, + "table-with-sorting": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/table/v1/table", + "name": "myTableWithSorting", + "jcr:title": "My Table With Sorting", + "fieldType": "panel", + "enableSorting": true + }, + "table-with-equal-widths": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/table/v1/table", + "name": "myTableWithEqualWidths", + "jcr:title": "My Table Equal Widths", + "fieldType": "panel", + "columnWidth": "1,1,1" + }, + "table-with-invalid-width": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/table/v1/table", + "name": "myTableWithInvalidWidth", + "jcr:title": "My Table Invalid Width", + "fieldType": "panel", + "columnWidth": "abc,1" + }, + "table-with-negative-width": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/table/v1/table", + "name": "myTableWithNegativeWidth", + "jcr:title": "My Table Negative Width", + "fieldType": "panel", + "columnWidth": "-1,2,3" + }, + "table-with-zero-widths": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/table/v1/table", + "name": "myTableWithZeroWidths", + "jcr:title": "My Table Zero Widths", + "fieldType": "panel", + "columnWidth": "0,0" + }, + "tableheader": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/tableheader/v1/tableheader", + "name": "myTableHeader", + "jcr:title": "My Table Header", + "fieldType": "panel" + }, + "tablerow": { + "jcr:primaryType": "nt:unstructured", + "sling:resourceType": "core/fd/components/form/tablerow/v1/tablerow", + "name": "myTableRow", + "jcr:title": "My Table Row", + "fieldType": "panel" + } +} diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/table/.content.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/table/.content.xml new file mode 100644 index 0000000000..94b7b43b75 --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/table/.content.xml @@ -0,0 +1,8 @@ + + diff --git a/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/table/_cq_template.xml b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/table/_cq_template.xml new file mode 100644 index 0000000000..da8b08472f --- /dev/null +++ b/examples/ui.apps/src/main/content/jcr_root/apps/forms-components-examples/components/form/table/_cq_template.xml @@ -0,0 +1,73 @@ + + + + +
+ + +
+ + + + + + + + + + +
diff --git a/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/table/.content.xml b/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/table/.content.xml new file mode 100644 index 0000000000..7256712059 --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/table/.content.xml @@ -0,0 +1,7 @@ + + diff --git a/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/table/basic/.content.xml b/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/table/basic/.content.xml new file mode 100644 index 0000000000..d727511cdf --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/dam/formsanddocuments/core-components-it/samples/table/basic/.content.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/.content.xml new file mode 100644 index 0000000000..a0ac99e384 --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/.content.xml @@ -0,0 +1,3 @@ + + diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/basic/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/basic/.content.xml new file mode 100644 index 0000000000..b8eba43a5f --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/basic/.content.xml @@ -0,0 +1,93 @@ + + + + + + +
+ + +
+ + + + + + + + + + +
+
+
+
diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/columnwidth/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/columnwidth/.content.xml new file mode 100644 index 0000000000..22bc42ad4a --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/columnwidth/.content.xml @@ -0,0 +1,86 @@ + + + + + + +
+ + + +
+ + + + + +
+
+
+
diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/mergesplit/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/mergesplit/.content.xml new file mode 100644 index 0000000000..ab04372bc4 --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/mergesplit/.content.xml @@ -0,0 +1,102 @@ + + + + + +
+ + + +
+ + + + + + + + + +
+
+
+
diff --git a/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/sorting/.content.xml b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/sorting/.content.xml new file mode 100644 index 0000000000..3274c4a7c6 --- /dev/null +++ b/it/content/src/main/content/jcr_root/content/forms/af/core-components-it/samples/table/sorting/.content.xml @@ -0,0 +1,125 @@ + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + +
+
+
+
diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/af-clientlibs/core-forms-components-runtime-all/.content.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/af-clientlibs/core-forms-components-runtime-all/.content.xml index c484806166..1cda561465 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/af-clientlibs/core-forms-components-runtime-all/.content.xml +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/af-clientlibs/core-forms-components-runtime-all/.content.xml @@ -5,4 +5,4 @@ cssProcessor="[default:none,min:none]" jsProcessor="[default:none,min:none]" categories="[core.forms.components.runtime.all]" - embed="[core.forms.components.runtime.base,core.forms.components.container.v2.runtime,core.forms.components.datePicker.v1.runtime,core.forms.components.textinput.v1.runtime,core.forms.components.numberinput.v1.runtime,core.forms.components.panelcontainer.v1.runtime,core.forms.components.radiobutton.v2.runtime,core.forms.components.text.v1.runtime,core.forms.components.checkboxgroup.v1.runtime,core.forms.components.button.v1.runtime,core.forms.components.image.v1.runtime,core.forms.components.dropdown.v1.runtime,core.forms.components.fileinput.v4.runtime,core.forms.components.accordion.v1.runtime,core.forms.components.tabs.v1.runtime,core.forms.components.wizard.v1.runtime,core.forms.components.verticaltabs.v1.runtime,core.forms.components.recaptcha.v1.runtime,core.forms.components.checkbox.v1.runtime,core.forms.components.fragment.v1.runtime,core.forms.components.switch.v1.runtime,core.forms.components.termsandconditions.v1.runtime,core.forms.components.review.v1.runtime,core.forms.components.scribble.v1.runtime,core.forms.components.datetime.v1.runtime]"/> + embed="[core.forms.components.runtime.base,core.forms.components.container.v2.runtime,core.forms.components.datePicker.v1.runtime,core.forms.components.textinput.v1.runtime,core.forms.components.numberinput.v1.runtime,core.forms.components.panelcontainer.v1.runtime,core.forms.components.radiobutton.v2.runtime,core.forms.components.text.v1.runtime,core.forms.components.checkboxgroup.v1.runtime,core.forms.components.button.v1.runtime,core.forms.components.image.v1.runtime,core.forms.components.dropdown.v1.runtime,core.forms.components.fileinput.v4.runtime,core.forms.components.accordion.v1.runtime,core.forms.components.tabs.v1.runtime,core.forms.components.wizard.v1.runtime,core.forms.components.verticaltabs.v1.runtime,core.forms.components.recaptcha.v1.runtime,core.forms.components.checkbox.v1.runtime,core.forms.components.fragment.v1.runtime,core.forms.components.switch.v1.runtime,core.forms.components.termsandconditions.v1.runtime,core.forms.components.review.v1.runtime,core.forms.components.scribble.v1.runtime,core.forms.components.datetime.v1.runtime,core.forms.components.table.v1.runtime,core.forms.components.tablerow.v1.runtime,core.forms.components.tableheader.v1.runtime]"/> diff --git a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/base/v1/base/_cq_editConfig.xml b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/base/v1/base/_cq_editConfig.xml index fc6d62c32d..7ba376a0b0 100644 --- a/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/base/v1/base/_cq_editConfig.xml +++ b/ui.af.apps/src/main/content/jcr_root/apps/core/fd/components/form/base/v1/base/_cq_editConfig.xml @@ -23,6 +23,68 @@ handler="CQ.FormsCoreComponents.editorhooks.viewQualifiedName" icon="viewSOMExpression" text="View Qualified Name"/> + +