Tuesday, October 03, 2006 8:04 AM
by
bsandeman
Validating Events & How to use them
Now I don't know if this is intended functionality but if it is, it's slightly crazy!
Through my continual exploration into the weirdness that is InfoPath 2007 I have discovered that Validating Events, function in a particularly odd way....
On form load, they are executed once.
On field value change they are executed twice.
although it would seem not to be every field value change that causes double execution, it seems to vary, my tests thus far seem to indicate that it's only when you delete values that it executes twice
However, the first time through the validating event function it would seem that e.NewValue & e.OldValue contain empty string no matter what the value really is. But on the 2nd time through the values are all correct, except for when the value is empty string
(null in xml). It would seem that they have chosen to represent empty string or null as a string containing "true".
Here is some example code
(this code works when executed twice) :
public void makeFieldRequired(int[] invoiceCategories, bool bFinanceUser, bool bApproverUser, XmlValidatingEventArgs e, String errDesc)
{
// this is to ignore the first time through which seems to contain empty string
// for the NewValue always, only on the 2nd pass does NewValue actually contain
// the correct value. Empty String on the 2nd pass is represented by "true", how weird....
// This is the functionality of Validating Events in Beta2 Tech Refresh.
XPathNavigator xpn = this.MainDataSource.CreateNavigator().SelectSingleNode(e.Match);
String errName = xpn.Name + "_Required";
// it would seem that "true" equals empty string in InfoPath!!
if (e.NewValue.Equals("") || e.NewValue.Equals("true"))
{
String invoiceCatPath = "/ns1:Invoice/ns1:InvoiceCategory";
String approverRolePath = "/ns1:Invoice/ns1:Control/ns1:UserTrail/ns1:CurrentUser/ns1:IsApproverRole";
String financeRolePath = "/ns1:Invoice/ns1:Control/ns1:UserTrail/ns1:CurrentUser/ns1:IsFinanceRole";
String invoiceCat = getFieldValue(invoiceCatPath);
String approverRole = getFieldValue(approverRolePath);
String financeRole = getFieldValue(financeRolePath);
if (invoiceCat == null || invoiceCat.Equals(""))
invoiceCat = "0";
int cat = Convert.ToInt32(invoiceCat);
bool catInList = false;
for (int x = 0; x <= invoiceCategories.Length; x++)
{ // check if the current category is in the list of categories where this is required
if ((int)invoiceCategories.GetValue(x) == cat)
{
catInList = true;
break;
}
}
if (catInList &&
(bFinanceUser && financeRole == "true") ||
(bApproverUser && approverRole == "true"))
{
Errors.Add(xpn, errName, errDesc);
}
}
else
{
FormError[] errs = Errors.GetErrors(errName);
if (errs.Length > 0)
Errors.Delete(errName);
}
}
public void Approvals_BuyerNumber_Validating(object sender, XmlValidatingEventArgs e)
{
// required when empty value and Cat 0,1,7 and Finance user
int[] cats = { 0, 1, 7 };
makeFieldRequired(cats, true, false, e, "Buyer/Authoriser number is required");
}
public void InvoiceDetail_CompanyNumber_Validating(object sender, XmlValidatingEventArgs e)
{
// required when empty value and Cat 0,1,7 and Finance user
int[] cats = { 0, 1, 7 };
makeFieldRequired(cats, true, false, e, "Company number is required");
}