Expand my Community achievements bar.

How to make a script that can work universally across any page and any object

Avatar

Level 3

I have a script, that due to how they wanted the form to look and all of these alerts that are necessary, there are 13 scripts which span across multiple pages, and multiple objects, and was trying to find a way that all I would have to do is change the field names, so i was wondering if someone could help me out, as I was trying to search for it, and I could not find it.

Here is the script

if(pmp.Page1.object1.kpi1.rawValue == null)
{// Field is empty, other fields not required
pmp.Page1.object1.Table1.Row1.ratingbox1_1.mandatory = "";
pmp.Page1.object1.Table1.Row1.ratingbox1_2.mandatory = "";
pmp.Page1.object1.Table1.Row1.ratingbox1_3.mandatory = "";
pmp.Page1.object1.Table1.Row1.ratingbox1_4.mandatory = "";
pmp.Page1.object1.Table1.Row1.ratingbox1_5.mandatory = "";

}
else
if(pmp.Page1.object1.kpi1.rawValue != null)
{// Field has data, other feilds required
pmp.Page1.object1.Table1.Row1.ratingbox1_1.mandatory = "error";
pmp.Page1.object1.Table1.Row1.ratingbox1_2.mandatory = "error";
pmp.Page1.object1.Table1.Row1.ratingbox1_3.mandatory = "error";
pmp.Page1.object1.Table1.Row1.ratingbox1_4.mandatory = "error";
pmp.Page1.object1.Table1.Row1.ratingbox1_5.mandatory = "error";

}

 

So the pages this code need to be on are pages 1 to 6, and the objects go from 1 to 13, then the ratingbox field changes from ratingbox1_ to ratingbox13_

 

I was going through and using the search and replace function, and saving the form every change, but i just realized, after going back to multiple fields, the code reverted back to the above code, so I was trying not to have to do that again.

19 Replies

Avatar

Level 5

I guess you could create a loop running through each object, i.e. from 1 thru 13, create a string variable to specify the targeted object and set the mandatory status using the resolveNode property. Something like:

for (var i=1; i<=13;i++){

  var sTarget = "object"+i;

  if(this.resolveNode(sTarget).kpi1.rawValue == null){   // Field is empty, other fields not required
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_1.mandatory = "disabled";
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_2.mandatory = "disabled";
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_3.mandatory = "disabled";
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_4.mandatory = "disabled";
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_5.mandatory = "disabled";

  } else  {  // Field has data, other fields required
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_1.mandatory = "error";
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_2.mandatory = "error";
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_3.mandatory = "error";
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_4.mandatory = "error";
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_5.mandatory = "error";

  }

}

 

[I learned that recently - thanks to this community - that while somefield.mandatory = ""; works, the preferred statement would be somefield.mandatory = "disabled";]

 

Avatar

Level 5

another thought though: since your fields have a default value (0), I think making these field "required" will visually show it, but it won't force the user to change the value of the field.  

Avatar

Level 5

And now I realize the rating box fields also change numbers,... so here is a revised script

for (var i=1; i<=13;i++){

  var sTarget = "object"+i;

  var sTargetRatingBox_1 = sTarget+".Table1.Row1.ratingbox"+i+"_1";

  var sTargetRatingBox_2 = sTarget+".Table1.Row1.ratingbox"+i+"_2";

  var sTargetRatingBox_3 = sTarget+".Table1.Row1.ratingbox"+i+"_3";

  var sTargetRatingBox_4 = sTarget+".Table1.Row1.ratingbox"+i+"_4";

  var sTargetRatingBox_5 = sTarget+".Table1.Row1.ratingbox"+i+"_5";

  if(this.resolveNode(sTarget).kpi1.rawValue == null){   // Field is empty, other fields not required
    this.resolveNode(sTargetRatingBox_1 ).mandatory = "disabled";
    this.resolveNode(sTargetRatingBox_2 ).mandatory = "disabled";
    this.resolveNode(sTargetRatingBox_3 ).mandatory = "disabled";
    this.resolveNode(sTargetRatingBox_4 ).mandatory = "disabled";
    this.resolveNode(sTargetRatingBox_5 ).mandatory = "disabled";

  } else  {  // Field has data, other fields required
    this.resolveNode(sTargetRatingBox_1 ).mandatory = "error";
    this.resolveNode(sTargetRatingBox_2 ).mandatory = "error";
    this.resolveNode(sTargetRatingBox_3 ).mandatory = "error";
    this.resolveNode(sTargetRatingBox_4 ).mandatory = "error";
    this.resolveNode(sTargetRatingBox_5 ).mandatory = "error";

  }

}

Avatar

