These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Help Me Simplify My Javascript Code

GlennOwns
Registered: Jun 30 2010
Posts: 18
Answered

I know... it's a mess.
but the weeks i put into this has saved me months of unnecessary work.
I'm running into a problem lately though... sometimes when i input certain values, it gets cut off like half way through or right before the last character... it throws my whole operation off then =/

is there a way to speed this up? like maybe a good way to recycle variables?

var fld = this.getField("8_1");
var out = this.getField("9a_1");
var inn = fld.valueAsString;
var fxtrm = (inn.slice(16, 20) + " " + inn.slice(20,24) + " " + inn.slice(24,28));
var fgtrm = (inn.slice(7,15) + " " + inn.slice(15,22));
var uspstrm = (inn.slice(0,2) + " " + inn.slice(2,5) + " " + inn.slice(5,8) + " " + inn.slice(8,11) + " " + inn.slice(11,13));
var uspsctrm = (inn.slice(0,4) + " " + inn.slice(4,8) + " " + inn.slice(8,12) + " " + inn.slice(12,16) + " " + inn.slice(16,20));
var browntrm = (inn.slice(0,2) + " " + inn.slice(2,5) + " " + inn.slice(5,8) + " " + inn.slice(8,10) + " " + inn.slice(10,14) + " " + inn.slice(14,18));
var dhltrm = (inn.slice(0,2) + " " + inn.slice(2,6) + " " + inn.slice(6,10));
var omtrm = (inn.slice(0,5) + " " + inn.slice(5,9) + " " + inn.slice(9,13) + " " + inn.slice(13,17) + " " + inn.slice(17,20));
var uspse = /^E\D{1}\d{9}\D{2}$/;
var uspsr = /^R\D{1}\d{9}\D{2}$/;
var uspsc = /^7\d{19}$/;
var uspsi = /^V\D{1}\d{9}\D{2}$/;
var fgreg = /^961[1-3](01[5-9]|02[0-1]|131|1[5-6][0-9]|3[0-9][0-9]|4[0-3][0-9]|44[0-4])\d{15}$/;
var fxig = /^961[1-3](02[2-8]|135|141|20[0-3]|4[7-8][0-9]|49[0-3])d{15}$/;
var fxgh = /^961[1-3][7-8][0-9][0-9]d{15}$/;
var fxgr = /^961[1-3]900d{15}$/;
var fxgsp = /^961[1-3](90[6-9]|91[0-8])d{15}$/;
var fxso = /^3\d{7}5\d{23}$/;
var fxpo = /^3\d{7}1\d{23}$/;
var fx2 = /^3\d{7}3\d{23}$/;
var fxs = /^3\d{7}2\d{23}$/;
var fxfo = /^3\d{7}6\d{23}$/;
var fxie = /^3\d{7}4\d{23}$/;
var fxm = /^3\d{7}0\d{23}$/;
var ugreg = /^1Z\w{6}(03|[247]2|78)\d{8}$/;
var usda = /^1Z\w{6}02\d{8}$/;
var unda = /^1Z\w{6}(01|13|15|32)\d{8}$/;
var unaa = /^1Z\w{6}A[0129A]\d{8}$/;
var ugas = /^1Z\w{6}A8\d{8}$/;
var u3d = /^1Z\w{6}12\d{8}$/;
var unas = /^1Z\w{6}(33|41|44)\d{8}$/;
var uwe = /^1Z\w{6}66\d{8}$/;
var ugr = /^1Z\w{6}90\d{8}$/;
var de = /^\d{10}$/;
var ome = /^00\d{18}$/;
var upsv = /^1Z\w{6}D\d{9}$/;
if (uspse.test(inn)){out.value = "USPS Express", fld.value =  uspstrm}
if (uspsr.test(inn)){out.value = "USPS Registered", fld.value = uspstrm}
if (uspsc.test(inn)){out.value = "USPS Certified", fld.value = uspsctrm}
if (uspsi.test(inn)){out.value = "USPS Insured", fld.value =uspstrm}
if (fgreg.test(inn)){out.value = "FedEx Ground",  fld.value = fgtrm}
if (fxig.test(inn)){out.value = "FedEx Intl Ground",  fld.value = fgtrm}
if (fxgh.test(inn)){out.value = "FedEx Ground Home",  fld.value = fgtrm}
if (fxgr.test(inn)){out.value = "FedEx Ground Returns",  fld.value = fgtrm}
if (fxgsp.test(inn)){out.value = "FedEx Ground SmartPost",  fld.value = fgtrm}
if (fxso.test(inn)){out.value = "FedEx Standard Overnight", fld.value = fxtrm}
if (fxpo.test(inn)){out.value = "FedEx Priority Overnight", fld.value = fxtrm}
if (fx2.test(inn)){out.value = "FedEx 2-Day Express", fld.value = fxtrm}
if (fxs.test(inn)){out.value = "FedEx Express Saver", fld.value = fxtrm}
if (fxfo.test(inn)){out.value = "FedEx First Overnight", fld.value = fxtrm}
if (fxie.test(inn)){out.value = "FedEx Intl Economy", fld.value = fxtrm}
if (fxm.test(inn)){out.value = "FedEx Express Master", fld.value = fxtrm}
if (ugreg.test(inn)){out.value = "UPS Ground", fld.value = browntrm}
if (upsv.test(inn)){out.value = "UPS Saver", fld.value = browntrm}
if (usda.test(inn)){out.value = "UPS 2nd Day Air", fld.value = browntrm}
if (unda.test(inn)){out.value = "UPS Next Day Air", fld.value = browntrm}
if (unaa.test(inn)){out.value = "UPS Next Day Air Adult", fld.value = browntrm}
if (ugas.test(inn)){out.value = "UPS Ground Adult Sign", fld.value = browntrm}
if (u3d.test(inn)){out.value = "UPS 3-Day Select", fld.value = browntrm}
if (unas.test(inn)){out.value = "UPS Next Day Air Sat", fld.value = browntrm}
if (uwe.test(inn)){out.value = "UPS Worldwide Express", fld.value = browntrm}
if (ugr.test(inn)){out.value = "UPS Ground Returns", fld.value = browntrm}
if (de.test(inn)){out.value = "DHL Express", fld.value = dhltrm}
if (ome.test(inn)){out.value = "OfficeMax Express", fld.value = omtrm}

