Search code examples
javascripthtmlservicenowjelly

ServiceNow Printing lines from an array in an UI page


I have a requirement where I need to dynamically select one option from a select box depending on the information coming from the record.

The best I could come with was this:

<div class="form-group" style="width:150px;">
  <label class="col-md-4 control-label" for="language">Customer's Language</label>
  <div class="col-md-2" style="width:100px;">
    <select id="language" name="language" class="form-control">

        <g:evaluate var="jvar_ur" object="true">
            var language = 'it';
            var languages = [
            {
                "text"  : "German",
                "value" : "de"
            },
            {
                "text"     : "French",
                "value"    : "fr"
            },
            {
                "text"  : "Italian",
                "value" : "it"
            },
            {
                "text"  : "English",
                "value" : "en"
            }
            ];
            var options = [];

            for (keys in languages){
                if (language == languages[keys].value){
                    options.push('<option value="' + languages[keys].value + '" selected="selected">' + languages[keys].text + '</option>');
                }else{
                    options.push('<option value="' + languages[keys].value + '">' + languages[keys].text + '</option>');
                }
            }
            options;
        </g:evaluate>
        <j2:forEach items="${jvar_ur}" var="jvar_array_item">   
        

            "${jvar_array_item}"

        </j2:forEach> 

(bare in mind that the value of "language" is hardcoded for testing, this info will be fetched from the url once this starts to work).

My problem is that I cannot find a way of "printing" those text/html lines inside the array "options". I've found many different solutions on how to create options from an array but none of them would allow me to have a preselected option.

Can someone help me figure out what is wrong in this code and/or how to make this work?

Thanks in advance


Solution

  • Rather than putting your HTML into an array and trying to "print" it, you should use jelly as a templating mechanism to control what you render. That means you should use control flow tags such as j:if and j:forEach to loop over your JS array and to do the comparison.

    <g:evaluate>
      var language = 'it';
      var languages = [{
          "text": "German",
          "value": "de"
        },
        {
          "text": "French",
          "value": "fr"
        },
        {
          "text": "Italian",
          "value": "it"
        },
        {
          "text": "English",
          "value": "en"
        }
      ];
    </g:evaluate>
    <j:set var="jvar_language" value="${language}" />
    
    <select>
      <j:forEach items="${languages}" var="jvar_array_item">
        <j:if test="${jvar_array_item.value == jvar_language}">
          <option value="${jvar_array_item.value}" selected="selected">${jvar_array_item.text}</option>
        </j:if>
        <j:if test="${jvar_array_item.value != jvar_language}">
          <option value="${jvar_array_item.value}">${jvar_array_item.text}</option>
        </j:if>
      </j:forEach>
    </select>
    

    Remember that phase 1 does cache, so you may want to change the above to use phase 2 rendering.