cancel
Showing results for 
Search instead for 
Did you mean: 

How to create dynamic multi-select list box in custom form

satheeshkumar
Champ in-the-making
Champ in-the-making
Hi All,

I have created a custom form with few text box fileds. I would like to add one more filed called multi-select box with dynamic list loaded into it.
The dynamic list I mean here is, looping through the specific sub folder of "Document Library" and create a list of folders available under this sub folder and pass it as a list to that multi-select box.
Is there any OOTB widgets available to be used, or do I need to write a custom widget, if so can you please help me with a sample example on how to do this.

Thanks in Advance.
11 REPLIES 11

s_palyukh
Star Contributor
Star Contributor

Hi Palyukh,

Thanks for your response. I have gone through the linked post you have shared. I could not grasp much from it, sorry, I am pretty new to this.

In that you have mentioned like,

<blockcode>You should make custom control for form field where you will call Alfresco webscript.

This webscript should return information that you want to display in section.</blockcode>
I didn't get where to put that custom control for form field and how can I create a webscript that will return list of sub folders.
Can you please elaborate and provide some more details, which will be greatly helpful for me.


s_palyukh
Star Contributor
Star Contributor
Introduction to the Share forms -> http://docs.alfresco.com/5.0/concepts/forms-intro.html
How to create custom form-field control -> http://docs.alfresco.com/5.0/tasks/forms-custom-formcontrol.html
Introduction to the Web Script -> http://ecmarchitect.com/alfresco-developer-series-tutorials/webscripts/tutorial/tutorial.html

 You should make custom control for form field where you will call Alfresco webscript. 


It means that you can add javascript code into the custom field control where you will make ajax request to the Alfresco interface.


 This webscript should return information that you want to display in section. 


It means you need to make custom webscript that will return data for dynamic control

Hi Palyukh,

Thanks for the links. I have gone through the links. Based on those details, I have created a Java backed webscript for returning a list of available folders under a specific path.

Here is my Java Backed Webscript code,

protected Map<String, Object> executeImpl(WebScriptRequest req,
         Status status, Cache cache) {
      String typeOfLibrary = req.getParameter("retrieve");
      
      if (typeOfLibrary == null || "".equals(typeOfLibrary)) {
         status.setCode(Status.STATUS_BAD_REQUEST);
         status.setRedirect(true);
         status.setMessage("Please provide typeofLibrary");
         logger.debug("Please provide typeofLibrary");
         return null;
      }
      else if (!("Product Library".equals(typeOfLibrary)) && !("Image Library".equals(typeOfLibrary))) {
         status.setCode(Status.STATUS_BAD_REQUEST);
         status.setRedirect(true);
         status.setMessage("Please provide valid typeofLibrary");
         logger.debug("Please provide valid typeofLibrary");
         return null;
      }
      StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
      String queryStrings = "";
      if (("Product Library".equals(typeOfLibrary))) {
         queryStrings = "PATH:\"/app:company_home/st:sites/cm:retail-channels-product-management/cm:documentLibrary/cm:Product_x0020_Library/*\"";
      }
      else if(("Image Library".equals(typeOfLibrary))){
         queryStrings = "PATH:\"/app:company_home/st:sites/cm:retail-channels-product-management/cm:documentLibrary/cm:Image_x0020_Library/*\"";
      }
      ResultSet rs1 = serviceRegistry.getSearchService().query(storeRef, SearchService.LANGUAGE_LUCENE, queryStrings);
      Map<String, Object> model = new HashMap<>();
      List<String> productLibraryList = new ArrayList<>();
      try {
         if(rs1 != null && rs1.length() != 0) {      
            
            FileFolderService fileFolderService = serviceRegistry.getFileFolderService();
            for (int i = 0; i < rs1.length(); i++) {
               NodeRef rsNodeRef = rs1.getNodeRef(i);
               String productTypeFolder = fileFolderService.getFileInfo(rsNodeRef).getName();
               productLibraryList.add(productTypeFolder);               
               logger.info("The ProductTypeFolder Name is :"+productTypeFolder);               
            }
         }
      }
      finally {
         rs1.close();
      }
      if(!productLibraryList.isEmpty()){
         model.put("isEmpty", false);
         model.put("libraryList", productLibraryList);
      }
      else{
         model.put("isEmpty", true);
         model.put("libraryList", null);
      }
      return model;
   }


Web Descriptor,

<webscript>
   <shortname>Retrieves the Library List of the type of library passed.</shortname>
   <description>Retrieves the Library List of the type of library passed.</description>
   <family>Harland Clarke WebScripts</family>
   <url>/retrieve-library-list?retrieve={typeOfLibrary}</url>   
   <format default="json">extension</format>
   <authentication>admin</authentication>
</webscript>


Response template, but I am not sure this is how it should be,