My Product Information:
Acrobat Pro 9.3.1, Windows
George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1876
You might want to describe the problem you're having in more detail. For example, I don't know what you mean by "it gets cut off halfway through or right before the last character".

It seems like what you're doing is setting the value of two fields based on the value of another input field. There are 28 possibilities, and each possibility has an associated regular expression, a description, and another string constructed by inserting spaces to the input string.

I might be inclined to set up a 28 element array, with each value being either an object (for regexp, description, modified input) or 3 element array (for regexp, description, modified input). You could then set up a loop to go through the array and test each regular expression against the input, and output the corresponding description and modified input. You could also break out of the loop and stop if it's not necessary to test any subsequent regular expressions after you've found a match. If it's not, and you order the elements in the array according to most likely to occur, it should speed things up considerably.

e.g.,

// First ten lines of your original script go here

// Populate array
var a = [];
a.push([/^E\D{1}\d{9}\D{2}$/, "USPS Express", uspstrm]);
a.push([/^R\D{1}\d{9}\D{2}$/, "USPS Registered", uspstrm]);
... // Continue adding elements here
a.push([/^1Z\w{6}D\d{9}$/, "OfficeMax Express", omtrm]);

for (var i = 0; i < a.length; i += 1) {
if (a[i][0].test(inn) {
out.value = a[i][1];
fld.value = a[i][2];
break; // unless you need to continue
}
}

If you do something like this, you can prepopulate the first two items of each subarray when the document opens, so you don't need to do it more than once at runtime, which may speed things up. It's not clear if this code normally gets executed more than once in a session.

Good luck!
GlennOwns
Registered: Jun 30 2010
Posts: 18
George_Johnson wrote:
You might want to describe the problem you're having in more detail. For example, I don't know what you mean by "it gets cut off halfway through or right before the last character".It seems like what you're doing is setting the value of two fields based on the value of another input field. There are 28 possibilities, and each possibility has an associated regular expression, a description, and another string constructed by inserting spaces to the input string.

I might be inclined to set up a 28 element array, with each value being either an object (for regexp, description, modified input) or 3 element array (for regexp, description, modified input). You could then set up a loop to go through the array and test each regular expression against the input, and output the corresponding description and modified input. You could also break out of the loop and stop if it's not necessary to test any subsequent regular expressions after you've found a match. If it's not, and you order the elements in the array according to most likely to occur, it should speed things up considerably.

e.g.,

// First ten lines of your original script go here

// Populate array
var a = [];
a.push([/^E\D{1}\d{9}\D{2}$/, "USPS Express", uspstrm]);
a.push([/^R\D{1}\d{9}\D{2}$/, "USPS Registered", uspstrm]);
... // Continue adding elements here
a.push([/^1Z\w{6}D\d{9}$/, "OfficeMax Express", omtrm]);

for (var i = 0; i < a.length; i += 1) {
if (a[i][0].test(inn) {
out.value = a[i][1];
fld.value = a[i][2];
break; // unless you need to continue
}
}

If you do something like this, you can prepopulate the first two items of each subarray when the document opens, so you don't need to do it more than once at runtime, which may speed things up. It's not clear if this code normally gets executed more than once in a session.

Good luck!
Wow, that is almost exactly what i was looking for.
Sorry that i was a little vague there... maybe if i explain my problem a little more..

Basically, I have a pdf that i HAVE to use for documenting transactions of mail (USPS/DHL/Fed/UPS/etc).
I have a 20 fields of input that determine 20 fields of text. i am forced to use regular expressions to verify the inputs (ie: 1Z 123 123 03 1234 1234 = UPS Ground, 1234 1234 1234 = FedEx Express, EX 123 123 123 US = USPS Express, etc...)

I use a scanner to input the tracking numbers into the fields. the scanner is automatically set to [enter] after input of the number (adobe only recognizes [tab]). so i set up this code to automatically ]tab] on [enter].
if (event.commitKey == 2)this.getField('8_2').setFocus();
if (event.commitKey == 2)this.getField('8_3').setFocus();
(Basically, i manually define each of the 20 inputs where to set focus on this event via "Custom Keystroke Script" in the Format options of the field (is there an easier way?).

Next, i wanted the input of the one field to determine the contents of another field next to it.
So how do i determine the event? I didn't want the regexp to run if the scanner hasn't finished inputting the WHOLE number, so i used "On Blur" as the event.

Action: On Blur, Run a JavaScript
if (uspse.test(inn)){out.value = "USPS Express", fld.value =  uspstrm}if (uspsr.test(inn)){out.value = "USPS Registered", fld.value = uspstrm}if (uspsc.test(inn)){out.value = "USPS Certified", fld.value = uspsctrm}if (uspsi.test(inn)){out.value = "USPS Insured", fld.value =uspstrm}if (fgreg.test(inn)){out.value = "FedEx Ground",  fld.value = fgtrm}if (fxig.test(inn)){out.value = "FedEx Intl Ground",  fld.value = fgtrm}if (fxgh.test(inn)){out.value = "FedEx Ground Home",  fld.value = fgtrm}if (fxgr.test(inn)){out.value = "FedEx Ground Returns",  fld.value = fgtrm}if (fxgsp.test(inn)){out.value = "FedEx Ground SmartPost",  fld.value = fgtrm}if (fxso.test(inn)){out.value = "FedEx Standard Overnight", fld.value = fxtrm}if (fxpo.test(inn)){out.value = "FedEx Priority Overnight", fld.value = fxtrm}if (fx2.test(inn)){out.value = "FedEx 2-Day Express", fld.value = fxtrm}if (fxs.test(inn)){out.value = "FedEx Express Saver", fld.value = fxtrm}if (fxfo.test(inn)){out.value = "FedEx First Overnight", fld.value = fxtrm}if (fxie.test(inn)){out.value = "FedEx Intl Economy", fld.value = fxtrm}if (fxm.test(inn)){out.value = "FedEx Express Master", fld.value = fxtrm}if (ugreg.test(inn)){out.value = "UPS Ground", fld.value = browntrm}if (upsv.test(inn)){out.value = "UPS Saver", fld.value = browntrm}if (usda.test(inn)){out.value = "UPS 2nd Day Air", fld.value = browntrm}if (unda.test(inn)){out.value = "UPS Next Day Air", fld.value = browntrm}if (unaa.test(inn)){out.value = "UPS Next Day Air Adult", fld.value = browntrm}if (ugas.test(inn)){out.value = "UPS Ground Adult Sign", fld.value = browntrm}if (u3d.test(inn)){out.value = "UPS 3-Day Select", fld.value = browntrm}if (unas.test(inn)){out.value = "UPS Next Day Air Sat", fld.value = browntrm}if (uwe.test(inn)){out.value = "UPS Worldwide Express", fld.value = browntrm}if (ugr.test(inn)){out.value = "UPS Ground Returns", fld.value = browntrm}if (de.test(inn)){out.value = "DHL Express", fld.value = dhltrm}if (ome.test(inn)){out.value = "OfficeMax Express", fld.value = omtrm}

And i have a "Custom Format Script" in place that set these variables.
if (event.commitKey == 2)this.getField('8_3').setFocus();var fld = this.getField("8_2");var out = this.getField("9a_2");var inn = fld.valueAsString;var fxtrm = (inn.slice(16, 20) + " " + inn.slice(20,24) + " " + inn.slice(24,28));var fgtrm = (inn.slice(7,15) + " " + inn.slice(15,22));var uspstrm = (inn.slice(0,2) + " " + inn.slice(2,5) + " " + inn.slice(5,8) + " " + inn.slice(8,11) + " " + inn.slice(11,13));var uspsctrm = (inn.slice(0,4) + " " + inn.slice(4,8) + " " + inn.slice(8,12) + " " + inn.slice(12,16) + " " + inn.slice(16,20));var browntrm = (inn.slice(0,2) + " " + inn.slice(2,5) + " " + inn.slice(5,8) + " " + inn.slice(8,10) + " " + inn.slice(10,14) + " " + inn.slice(14,18));var dhltrm = (inn.slice(0,2) + " " + inn.slice(2,6) + " " + inn.slice(6,10));var omtrm = (inn.slice(0,5) + " " + inn.slice(5,9) + " " + inn.slice(9,13) + " " + inn.slice(13,17) + " " + inn.slice(17,20));var uspse = /^E\D{1}\d{9}\D{2}$/;var uspsr = /^R\D{1}\d{9}\D{2}$/;var uspsc = /^7\d{19}$/;var uspsi = /^V\D{1}\d{9}\D{2}$/;var fgreg = /^961[1-3](01[5-9]|02[0-1]|131|1[5-6][0-9]|3[0-9][0-9]|4[0-3][0-9]|44[0-4])\d{15}$/;var fxig = /^961[1-3](02[2-8]|135|141|20[0-3]|4[7-8][0-9]|49[0-3])d{15}$/;var fxgh = /^961[1-3][7-8][0-9][0-9]d{15}$/;var fxgr = /^961[1-3]900d{15}$/;var fxgsp = /^961[1-3](90[6-9]|91[0-8])d{15}$/;var fxso = /^3\d{7}5\d{23}$/;var fxpo = /^3\d{7}1\d{23}$/;var fx2 = /^3\d{7}3\d{23}$/;var fxs = /^3\d{7}2\d{23}$/;var fxfo = /^3\d{7}6\d{23}$/;var fxie = /^3\d{7}4\d{23}$/;var fxm = /^3\d{7}0\d{23}$/;var ugreg = /^1Z\w{6}(03|[247]2|78)\d{8}$/;var usda = /^1Z\w{6}02\d{8}$/;var unda = /^1Z\w{6}(01|13|15|32)\d{8}$/;var unaa = /^1Z\w{6}A[0129A]\d{8}$/;var ugas = /^1Z\w{6}A8\d{8}$/;var u3d = /^1Z\w{6}12\d{8}$/;var unas = /^1Z\w{6}(33|41|44)\d{8}$/;var uwe = /^1Z\w{6}66\d{8}$/;var ugr = /^1Z\w{6}90\d{8}$/;var de = /^\d{10}$/;var ome = /^00\d{18}$/;var upsv = /^1Z\w{6}D\d{9}$/;

That is the entirety of ONE field of input.
I have to copy, paste and tweak this 20x for all the other fields...


Is there a better way to do this? This script is REALLY stretching the bounds of my knowledge. I'm surprised I even got it working in the first place! Thanks in advance!
GlennOwns
Registered: Jun 30 2010
Posts: 18
Also, when i said "it gets cut off," i meant that sometimes, the commit key event would execute before the entire number was enter (thus rendering the regexp function that determines the output, useless).

From what i can tell.. the scanner scans a barcode, decodes the number from it, and then sends the entire number+the [enter] key event in a sequence (as if someone was typing it very fast followed by [enter])

I think sometimes adobe gets ahead of itself and interrupts the text and applies [enter] mid input =/
George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1876
In my mind the correct event to call all of this code is in an input field's Validate event, which gets triggered after the field's value is changed and committed. It is best to place the code in a document-level function and call the function from the Validate event of the field.
GlennOwns
Registered: Jun 30 2010
Posts: 18
Alright, so the first guy's suggestion is working great. I'm building it this way now.
But i can see how putting it in a document-level function and calling on it by validation would make sense..

The only problem with that is, I don't know anything about functions. i am shoulder deep as it is. everything i have shown you is about all i know. anything not described here, i really don't know. before this project, i didn't know squat about JavaScript, Regular Expressions, Variables, Arrays, anything.

Some more help would be very appreciated. I'll post the finished code when i'm done. Thanks a bunch! =]
George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1876
For more information on document-level JavaScripts, see: http://acrobatusers.com/tutorials/2007/07/js_document_scripts

