Quantcast
Channel: Experiencing Adobe Experience Manager (AEM, CQ)
Viewing all articles
Browse latest Browse all 525

AEM CQ 56 - Extend Combo Box (CQ.Ext.form.ComboBox) Widget

$
0
0

Goal


This post is about extending the CQ Combo Box (CQ.Ext.form.ComboBox) widget to provide simple hierarchical (2-level) content. It also has a sample Sling Servlet to retrieve users and groups from CRX as json. Source code and video are available for download

Here is a screenshot and demo







Prerequisites


If you are new to CQ

1) Read this post on how to create a sample page component

2) Read this post on how to setup your IDE and create an OSGI component

Create Servlet


1) Create and deploy servlet to read users and groups from CRX. Here the servlet RepoGroupsUsers ( deployed as OSGI component ) returns the groups and users in json response.

package com.mycomponents.groupsusers;

import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.jackrabbit.api.security.user.*;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.io.JSONWriter;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Session;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Iterator;

@SlingServlet(
paths="/bin/mycomponents/groupsusers",
methods = "GET",
metatype = true,
label = "Groups and Users Servlet"
)
public class RepoGroupsUsers extends SlingAllMethodsServlet {
private static final long serialVersionUID = 1L;

private static final Logger LOG = LoggerFactory.getLogger(RepoGroupsUsers.class);

@Override
protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");

try{
ResourceResolver resolver = request.getResourceResolver();
Session session = resolver.adaptTo(Session.class);

UserManager um = AccessControlUtil.getUserManager(session);
JSONWriter jw = new JSONWriter(response.getWriter());

Group group = null;
User user = null; Object obj = null;String id = null;

Iterator<Authorizable> users, groups = um.findAuthorizables(new Query() {
public void build(QueryBuilder builder) {
builder.setSelector(Group.class);
}
});

jw.object();
jw.key("data").array();

while(groups.hasNext()){
group = (Group)groups.next();

jw.object();
jw.key("id").value(group.getID());
jw.key("text").value(group.getPrincipal().getName());
jw.key("group").value("y");
jw.endObject();

users = group.getMembers();

while(users.hasNext()){
obj = users.next();

if(!(obj instanceof User)){
continue;
}

user = (User)obj;
id = user.getID();

if(id.contains("@")){
id = id.substring(0, id.indexOf("@"));
}

jw.object();
jw.key("id").value(id);
jw.key("text").value(user.getPrincipal().getName());
jw.endObject();
}
}

jw.endArray();
jw.endObject();
}catch(Exception e){
LOG.error("Error getting groups and users",e);
throw new ServletException(e);
}
}
}

2) Install ( this post explains how-to ) the servlet; you should see folder /apps/groupsuserscombo/install created in CRXDE Lite (http://localhost:4502/crx/de) with the bundle jar

3) Access the servlet in browser with url http://localhost:4502/bin/mycomponents/groupsusers; groups and users in CRX repository ( under /home ) are returned in json response

Create Component


1) Create the component (of type cq:Component) /apps/groupsuserscombo/groupsuserscombo with following properties



2) Create clientlib /apps/groupsuserscombo/groupsuserscombo/clientlib of type cq:ClientLibraryFolder with the following properties



3) Create file /apps/groupsuserscombo/groupsuserscombo/clientlib/combo.js and add the following code. Here we are creating a combo extension and registering it as xtype stepcombo

var MyClientLib = MyClientLib || {};

MyClientLib.StepCombo = CQ.Ext.extend(CQ.Ext.form.ComboBox, {
constructor: function(config){
config = config || {};

config.store = new CQ.Ext.data.Store({
proxy: new CQ.Ext.data.HttpProxy({
"autoLoad":false,
url: "/bin/mycomponents/groupsusers",
method: 'GET'
}),
reader: new CQ.Ext.data.JsonReader({
root: 'data',
fields: [
{name: 'id', mapping: 'id'},
{name: 'text', mapping: 'text'},
{name: 'group', mapping: 'group'}
]
})
});

config.mode = "remote";
config.triggerAction = "all";
config.valueField = 'id';
config.displayField = 'text';

config.tpl ='<tpl for=".">' +
'<tpl if="!group">' +
'<div class="x-combo-list-item" style="margin-left: 20px">{text}</div>' +
'</tpl>' +
'<tpl if="group == \'y\'">' +
'<div class="x-combo-list-item"><b>{text}</b></div>' +
'</tpl>' +
'</tpl>';

MyClientLib.StepCombo.superclass.constructor.call(this, config);
},

initComponent: function () {
MyClientLib.StepCombo.superclass.initComponent.call(this);

var resizeFn = function(combo){
var size = combo.getSize();
size.width = 200;
combo.setSize(size);
};

this.on('loadcontent', resizeFn);
}
});

CQ.Ext.reg("stepcombo", MyClientLib.StepCombo);

4) Create file /apps/groupsuserscombo/groupsuserscombo/clientlib/js.txt and add the following code

               combo.js

5) Create dialog /apps/groupsuserscombo/groupsuserscombo/dialog (of type cq:Dialog) with following properties

The xtype of /apps/groupsuserscombo/groupsuserscombo/dialog/items/items/tab1/items/user is set to stepcombo, we've created and registered above

<?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"
jcr:primaryType="cq:Dialog"
title="Groups Users"
xtype="dialog">
<items
jcr:primaryType="cq:Widget"
xtype="tabpanel">
<items jcr:primaryType="cq:WidgetCollection">
<tab1
jcr:primaryType="cq:Panel"
layout="form"
title="Add"
xtype="panel">
<items jcr:primaryType="cq:WidgetCollection">
<user
jcr:primaryType="cq:Widget"
fieldLabel="Select User"
name="./user"
xtype="stepcombo"/>
</items>
</tab1>
</items>
</items>
</jcr:root>

6) Add the following code in /apps/groupsuserscombo/groupsuserscombo/groupsuserscombo.jsp

<%@include file="/libs/foundation/global.jsp" %>
<%@page session="false" %>

Selected User : <%= ( properties.get("user") == null ) ? "None selected" : properties.get("user") %>


7) Here is the component structure


Viewing all articles
Browse latest Browse all 525

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>