Jelly, Javascript and html <select>ions

tobrien
Kilo Guru

Hi,

I am trying to understand how to dynamically add to a <select> from elements created in the Jelly -- here's the basics of my endeavor ==>

Extremely Simple Example for a single entry (one ID, and one NAME) :: I can use this in my UI PAGE html

<g2:evaluate var="jvar_some_name">

var id = '123456';    

var name = 'tobtobtob';

//you may assume that the values were actually developed from some GlideRecord calls

</g2:evaluate>

<select>

<option value="$[id]">$[name]</option>

</select>

But suppose I need to add an "array of values" using a var id = [ ];   like so ...

<g2:evaluate var="jvar_some_name">

var id = [ ];    

var name = [ ];

for (var k9=0;k9<10;k9++) {

        id.push(k9);

        name.push(k9.toString());

}

</g2:evaluate>

Trying to add the array contents as 'options' seems to be difficult for me. Below is one of many attempts ==>

I know this fails for a variety of reasons not the least which is:

        (a) Mixing the <option> line between the <g2:evaluate> of the for loop is just nuts.

        (b) the doubling of the square brackets doesn't get past the compiler.

<select>

<g2:evaluate>

for (var k9=0;k9<10;k9++) {

        </g2:evaluate>

          <option value="$[id[k9]]"> $[name[k9]] </option>

<g2:evaluate>

}

</g2:evaluate>

</select>

Any assistance you can offer would be greatly appreciated.

1 ACCEPTED SOLUTION

mike_allgire
Giga Guru

When ever writing Jelly in a UI Page, I frequent the two pages often. I would keep them handy. In addition, there are other available jelly tags, that they don't provide, but you can "discover" after trial and error.



http://wiki.servicenow.com/index.php?title=Jelly_Tags#gsc.tab=0


Extensions to Jelly Syntax - ServiceNow Wiki



The first question would be; what are you getting the user ID/name from? Is it from the user table or from another query of values from a different table. If it is a direct look up, you can use the extension for Extensions to Jelly Syntax - UI Reference. This will allow you to use a similar reference look up (like a reference field). If you are querying information from a list of user values created from other table(s), then you would want to use the Jelly Tags - While   jelly tag to loop through. In jelly, there isn't a "for" to be used directly in the contents of the scripting (Edit: or listen to ctomasi who knows more than I).



Below is an example of a bootstrap carousel that I created to reference some images from the db_image table.


<?xml version="1.0" encoding="utf-8" ?>


<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">


      <!--Query the image table to look for images that are active and start with 'test_slide'-->


<!--Retrieve the images in descending order by created date-->


      <g:evaluate var="jvar_gr" object="true">


              var gr = new GlideRecord('db_image');


              gr.addQuery('active',true);


              gr.addQuery('name','STARTSWITH','test_slide');


              gr.orderByDesc('sys_created_on');


              gr.query();


              gr;


      </g:evaluate>


<div id="myCarousel" class="carousel slide" data-ride="carousel">


  <!-- Wrapper for slides -->


  <div class="carousel-inner" role="listbox">


          <div class="item active">


                      <center><img src="main_slide_0.png" alt="Main"/></center>


              </div>


<!--Using Jelly while test, loop through the retrieved images and display them in the carousel-->


          <j:while test="${jvar_gr.next()}">


              <div class="item">


                      <center><img src="${gr.name}" alt="TEST"/></center>


              </div>


          </j:while>


  </div>



  <!-- Left and right controls -->


  <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">


      <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>


      <span class="sr-only">Previous</span>


  </a>


  <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">


      <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>


      <span class="sr-only">Next</span>


  </a>


</div>


</j:jelly>



For your usage, you would just change the lines to be relevant to the select html tag.


<select>


        <j:while test="${jvar_gr.next()}">


                <option value="${gr.id}">${gr.name}</option>


        </j:while>


</select>



Hope that helps some.


View solution in original post

9 REPLIES 9

mike_allgire
Giga Guru

When ever writing Jelly in a UI Page, I frequent the two pages often. I would keep them handy. In addition, there are other available jelly tags, that they don't provide, but you can "discover" after trial and error.



