Expand my Community achievements bar.

SOLVED

Checking for a value in a field within a subform before allowing a user to add a new Instance

Avatar

Level 6

Form setup:

Page name = Page1

1st Subform within Page1 = Info (set to flowed)

Objects within Info subform: Name (textfield) and Email (textfield)

I also have a 2nd subform within Page 1 which contains an add instance button

What I'm trying to do:


1. The user needs to enter their Name and Email address then click "Add Instance button" to create a new instance of the Info subform :  _Info.addInstance(1);

2. If the user fails to enter an email address, I want there to be a mesage box that infos the user that an email address is required before he/she can create a new instance. Note: It would also be nice if the cursor is Set to foucs on the email field within that particular subform instance.

3. As long as the user tries to continue adding an instance, he/she will be denied if they do not enter an email in that instance

4. If the user includes an email address in that instance, then the script will create add a new isntance

5. The process should continue in this manner for each each click of the add instance button

I presume there nees to be a loop and perhaps a somExpression scipt, but I'm not sure.

Here's what i have so far (see below)....The script works for the first instance on the page, but it doesn't prevent new instances from being created when the email field in that "current instance" is empty. I want it to prevent the user from adding new instances if the email field is balnk in that "current instance". So, I guess I'm not sure how ot test a field in the current instance in a repeating subform.

var vName = Info.somExpression + ".email";

    var vEmail = xfa.resolveNode(vName).rawValue;

    if(vEmail == null)

    {

xfa.host.messageBox("PLease enter an email address.");

    }

   

else{

Form._Info.addInstance(1);

       

        var i = Form._Info.count - 1;

        xfa.host.setFocus(xfa.resolveNode("Info[" + i + "].Name")); //This set's the focus of the cursor in the Name field of the newly created subform

       

    }

Please advise, and thank you in advance!!!!!!

1 Accepted Solution

Avatar

Correct answer by
Level 10

Hi,

Try something like;

var lastRow = Form.resolveNode("Info["+(_Info.count - 1)+"]"); // Get last row

if (lastRow.Email.isNull) // If email field empty

{

    xfa.host.messageBox("Please enter an email address.");

}

else

{

    var newRow = _Info.addInstance();

    xfa.host.setFocus(newRow.Name.somExpression); // set focus to Name field on the row just added

}

Regards

Bruce

View solution in original post

11 Replies

Avatar

Correct answer by
Level 10

Hi,

Try something like;

var lastRow = Form.resolveNode("Info["+(_Info.count - 1)+"]"); // Get last row

if (lastRow.Email.isNull) // If email field empty

{

    xfa.host.messageBox("Please enter an email address.");

}

else

{

    var newRow = _Info.addInstance();

    xfa.host.setFocus(newRow.Name.somExpression); // set focus to Name field on the row just added

}

Regards

Bruce

Avatar

Level 6

Bruce,

Thanks a million; works like a charm!

Quick question:You don't have to go in detail, but why did you remove the 1 from addInstance()...just curious? I know it has something to do with the data model, but will it cause issues had it remained? What does it do?

Also, using your script logic, I was able to get the cursor to AutoFocus on the null email field by using the following script under the messageBox script: xfa.host.setFocus(lastRow.email.somExpression);

Thanks again.

Avatar

Level 10

Hi,

I remove the one from the addInstance because that is the default.  If you had used 0 (zero) or false then the row would have been added to your form but no row would have been added to the data model.  There are very few times when this is helpful so almost worth ignoring the parameter altogether.

Glad to hear it worked.

Bruce

Avatar

Level 6

Cool. But, if I wanted to export data, should I keep it (1), or will it still exported each instance of data with ()? The only reason I ask is because I'm planning to export the data to Excel workbook and when it was (1) all instances of records came over fine. I guess I can test it with (), but figured I'd ask .

Avatar

Level 6

Bruce,

Pardon, but one last question..I promise