Level 3

Thank you for your help.  So just so I understand, using

 this.resolveNode

in the script makes it so it doesn't matter where in the project it is, as long as there is a field with the name, the code will execute properly, correct?  would using this code also work, i know with some tweaks from the videos you sent me in a previous post, for objects that I set to repeat as well?

Avatar

Level 5

There are exceptions to that I believe: if the script is included in a script object or attached to an object of the master page, I believe the complete SOM would be needed… but I’m not 100% sure. 

Avatar

Level 3

ok, well when i get to that point, I will have to take a better look.  I tested the script out and it works perfectly on the first object because the field it is in is "kpi1" and I forgot to mention that the "kpi" field is from "kpi1" to "kpi13" as well, so I have been experimenting with different combinations to this line of code:

 if(this.resolveNode(sTarget).kpi1.rawValue == null)

I have tried doing this

 if(this.resolveNode(sTarget).kpi"+i+".rawValue == null)

as well as take the kpi out like so

 if(this.resolveNode(sTarget).rawValue == null)

but of course neither of those work as well.  Would i just have to add another var loop?

all of the "kpi" fields are located in each of the pages in the following hiearchy

pmp.Page.object.kpi

Avatar

Level 5

what if you re-define sTarget as

 var sTarget = "object"+i+".kpi"+i;

...

 if(this.resolveNode(sTarget).rawValue == null){ 

...

Avatar

Level 3

nope no go, I tried that to.... not sure why its not working???

Avatar

Level 3

I even tried using your first piece of code, and manually changing

 if(this.resolveNode(sTarget).kpi1.rawValue == null){   // Field is empty, other fields not required
    this.resolveNode(sTarget).Table1.Row1.ratingbox1_1.mandatory = "disabled";

to this

 if(this.resolveNode(sTarget).kpi2.rawValue == null){   // Field is empty, other fields not required
    this.resolveNode(sTarget).Table1.Row1.ratingbox2_1.mandatory = "disabled";

and so on, but that wouldn't work on the 2nd instance either.

Avatar

Level 3

sure here is the form  https://drive.google.com/file/d/11Ds94HjTr2wrZNKYq61_S7b3TqXe97v8/view?usp=sharing

 

i was playing around with field kpi2 as you will see to trial and error to no success.

Avatar

Level 5

Not sure it saves you a lot but here is an option. 

1. create a script object to set the rating fields as required or optional based on 3 parameters:

   - the page number

   - the object number

   - the status of KPI (empty or not)

2 include a script in the exit event of each KPI field to test if KPI is empty or not and call for the script object.

 

I tried this and it worked:

Script Object:

pmp.#variables[0].RatingMandatorySetting - (JavaScript, client)
function CheckMandatory(PageNumber,ObjectNumber,Status){
// sets the rating criteria as mandatory or optional
// Call for RatingMandatorySetting.CheckMandatory([PageNumber: number between 1 and 6],[ObjectNumber: number between 1 and 13],[Status: 1: required; 0: optional]);
for (var i = 1; i<=5; i++){
var sTargetRatingBox = "pmp.Page"+PageNumber+".object"+ObjectNumber+".Table1.Row1.ratingbox"+ObjectNumber+"_"+i;
if (Status == "1"){
xfa.resolveNode(sTargetRatingBox).mandatory = "error";
} else {
xfa.resolveNode(sTargetRatingBox).mandatory = "disabled";
}
}
}

 

KPI field script of object 3 on Page2:

pmp.Page2.object3.kpi3::exit - (JavaScript, client)
if ((this.rawValue == null) || (this.rawValue == "")) {
RatingMandatorySetting.CheckMandatory(2,3,0); //CheckMandatory(Page2,object3,optional)
} else {
RatingMandatorySetting.CheckMandatory(2,3,1); //CheckMandatory(Page2,object3,required)
}

Avatar

Level 3

thank you, for your help, just FYI i am unable to access the file and have requested access

Avatar

Level 3

Thanks, I really appreciate your help.  was trying to find more information on the RatingMandatorySetting.CheckMandatory code, i tried looking it up but couldn't find anything.  do you know where I can read up about this so I can learn more about other places I can possibly use this?

Avatar

Level 3

thank you, I appreciate it, will definitely review this document

Avatar

Level 10

You can do this the same way a the average calculations.

var oNodes = pmp.resolveNodes("#subform[*].#subform[*].Table1.Row1.#field.[Exists($.ui.#choiceList) eq 1]");
for (var i = 0; i < oNodes.length; i += 1)  {
	oNodes.item(i).mandatory = pmp.Page1.object1.kpi1.isNull ? "error" : "disabled";
}