Article summary

Summary

Discusses how to create a custom HTL Tab component. This article uses Bootstrap and also describes how to use the HTL JavaScript Use-API. In this example, the JS logic parses a Multi-field component.   

A special thank you to Prince Shivhare for contributing code used in this community article. 

Also, thank you to Ratna Kumar Kotla for testing this article to ensure it works. 

Digital Marketing Solution(s) Adobe Experience Manager 6.3
Audience Developer
Required Skills HTML, JavaScript
Version 6.3

Note:

You can download an AEM package that contains the code used in this article. Download the package and deploy using package manager. The purpose of this code is to show the community these concepts in action. That is, it's to illustrate how to write a HTL Tab component that lets an author set various options. This community code is for teaching purposes only and not meant to go into production as is.

Once you install this package, you can add the component to a site like We Retail as shown in the video at the end of this article. 

Download

Note:

To ensure that the Multifield works in the component dialog, also install the ACS-Commons for AEM 6.3 located here: https://adobe-consulting-services.github.io/acs-aem-commons/. Otherwise, the Multi-field dialog will not store values. 

Introduction

You can create an Adobe Experience Manager HTL component that displays data within a tab layout style. By developing a tab layout component, you can organize your data under tabs. That is, a web site visitor can click on a tab on the web page to see different data set. Tab components are located in web-sites, such as the following one that shows sports data. 

tab
An example of a tab component displaying sports data

The following illustration shows the component that is developmented in this article. Notice the following illustration displays an AEM component with four tab headings: Home Page, Career Section, Contact Us, and About US.

 

client
An Experience Manager Tab Layout component

An author can set different values such as Tab headings and Tab content by using the component dialog, as shown in this illustration. 

dialog
The Tab Component dialog

The following list describes the dialog fields:

  • Tab Id - specifies the unique identifier of the tab 
  • Tab Heading - specifies the text value located in the Tab heading 
  • Tab Description - specifies the text that appears when the user clicks the tab

The Banner component built in this article uses the Bootstrap library. For information, see Bootstrap.

Create an AEM application folder structure

Create an AEM application folder structure that contains templates, components, and pages by using CRXDE Lite.  

struc
The JCR Folder Structure

The following describes each application folder:

  • application name (sightlymf): contains all of the resources that an application uses. The resources can be templates, pages, components, and so on.
  • components: contains components that your application uses.
  • page: contains page components. A page component is a script such as a JSP file.
  • content: contains content usch as components.
  • template: contains templates on which you base page components.

To create an application folder structure:

  1. Go to CRXDE Lite at http://localhost:4502/crx/de/index.jsp.
  2. Right-click the apps folder (or the parent folder), select Create, Create Folder.
  3. Enter the folder name into the Create Folder dialog box. Enter sightlymf.
  4. Repeat steps 1-4 for each folder specified in the previous illustration.
  5. Click the Save All button.

Create an Experience Manager Template

You can create a static template by using CRXDE Lite (as opposed to an editable template). An Experience Manager template enables you to define a consistent style for the pages in your application. A template comprises of nodes that specify the page structure. For more information about templates, see Templates.

To create a template, perform these tasks:

1. Go to CRXDE Lite at http://localhost:4502/crx/de/index.jsp#.

2. Right-click the template folder (within your application), select Create, Create Template.

3. Enter the following information into the Create Template dialog box:

  • Label: The name of the template to create. Enter templateSightlyMF.
  • Title: The title that is assigned to the template.
  • Description: The description that is assigned to the template.
  • Resource Type: The component's path that is assigned to the template and copied to implementing pages. Enter /apps/sightlymf/components/page/templateSightlyMF.
  • Ranking: The order (ascending) in which this template will appear in relation to other templates. Setting this value to 1 ensures that the template appears first in the list.

4. Add a path to Allowed Paths. Click on the plus sign and enter the following value: /content(/.*)?.

5. Click Next for Allowed Parents.

6. Select OK on Allowed Children.

Create the page component based on the template

Components are re-usable modules that implement specific application logic to render the content of your web site. You can think of a component as a collection of scripts (for example, JSPs, Java servlets, and so on) that completely realize a specific function. In order to realize this functionality, it is your responsibility as a CQ developer to create scripts that perform specific functionality. For more information about components, see Components.

