Client Script Help

jared_wentzel
Kilo Contributor

What am I missing here... It worked like one time then after that it's not pulling the correct value! I think it has something to do with the my use of the toLowerCase() function or something. I need to use that because some values are populated as lower case and some are uppercase and it is not uniform from the source. Any ideas what I might be doing wrong?

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

{

      if (g_form.getValue('caller_id') != "")

              {

              var userNetID = g_form.getValue('caller_id.user_name');

              g_form.setValue('u_last', getLastMachine(userNetID));

              }

      else

      {

              g_form.setValue('u_last', "");

      }

function getLastMachine(userNetID)

      {

      var gr = new GlideRecord('u_cilastloggedinto');

      gr.addQuery('u_userid.toLowerCase()', userNetID.toLowerCase());

      gr.query();

      if(gr.next())

              {

              return gr.u_machine;

              }

      }

}

1 ACCEPTED SOLUTION

jonathanurie1
Mega Contributor

Hi Jared,



That's funny that you say that it worked the first time you ran it, because I don't think that you can dot walk on a reference field from a client-side script. As far as the client script is concerned, caller_id just contains a sys_id, so using the g_form.getValue('caller_id.user_name') call won't actually return anything.   It looks like Chanchal Chandrakar suggested you try g_form.getReference(), which is a good step in the right direction.



As I'm looking at your script further, I think you're right in that the toLowerCase is messing you up as well.   This line here, in fact seems to be the offending line:



gr.addQuery('u_userid.toLowerCase()', userNetID.toLowerCase());



Notice that the first parameter/argument is 'u_userid.toLowerCase()' which means you're telling the system to query for a column named 'u_userid.toLowerCase().' If you're trying to match up strings exactly, you need to either (1) scrub your data when it gets stored in the new table or (2) change your field type for u_userid to a reference field.   When you go to store data in the table "u_cilastloggedinto" do a toLowerCase() operation on that u_userid field so you are guaranteed that it is lower case when you query it later. The better option, though, would be to change u_userid into a reference field that references the sys_user table.   That way, it would store the person's sys_id and make querying a breeze.



If you were to change the u_userid into a reference field, your script would look something like this:



//On Change client script on the caller_id field


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


        if (newValue != ""){


                  var gr = new GlideRecord('u_cilastloggedinto');


                  gr.addQuery('u_userid', newValue); //newValue is the sys_id of the user in the caller_id field. This value should match a user in the u_cilastloggedinto table's u_userid field.


                  gr.query();


                  if(gr.next()) {


                        g_form.setValue("u_last", gr.u_machine);


                  }


        }


}



Anyway, I think that you can make one of those changes and have it work, but if I may be so bold, I think you can make this script better



When building a client script, there are two things to keep in mind: (1) Always try to minimize your server calls and (2) When you need to make server calls using getReference, make sure you have a callback function specified so you can run the call asynchronously.



In looking at your script, it looks like you want to get the machine they last logged into based on the "u_cilastloggedinto" table, right?   (Actually, I think I saw a similar question from you last week on this, now that I think about it-- I'm glad it's coming along!)   Instead of doing two server calls like your code is doing now, why not set up a GlideAjax script include to do all the heavy lifting for you? The script include itself would reside on the server-side of things and take in a user sys_id as a parameter. Then it would use that sys_id to lookup and return the info you're looking for.



I'll do my best to rough this out, but no promises on it actually working first time, though




Client Side


//Client Side onChange code


//Put this in as an onChange client script attached to the caller_id field



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


        if (newValue != ""){


                  //I'm assuming that this onChange script is attached to caller_id, so the if statement above should prevent this running when the field is blank


                  var ga = new GlideAjax('LastLoggedInHelper'); //the name of the   GlideAjax Script Include


                  ga.addParam("sysparm_name", "getLastMachine"); //The name of the function in the script include you want to call                  


                  ga.addParam("sysparm_user_id", newValue); //This is the new sys_id just entered in the caller_id field


                  ga.getXML(processResponse); //callback function (see below). This allows the script to fire off a request but not lock up the browser while you wait for it to come back.


        }


}



function processResponse(response){


        var answer = response.responseXML.documentElement.getAttribute("answer"); //In this case, I'm going to set my response to be the sys_id of the machine they used last.


        g_form.setValue("u_last", answer);//I"m assuming that u_last is a reference field, so it will know what to do with a sys_id


}





//Server side GlideAjax Code.


//Create a new Script Include and Name it LastLoggedInHelper, then user in this code for the script



var LastLoggedInHelper = Class.create();


