UI Action - Copy Form

josephtucker
Giga Contributor

I'm attempting to copy form values from a form into a new form (before insert).

What I've essentially done is:

var fieldsToIgnore = "sys_id, u_rescheduled_entry, schedule, u_change_request, start_date_time, end_date_time";

  var urlString = "";

  // Copy all of the fields not listed in fieldsToIgnore

  try

  {

  for(p in current)

  {

  if(fieldsToIgnore.indexOf(p.toString()) == -1 )

  {

  urlString += p.toString()+"="+current[p]+"^";

  }

  }

  }

  catch(err)

  {

  gs.log(p + " = " + err);

  }

action.setRedirectURL('/cmn_schedule_span.do?sys_id=-1&sysparm_query='+urlString);

The field values appear to be copied properly, however, upon attempting to submit the new entry, I receive this error above one of the reference fields:

Match.PNG

with an error message displayed at the top stating "Invalid update".

Is there anything I perhaps am missing from this? My goal is to allow this form to have the values copied into a new form and allow some modification prior to insert.

1 ACCEPTED SOLUTION

coryseering
ServiceNow Employee
ServiceNow Employee

Joseph,



The for...in syntax is not optimal, since GlideRecord objects can have methods and properties that aren't accessible that way. I've written up a couple of options for you try, which should get the query encoded in the way you expect.


The first block should work if your action is part of the global scope.



//not in scoped app - use this section if you are in global scope


var fieldsToIgnore = ["sys_id", "u_rescheduled_entry", "schedule", "u_change_request", "start_date_time", "end_date_time"];


var recForQuery = new GlideRecord(current.getTableName());


var au = new ArrayUtil();



var name, elem, list = current.getFields();


for (var i = 0; i < list.size(); ++i) {


      elem = list.get(i);


      name = elem.getName();


      if(name && !au.contains(fieldsToIgnore, name))


              if(current.getValue(name))


                      recForQuery.addQuery(name,current.getValue(name));


}


action.setRedirectURL('/cmn_schedule_span.do?sys_id=-1&sysparm_query=' + recForQuery.getEncodedQuery());



If your action is part of a scoped app, the script is a little bit different:


//in scoped app   - use this section if you are in a scoped app


var fieldsToIgnore = ["sys_id", "u_rescheduled_entry", "schedule", "u_change_request", "start_date_time", "end_date_time"];


var recForQuery = new GlideRecord(current.getTableName());


var au = new global.ArrayUtil();



var name, elem, list = current.getElements();


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


      elem = list[i];


      try {


              name = elem.getName();


              if(name && !au.contains(fieldsToIgnore, name))


                      if(current.getValue(name))


                              recForQuery.addQuery(name,current.getValue(name));


      } catch (e) {


              //sometimes the element can't be accessed in scoped app


              //skip it


      }


}



action.setRedirectURL('/cmn_schedule_span.do?sys_id=-1&sysparm_query=' + recForQuery.getEncodedQuery());



You'll see that we build the query using a GlideRecord object- this allows us to take advantage of the getEncodedQuery() method, since the standard URL-params don't pre-fill the fields as you expect them to.



You will want to go through the actual fields that typically get submitted and add more to the list of exclusions- or pick-and-choose the specific fields you want, and reverse the 'contains' condition, thereby limiting the pre-filled fields to ones you specifically choose.



The scoped version can't use getFields, which actually opens it up to errors when the particular GlideElement can't be accessed in JavaScript. This happens infrequently, but will throw an error. I've wrapped a try/catch around it, which isn't ideal. However, unless this UI Action is being used hundreds of times a minute, this should work fine.


View solution in original post

10 REPLIES 10

Michael Fry1
Kilo Patron

You have a gs.log statement, what shows in the system log?


No log shows in this case.


So why not using an after-the-fact, custom Insert&Stay with your limited fields? Otherwise, not sure. Sorry


I may have to leave out the reference fields from the copy, which is not desired, since those are causing the issue.