By default, a component has at least one default script, identical to the name of the component. To create a render component, perform these tasks:

1. Go to CRXDE Lite at http://localhost:4502/crx/de/index.jsp#.

2. Right-click http://localhost:4502/crx/de/index.jsp#/apps/sightlymf/components/page, then select Create, Create Component.

3. Enter the following information into the Create Component dialog box:

  • Label: The name of the component to create. Enter templateSightlyMF.
  • Title: The title that is assigned to the component.
  • Description: The description that is assigned to the template.
  • Super Type: foundation/components/page 

4. Select Next for Advanced Component Settings and Allowed Parents.

5. Select OK on Allowed Children.

6. Open the templateSightlyMF.jsp located at: /apps/sightlymf/components/page/templateSightlyMF/templateSightlyMF.jsp.

7. Enter the following HTML code.

<html>
<%@include file="/libs/foundation/global.jsp" %>
<cq:include script="/libs/wcm/core/components/init/init.jsp"/>
<body>
<h1>Here is where your Touch UI component will go</h1>
<cq:include path="par" resourceType="foundation/components/parsys" />
</body>
</html>

Create the Experience Manager Tab Component

To create the Tab component, perform these tasks using CRXDE Lite:

1. Right click on After you setup the AEM folder structure, create the AEM Touch UI component. Perform these tasks using CRXDE Lite:

1. Right click on /apps/sightlymf/components/content and then select New, Component.

2. Enter the following information into the Create Component dialog box:

  • Label: The name of the component to create. Enter TabComponent
  • Title: The title that is assigned to the component. Enter TabComponent.
  • Description: The description that is assigned to the component.
  • Super Resource Type: Enter foundation/components/parbase.
  • Group: The group in the side rail or side kick where the component appears. Enter sightlymf

3. Click Ok.

Change the file extention of  /apps/sightlymf/components/content/TabComponent/TabComponent.jsp to .HTML. Next, add the following code to TabComponent.html.

<div class="cq-placeholder section" data-emptytext="Tab Component"></div>

	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


<div class="container">
	<h2>${properties.heading}</h2>
		
		<sly data-sly-use.convertToJSON="${'script.js'}">
			<ul class="nav nav-tabs">
				<sly data-sly-list.multival="${convertToJSON.proposerObjs}" data-sly-unwrap>
						<li><a data-toggle="tab" href="#${multival.tabId}">${multival.tabHeading}</a></li>
				</sly>
			</ul>
			<div class="tab-content">
				<sly data-sly-list.multival1="${convertToJSON.proposerObjs}" data-sly-unwrap>
					<div id="${multival1.tabId}" class="tab-pane fade">
						<h3>${multival1.tabname}</h3>
						${multival1.first}
						<p><div data-sly-resource="${'item{0}' @ format=multival1List.count, resourceType='wcm/foundation/components/parsys'}" data-sly-unwrap></div></p>
					</div>
				</sly>
			</div>
		</sly>
</div>

Note:

Notice that the bootstrap library is included using this line of code: 

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

In this example, notice:

<sly data-sly-use.convertToJSON="${'script.js'}">

data-sly-use.convertToJSON references the JavaScript located in script.js that is located at /apps/sightlymf/components/content/TabComponent/script.js. If you did not install the package, make sure you create this file and add the following code.

In this script file, notice this function.  

 

use(function () {

	var proposerMap = [];

	var tempProposerMap = properties.subscriptionmulti;

	try{
		if (typeof tempProposerMap === 'string' || tempProposerMap instanceof String){
			var item = tempProposerMap;
			 item = JSON.parse(item);
			if(item.hasOwnProperty("multivalues")){
                for(var cnt in item.multivalues) {
                    item.multivalues[cnt] = JSON.parse(item.multivalues[cnt]);
                }
            }
			proposerMap.push(item)
		}
	}catch(e){
		for(var i in tempProposerMap) {
			var item = tempProposerMap[i];
			 item = JSON.parse(item);
			if(item.hasOwnProperty("multivalues")){
                for(var cnt in item.multivalues) {
                    item.multivalues[cnt] = JSON.parse(item.multivalues[cnt]);
                }
            }
			proposerMap.push(item)
		}
	}

		return {
			proposerObjs : proposerMap

		};
	});

