wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

Mustache and CKEditor - Round two


Having just a few static values in the CK Editor drop down list really doesn't cut it. So we extend the bean today to have more flexible options. There are a few that spring to mind:
  1. List of all items in a given document
  2. List of all fields in a form (including subforms), eventually with or without the $ fields
  3. List of provided field names
So here we go:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
 <xp:scriptBlock id="scriptBlock1">
  <xp:this.value><![CDATA[#{javascript:mustache.getFormFields(database, "Memo,Person", false);}]]></xp:this.value>
 </xp:scriptBlock>
 <h1>Mustache and CKEdit demo</h1>
 <xp:inputRichText id="inputRichText1">
  <xp:this.dojoAttributes>
   <xp:dojoAttribute name="extraPlugins" value="mustache">
   </xp:dojoAttribute>  
  </xp:this.dojoAttributes>
 </xp:inputRichText>
</xp:view>

The big change here is the replacement of the EL Expression mustache.sampleData with a SSJS expression, so we can hand over all needed parameters. The pattern is the same for the other variations, so I won't repeat it further onwards. The interesting part is the Java method. Since a form might contain subforms you are interested it, I use an array like sting, that I'll split and a boolean parameter to include system fields. Of course one could vary the approach and automatically figure out the subforms in use (have fun with that once it is conditionally computed) or first present a list of forms and then the respective fields. Also, not to depend on some magic, I add the database dependency as parameter. So you have options to play with.

@SuppressWarnings("unchecked")
public String getFormFields(Database db, String formNameString, boolean includeSystemFields) {
    StringBuilder result = new StringBuilder();
    // Get a sorted set first
    Set<String> fieldNames = new TreeSet<>();
    String[] formNames = formNameString.split(",");
    for (String formName : formNames) {
       try {
            Form form = db.getForm(formName);
            if (form != null) {
                Vector fields = form.getFields();
                for (int i = 0; i < fields.size(); i++) {
                    String curField = fields.get(i).toString();
                    if (includeSystemFields || !curField.startsWith("$")) {
                        fieldNames.add(curField);
                    }
                }
            }
            form.recycle();
        } catch (NotesException e) {
            // Too bad
        }
    }
    result.append(this.preText);
    // Now the content
    for (String f : fieldNames) {
        this.add(result, f);
    }
    result.append(this.postText); return result.toString();
}

The pulling of existing document items (a very typical use case for CRM or marketing applications) looks very similar:

 @SuppressWarnings("unchecked")
    public String getDocumentItems(Document doc, boolean includeSystemFields) {
  StringBuilder result = new StringBuilder();
  Set<String>itemNames = new TreeSet<>();
  try { Vector allItems = doc.getItems();
       for (int i = 0; i < allItems.size(); i++) {
           Item item = (Item) allItems.get(i);
           if (includeSystemFields || !item.getName().startsWith("$")) {
               itemNames.add(item.getName());
            }
         }
    } catch (NotesException e) {
        //Too Bad
    }
    result.append(this.preText);
    // Now the content
    for (String item : itemNames) {
        this.add(result, item);
    }
    result.append(this.postText);
    return result.toString();
}

The last variation is a comma separated list of possible values. Using a pipe one can now add a hover description, something like that: "Color|Rainbow and such,Shape|Triangles and Squares,Taste,Age". The function is quite short. Keep in mind, the split function takes a RegEx, so it isn't String.split("|") but String.split("\\|"). The rest is simple

        public String getItems(String candidates) {
  StringBuilder result = new StringBuilder();
  result.append(this.preText);
  String[] allFields = candidates.split(",");
  for (String oneField : allFields) {
   add(result, oneField);
  }
  result.append(this.postText);
  return result.toString();
 }

Now that we create wonderful templates, we need to put them to use, but that's a story for another time

Posted by on 14 April 2014 | Comments (0) | categories: XPages

Comments

  1. No comments yet, be the first to comment