Static and dynamic dialogs in Adobe CQ5

Static and dynamic dialogs in Adobe CQ5

In a selection widget there are two ways to provide the available options, dynamic or static. In the following lines we will discuss how to use them and when.

Static options

They are used when the the options are always the same. Making them static will result in a faster response and better performance of our dialog, but once written, we will not be able to change them. Here is how to do it.

In the selection widget example above, we create directly an array in the dialog’s XML code, providing the text to display and the value to save in JCR. But what happens if the options are not always the same?

Dynamic options

If for some reason we have to calculate our options based on some parameters, or this options depend on the content, it would be interesting to have a mechanism to generate them. This mechanism is known as dynamic options.
To generate the options we will use a Java Servlet. This Servlet can be also developed in JavaScript or we can even develop a JavaScript function, but I prefer to left JavaScript for client side validation. Lets see how the code would look like.

First of all in the dialog’s XML instead of having a static options array we have a Servlet path, in which we could also pass parameters in a RESTful way to process them latter in our Servlet.

For the Servlet we extend the SlingSafeMethodsServlet class. We provide the path with the annotation “property” giving as name “sling.servlet.paths” and as value the same path provided in the dialog XML file. The communication will be done, as we ask in the dialog’s path, in JSON format, so it is necessary to set the content type of the Servlet’s response and write the response in a JSON format. In this example, for simplicity, we create a JSON object with the class JSONWriter, with fixed options only to show how it is done, but in a real environment we would take advantage of Java’s possibilities to generate the options dynamically based on our needs. To finish this post, clarify that what you put under “text” is what will be displayed on your dialog and what you put under “value” is what will be saved in CRX.
I hope this post was useful to you, if you have questions or suggestions just let me know. Thanks!
Tags:
, ,
22 Comments
  • Anonymous
    Posted at 21:26h, 12 December

    great job!!

    sas.

  • albertoalmagro
    Posted at 12:20h, 13 December

    Thank you sas!

  • Anonymous
    Posted at 17:58h, 20 March

    Very nice feature!
    For similar result, it is possible to use optionProvider under xtype=selection , in this case
    optionProvider=function(path, record){var st='/bin/dynamicdialog/options.json'+(new Date().getTime()); return CQ.Util.formatData(CQ.HTTP.eval(CQ.HTTP.noCaching(st))) }

  • albertoalmagro
    Posted at 17:13h, 21 March

    Hi Anonymous,

    thanks! I appreciate your feedback, I have to try that.

  • Sabarno Mondal
    Posted at 11:13h, 15 January

    Hi,

    Is there any way to create a tab dynamically in a dialog in cq5.please let me know it that's possible or not .
    Thanks in advance .

  • albertoalmagro
    Posted at 08:46h, 18 January

    Hi Sabarno, yes you can, try to execute a JavaScript function in a widget event and within this function execute the .enable() or disable() function of your tab.

    Regards,
    Alberto

  • AJAY BHATT
    Posted at 16:44h, 26 January

    Hi,

    Can u please tell me how to access value of selectionchanged event in select xtype. in dialog listener like beforeSubmit

    • albertoalmagro
      Posted at 07:53h, 07 February

      Hi AJAY,

      when you invoke a listener some objects are always passed to it, take a look at http://dev.day.com/docs/en/cq/current/widgets-api/ , search for the selectionChanged listener of your component and see which objects are passed to it. Then you will be able to navigate and find what you want. Regards.

  • Alisneaky
    Posted at 03:46h, 24 April

    hi Alberto,

    Thanks for your great examples. I'm very new to CQ5 and have made some basic components so far. I have not as yet created any with actual Java packages and classes. Generally they've just been using JSP's.

    With this example, where do you actually put the Servlet? Could you give a contextual diagram of the folder structure for this to work please?

    Thanks in advance.

    • albertoalmagro
      Posted at 14:57h, 24 April

      Hi Alisneaky!

      as you can see in the code, I placed it at the same package as the sample component "com.example.cq.components.dynamicdialog". With that you have to figure out that it would be a package for all the components "com.example.cq.components" and inside of it you would find the component, in this case I named it "dynamicdialog".

      For the Server registration I registered it via path at "/bin/dynamicdialog/options but you could register it in any other path based maybe on your architectural design

      To register it as path you would need:
      @Property(name = "sling.servlet.paths", value = "/bin/dynamicdialog/options")

      There are other ways to register a servlet in Adobe AEM depending on your needs. But in this case I would do it definitely by path. Here you can find more information about this topic: https://sling.apache.org/old-stuff/servlet-resolution.html

  • mamsha
    Posted at 12:48h, 02 June

    Hi I got the dropdown , but after selecting dropdown value, its not geting stored in crxde

    • mamsha
      Posted at 12:49h, 02 June

      Thanks for the replay in advance

    • Julien Griffon
      Posted at 14:27h, 25 July

      Hi,
      I got exactly the same bug.
      Nothing is stored.
      Did you fing a issue ?

    • Julien Griffon
      Posted at 14:42h, 25 July

      Hi,
      I found the solution :

      writer.object();
      writer.key("text").value( value );
      writer.key("value").value( key ); // value escaped
      writer.endObject();

      Set only "text" does not fix the value.

    • albertoalmagro
      Posted at 09:33h, 26 July

      Thank you Julien for your correction and for reading my blog, I'm going to change it now!

  • albertoalmagro
    Posted at 18:04h, 02 June

    Hi Mamsha, yep, there is a bug in the code I posted, instead of name = .selection I should have written name = ./selection. I will correct it now. Thanks!!!

    • mamsha
      Posted at 05:55h, 03 June

      Hi Alberto, Thanks for the reply, but its still not getting stored

  • albertoalmagro
    Posted at 14:37h, 04 June

    Hi,

    it is working for me, if you want I can export it as a component and send it to you, so you can compare and see what's wrong.

  • Ankur Chauhan
    Posted at 05:28h, 10 June

    very Nicely explained….
    Thanks a lot……

  • Julien Griffon
    Posted at 15:04h, 25 July

    Finaly works perfectly, Thanks a lot Alberto for this article !

  • Nitin Tyagi
    Posted at 08:09h, 31 July

    Hi Alberto,

    Nice Explanation. Is there a way by which we can the default value of the selection from the dynamically generated list. For eg I would to set value1 as default for the example given above, but don't want to hard code it using defaultValue as it dynamically generated list.

    Thanks
    Nitin

  • Srikanth Pogula
    Posted at 12:56h, 20 April

    Hi Alberto,
    Can we pass the author entered value for another field(in the same dialog where the dropdown exists) as a parameter to the servlet invoked to fetch JSON response?
    Something similar to this
    options="/bin/dynamicdialog/options.json?q="${param}