I've been trying to edit a Table component in place (without needing to open the dialog), for i.e.: add new rows or columns.
The component has its dialog properly configured, so you can select the number of columns and rows from there, although to improve the UX I've added a button next to the table that's only visible in edit mode to add a new row programatically from the clientlib.edit javascript. But don't know what's the way to actually persist the data (save changes).
Any ideas that could take me on the right path will be massively appreciated!
One possible solution is 3 component based -
To achieve the '+' sign functionality and persistence do following -
Create a cq:ClientLibraryFolder
and specify its property categories="cq.authoring.dialog"
, to this client library add JS as -
/* global Granite, $ */
$(document).on('cq-page-info-loaded', function() {
'use strict';
// initialisation for Mysite
window.mysite = window.mysite || {};
window.mysite.app = window.mysite.app || {};
window.mysite.app.auth = window.mysite.app.auth || {};
(function(window, ns, undefined) {
/**
* Adds a child component of a specified type to a parent editable component.
* (event handler for clicking the 'add' button in the edit interface on the sections or questions component)
*
* @param {Granite.author.Editable} parentEditable The editable parent component
* @param {string} componentName Name of the child component to add e.g. 'mysite-app/ui/components/content/link'
* @param {boolean} componentTemplate If true, call the low level interface directly. If false, call higher level Granite.author.edit methods.
*/
var createChildComponent = function(parentEditable, componentName, componentTemplate) {
return (
new ns.persistence.PostRequest()
.prepareCreateParagraph({
resourceType: componentName,
parentPath: parentEditable.path,
relativePosition: 'last',
templatePath: componentTemplate
})
.send()
).done(function() {
parentEditable.refresh();
});
};
window.mysite.app.auth.component = (function() {
return {
tablerow: {
add: function(editable) {
createChildComponent(editable, '/apps/mysite-app/ui/components/<path to row component>', false);
}
},
rowcell: {
add: function(editable) {
createChildComponent(editable, '/apps/mysite-app/ui/components/<path to column cell>', false);
}
}
};
})();
})(window, Granite.author);
});
Next is to setup your actionConfigs
in editConfig
for individual components and point it to the above script's handler.
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
cq:actions="[edit,delete]"
jcr:primaryType="cq:EditConfig">
<cq:actionConfigs jcr:primaryType="nt:unstructured">
<addCell
jcr:primaryType="nt:unstructured"
handler="mysite.app.auth.component.rowcell.add"
icon="coral-Icon--add"
text="Add column to table row"/>
</cq:actionConfigs>
</jcr:root>
On your component editbar you will start seeing the '+' sign that allows you to add configured component and persist its node(s).
Refer here to add custom action to edit bar if you need more details.
In case you dont want to follow this approach, the first script has the logic that allows you to persist the component nodes, you can reuse it and embed it in your own implementation.