Hi,
I'm trying to build a table component from scratch as the existing OOTB table is deprecated for AEM 6.5.
I wanted to include a component inside a table cell and should be able to edit it. For example, I want to include an image component in the last column of the table, I should be able to add it via dialog and edit it in page.
I got to know that it is not possible with the existing Core Text component table structure as RTE plugins would not allow adding a component inside a cell except text input.
So, I tried to add custom dialog with multifield inputs and output the table as below.
<table width="100%" cellspacing="0" cellpadding="1" border="1">
<!--/* Get all child resources */-->
<div data-sly-list.rowsMultifield="${resource.getChildren}">
<div data-sly-test="${rowsMultifield.name == 'rows'}">
<ul data-sly-list.rows="${rowsMultifield.getChildren}">
<tr>
<!--/* Get all child resources */-->
<div data-sly-list.cellMultifield="${rows.getChildren}">
<!--/* Keep only the countries multifield and iterate over its children */-->
<ul data-sly-test="${cellMultifield.name == 'cells'}"
data-sly-list.cell="${cellMultifield.getChildren}">
<div data-sly-test="${properties.headerRow && (rowsList.index == 0)}">
<th>
<sly data-sly-resource="${ 'rows/{0}/cells/{1}/*' @ format=[rows.name,cell.name], resourceType='macnicagwi/components/content/text', decorationTagName='div', cssClassName='header-row'}">
</sly>
</th>
</div>
<div data-sly-test="${properties.headerRow && (rowsList.index != 0) }">
<th data-sly-test="${properties.headerColumn && (cellList.index == 0)}">
<sly data-sly-resource="${ 'rows/{0}/cells/{1}/*' @ format=[rows.name,cell.name], resourceType='macnicagwi/components/content/text', decorationTagName='div', cssClassName='header-column'}">
</sly>
</th>
<td data-sly-test="${properties.headerColumn && (cellList.index != 0)}">
<sly data-sly-resource="${ 'rows/{0}/cells/{1}/*' @ format=[rows.name,cell.name], resourceType=cell.type, decorationTagName='div'}">
</sly>
</td>
<td data-sly-test="${!properties.headerColumn}">
<sly data-sly-resource="${ 'rows/{0}/cells/{1}/*' @ format=[rows.name,cell.name], resourceType=cell.type, decorationTagName='div'}">
</sly>
</td>
</div>
<div data-sly-test="${!properties.headerRow}">
<th data-sly-test="${properties.headerColumn && (cellList.index == 0)}">
<sly data-sly-resource="${ 'rows/{0}/cells/{1}/*' @ format=[rows.name,cell.name], resourceType='macnicagwi/components/content/text', decorationTagName='div', cssClassName='header-column'}">
</sly>
</th>
<td data-sly-test="${properties.headerColumn && (cellList.index != 0)}">
<sly data-sly-resource="${ 'rows/{0}/cells/{1}/*' @ format=[rows.name,cell.name], resourceType=cell.type, decorationTagName='div'}">
</sly>
</td>
<td data-sly-test="${!properties.headerColumn}">
<sly data-sly-resource="${ 'rows/{0}/cells/{1}/*' @ format=[rows.name,cell.name], resourceType=cell.type, decorationTagName='div'}">
</sly>
</td>
</div>
</ul>
</div>
</tr>
</ul>
</div>
</div>
</table>
And this is the dialog
So, the problem is everytime I add a new multifield and click on done, the entire table data is getting refactored to the beginning. All the edited data is getting lost.
How do I retain the data in case if I add a new row or a cell?
OR, in short, how to add a component in a table cell ?@
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @vijay_karthik ,
Here is a tutorial to have a table component and also customising it in AEM :
https://www.youtube.com/watch?v=RRqovsPq5Lo
Please refer the same, let us know if you have any further concerns.
Thanks.
Hi @vijay_karthik ,
Here is a tutorial to have a table component and also customising it in AEM :
https://www.youtube.com/watch?v=RRqovsPq5Lo
Please refer the same, let us know if you have any further concerns.
Thanks.
<!-- /apps/your-project/components/custom-table/custom-table.html -->
<div class="custom-table">
<table>
<thead>
<tr>
<!-- Generate table headers -->
<sly data-sly-use.table="com.example.CustomTable">
<sly data-sly-repeat.header="${table.getHeaders()}">
<th>${header}</th>
</sly>
</sly>
</tr>
</thead>
<tbody>
<!-- Generate table rows and columns based on the provided data -->
<sly data-sly-use.table="com.example.CustomTable">
<sly data-sly-repeat.row="${table.getRows()}">
<tr>
<sly data-sly-repeat.col="${table.getColumns()}">
<td>Row ${row.index + 1}, Col ${col.index + 1}</td>
</sly>
</tr>
</sly>
</sly>
</tbody>
</table>
</div>
Views
Replies
Total Likes
custom-table
└── cq:dialog
├── content
│ └── items
│ └── root
│ ├── jcr:primaryType: nt:unstructured
│ ├── sling:resourceType: cq/gui/components/authoring/dialog
│ └── items
│ └── tab1
│ ├── jcr:primaryType: nt:unstructured
│ ├── sling:resourceType: cq/gui/components/authoring/dialog/tab
│ ├── title: Table Properties
│ └── items
│ └── columns
│ ├── jcr:primaryType: nt:unstructured
│ ├── sling:resourceType: cq/gui/components/authoring/dialog/column
│ ├── items
│ │ └── column
│ │ ├── jcr:primaryType: nt:unstructured
│ │ ├── sling:resourceType: cq/gui/components/authoring/dialog/fieldset
│ │ ├── items
│ │ │ ├── rows
│ │ │ │ ├── jcr:primaryType: nt:unstructured
│ │ │ │ ├── sling:resourceType: cq/gui/components/authoring/dialog/numberfield
│ │ │ │ ├── fieldLabel: Rows
│ │ │ │ ├── name: ./rows
│ │ │ │ ├── allowBlank: false
│ │ │ │ ├── minValue: 1
│ │ │ │ └── xtype: numberfield
│ │ │ ├── columns
│ │ │ │ ├── jcr:primaryType: nt:unstructured
│ │ │ │ ├── sling:resourceType: cq/gui/components/authoring/dialog/numberfield
│ │ │ │ ├── fieldLabel: Columns
│ │ │ │ ├── name: ./columns
│ │ │ │ ├── allowBlank: false
│ │ │ │ ├── minValue: 1
│ │ │ │ └── xtype: numberfield
│ │ │ ├── tableHeaders
│ │ │ │ ├── jcr:primaryType: nt:unstructured
│ │ │ │ ├── sling:resourceType: cq/gui/components/authoring/dialog/multifield
│ │ │ │ ├── fieldLabel: Table Headers
│ │ │ │ └── field
│ │ │ │ ├── jcr:primaryType: nt:unstructured
│ │ │ │ ├── sling:resourceType: cq/gui/components/authoring/dialog/textfield
│ │ │ │ ├── name: ./headers
│ │ │ │ └── allowBlank: false
│ │ └── jcr:primaryType: nt:unstructured
│ └── jcr:primaryType: nt:unstructured
└── jcr:primaryType: nt:unstructured
Java code:
======
package com.example;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import java.util.List;
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class CustomTable {
@Self
private Resource resource;
@ValueMapValue
private int rows;
@ValueMapValue
private int columns;
@ValueMapValue
private List<String> headers;
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
public List<String> getHeaders() {
return headers;
}
}
Views
Replies
Total Likes
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Dialog"
cq:dialogType="floating">
<content jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog">
<items jcr:primaryType="nt:unstructured">
<root jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<tab1 jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/tab" title="Table Properties">
<items jcr:primaryType="nt:unstructured">
<columns jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/column">
<items jcr:primaryType="nt:unstructured">
<column jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/fieldset">
<items jcr:primaryType="nt:unstructured">
<rows jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/numberfield"
fieldLabel="Rows"
name="./rows"
allowBlank="{Boolean}false"
minValue="{Long}1"
xtype="numberfield"/>
<columns jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/numberfield"
fieldLabel="Columns"
name="./columns"
allowBlank="{Boolean}false"
minValue="{Long}1"
xtype="numberfield"/>
<tableHeaders jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/multifield"
fieldLabel="Table Headers">
<field jcr:primaryType="nt:unstructured" sling:resourceType="cq/gui/components/authoring/dialog/textfield"
name="./headers"
allowBlank="{Boolean}false"/>
</tableHeaders>
</items>
</column>
</items>
</columns>
</items>
</tab1>
</items>
</root>
</items>
</content>
</jcr:root>
Views
Replies
Total Likes
<table>
<thead>
<tr class="header-content-row">
<td class="blank-cell"></td>
<td class="table-spacer-column"></td>
<sly data-sly-list.header="${model.addHeaders}">
<sly data-sly-test="${headerList.count < model.headercolumn}">
<th>
<div class="cell-container">
<div class="cell-container--content">
<div class="preline">
${header.headerTitle @ context='html'}
</div>
<div class="headline"></div>
${header.headerContent @ context='html'}
</div>
</div>
</th>
</sly>
</sly>
<td class="table-spacer-column"></td>
</tr>
</thead>
<tbody>
<sly data-sly-repeat.table="${model.addRows}">
<tr class="roundedTop-sm">
<th class="cell-header">
<div class="cell-header--content">
${table.title @ context='html'}
</div>
</th>
<td class="table-spacer-column"></td>
<sly data-sly-list.table="${model.addRows}">
<sly data-sly-test="${tableList.count < model.columns}">
<td>
<div class="cell-container">
<div class="cell-container--content">
${table.content @ context='html'}
</div>
</div>
</td>
</sly>
</sly>
<td class="table-spacer-column"></td>
</tr>
</sly>
</tbody>
</table>
Views
Replies
Total Likes
<table>
<thead>
<tr class="header-content-row">
<td class="blank-cell"></td>
<td class="table-spacer-column"></td>
<sly data-sly-list.header="${model.addHeaders}">
<sly data-sly-test="${headerList.count < model.headercolumn}">
<th>
<div class="cell-container">
<div class="cell-container--content">
<div class="preline">
${header.headerTitle @ context='html'}
</div>
<div class="headline"></div>
${header.headerContent @ context='html'}
</div>
</div>
</th>
</sly>
</sly>
<td class="table-spacer-column"></td>
</tr>
</thead>
<tbody>
<sly data-sly-repeat.row="${model.addRows}">
<tr class="roundedTop-sm">
<th class="cell-header">
<div class="cell-header--content">
${row.title @ context='html'}
</div>
</th>
<td class="table-spacer-column"></td>
<sly data-sly-list.cell="${row.cells}">
<sly data-sly-test="${cellList.count < model.columns}">
<td>
<div class="cell-container">
<div class="cell-container--content">
${cell.content @ context='html'}
</div>
</div>
</td>
</sly>
</sly>
<td class="table-spacer-column"></td>
</tr>
</sly>
</tbody>
</table>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Dialog"
cq:dialogMode="floating">
<content jcr:primaryType="nt:unstructured"
sling:resourceType="cq/gui/components/authoring/dialog">
<items jcr:primaryType="nt:unstructured">
<tabs jcr:primaryType="nt:unstructured"
sling:resourceType="cq/gui/components/authoring/dialog/tabs">
<items jcr:primaryType="nt:unstructured">
<properties jcr:primaryType="nt:unstructured"
jcr:title="Properties"
sling:resourceType="cq/gui/components/authoring/dialog/tab">
<items jcr:primaryType="nt:unstructured">
<!-- Header Configuration -->
<headercolumn jcr:primaryType="nt:unstructured"
fieldLabel="Number of Header Columns"
name="./headercolumn"
sling:resourceType="cq/gui/components/authoring/dialog/numberfield"
allowBlank="{Boolean}false"
minValue="1"/>
<addHeaders jcr:primaryType="nt:unstructured"
fieldLabel="Table Headers"
name="./addHeaders"
sling:resourceType="cq/gui/components/authoring/dialog/multifield">
<field jcr:primaryType="nt:unstructured"
sling:resourceType="cq/gui/components/authoring/dialog/compositefield">
<items jcr:primaryType="nt:unstructured">
<headerTitle jcr:primaryType="nt:unstructured"
fieldLabel="Header Title"
name="./headerTitle"
sling:resourceType="cq/gui/components/authoring/dialog/textfield"
allowBlank="{Boolean}false"/>
<headerContent jcr:primaryType="nt:unstructured"
fieldLabel="Header Content"
name="./headerContent"
sling:resourceType="cq/gui/components/authoring/dialog/textfield"
allowBlank="{Boolean}true"/>
</items>
</field>
</addHeaders>
<!-- Row Configuration -->
<columns jcr:primaryType="nt:unstructured"
fieldLabel="Number of Columns"
name="./columns"
sling:resourceType="cq/gui/components/authoring/dialog/numberfield"
allowBlank="{Boolean}false"
minValue="1"/>
<addRows jcr:primaryType="nt:unstructured"
fieldLabel="Table Rows"
name="./addRows"
sling:resourceType="cq/gui/components/authoring/dialog/multifield">
<field jcr:primaryType="nt:unstructured"
sling:resourceType="cq/gui/components/authoring/dialog/compositefield">
<items jcr:primaryType="nt:unstructured">
<title jcr:primaryType="nt:unstructured"
fieldLabel="Row Title"
name="./title"
sling:resourceType="cq/gui/components/authoring/dialog/textfield"
allowBlank="{Boolean}false"/>
<cells jcr:primaryType="nt:unstructured"
fieldLabel="Cells"
name="./cells"
sling:resourceType="cq/gui/components/authoring/dialog/multifield">
<field jcr:primaryType="nt:unstructured"
sling:resourceType="cq/gui/components/authoring/dialog/textfield"
name="./content"
fieldLabel="Cell Content"
allowBlank="{Boolean}false"/>
</cells>
</items>
</field>
</addRows>
</items>
</properties>
</items>
</tabs>
</items>
</content>
</jcr:root>
Views
Replies
Total Likes
Views
Likes
Replies