LastLoggedInHelper.prototype = Object.extendsObject(AbstractAjaxProcessor, {


    getLastMachine: function(user_sys_id) {



        var user = new GlideRecord("sys_user");        


        if (gr.get(user_sys_id){


                  //we're looking up the user record here so we can get the user_name for that user


                  //If the u_cilastloggedinto table actually stored a reference field with the user's sys_id in it instead of the user's user_name, it would make things much easier.


                  //That would take care of your lowerCase problem too, I think.


       



                  var gr = new GlideRecord('u_cilastloggedinto');


                  gr.addQuery('u_userid', user.user_name);


                  gr.query();


                  if(gr.next()){


                      return gr.u_machine;


                  } else {


                      return "";


                  }


        }


    }



});





Yeah, that's my first draft.   I hope that makes sense!   Like I said, you can do some re-architecting of your u_cilastloggedin table and be okay, but changing things to a GlideAjax will prevent the page from freezing up and it's just good practice.   There's a fantastic wiki article about GlideAjax, so I would defienitely check that out.



Good luck!


View solution in original post

8 REPLIES 8

jonathanurie1
Mega Contributor

Hi Jared,



That's funny that you say that it worked the first time you ran it, because I don't think that you can dot walk on a reference field from a client-side script. As far as the client script is concerned, caller_id just contains a sys_id, so using the g_form.getValue('caller_id.user_name') call won't actually return anything.   It looks like Chanchal Chandrakar suggested you try g_form.getReference(), which is a good step in the right direction.



As I'm looking at your script further, I think you're right in that the toLowerCase is messing you up as well.   This line here, in fact seems to be the offending line:



gr.addQuery('u_userid.toLowerCase()', userNetID.toLowerCase());



Notice that the first parameter/argument is 'u_userid.toLowerCase()' which means you're telling the system to query for a column named 'u_userid.toLowerCase().' If you're trying to match up strings exactly, you need to either (1) scrub your data when it gets stored in the new table or (2) change your field type for u_userid to a reference field.   When you go to store data in the table "u_cilastloggedinto" do a toLowerCase() operation on that u_userid field so you are guaranteed that it is lower case when you query it later. The better option, though, would be to change u_userid into a reference field that references the sys_user table.   That way, it would store the person's sys_id and make querying a breeze.



If you were to change the u_userid into a reference field, your script would look something like this:



//On Change client script on the caller_id field


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


        if (newValue != ""){


                  var gr = new GlideRecord('u_cilastloggedinto');


                  gr.addQuery('u_userid', newValue); //newValue is the sys_id of the user in the caller_id field. This value should match a user in the u_cilastloggedinto table's u_userid field.


                  gr.query();


                  if(gr.next()) {


                        g_form.setValue("u_last", gr.u_machine);


                  }


        }


}



Anyway, I think that you can make one of those changes and have it work, but if I may be so bold, I think you can make this script better



When building a client script, there are two things to keep in mind: (1) Always try to minimize your server calls and (2) When you need to make server calls using getReference, make sure you have a callback function specified so you can run the call asynchronously.



In looking at your script, it looks like you want to get the machine they last logged into based on the "u_cilastloggedinto" table, right?   (Actually, I think I saw a similar question from you last week on this, now that I think about it-- I'm glad it's coming along!)   Instead of doing two server calls like your code is doing now, why not set up a GlideAjax script include to do all the heavy lifting for you? The script include itself would reside on the server-side of things and take in a user sys_id as a parameter. Then it would use that sys_id to lookup and return the info you're looking for.



I'll do my best to rough this out, but no promises on it actually working first time, though




Client Side


//Client Side onChange code


//Put this in as an onChange client script attached to the caller_id field



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


        if (newValue != ""){


                  //I'm assuming that this onChange script is attached to caller_id, so the if statement above should prevent this running when the field is blank


                  var ga = new GlideAjax('LastLoggedInHelper'); //the name of the   GlideAjax Script Include


                  ga.addParam("sysparm_name", "getLastMachine"); //The name of the function in the script include you want to call                  


                  ga.addParam("sysparm_user_id", newValue); //This is the new sys_id just entered in the caller_id field


                  ga.getXML(processResponse); //callback function (see below). This allows the script to fire off a request but not lock up the browser while you wait for it to come back.


        }


}



function processResponse(response){


        var answer = response.responseXML.documentElement.getAttribute("answer"); //In this case, I'm going to set my response to be the sys_id of the machine they used last.


        g_form.setValue("u_last", answer);//I"m assuming that u_last is a reference field, so it will know what to do with a sys_id


}





//Server side GlideAjax Code.


//Create a new Script Include and Name it LastLoggedInHelper, then user in this code for the script



var LastLoggedInHelper = Class.create();


LastLoggedInHelper.prototype = Object.extendsObject(AbstractAjaxProcessor, {


    getLastMachine: function(user_sys_id) {



        var user = new GlideRecord("sys_user");        


        if (gr.get(user_sys_id){


                  //we're looking up the user record here so we can get the user_name for that user


                  //If the u_cilastloggedinto table actually stored a reference field with the user's sys_id in it instead of the user's user_name, it would make things much easier.


                  //That would take care of your lowerCase problem too, I think.


       



                  var gr = new GlideRecord('u_cilastloggedinto');


                  gr.addQuery('u_userid', user.user_name);


                  gr.query();


                  if(gr.next()){


                      return gr.u_machine;


                  } else {


                      return "";


                  }


        }


    }



});





Yeah, that's my first draft.   I hope that makes sense!   Like I said, you can do some re-architecting of your u_cilastloggedin table and be okay, but changing things to a GlideAjax will prevent the page from freezing up and it's just good practice.   There's a fantastic wiki article about GlideAjax, so I would defienitely check that out.



Good luck!


You got it right, it was that line! too bad I didn't see this post before wasting time figuring it out... Thank you! Looks like you can dotwalk in this case



I will look into creating the GlideAjax code as well. Lots of good info on your post!


I'm glad it's all is coming together!


jared_wentzel
Kilo Contributor

I actually figured it out!! I had my single quote in the wrong place... that's why it worked the first time bc I had added the toLowerCase function later on with some other things.



I changed this line


gr.addQuery('u_userid.toLowerCase()', userNetID.toLowerCase());


to this


gr.addQuery('u_userid'.toLowerCase(), userNetID.toLowerCase());



Final code for others to use as a template


=============


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


{


      if (g_form.getValue('caller_id') != "")


              {


              var userNetID = g_form.getValue('caller_id.user_name');


              g_form.setValue('u_last', getLastMachine(userNetID));


              }


      else


      {


              g_form.setValue('u_last', "");


      }



function getLastMachine(userNetID)


      {


      var gr = new GlideRecord('u_cilastloggedinto');


      gr.addQuery('u_userid'.toLowerCase(), userNetID.toLowerCase());


      gr.query();


      if(gr.next())


              {


              return gr.u_machine;


              }


      }


}