This is how you handle a multifield located in the component dialog by using JavaScript. Notice this line of code: 

var tempProposerMap = properties.subscriptionmulti;

This is referencing the node located here: 

/apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field

The rest of the code parses that values from the multifield and places them into an Array named proposerMap. 

Note:

For more information about the JS USE API, see the HTL Specification

Build the Component dialog

Use CRXDE Lite to develop the Tab component dialog so it resembles the following illustration. 

jcrdialog
JCR Nodes that create a Touch UI dialog. The multi-field node is shown

Note:

If you install the package at the start of this article, then you do not need to create the dialog by following this procedure. 

Build the Touch UI dialog by performing these tasks:

1. Select /apps/sightlymf/components/content/TabComponent.

2. Right click and select Create, Create Node.

3. Enter the following values:

  • Name: cq:dialog
  • Type: nt:unstructured

4. Add the following property to the cq:dialog node.

  • sling:resourceType (String) - cq/gui/components/authoring/dialog

5. Select /apps/sightlymf/components/content/TabComponent/cq:dialog.

6. Right click and select Create, Create Node. Enter the following values:

  • Name: content
  • Type: nt:unstructured

7. Add the following properties to the content node.

  • sling:resourceType (String) - granite/ui/components/foundation/container

8. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content.

9. Right click and select Create, Create Node. Enter the following values:

  • Name: layout
  • Type: nt:unstructured

10. Add the following properties to the layout node.

  • sling:resourceType (String) - granite/ui/components/foundation/layouts/fixedcolumns

11. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content.

12. Right click and select Create, Create Node. Enter the following values:

  • Name: items
  • Type: nt:unstructured

13. Click on the following node:/apps/sightlymf/components/content/TabComponent/cq:dialog/content/items.

14. Right click and select Create, Create Node.

15. Enter the following values:

  • Name: column
  • Type: nt:unstructured

16. Add the following property to the currentissue node.

  • sling:resourceType (String) - granite/ui/components/foundation/container

17. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column.

18. Right click and select Create, Create Node.

19. Enter the following values:

  • Name: items
  • Type: nt:unstructured

20. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items.

21. Right click and select Create, Create Node.

22. Enter the following values:

  • Name: fieldset
  • Type: nt:unstructured

23. Add the following propery to this node: 

  • sling:resourceType (String) - granite/ui/components/foundation/form/fieldset

24. Click on the following node: /apps/sightlymf/components/content/Tabomponent/cq:dialog/content/items/column/items/fieldset.

25. Right click and select Create, Create Node.

  • Name: layout
  • Type: nt:unstructured

26. Add the following property to this node.

sling:resourceType (String) - granite/ui/components/foundation/layouts/fixedcolumns


27. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset.

28. Right click and select Create, Create Node.

29. Enter the following values:

  • Name: items
    Type: nt:unstructured

30. Click on the following node:/apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items.

31. Right click and select Create, Create Node.

32. Enter the following values:

  • Name: column
  • Type: nt:unstructured

33. Add the following property to this node.

  • sling:resourceType (String) - granite/ui/components/foundation/container


34. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column.

35. Right click and select Create, Create Node.

36. Enter the following values:

  • Name: items
  • Type: nt:unstructured

37. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items.

38. Right click and select Create, Create Node.

39. Enter the following values:

  • Name: heading
  • Type: nt:unstructured

40. Add the following properties to this node.

  • fieldDescription(String) - Tab Heading
  • fieldLabel (String) - Heading
  • sling:resourceType (String) - granite/ui/components/foundation/form/textfield
  • name (String) - ./heading

41. Click on the following node: /apps/sightlymf/components/content/bannerComponent/cq:dialog/content/items/column/items/fieldset/items/column/items.

42. Right click and select Create, Create Node.

43. Enter the following values:

  • Name: well 2
  • Type: nt:unstructured

44. Add the following properties to this node.

  • sling:resourceType (String) - granite/ui/components/foundation/container

45. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2.

46. Right click and select Create, Create Node.

47. Enter the following values:

  • Name: layout
  • Type: nt:unstructured

48. Add the following properties to this node.

  • sling:resourceType (String) - granite/ui/components/foundation/layouts/well

49. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2.

50. Right click and select Create, Create Node.

51. Enter the following values:

  • Name: items
  • Type: nt:unstructured

53. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/.

54. Right click and select Create, Create Node.

55. Enter the following values:

  • Name: category
  • Type: nt:unstructured

56. Add the following properties to this node (this node represents the multifield).

  • class (String) - full-width
  • fieldLabel (String) - Tab Information
  • sling:resourceType (String) - granite/ui/components/foundation/form/multifield

57. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category.

58. Right click and select Create, Create Node.

59. Enter the following values:

  • Name: field
  • Type:  nt:unstructured

60. Add the following properties to this node.

  • acs-commons-nested (String) - "" (empty string)
  • name (String) - ./subscriptionmulti (this value is referenced in the JS Script)
  • sling:resourceType (String) - granite/ui/components/foundation/form/fieldset

61. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field.

62. Right click and select Create, Create Node.

63. Enter the following values:

  • Name: layout
  • Type: nt:unstructured

64. Add the following properties to this node.

  • method (String) - absolute
  • sling:resourceType (String) - granite/ui/components/foundation/layouts/fixedcolumns

65. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field.

66. Right click and select Create, Create Node.

67. Enter the following values:

  • Name: items
  • Type: nt:unstructured

68. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field/items.

69. Right click and select Create, Create Node.

70. Enter the following values:

  • Name: column
  • Type: nt:unstructured

71. Add the following properties to this node.

  • sling:resourceType (String) - granite/ui/components/foundation/container

72. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field/items/column.

73. Right click and select Create, Create Node.

74. Enter the following values:

  • Name: items
  • Type: nt:unstructured

75. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field/items/column/items.

76. Right click and select Create, Create Node.

77. Enter the following values:

  • Name: desc
  • Type: nt:unstructured

78. Add the following properties to this node.

  • fieldLabel (String) - Tab Id
  • name (String) - ./tabId
  • sling:resourceType (String) - granite/ui/components/foundation/form/textfield

79. Click on the following node: /apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field/items/column/items.

80. Right click and select Create, Create Node.

81. Enter the following values:

  • Name: tabhead
  • Type: nt:unstructured

82. Add the following properties to this node.

  • fieldLabel (String) - Tab Heading
  • name (String) - ./tabHeading
  • sling:resourceType (String) - granite/ui/components/foundation/form/textfield

83. Click on the following node:
/apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field/items/column/items.

84. Right click and select Create, Create Node.

85. Enter the following values:

  • Name: tabname
  • Type: nt:unstructured

86. Add the following properties to this node.

  • fieldLabel (String) - Tab Description
  • name (String) - ./tabname
  • sling:resourceType (String) - granite/ui/components/foundation/form/textfield

Note:

To use acs commons multifield, it is mandatory to add acs-commons-nested=”” property to a fieldset within a multifield node like at ./subscriptionmulti node in our example (/apps/sightlymf/components/content/TabComponent/cq:dialog/content/items/column/items/fieldset/items/column/items/well 2/items/category/field).

The value acs-commons-nested=”JSON_STORE” means we want to store multifiled data as JSON Array. To store multi filed data as seperate child node use acs-commons-nested=”NODE_STORE”.

Read more at AEMCQ5Tutorials: Create TouchUI Multifield Component using HTL.

View the Tab Component within an Experience Manager page

To access the component, enter the following URL:

http://localhost:4502/editor.html/content/we-retail/us/en.html (after your installed the package)

Drag the Tab  Component BootStrap component into the page.

client
The Tab component displayed in an AEM Web page

If you drag the Banner component onto a new page, you will see this before you set the values in the component dialog. 

dandd
The Tab component without the dialog values set

Click on the component to access the Touch UI dialog and enter values into the multifield, as shown in this video.


Note:

To use the Tab  Component BootStrap component in a We Retail page, make sure you edit the policy in Hero Page template located here: http://localhost:4502/libs/wcm/core/content/sites/templates.html/conf/we-retail.

See also

Join the AEM community at: Adobe Experience Manager Community

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License  Twitter™ and Facebook posts are not covered under the terms of Creative Commons.

Legal Notices   |   Online Privacy Policy