The CreatorCon Call for Content is officially open! Get started here.

script to auto populate fields!

SNnewbie2
Tera Expert

I have a reference field called servers. This table contains information ip address and description. I want to be able to autopopulate ip address and decription.

For example, in the hostname field I will select a server name, and after I select the server name it will autopopulate the IP Address and Description.

How do I do that?   Thank you.

Table name : cmdb_ci_server

Capture74.PNG

Capture73.PNG

1 ACCEPTED SOLUTION

Ivano B
ServiceNow Employee
ServiceNow Employee

Ok let me try to help you without the context because it seems that i can't explain what i need.



First of all you need to create a client script on change.


Set the basic information such as table (the table where the hostname reference field is placed) and field name (e.g. u_hostname).


Supposing the fields you want to populate are named u_ip and u_desc



Than create something like this one


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



  if (isLoading || newValue === '') {


  return;


  }



  var serverId = g_form.getValue('u_server');


  var ga = new GlideAjax('myCmdbUtils');


  ga.addParam('sysparm_name', 'getServerInfo');


  ga.addParam('sysparm_server_id', serverId);


  ga.getXML(ajaxResponse);



  function ajaxResponse(serverResponse) {


  // get result element and attributes



  var result = serverResponse.responseXML.getElementsByTagName("result");


  // get favorite elements


  var info = serverResponse.responseXML.getElementsByTagName("info");


  for(var i = 0; i < info.length; i++) {


  var name = info[i].getAttribute("name");


  var value = info[i].getAttribute("value");


  //This is just for cotrol you need to comment later


  alert('name :: ' + name + ' - value ::' + value);


  if(name == 'ip'){


      g_form.setValue('u_ip', value);


  }


  if(name == 'desc'){


      g_form.setValue('u_desc', value);


  }


  }


  }



}



Now you need to create a new script include named 'myCmdbUtils'


The script include must have the 'client callable' tick box ticked.



The script should be something like this



var myCmdbUtils = Class.create();


myCmdbUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {




getServerInfo : function() {




  var serverId = this.getParameter('sysparm_server_id');


  var gr = new GlideRecord('cmdb_ci_server');


  gr.addQuery('sys_id', serverId);


  gr.query();


  if(gr.next()){



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


      this._addInfo("desc", gr.description);



      var netAdpt = new GlideRecord('cmdb_ci_network_adapter');


      netAdpt.addQuery('cmdb_ci', gr.sys_id);


      netAdpt.query();


      if(netAdpt.next()){


            this._addInfo("ip", netAdpt.ip_address);


      }



  }


},




  _addInfo : function(name, value) {


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


  info.setAttribute("name", name);


  info.setAttribute("value", value);


  },



  type: 'myCmdbUtils'


});



I hope this will help/answer your question and if it does please mark it



Cheers


R0b0


View solution in original post

12 REPLIES 12

Ivano B
ServiceNow Employee
ServiceNow Employee

Ok let me try to help you without the context because it seems that i can't explain what i need.



First of all you need to create a client script on change.


Set the basic information such as table (the table where the hostname reference field is placed) and field name (e.g. u_hostname).


Supposing the fields you want to populate are named u_ip and u_desc



Than create something like this one


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



  if (isLoading || newValue === '') {


  return;


  }



  var serverId = g_form.getValue('u_server');


  var ga = new GlideAjax('myCmdbUtils');


  ga.addParam('sysparm_name', 'getServerInfo');


  ga.addParam('sysparm_server_id', serverId);


  ga.getXML(ajaxResponse);



  function ajaxResponse(serverResponse) {


  // get result element and attributes



  var result = serverResponse.responseXML.getElementsByTagName("result");


  // get favorite elements


  var info = serverResponse.responseXML.getElementsByTagName("info");


  for(var i = 0; i < info.length; i++) {


  var name = info[i].getAttribute("name");


  var value = info[i].getAttribute("value");


  //This is just for cotrol you need to comment later


  alert('name :: ' + name + ' - value ::' + value);


  if(name == 'ip'){


      g_form.setValue('u_ip', value);


  }


  if(name == 'desc'){


      g_form.setValue('u_desc', value);


  }


  }


  }



}



Now you need to create a new script include named 'myCmdbUtils'


The script include must have the 'client callable' tick box ticked.



The script should be something like this



var myCmdbUtils = Class.create();


myCmdbUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {




getServerInfo : function() {




  var serverId = this.getParameter('sysparm_server_id');


  var gr = new GlideRecord('cmdb_ci_server');


  gr.addQuery('sys_id', serverId);


  gr.query();


  if(gr.next()){



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


      this._addInfo("desc", gr.description);



      var netAdpt = new GlideRecord('cmdb_ci_network_adapter');


      netAdpt.addQuery('cmdb_ci', gr.sys_id);


      netAdpt.query();


      if(netAdpt.next()){


            this._addInfo("ip", netAdpt.ip_address);


      }



  }


},




  _addInfo : function(name, value) {


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


  info.setAttribute("name", name);


  info.setAttribute("value", value);


  },



  type: 'myCmdbUtils'


});



