Find your people. Pick a challenge. Ship something real. The CreatorCon Hackathon is coming to the Community Pavilion for one epic night. Every skill level, every role welcome. Join us on May 5th and learn more here.

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>