Hi All,
I have a multifield component and saving the node value based on the highest index but i have the problem let us assume we have three nodes (field_0, field_1, field_2) at the time, we are removing the 2nd node and try to add one more node, at this time its saving as field_3 but i need as field_2.
Also when a node is deleted, it should rearrange or rename the nodes and provide it in a numerical order as field_0, field_1, field_2.
Do we need to make this through custom js or do we have any AEM default functionality to fix this.
All suggestions are welcome.
Thanks in advance!!
Nirmal
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @Nirmal_Kumar1 ,
To achieve renaming nodes in a multifield component to maintain numerical order after deleting a node, you will need to implement custom JavaScript as AEM does not provide built-in functionality to handle this automatically.
Here is a step-by-step approach to implement this custom JavaScript solution:
You need to create or update a client library to include the custom JavaScript for your multifield component.
Create/Update Client Library
<!-- /apps/your-project/clientlibs/your-component/.content.xml -->
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
categories="[your-component-category]"
dependencies="[cq.jquery]"/>
Include JavaScript File
// /apps/your-project/clientlibs/your-component/multifield-reorder.js
(function ($, document) {
"use strict";
// Function to renumber the multifield items
function renumberMultifieldItems(multifield) {
multifield.children('.coral-Multifield-item').each(function (index, element) {
var item = $(element);
var oldName = item.find("[data-cq-multifield-item-name]").attr("data-cq-multifield-item-name");
if (oldName) {
var newName = oldName.replace(/field_\d+/, 'field_' + index);
item.find("[data-cq-multifield-item-name]").attr("data-cq-multifield-item-name", newName);
item.find("input, textarea, select").each(function () {
var input = $(this);
var inputName = input.attr("name");
if (inputName) {
inputName = inputName.replace(/field_\d+/, 'field_' + index);
input.attr("name", inputName);
}
});
}
});
}
// Event listener for multifield add/remove actions
$(document).on('click', '.coral-Multifield-add, .coral-Multifield-remove', function () {
var multifield = $(this).closest('.coral-Multifield');
setTimeout(function () {
renumberMultifieldItems(multifield);
}, 500); // Slight delay to allow the DOM to update
});
})(jQuery, document);
Include the JavaScript in the Dialog
<!-- /apps/your-project/components/your-component/_cq_dialog/.content.xml -->
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
jcr:primaryType="nt:unstructured"
cq:dialogMode="floating"
jcr:title="Your Component"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<yourField
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
fieldLabel="Your Multifield">
<field jcr:primaryType="nt:unstructured" name="./yourField">
<items jcr:primaryType="nt:unstructured">
<!-- Your multifield item configuration -->
</items>
</field>
</yourField>
</items>
</content>
<cq:clientlibs
jcr:primaryType="cq:ClientLibrary"
categories="[your-component-category]"/>
</jcr:root>
Deploy the changes to your AEM instance.
mvn clean install -PautoInstallPackage
Test the functionality:
By adding this custom JavaScript to your AEM project, you ensure that the fields within the multifield are renumbered correctly after an item is removed, preventing gaps in the numbering sequence. This approach ensures a consistent and predictable order for the multifield items.
As far as I understand your requirement is, you have saved a dialog with multifield, on save it creates some node for all the authored multifield data as node_1, node_2 and so on so you have deleted one node then again saving it so why it is not creating a node as perviously deleted node name right?
If this is so called issue you are facing, before answering your question, can you please tell me why this is an issue for you to have different node name ?
Ideally any node name should be fine, as reading data from multifield we do the node iteration. If you have any logic to do some operation on node name then this is going to be a big problem for you as you don't have control on it. AEM will put any name for nodes.
For node deletion you should take help from Java api but it should be used with extra care.
Hope this helps
Umesh Thakur
Hi @Nirmal_Kumar1 ,
To achieve renaming nodes in a multifield component to maintain numerical order after deleting a node, you will need to implement custom JavaScript as AEM does not provide built-in functionality to handle this automatically.
Here is a step-by-step approach to implement this custom JavaScript solution:
You need to create or update a client library to include the custom JavaScript for your multifield component.
Create/Update Client Library
<!-- /apps/your-project/clientlibs/your-component/.content.xml -->
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
categories="[your-component-category]"
dependencies="[cq.jquery]"/>
Include JavaScript File
// /apps/your-project/clientlibs/your-component/multifield-reorder.js
(function ($, document) {
"use strict";
// Function to renumber the multifield items
function renumberMultifieldItems(multifield) {
multifield.children('.coral-Multifield-item').each(function (index, element) {
var item = $(element);
var oldName = item.find("[data-cq-multifield-item-name]").attr("data-cq-multifield-item-name");
if (oldName) {
var newName = oldName.replace(/field_\d+/, 'field_' + index);
item.find("[data-cq-multifield-item-name]").attr("data-cq-multifield-item-name", newName);
item.find("input, textarea, select").each(function () {
var input = $(this);
var inputName = input.attr("name");
if (inputName) {
inputName = inputName.replace(/field_\d+/, 'field_' + index);
input.attr("name", inputName);
}
});
}
});
}
// Event listener for multifield add/remove actions
$(document).on('click', '.coral-Multifield-add, .coral-Multifield-remove', function () {
var multifield = $(this).closest('.coral-Multifield');
setTimeout(function () {
renumberMultifieldItems(multifield);
}, 500); // Slight delay to allow the DOM to update
});
})(jQuery, document);
Include the JavaScript in the Dialog
<!-- /apps/your-project/components/your-component/_cq_dialog/.content.xml -->
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
jcr:primaryType="nt:unstructured"
cq:dialogMode="floating"
jcr:title="Your Component"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<yourField
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
fieldLabel="Your Multifield">
<field jcr:primaryType="nt:unstructured" name="./yourField">
<items jcr:primaryType="nt:unstructured">
<!-- Your multifield item configuration -->
</items>
</field>
</yourField>
</items>
</content>
<cq:clientlibs
jcr:primaryType="cq:ClientLibrary"
categories="[your-component-category]"/>
</jcr:root>
Deploy the changes to your AEM instance.
mvn clean install -PautoInstallPackage
Test the functionality:
By adding this custom JavaScript to your AEM project, you ensure that the fields within the multifield are renumbered correctly after an item is removed, preventing gaps in the numbering sequence. This approach ensures a consistent and predictable order for the multifield items.
This works fine after few changes made in the class and attributes used in it.
Thanks,
Nirmal
Views
Replies
Total Likes
Views
Likes
Replies