I hope this will help/answer your question and if it does please mark it



Cheers


R0b0


Thank you for your reply. There are a few lines that I do not understand. what does this._addinfo do?



This how I was doing my include script. Could you please tell me if it is right?



Could you also explain line by line. I am new in SN and I am trying to learn as much as I can.




var PenTestCatalogTaskAjax = Class.create();


PenTestCatalogTaskAjax.prototype = {


      getIPAddressAndDescription: function() {



  var serverID = this.getParameter('sysparm_server_id'); //get server ID


  var gr = new GlideRecord('cmdb_ci_server'); //Go to the server table


  gr.addQuery('sys_id', serverId);   //??


  gr.query();   //????


  gr.next(); //????



  var description = gr.short_description; //get short description




  var ipAddress = new GlideRecord ('cmdb_ci_network_adapter'); //go to network table


  ipAddress.addQuery(); // what do we pass i here?


  ipAddress.query(); //??


  ipAddress.next(); //???


  //how do i pass ip address?





  return description + ipAddress; //i want to return ip address and description


},




      type: 'PenTestCatalogTaskAjax'


};


Ivano B
ServiceNow Employee
ServiceNow Employee

Hi Claudia



you can find more info here



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



_addinfo is a private function that can be called only inside the script include.


As explained in the wiki creates an xml document.


In this way you don't need to create a string concatenating the 2 info as you did but a proper document



Something like this.



<xml>


<info>


        <desc>myDescHere</desc>


        <ip>myIpHere<ip/>


</info>


</xml>



About your code.



Line 5 won't work because your are defining an encoded query.


The canonical way of executing a query is


gr.addQuery('fieldName', 'Value');


Otherwise your code will work if you execute


gr.addEncodedQuery('sys_id=' + value);



Line 7. Probably will work but as described in the wiki you need to define an if statement OR while loop when you use next.


The reason is simple when you execute a query the system return an array.


You can cycle into this array while(gr.next()) OR taking the first value - if (gr.next())



Line 11. The query you need to create for this one refers on the network adapter table.


Network_Adapter___ServiceNow.png



If you check that table you will notice that there is a field named configuration item that define the link with your server.


This means that you need to retrieve the right network adapter linked with your server.


So if you have a look to my code line 18, i'm reusing the sys_id of the server to obtain the right net adapter and than retrieve the IP



I hope this will help.



More info about query here


GlideRecord - ServiceNow Wiki



Kind Regard



R0b0


Thank you for your reply.


I have a few questions in green. I hope you can help me understand those lines. Thank you.



  var serverId = this.getParameter('sysparm_server_id');  


  var gr = new GlideRecord('cmdb_ci_server');  


  gr.addQuery('sys_id', serverId);  


  gr.query();     //?


  if(gr.next()){  


 


      var result = this.newItem("result");   //what does this do?


      this._addInfo("desc", gr.description);  



      var netAdpt = new GlideRecord('cmdb_ci_network_adapter');   //is this searching inside the network table?


      netAdpt.addQuery('cmdb_ci', gr.sys_id); //why are you passing cmdb_ci and gr.sys_id


      netAdpt.query();     //what does this do?


      if(netAdpt.next()){     //why is this inside of an if


            this._addInfo("ip", netAdpt.ip_address);   //what does this do?


      }  


 


  }  


},  


 


 


  _addInfo : function(name, value) {   //why are you passing name and value?


  var info = this.newItem("info");     // what does this do?


  info.setAttribute("name", name);     //what does setAttribute do? why is it name?


  info.setAttribute("value", value);   //what does setAttribute do? why is it value?


  },  


 


  type: 'PenTestCatalogTaskAjax'  


});  


Ivano B
ServiceNow Employee
ServiceNow Employee

Ok


.query() >> this is the command that used to execute the query


var result >> apologies this is something useless. I didn't notice you can remove it from both the scripts



Line 10 > Declare the table on which the query will be executed.


Line 11 > As explained network adapter is connected through the server using a field named cmdb_ci. This means that you have to provide the sys_id of your sever (gr.sys_id). It was ok also to use netAdpt.addQuery('cmdb_ci', serverId);


Line 13 > After the query netAdpt is an array. Supposing there is just one network adapter of the server the array has - possibly - just one element. The if statement is used as control to check the array and pick the first element.


Line 14 > call the private function providing a name and a value


Line 21-25 > when the function is called, a new xml node marked 'info' is created. Inside this node there will be 2 attributes the first one called name set with the name provided and another one named value set with the value provided.


for instance


      <info name='ip' value='myIP'>


      <info name='desc' value='myDescription'>



I hope this will help/answer your question and if it does please mark it



More info around the query here



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



Cheers


R0bo