1. In the example we've been working on, is there an easy way to hide the current subform after the user clicks the add button? FYI, I can create scripts for the majority of my needs, but I always get hung-up on Loops and somExpressions.

Basically, right now everything is working fine, but the way I have it designed, each new instance shows up on a new page.  Considering this form will be used in a fashion where multiple people will share a common computer, I want to hide the current/active subForm (and also ensure all previous instances -- other than the newly created subform -- are hidden) as soon as the user clicks the Add button and it passes the null test.  Right now, the user can scroll up to the previous instance and see the previous recorded data. I already have plans to include a prompt to ask the user to verify all information is complete before continuing.

P.S. I know how work with the "presence" of pages when they are predefined pages, but not sure how to do this with repeating Subforms.If it's asking too much of your time, nevermind.

2. Then, I'll probably need a way for the admin to reveal all "hidden" Subform instances once the last user has completed the last Subform instance.

Avatar

Level 10

I've never had any problem exporting data using addInstance(), it does seem to work exactly the same as addInstance(1) or sometimes you will also see addInstance(true). Bruce

Avatar

Level 10

Hi Bruce,

A you know, passing a parameter of 1 or true makes no difference as they are both the same. From my experiences, I tend to use true, so that when explaining to people they understand that the addInstance() method is expecting a boolean, whereas removeInstance() method is expecting a number.

Just me two cents,

Niall

Avatar

Level 10

Hi,

I think you can acheive what you want just by adding "lastRow.presence = "hidden";" when you do the addInstance, so it now looks like;

var lastRow = Form.resolveNode("Info["+(_Info.count - 1)+"]"); // Get last row

if (lastRow.Email.isNull) // If email field empty

{

    xfa.host.messageBox("Please enter an email address.");

}

else

{

    lastRow.presence = "hidden";

        var newRow = _Info.addInstance();

    xfa.host.setFocus(newRow.Name.somExpression); // set focus to Name field on the row just added

}

So whenever you add a row the previous one is hidden?

For your second issue, if you could have another button on your form, you could ask the user for a password and if they enter it correctly then show for the Info subforms, so;

 

var response = app.response({ cQuestion: "Do you want to see all respones?",

                              cTitle: "Unlock Form",

                              bPassword: true,

                              cLabel: "Please enter the password:" });

if (response === "Password")

{

    var infoSubforms = Form.resolveNodes("Info[*]");

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

    {

                var infoSubform = infoSubforms.item(i);

        infoSubform.presence = "visible";

    }

}

You would want to password protect your template as well (in Form ... Form Properties ... PDF Security) so people couldn't just open the form and look at the password.

Probably the simplest approach.

Hope this helps

Bruce

Avatar

Level 10

Hi Niall,  I agree passing 1 is likely to cause confusion to the reader of the code, I generally like being explicit about the parameters, even when they are the default.  I have only used addInstance(false) once in the past so thishas been an exception to the rule.  But fot clarity I will try and post code using true in future.  Regards, Bruce

Avatar

Level 6

Bruce,

I just wanted to quickly THANK YOU for  ALL your help. These solutions have all worked for my needs. It's great to see people like yourself willing to go to great lengths to help others.

May such kindness be bestowed upon you.

And Niall, thanks for your "two cents" as well.

Avatar

Level 6

Hi BR001,

Since the last time you helped me with this, things have worked out wonderfully. 

Based on this last part of the solution were the user enters his/her password to reveal all previously hidden subforms, now I need a way to "hide" all previous subform instances but ONLY keep the most recent subform instance "visible".  I'm sure this is very easy to do by modifying the following script below, but nothing I've tired sees to work....

if (response === "Password")

{

    var infoSubforms = Form.resolveNodes("Info[*]");

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

    {

                var infoSubform = infoSubforms.item(i);

        infoSubform.presence = "visible";

    }

}

If oyu, or anyone else can help, I'd greatly apprciate it.

Thanks in advance!