and browse through the other JavaScript related tutorials by Thom to pick up other useful information.

Best practice is to place as much code as possible in document-level scripts and call your functions from field events.
GlennOwns
Registered: Jun 30 2010
Posts: 18
Alright, alright. Did so. Copying the code into the document level area doesn't seem to work for some reason... Do i just paste it as a new Javascript function? Then how would i call it in validate? I thought it was something like Validate (xxx, xxx, xxx) or something. But this is beatin me up. Sorry if I'm a bit confusing.
var inn = fld.valueAsString;var fxtrm = (inn.slice(16, 20) + " " + inn.slice(20,24) + " " + inn.slice(24,28));var fgtrm = (inn.slice(7,15) + " " + inn.slice(15,22));var uspstrm = (inn.slice(0,2) + " " + inn.slice(2,5) + " " + inn.slice(5,8) + " " + inn.slice(8,11) + " " + inn.slice(11,13));var uspsctrm = (inn.slice(0,4) + " " + inn.slice(4,8) + " " + inn.slice(8,12) + " " + inn.slice(12,16) + " " + inn.slice(16,20));var browntrm = (inn.slice(0,2) + " " + inn.slice(2,5) + " " + inn.slice(5,8) + " " + inn.slice(8,10) + " " + inn.slice(10,14) + " " + inn.slice(14,18));var dhltrm = (inn.slice(0,2) + " " + inn.slice(2,6) + " " + inn.slice(6,10));var omtrm = (inn.slice(0,5) + " " + inn.slice(5,9) + " " + inn.slice(9,13) + " " + inn.slice(13,17) + " " + inn.slice(17,20)); var a = [];a.push([/^1Z\w{6}D\d{9}$/, "OfficeMax Express", omtrm]);a.push([/^7\d{19}$/, "USPS Certified", uspsctrm]);a.push([/^E\D{1}\d{9}\D{2}$/, "USPS Express", uspstrm]);a.push([/^R\D{1}\d{9}\D{2}$/, "USPS Registered", uspstrm]);a.push([/^V\D{1}\d{9}\D{2}$/, "USPS Insured", uspstrm]);a.push([/^961[1-3](01[5-9]|02[0-1]|131|1[5-6][0-9]|3[0-9][0-9]|4[0-3][0-9]|44[0-4])\d{15}$/, "FedEx Ground", fgtrm]);a.push([/^961[1-3](02[2-8]|135|141|20[0-3]|4[7-8][0-9]|49[0-3])d{15}$/, "FedEx Intl Ground", fgtrm]);a.push([/^961[1-3][7-8][0-9][0-9]d{15}$/, "FedEx Ground Home", fgtrm]);a.push([/^961[1-3](90[6-9]|91[0-8])d{15}$/, "FedEx Ground Returns", fgtrm]);a.push([/^3\d{7}5\d{23}$/, "FedEx Ground SmartPost", fgtrm]);a.push([/^3\d{7}1\d{23}$/, "FedEx Standard Overnight", fxtrm]);a.push([/^3\d{7}3\d{23}$/, "FedEx Priority Overnight", fxtrm]);a.push([/^3\d{7}3\d{23}$/, "FedEx 2-Day Express", fxtrm]);a.push([/^3\d{7}2\d{23}$/, "FedEx Express Saver", fxtrm]);a.push([/^3\d{7}6\d{23}$/, "FedEx First Overnight", fxtrm]);a.push([/^3\d{7}4\d{23}$/, "FedEx Intl Economy", fxtrm]);a.push([/^3\d{7}0\d{23}$/, "FedEx Express Master", fxtrm]);a.push([/^1Z\w{6}(03|[247]2|78)\d{8}$/, "UPS Ground", browntrm]);a.push([/^1Z\w{6}D\d{9}$/, "UPS Saver ", browntrm]);a.push([/^1Z\w{6}02\d{8}$/, "UPS 2nd Day Air", browntrm]);a.push([/^1Z\w{6}(01|13|15|32)\d{8}$/, "UPS Next Day Air", browntrm]);a.push([/^1Z\w{6}A[0129A]\d{8}$/, "UPS Next Day Air Adult", browntrm]);a.push([/^1Z\w{6}A8\d{8}$/, "UPS Ground Adult Sign", browntrm]);a.push([/^1Z\w{6}12\d{8}$/, "UPS 3-Day Select ", browntrm]);a.push([/^1Z\w{6}(33|41|44)\d{8}$/, "UPS Next Day Air Sat", browntrm]);a.push([/^1Z\w{6}66\d{8}$/, "UPS Worldwide Express", browntrm]);a.push([/^1Z\w{6}90\d{8}$/, "UPS Ground Returns", browntrm]);a.push([/^\d{10}$/, "DHL Express ", dhltrm]); for (var i = 0; i < a.length; i += 1) {if (a[i][0].test(inn)) {out.value = a[i][1]; fld.value = a[i][2]; break;}}

