Some­times, cus­tomers want to use more sophis­ti­cat­ed wid­gets while cap­tur­ing data from the end user in order to improve their over­all data entry expe­ri­ence. For exam­ple, instead of mak­ing user type the dig­its for numer­ic fields, cus­tomer might want to show a slid­er to cap­ture data. Sim­i­lar­ly, they might want to present data in more intu­itive way to end user like when show­ing the address to end user, they might like to show him the address on map instead of just as text.

Adap­tive Forms allows devel­op­ers to build cus­tom wid­gets which can inte­grate with rest of the Forms eco sys­tem and still sup­port all the busi­ness rules (aka expres­sions) that Form Author might write for that field. Once a devel­op­er deploys these cus­tom wid­gets, AEM Form author can eas­i­ly enable that for any par­tic­u­lar form field using Adap­tive Form Field prop­er­ties Dia­log in Form Author­ing mode. The wid­get frame­work has been tak­en from AEM XFA HTML5 Forms (aka AEM Mobile Forms), the approach to use the cus­tom wid­gets is same as in Adobe XFA HTML5 Forms. The XFA HTML5 Form Wid­get Spec­i­fi­ca­tion pro­vides good details about Wid­get Framework. One can use reuse exist­ing jquery or oth­er ui wid­gets by cre­at­ing a wrap­per around those wid­gets that adheres to the Form Wid­get spec­i­fi­ca­tion. This spec­i­fi­ca­tion pro­vides a basic widget(abstractWidget) and defines cer­tain func­tion that cus­tom wid­get may over­ride and cer­tain events that it should dis­patch, more details here.

 In this arti­cle we would be build­ing an address look up wid­get in which, when user start typ­ing city name, it would start show­ing him sug­ges­tions from which he can select the appro­pri­ate address. We would be using jQuery auto­com­plete wid­get for this. Code for sam­ple is shared at github repos­i­to­ry. I’ll high­light cou­ple from things from that:

Creating Custom Widget

We have cre­at­ed cus­tom wid­get called address­Lookup­Wid­get which extends from exist­ing textField wid­get. We have main­ly over­rid­ed ren­der func­tion of textField wid­get and plugged jquery ui auto­com­plete wid­get on that field which makes REST call to geon­ames serv­er and return address. Below snip­pet high­t­lights the call to REST end­point:

Note: In order for Adap­tive Form to be able to use the wid­get, the wid­get   javascript code must be reg­is­tered as AEM Client Library with cat­e­go­ry named af.customwidgets.

 render : function() {
            var $control = $.xfaWidget.defaultWidget.prototype.render.apply(this, arguments);
                    source: function( request, response ) {
                            url: "", //one can have their own username registered with
                            dataType: "jsonp",
                            data: {
                                featureClass: "P",
                                style: "MEDIUM",
                                maxRows: 12,
                                name_startsWith: request.term
                            success: function( data ) {
                                response( $.map( data.geonames, function( item ) {
                                    return {
                                        label: [, item.adminName1, item.countryName],
                                        value: [, item.adminName1, item.countryName]
                    minLength: 2,
                    open: function() {
                        $( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
                    close: function() {
                        $( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
            return $control;

Enable widget for a particular Form Field

Form Author can enable the wid­get by adding a spe­cif­ic CSS class name in the field dia­log. The class name should be of the fol­low­ing for­mat: widget_. In above case, we would add the widget_addressLookupWidget.  If this wid­get is deployed on the serv­er as men­tioned in pre­vi­ous step, Adap­tive Form Run­time would auto­mat­i­cal­ly enable that for this par­tic­u­lar field where this css class is applied.

Writing Expression to Prefill other Form Fields from selected Field

Pack­age cre­at­ed from github repos­i­to­ry also con­tains an Sam­ple Adap­tive Form. This Adap­tive Form has Find City but­ton in Address Pan­el. On click­ing that, it shows Address Lookup Pan­el. End user can type city name in that wid­get and it would start mak­ing sug­ges­tions. When user selects one of the sug­ges­tions and click ok, City, State and Coun­try field in Form Address Pan­el are pop­u­lat­ed from select­ed sug­ges­tion. This pop­u­la­tion of city, state and coun­try is done by writ­ing click expres­sion on ok but­ton in form author­ing mode. There are two part to writ­ing expres­sion:

  • Writ­ing Cus­tom Func­tion: The wid­get library also reg­is­ters a cus­tom Func­tion Func­tion called AdressLookupUtil.addressFill  which pop­u­lates city, state and coun­try field from giv­en field val­ue.
  • Call­ing Cus­tom Func­tion From Expres­sion: The ok but­ton of Find City Pan­el, has click expres­sion which calls above expres­sion to set val­ue for city, state,coundtry field from select­ed address: AdressLookupUtil.addressFill(addlookup, city, state, coun­try); Besides that, Ok click expres­sion also tog­gles Find City Pan­el to back to Address Pan­el.


Deploying and Running the Sample

The address-lookup-wid­get fold­er in aem-forms-sam­ples github repos­i­to­ry con­tains the source code for the sam­ple along with instruc­tions about how to build and deploy the sam­ple. When you deploy the built pack­age using pack­age man­ag­er, it would also deploy a sam­ple Adap­tive Form which would be acces­si­be at http://:/content/forms/af/widget-sample/addreslookupsample.html . This Sam­ple would have Find City but­ton in Address Pan­el which would show City Look Up field where above wid­get has been enabled. When you type more than 2 char­ac­ters, it would start show­ing sug­ges­tions. Below is the screen shot from final end user expe­ri­ence. 1404656673150

// <![CDATA[
(func­tion() {
var image­Div = document.getElementById(“cq-image-jsp-/content/cemblog/en/experiencedelivers/2014/07/aem_forms_using_customwidgetinadaptiveform/jcr:content/par/image”);
var imageE­vars = ‘{ imageLink: “/”, image­As­set: “”, imageTi­tle: “” }’;
var tagN­odes = imageDiv.getElementsByTagName(‘A’);
for (var i = 0; i


Note: We have used demo account for access­ing geon­ames REST end­point which may hit dai­ly lim­it of demo account request counts. You can reg­is­ter and use your own user account for access­ing geon­ames ser­vices. Few details here.