Catalog Item Macro

Ken83
Mega Guru

Hello Community,

 

        I believe this would be something simple that i'm overlooking but I haven't found it yet. On a Catalog Item, I had a reference field to the sys_user table to indicate who the Request was for. We utilize the 2 step checkout so even though that field was populated with a name, the end user would have to enter the name again on the second page of the checkout. So, to resolve that problem, I decided to add the Macro to the Catalog Item that already exists on the second page of the checkout.(sys_display.sc_cart.requested_for). I have another reference field on the same Catalog Item. When I populate field1 with a value, I want it to trigger an onChange Client Script and populate field2(the Macro). The problem is, this isn't working with a Macro variable type. It works from one reference field to another but not for the Macro field. Any suggestions?

 

Currently, my onChange Client Script is below...

 

function onChange(control, oldValue, newValue, isLoading) {

 

  var person1 = g_form.getValue("field1");

  g_form.setValue("field2", person1);

 

}

8 REPLIES 8

Ken83
Mega Guru

I've figured out how to get the value inserted into the UI Macro but it won't validate. Anybody else had any trouble getting a UI Macro to validate a value inserted into it?


Hi Kenneth,



How did you set the value on the macro (what code did you use)? I don't think you can use the standard API (e.g g_form.setValue() ) to do this.



Regards,


Jake


Hi Kenneth,



The g_form API doesn't work with macros as these are custom elements. However, after reviewing the HTML structure of the Jelly tag for reference fields (<g:ui_reference> etc), I believe you can manipulate the HTML by adding some client side functions and a script include extending Glide Ajax (used to retrieve the Display Value of the record). Please see my scripts below.



SCRIPT INCLUDE


// Script Include


var AjaxReferenceUtil = Class.create();


AjaxReferenceUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {


  // returns debit fees


  getReferenceDisplay : function () {


  var display_value = "";


  var sys_id = this.getParameter('sysparm_sys_id');


  var table_name = this.getParameter('sysparm_table_name');


  var field_name = '';



  var rec = new GlideRecord(table_name);


  if(rec){


  if(rec.get(sys_id)){


  display_value = rec.getDisplayValue()+'';


  field_name = this.getParameter('sysparm_field_name');


  }


  }


  // return results


  var result = this.newItem("result");


  result.setAttribute("field_name", field_name);


  result.setAttribute("display_value", display_value);


  result.setAttribute("sys_id", sys_id);


  }


});




MACRO


<!-- macro with single reference field element 'called_id' -->


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


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


      <g:ui_reference name="caller_id" id="caller_id" table="sys_user" query="active=true^roles=itil" completer="AJAXTableCompleter"


columns="user_name;email"/>


<script>


function setReferenceValue(field_name, sys_id){


      if(sys_id!=''){


      // get table name


              var table_name = '';


              var tableNameEle = document.getElementById(field_name+'TABLE');


              if(tableNameEle){


                      table_name = tableNameEle.value+'';


              }


              // call ajax to get display name


              var ajax = new GlideAjax('AjaxReferenceUtil');


              ajax.addParam('sysparm_name', 'getReferenceDisplay');


              ajax.addParam('sysparm_sys_id', sys_id);


              ajax.addParam('sysparm_table_name', table_name);


              ajax.addParam('sysparm_field_name', field_name);


              ajax.getXML(setReferenceValueCallBack);


      }


      else{


              clearReferenceValue(field_name);


      }


}




function setReferenceValueCallBack(response){


      //process result


      var result = response.responseXML.getElementsByTagName('result');


      var field_name = result[0].getAttribute("field_name");


      var sys_id = result[0].getAttribute("sys_id");


      var display_value = result[0].getAttribute("display_value");


      // set display value first


      var displayEle = document.getElementById('sys_display.'+field_name);


      if(displayEle){


              var valueEle = document.getElementById(field_name);


              if(valueEle){


                      displayEle.value = display_value;


                      // then set sys id


                      valueEle.value = sys_id;


                      // enable reference icon


                      setLightWeightLink(field_name);


              }


             


      }


}




function clearReferenceValue(field_name){


      var displayEle = document.getElementById('sys_display.'+field_name);


      if(displayEle){


              var valueEle = document.getElementById(field_name);


              if(valueEle){


                      displayEle.value = '';


                      // then set sys id


                      valueEle.value = '';


                      // enable reference icon


                      setLightWeightLink(field_name);


              }


      }    


}




</script>


</j:jelly>






</script>


</j:jelly>





To set your reference field by script, you can use the following function (just add the field name specified in the macro's 'id' attribute e.g 'caller_id', and the sys_id of the record):



setReferenceValue(field_name, sys_id);


e.g setReferenceValue('caller_id', '5137153cc611227c000bbd1bd8cd2005'); // sets the user reference to Fred Luddy



Using a null value for sys_id (e.g '') will clear the field.



Please note that this involves some very specific DOM manipulation of HTML elements, and these could potentially change with future ServiceNow upgrades.



Regards,


Jake


Hi Kenneth,



Were you able to use my script to set your reference macro field by script?



Regards,


Jake