Also, here is the code I can't seem to automate and have to assign manually.
var fld = this.getField("8_1");var out = this.getField("9a_1");

var fld = this.getField("8_2");var out = this.getField("9a_2");

var fld = this.getField("8_3");var out = this.getField("9a_3");

etc...

Thanks in advance!
George_Johnson
Expert
Registered: Jul 6 2008
Posts: 1876
After taking a closer look at your code, I realized that a better approach would likely be to use a custom Format script for all of you input fields, as opposed to a Validate script, since you're adding spaces at strategic locations to the value that gets placed in the input fields. A Format script is primarily used to alter the way a field value is displayed, without changing the underlying field value.

So try the following. All of it is intended to be placed in a document-level JavaScript:

// Set up array// [regular expression, description, format id for adding spaces]var a = [];a.push([/^1Z\w{6}D\d{9}$/, "OfficeMax Express", "omtrm"]);a.push([/^7\d{19}$/, "USPS Certified", "uspsctrm"]);a.push([/^E\D{1}\d{9}\D{2}$/, "USPS Express", "uspstrm"]);a.push([/^R\D{1}\d{9}\D{2}$/, "USPS Registered", "uspstrm"]);a.push([/^V\D{1}\d{9}\D{2}$/, "USPS Insured", "uspstrm"]);a.push([/^961[1-3](01[5-9]|02[0-1]|131|1[5-6][0-9]|3[0-9][0-9]|4[0-3][0-9]|44[0-4])\d{15}$/, "FedEx Ground", "fgtrm"]);a.push([/^961[1-3](02[2-8]|135|141|20[0-3]|4[7-8][0-9]|49[0-3])d{15}$/, "FedEx Intl Ground", "fgtrm"]);a.push([/^961[1-3][7-8][0-9][0-9]d{15}$/, "FedEx Ground Home", "fgtrm"]);a.push([/^961[1-3](90[6-9]|91[0-8])d{15}$/, "FedEx Ground Returns", "fgtrm"]);a.push([/^3\d{7}5\d{23}$/, "FedEx Ground SmartPost", "fgtrm"]);a.push([/^3\d{7}1\d{23}$/, "FedEx Standard Overnight", "fxtrm"]);a.push([/^3\d{7}3\d{23}$/, "FedEx Priority Overnight", "fxtrm"]);a.push([/^3\d{7}3\d{23}$/, "FedEx 2-Day Express", "fxtrm"]);a.push([/^3\d{7}2\d{23}$/, "FedEx Express Saver", "fxtrm"]);a.push([/^3\d{7}6\d{23}$/, "FedEx First Overnight", "fxtrm"]);a.push([/^3\d{7}4\d{23}$/, "FedEx Intl Economy", "fxtrm"]);a.push([/^3\d{7}0\d{23}$/, "FedEx Express Master", "fxtrm"]);a.push([/^1Z\w{6}(03|[247]2|78)\d{8}$/, "UPS Ground", "browntrm"]);a.push([/^1Z\w{6}D\d{9}$/, "UPS Saver ", "browntrm"]);a.push([/^1Z\w{6}02\d{8}$/, "UPS 2nd Day Air", "browntrm"]);a.push([/^1Z\w{6}(01|13|15|32)\d{8}$/, "UPS Next Day Air", "browntrm"]);a.push([/^1Z\w{6}A[0129A]\d{8}$/, "UPS Next Day Air Adult", "browntrm"]);a.push([/^1Z\w{6}A8\d{8}$/, "UPS Ground Adult Sign", "browntrm"]);a.push([/^1Z\w{6}12\d{8}$/, "UPS 3-Day Select ", "browntrm"]);a.push([/^1Z\w{6}(33|41|44)\d{8}$/, "UPS Next Day Air Sat", "browntrm"]);a.push([/^1Z\w{6}66\d{8}$/, "UPS Worldwide Express", "browntrm"]);a.push([/^1Z\w{6}90\d{8}$/, "UPS Ground Returns", "browntrm"]);a.push([/^\d{10}$/, "DHL Express ", "dhltrm"]); function addSpaces(v, id) { // v = input string// Add spaces to input string depending on what type (id) it is switch (id) {case "fxtrm" :return  v.slice(16, 20) + " " + v.slice(20,24) + " " + v.slice(24,28);break;case "fgtrm" :return v.slice(7,15) + " " + v.slice(15,22);break;case "uspstrm" :return v.slice(0,2) + " " + v.slice(2,5) + " " + v.slice(5,8) + " " + v.slice(8,11) + " " + v.slice(11,13);break;case "uspsctrm" :return v.slice(0,4) + " " + v.slice(4,8) + " " + v.slice(8,12) + " " + v.slice(12,16) + " " + v.slice(16,20);break;case "browntrm" :return v.slice(0,2) + " " + v.slice(2,5) + " " + v.slice(5,8) + " " + v.slice(8,10) + " " + v.slice(10,14) + " " + v.slice(14,18);break;case "dhltrm" :return v.slice(0,2) + " " + v.slice(2,6) + " " + v.slice(6,10);break;case "omtrm" :return v.slice(0,5) + " " + v.slice(5,9) + " " + v.slice(9,13) + " " + v.slice(13,17) + " " + v.slice(17,20);break;default:return v;break;}} function formatTrackingNum() { // Get input field's valuevar inn = event.value; // Determine description field name by stripping index number from this field's namevar out = getField("9a_" + event.target.name.split("_")[1]); // Try to find a match, then get description and value with spaces addedfor (var i = 0; i < a.length; i += 1) {if (a[i][0].test(inn)) {out.value = a[i][1];  // Descriptionevent.value = addSpaces(inn, a[i][2]); // Input with spaces added//break;}}}

Then, in each of the input field's custom Format script you can simply use the following function call:

formatTrackingNum();
Note that the final "break" statement is commented out since it's not clear to me whether this is required or not. Not all of your regular expressions are mutually exclusive (e.g., UPS 2nd Day Air and UPS Next Day Air are the same), so you may need to go through them all each time.

Also, the field name for the description fields (9a_#) are determined based on the field name of the input field that triggered the Format script, so your last question is taken care of, as long as you maintain that field naming convention.

Now the code is all in one place, making revisions easier. It is also more generic, so the same code can be used by multiple fields. And it should be more efficient since much of the code is not executed every time a field value is changed. For example, the code that sets up the array is executed once when the document is opened. More improvements could be made, but this should get you started.

Only one global variable, one if, and one switch!