<#if isEmpty> []
<#else>
{"libraryList":{<#list libraryList as listItem>
"${listItem}"<#if listItem_has_next>,</#if>
</#list>}}
</#if>


I am getting a response as shown in the screen shot, when I access this custom webscript.
But I am not able to iterate this and show it up in my custom form control.

My Custom Form control, I haven't changed much in it except the URL and "result.people.length"

<div class="form-field">

    <script type="text/javascript">//<![CDATA[
    YAHOO.util.Event.onAvailable("${fieldHtmlId}_assign", function(){
        new selectAuthor("${fieldHtmlId}");
    });

    function selectAuthor(currentValueHtmlId) {
        this.currentValueHtmlId = currentValueHtmlId;
        var selectAuthors = Dom.get(this.currentValueHtmlId);

        this.register = function () {
// Call webscript
            Alfresco.util.Ajax.jsonGet({
                url: "http://localhost:8080/alfresco/service/retrieve-library-list?retrieve=Product%20Library",
                successCallback: {
                    fn: this.updateOptions,
                    scope: this
                },
                failureCallback: {
                    fn: function () {
                    },
                    scope: this
                }
            });
        };

// Add options into <select>
        this.updateOptions = function (res) {
            var result = Alfresco.util.parseJSON(res.serverResponse.responseText);
            if (result.libraryList.length > 0) {
                var people = result.libraryList;
                selectAuthors.options[selectAuthors.options.length] = new Option("", "", true, true);
                for (var i in people) {
                    var option = new Option(people, people);
                    selectAuthors.options[selectAuthors.options.length] = option;
                }
            }
        };

        this.register();
    }
    //]]></script>

    <label for="${fieldHtmlId}">${field.label?html}:<#if field.mandatory><span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></#if></label>
    <select id="${fieldHtmlId}" name="${field.name}" tabindex="0"
            <#if field.description??>title="${field.description}"</#if>
            <#if field.control.params.size??>size="${field.control.params.size}"</#if>
            <#if field.control.params.styleClass??>class="${field.control.params.styleClass}"</#if>
            <#if field.control.params.style??>style="${field.control.params.style}"</#if>
            <#if field.disabled  && !(field.control.params.forceEditable?? && field.control.params.forceEditable == "true")>disabled="true"</#if>>
    </select>
</div>


Can you please point me out, where I am going wrong. I am trying "result.libraryList.length", is this the way to access the list return by my custom wescript?
If so, why am I getting a blank dropdown? Or is there anything wrong in my code?


Even changed my Java Backed webscript to render a Json response directly. But still could not access them in the form field.

@Override
   public void execute(WebScriptRequest req,
         WebScriptResponse res) throws IOException {
      
      String typeOfLibrary = req.getParameter("retrieve");
      
      
      StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
      String queryStrings = "";
      if (("Product Library".equals(typeOfLibrary))) {
         queryStrings = "PATH:\"/app:company_home/st:sites/cm:retail-channels-product-management/cm:documentLibrary/cm:Product_x0020_Library/*\"";
      }
      else if(("Image Library".equals(typeOfLibrary))){
         queryStrings = "PATH:\"/app:company_home/st:sites/cm:retail-channels-product-management/cm:documentLibrary/cm:Image_x0020_Library/*\"";
      }
      ResultSet rs1 = serviceRegistry.getSearchService().query(storeRef, SearchService.LANGUAGE_LUCENE, queryStrings);
      
      List<String> productLibraryList = new ArrayList<>();
      try {
         if(rs1 != null && rs1.length() != 0) {      
            
            FileFolderService fileFolderService = serviceRegistry.getFileFolderService();
            for (int i = 0; i < rs1.length(); i++) {
               NodeRef rsNodeRef = rs1.getNodeRef(i);
               String productTypeFolder = fileFolderService.getFileInfo(rsNodeRef).getName();
               productLibraryList.add(productTypeFolder);               
               logger.info("The ProductTypeFolder Name is :"+productTypeFolder);               
            }
         }
      }
      finally {
         rs1.close();
      }
      
      JSONObject jsonObject = new JSONObject();
      try {
         jsonObject.put("libraryList", productLibraryList);
      } catch (JSONException e) {
         
         logger.error("Error occured while creating Json Object."+e.getMessage());
         
      }
      
      String jsonString = jsonObject.toString();
      res.getWriter().write(jsonString);
      
   }


Can someone help me on how to access this list in the custom form field.

Hi Satheesh,

It looks your JSON data is invalid format.
The child items should have "[ ]" for the array and you have used "{}" for the child elements.

Here is the correct format.



{
"libList":
[
   "Banner Small",
   "Banner Large"
]
}


Change the FTL like,



<#if isEmpty> []

<#else>

{"libraryList":[
<#list libraryList as listItem>

"${listItem}"<#if listItem_has_next>,</#if>

</#list>
]
}

</#if>



You can use the below link to verify the JSON format.
http://json.parser.online.fr/

Please let me know, if it is not helping you.

I too noticed the format was wrong after I changed my Java Backed Web Script to render the JSON Response directly. I figured out the correct format, it looks just like yours.
Here is my JSON Output.
{"libraryList":["Banner Small","Buiness Vertical","Banner Medium","Business Accessories","Banner Large"]}


But, yeah, it is not helping me yet, my actual problem lies in accessing this JSON List and showing up in my custom form control.
Can you please help me out, I have shown my control template in my above post.

That I tried based on the example given in the link https://forums.alfresco.com/comment/149739#comment-149739
But I was not able to show up this JSON list in that template.

Thanks in Advance.

It hard to say where is a mistake, you need to debug your JS code… Take a look what do you get in the "res" variable also pay attention on "selectAuthors" maybe it equals null

muralidharand
Star Contributor
Star Contributor
Hi Satheesh,
I hope, you're looking for the suggestion on Aikau style forms (building the JSON model in get.js file) and not the Form Service forms.


If so, there is no predefined widgets are available for the multi-select checkbox control, but you can use it from the dojox.

http://dojotoolkit.org/reference-guide/1.10/dojox/form/CheckedMultiSelect.html

http://jsfiddle.net/down_quark/cNATk/

Aikau is running on top of Dojo framework, so you should be able to use this in your case.

Please let me know, if you're not clear.