2
votes

In CQ5, the Item Load Path field allow an author to provide a url from which it loads the options available in a dropdown list/checkbox group etc. But how does it actually work?

EDIT: I'm using version 5.6.1 in case that is relevant

Here is what I do know:

1) I know that component dialogs in CQ5 stores its content under:

/content/page/jcr:content/<component node>

In this case, it's stored in a property called './optionLoadPath':

enter image description here

2) I know that Inside any component (for example, the checkbox components), the list of values to be displayed is loaded into a List of Strings via:

EDIT 2: @awadheshv just pointed out that the list of values to be displayed is actually loaded using FormsHelper.getOptions(). If that's the case, what is getValueAsList doing?

final List<String> values = FormsHelper.getValuesAsList(slingRequest, resource);

before being displayed using a forloop:

for (String v : displayValues.keySet()) {
    final String t = displayValues.get(v);
    final String currentId = id + "-" + i;

%><div class="form_row"><%
    LayoutHelper.printTitle(currentId, t, false, true, out);
    %><div class="form_rightcol"><%

            String checked = "";
            if (values.contains(v)) {
                checked = " checked=\"checked\"";
            }
        %><input class="<%= FormsHelper.getCss(properties, "form_field form_field_checkbox") %>" type="checkbox"
                 id="<%= StringEscapeUtils.escapeHtml4(currentId) %>" name="<c:out value="<%= name %>"/>"
                 value="<c:out value="<%= v %>"/>" <%= checked %> />&nbsp;<c:out value="<%= t %>" />
    </div>
</div><%

    i++;
}

3) I also know that FormsHelper.getValuesAsList just calls FormsHelper.getValues and just converts the returned array into a list.

public static List<String> getValuesAsList(final SlingHttpServletRequest request, final Resource elementResource) {
    final String[] values = getValues(request, elementResource);
    if ( values == null ) {
        return Collections.emptyList();
    }
    return Arrays.asList(values);
}

But I don't understand how everything comes together. At what point/how is the list of items in optionLoadPath passed to FormsHelper?

Furthermore, if I want to load in the values by default, how would I go about doing that? For example, say if there is a list of countries I want to load into the componenet. I still want to give user the ability to change the URL to a different list of countries if they want, but I want to load in a default list as soon as the component is dropped into the page. How would I go about doing that?

1

1 Answers

1
votes

I don't think loadOptions are fetched via getValues. FormsHelper class has a separate method getOptions which fetches optionsLoadPath property from jcr; implemented as follows-

public static Map<String, String> getOptions(SlingHttpServletRequest request, Resource elementResource)
  {
    ValueMap properties = ResourceUtil.getValueMap(elementResource);

    String[] options = null;
    String loadPath = (String)properties.get("optionsLoadPath", "");
    if (loadPath.length() > 0)
    {
      Resource rsrc = request.getResourceResolver().getResource(loadPath);
      if (rsrc != null) {
        options = (String[])rsrc.adaptTo([Ljava.lang.String.class);
      }
    }

    if (options == null) {
      options = (String[])properties.get("options", [Ljava.lang.String.class);
    }

    if (options == null) {
      return null;
    }

    Map splitValues = new LinkedHashMap();
    for (int i = 0; i < options.length; ++i) {
      String value = options[i].trim();
      if (value.length() > 0) {
        boolean endLoop = true;
        int pos = -1;
        int start = 0;
        do {
          pos = value.indexOf(61, start);

          if ((pos > 0) && (value.charAt(pos - 1) == '\\')) {
            start = pos + 1;
            endLoop = false;
          } else {
            endLoop = true; }
        }
        while (!(endLoop));
        String t;
        if (pos == -1) {
          String v = value;
          t = value;
        } else {
          v = value.substring(0, pos);
          t = value.substring(pos + 1);
        }
        String v = v.replace("\\=", "=");
        String t = t.replace("\\=", "=");
        splitValues.put(v, t);
      } else {
        splitValues.put("", "");
      }
    }
    if (splitValues.size() == 0) {
      return null;
    }
    return splitValues;
  }

component code would call getOptions explicitly. e.g.-

 Map<String, String> displayValues = FormsHelper.getOptions(slingRequest, resource);

to you second point - you can put the default values in options property.