How to rename the nodes in multifield in a numerical order after deleting a node | Community
Skip to main content
Level 2
May 31, 2024
Solved

How to rename the nodes in multifield in a numerical order after deleting a node

  • May 31, 2024
  • 3 replies
  • 1130 views

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

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by HrishikeshKagne

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:

Step 1: Add Custom JavaScript to Your Component

You need to create or update a client library to include the custom JavaScript for your multifield component.

  1. Create/Update Client Library

    • Ensure you have a client library defined for your component. If not, create one under /apps/your-project/clientlibs/your-component.

 

<!-- /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

  • Create a JavaScript file in your client library, for example, multifield-reorder.js.

 

// /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

  • Ensure your dialog includes this client library.

 

<!-- /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> ​

 

Step 2: Deploy and Test

  1. Deploy the changes to your AEM instance.

 

mvn clean install -PautoInstallPackage

 

  1. Test the functionality:

    • Open the dialog of the component with the multifield.
    • Add and remove items from the multifield.
    • Verify that the names of the fields are renumbered correctly after each add/remove action.

 

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.

3 replies

Umesh_Thakur
Community Advisor
Community Advisor
May 31, 2024

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

 

gkalyan
Community Advisor and Adobe Champion
Community Advisor and Adobe Champion
May 31, 2024

@nirmal_kumar1 

There is no out-of-the-box functionality in AEM to automatically rename or reorder the nodes created by a multifield component when nodes are added or removed. The node names are generated sequentially (item0, item1, item2, etc.) based on the order they are created.
 
So, yes you should go with custom js for this.
HrishikeshKagne
Community Advisor
HrishikeshKagneCommunity AdvisorAccepted solution
Community Advisor
June 2, 2024

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:

Step 1: Add Custom JavaScript to Your Component

You need to create or update a client library to include the custom JavaScript for your multifield component.

  1. Create/Update Client Library

    • Ensure you have a client library defined for your component. If not, create one under /apps/your-project/clientlibs/your-component.

 

<!-- /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

  • Create a JavaScript file in your client library, for example, multifield-reorder.js.

 

// /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

  • Ensure your dialog includes this client library.

 

<!-- /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> ​

 

Step 2: Deploy and Test

  1. Deploy the changes to your AEM instance.

 

mvn clean install -PautoInstallPackage

 

  1. Test the functionality:

    • Open the dialog of the component with the multifield.
    • Add and remove items from the multifield.
    • Verify that the names of the fields are renumbered correctly after each add/remove action.

 

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.

Hrishikesh Kagane
Level 2
June 4, 2024

Hi @hrishikeshkagne 

 

This works  fine after few changes made in the class and attributes used in it.

 

Thanks,

Nirmal