Expand my Community achievements bar.

Parsys node in content node based on user selection

Avatar

Community Advisor

IMG_3392.jpeg

 we have a specific use can where we have to provide the parsys placeholder from 1 to 12 based on user selection. Problem o am facing here is that I have to create a 12 node in aem dialog to hold the parsys in sling resource and even authors select 2 placeholder for oarsys the nodes created inside content node is still 12. Is there a way a to control this parsys node number limiting to the number selected by author just the way core tabs component works. I don’t want to write any backend code to achieve this.

All suggestions and feedback are welcomed.

thanks

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

8 Replies

Avatar

Level 8

The primary concern regarding the requirements is that each parsys must have a unique name in order to function correctly. In theory, you could utilize data-sly-list if you are certain that you can list at least 12 child pages.

<!--/* Iteration control; start from the beginning, stop after the first 12 elements (index 11) */-->
<div data-sly-list="${currentPage.listChildren @ begin = 0, end = 11}">
    <div >${item.title.hashCode @ resourceType='wcm/foundation/components/parsys', prependPath='parsys-'}</div>
</div>

However, I've encountered issues with the prependPath directive in the past, so I can't recommend using it.

 

Alternatively, you can create a straightforward Sling Model with a getter method.

// Sling model
public List<String > getParsys() {
	IntStream.range(0, Integer.valueOf(numberOfPlaceholders)).boxed().map(value -> "par-"+ value).collect(Collectors.toList());
}

// HTL
<div data-sly-list="${model.parsys}">
    <div data-sly-resource="${ item @ resourceType='wcm/foundation/components/parsys'}"/>
</div>

 

Or you can use a static approach where you write all 12 data-sly-resource:

    
    <!--/* Generate parsys components based on numberOfPlaceholders */-->
    <div data-sly-test="${numberOfPlaceholders >= 1}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_1' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 2}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_2' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 3}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_3' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 4}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_4' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 5}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_5' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 6}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_6' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 7}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_7' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 8}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_8' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 9}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_9' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 10}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_10' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 11}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_11' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>
    
    <div data-sly-test="${numberOfPlaceholders >= 12}" class="placeholder-container">
        <div data-sly-resource="${ 'parsys_12' @ resourceType='wcm/foundation/components/parsys'}"></div>
    </div>

 

Avatar

Community Advisor

Problem is not with creating 12 parsys. I don’t want my component to create 12 node for parsys in the the content node once drag and dropped if user has selected to have only 3 parsys. It should only create 3 nodes.

Avatar

Level 8

In my previous "static" example, no parsys will render unless the editor selects the desired count because each uses data-sly-test wrapping.


Consider this: What happens when a user reduces the number of configured parsys? For example, if they initially configure four, then later they change it to two, parsys three and four will remain unless custom code removes these unused child nodes. Highly configurable components can create deeply nested, yet unused, content trees. This should be considered during design and implementation.

 
 
 

Avatar

Community Advisor

That’s my ask is how to get rid of unused content nodes without writing custom code to delete the node. For example the way core Tab components work. Is there a way to achieve something similar to core Tabs components 

Avatar

Level 8

When you edit the Tabs component, a POST request is sent, which triggers a servlet. Pay attention to the use of the parameter PARAM_DELETED_CHILDREN. You could use this class as starting point.

If you prefer not to write custom code for deletion or ordering, you can extend the Tabs component by starting with your own HTML instead of using tabs.html. Your component does not require tab panels so you can omit the <ol> HTML tag. If you decide to follow this route, please pay attention to the section JavaScript Data Attribute Bindings to enable initialization of the related JS. 

Avatar

Community Advisor

Extending tabs component is not going to be feasible in my use case as tabs component uses childreneditor component as resource type and they provide the allowed component list for parsys to be configured on tabs dialog but in mine use case I only need to provide parsys not any components. I don’t want to reengineer everything on tabs component. In existing tabs component they are creating a form with action value as path to the content node where component is authored. I don’t think you can create a node with front end code and am not able to find the service that they are calling to create an items node in jcr path. Wondering if I can directly call that service or servlet with my list of parameter to achieve this?

Tabs component was only for reference to achieve the dynamic creation of nodes in jcr path based on authored value 

Avatar

Administrator

@DPrakashRaj Did you find the suggestion helpful? Please let us know if you need more information. If a response worked, kindly mark it as correct for posterity; alternatively, if you found a solution yourself, we’d appreciate it if you could share it with the community. Thank you!



Kautuk Sahni

Avatar

Community Advisor

No, this is not what I am looking for. I am looking for a way to create parsys node in jcr based on user selection and not the number of parsys node created in dialog. For reference Tabs component or layout foundation component. Extending a tab component is not going to work for me because of multiple reasons as their functionality is totally different from what I am looking for and extending tab component for my use case requires lots of re-engineering that I am already aware of. May be any hint on how the core tab is doing it for the reference and feasibility of just calling the service that is responsible for managing the parsys node in jcr dynamically based on selection.