The Zurich release has arrived! Interested in new features and functionalities? Click here for more

Is there an "After Related List Edit" Event ?

GeoffreyOptumOp
Tera Expert

Oh Wow, it's been a very long day...  Need help...

How do I run some code AFTER the user has edited a related list, and maybe added 10 items and removed 500 items, all at once?  I need to perform an action ONE TIME after all the records have been added to and removed from the task_ci table that is represented by this related list.

find_real_file.png

Currently I have a business rule with some very intensive logic behind it, that is running EVERY TIME a record is deleted from the task_ci table for a task.  It's major overkill.  So again, I need to figure out a clean way to run some code ONLY WHEN all of the "Editing" (adding / deleting) is Done.  Ideally it would happen before the Incident form reloads itself.

Follow?

Thanks!!

1 ACCEPTED SOLUTION

So I ended up replacing code which was running one time for each deletion from the slush bucket TIMES the number of items IN the slush bucket, which ended up being an untenable Order N*N (or N Squared) algorithm, with something that runs JUST ONCE in an On Display business rule.

When the slush bucket is dismissed, there is a round-trip to the server, and On Display is triggered for the parent Incident record.

So what used to sometimes take 5 minutes to run, and sometimes timed out completely, now takes 2 or 3 seconds max.  I'm pretty happy with the result, if I don't say so myself...

The only drawback I can think of is that the "old code", before I changed it, was tied to the related list TABLE itself, whereas my code is now more tied to a USER INTERFACE concept.  So I guess, in theory, if the table was modified NOT by the user, but by back end code (somehow, for some reason), then my super-duper On Display code would never be triggered.

I don't envision that happening, but if someone can think of an even better solution than On Display, I'm all ears.  Thanks!

View solution in original post

6 REPLIES 6

Hi, @Valor .

I'm using "Rome" currently.  When the user hits Edit, a model window appears with a Slush Bucket.  I'm actually confused about where that model Edit button is defined, and if I can configure it in any way.  It seems to be magic, but I'm probably missing something.  (Again, it was a long day.)

I'm leaning towards a design that looks something like this...

User edits the list.  700 "After Delete" Business Rules fire and 100 "After Insert" Business Rules fire.  For each of those I set a Global Flag somewhere that says Incident Number INC123456 Needs additional processing. Maybe I update the "Tag" field of the Incident (?).  Or I could use a custom field, or perhaps even the "Scratch Pad".  Then maybe I can use an "On Load" client side script to check for the flag, do my additional one-time processing, and then turn Off the flag.

Thoughts?

Here's the "Edit..." button -- it's marked as "Global" which is why you couldn't find it.

Since you're using the slushbucket for the edit activity, you wouldn't be able to do a whole lot of magic within the UI action like you can with the newer "Add" modal.

https://<<YOUR INSTANCE>>.service-now.com/nav_to.do?uri=sys_ui_action.do?sys_id=7ca0a8d60a0a0b340080d6f48c880640

 

Now here are two additional approaches you can explore:

  1. add "action.setReturnURL('CUSTOM_UI_PAGE.do')" to a UI Page that you've made that performs your desired action. You could look in the user's stack for her browse history and pull the related incident from that (or the sys_m2m_template page's query string which should have the incident and sys_id
  2. add a "global" UI Script to look for the URL then monkey patch the "saveAllSelected" function to trigger an AJAX call when the M2M form is submitted

Option one would probably be a bit safer, but option 2 is easier.

 

Here's the code for "saveAllSelected"

function saveAllSelected(fromSelectArray, toArray, delim, escape, emptyLabel, doEscape) {
    var translatedEmptyLabel = getMessage(emptyLabel);
    for (var i = 0; i < fromSelectArray.length; i++) {
        if (typeof fromSelectArray[i] == "undefined") {
            toArray[i].value = "";
            continue;
        }
        var toValue = "";
        for (var j = 0; j < fromSelectArray[i].length; j++) {
            if (!(fromSelectArray[i].length == 1 && fromSelectArray[i].options[0].value == translatedEmptyLabel)) {
                var val = fromSelectArray[i].options[j].value;
                if (doEscape) val = encodeURIComponent(val);
                toValue += val.replace(new RegExp(delim, "g"), escape + delim);
            }
            if (j + 1 < fromSelectArray[i].length) toValue += delim;
        }
        toArray[i].value = toValue;
    }
}