http://wiki.servicenow.com/index.php?title=Jelly_Tags#gsc.tab=0


Extensions to Jelly Syntax - ServiceNow Wiki



The first question would be; what are you getting the user ID/name from? Is it from the user table or from another query of values from a different table. If it is a direct look up, you can use the extension for Extensions to Jelly Syntax - UI Reference. This will allow you to use a similar reference look up (like a reference field). If you are querying information from a list of user values created from other table(s), then you would want to use the Jelly Tags - While   jelly tag to loop through. In jelly, there isn't a "for" to be used directly in the contents of the scripting (Edit: or listen to ctomasi who knows more than I).



Below is an example of a bootstrap carousel that I created to reference some images from the db_image table.


<?xml version="1.0" encoding="utf-8" ?>


<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">


      <!--Query the image table to look for images that are active and start with 'test_slide'-->


<!--Retrieve the images in descending order by created date-->


      <g:evaluate var="jvar_gr" object="true">


              var gr = new GlideRecord('db_image');


              gr.addQuery('active',true);


              gr.addQuery('name','STARTSWITH','test_slide');


              gr.orderByDesc('sys_created_on');


              gr.query();


              gr;


      </g:evaluate>


<div id="myCarousel" class="carousel slide" data-ride="carousel">


  <!-- Wrapper for slides -->


  <div class="carousel-inner" role="listbox">


          <div class="item active">


                      <center><img src="main_slide_0.png" alt="Main"/></center>


              </div>


<!--Using Jelly while test, loop through the retrieved images and display them in the carousel-->


          <j:while test="${jvar_gr.next()}">


              <div class="item">


                      <center><img src="${gr.name}" alt="TEST"/></center>


              </div>


          </j:while>


  </div>



  <!-- Left and right controls -->


  <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">


      <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>


      <span class="sr-only">Previous</span>


  </a>


  <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">


      <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>


      <span class="sr-only">Next</span>


  </a>


</div>


</j:jelly>



For your usage, you would just change the lines to be relevant to the select html tag.


<select>


        <j:while test="${jvar_gr.next()}">


                <option value="${gr.id}">${gr.name}</option>


        </j:while>


</select>



Hope that helps some.


Good example Mike. It looks like you have a pretty good grasp on this.



Anthony, be sure to change the j: and g: tags to j2: and g2: to match the phase 1/phase 2 in your script. That often trips people up when copying/pasting code.


Mr Allgire -- pardon my subtle hijack of this thread but this followup question is related (in a 5th cousin twice removed kinda way ;<>)



I reviewed (and Bookmarked !!!) the 2 URLs you provided regarding Jelly -- it made me wonder if one of the "discovered" mechanisms I might use is to incorporate other 'normal' javascript-y actions into the Jelly statements -- such as --->



//iI want to limit the rows added as options based upon some criteria, such if the NAME 'contains' (not an exact match) of a string ---


<j2: test "$[gr.name.indexOf('DoNotUseTheCurrentGRRowIfItHasThisString') == -1)]">


        <option value="$[gr.sys_id]"> $[gr.name] </option>


</j2>



Yes, it does except things like indexOf as well as additional tests in the string (a.k.a. condition 1 && condition 2); however if you are trying to eliminate something from the query itself, I would add it to the evaluation instead of as a test line. See example below, I added in line 04 to exclude the 'name' value of XXXXX.


  1.       var gr = new GlideRecord('db_image');  
  2.               gr.addQuery('active',true);  
  3.               gr.addQuery('name','STARTSWITH','test_slide');  
  4.               gr.addQuery('name','DOES NOT CONTAIN','XXXXX');    
  5.               gr.orderByDesc('sys_created_on');  
  6.               gr.query();  
  7.               gr;


This may help you with the Glide Record query options


Using GlideRecord to Query Tables



Also, your below xml is missing the equals sign between test and the statement


<j2: test "$[gr.name.indexOf('DoNotUseTheCurrentGRRowIfItHasThisString') == -1)]">


        <option value="$[gr.sys_id]"> $[gr.name] </option>


</j2>