Stefan Cameron on Forms
Building intelligent forms using Adobe LiveCycle Designer

What About the Other Field?

A common need in forms is to ask the user to choose between a set of options within a list, be it a radio button list, list box or drop down list. What’s more is that these lists often include an “other” option to let the user specify something more specific that isn’t included in the list. The trouble is, how do you ensure that the user fills-in the “other” field prior to submitting their form?

I thought it might be useful to provide a sample form which demonstrates how to build a list field which has an “other” option and clicking on the “other” option displays a field for entering the specific value and makes that field required — but only if the user chooses the “other” option. (You wouldn’t want the “other” field to be hidden and required or else the user would never be able to submit their form since Acrobat would prevent the submission on the premise that there’s an un-filled required field somewhere.)

“Other” Fields in Acrobat/Reader 8.1+

The first thing I did was create my sample form using Designer 8.1 and Acrobat 8.1. That was very easy and just as straight-forward as I expected it would be: One radio button list, one list box and one drop down list, each set to be required and with their own “other” item and script to show their respective “other” field (and make it mandatory) when their “other” item is selected and hide it (and make it optional) when their “other” item is de-selected. Add a submit button and Acrobat/Reader 8.1 automatically takes care of preventing the submission if any required field isn’t filled.

To keep things simple, each list field has script that detects when the user either selects the “other” item or an alternate item and sets the presence and mandatory properties of its “other” field to be visible/required or invisible/optional, respectively.

Download 8.1 sample [pdf]

Minimum requirements: Designer 8.1, Acrobat/Reader 8.1

“Other” Fields in Acrobat/Reader 8.0 or Earlier

Unfortunately, I didn’t have the same kind of experience getting this form to work in Acrobat/Reader 8.0 or earlier.

The first thing I did, since my 8.1 sample form doesn’t use any functionality only available as of Designer/Acrobat 8.1 (in fact, it uses XFA properties and script functions that have been available since Designer/Acrobat 7 and likely even earlier), I simply used Designer 8.1 to set my form’s Target Version to Acrobat/Reader 7.0.5 and figured I would open it in Acrobat 7.0.9 and all would be good. Well, that wasn’t the case.

Aside from Acrobat not respecting the “required” setting on the radio button list (which was expected since required radio button lists weren’t supported until Acrobat 8.0), I discovered a very strange behaviour in the list box where simply having a statement within its Change event that sets a field’s mandatory property to “error” will always result in that field being required, as far as Acrobat/Reader is concerned, even if the statement doesn’t appear ever to be executed on form initialization. The result is that selecting an item other than the “other” item in the list box and attempting to submit the form prompts Acrobat to cancel the submission because a required field isn’t filled. The problem is that the required field is the list box’s “other” field which is hidden from view because it isn’t supposed to be required. Finally, there was also another issue with list boxes that have Change event script: Their value is never committed to the Data DOM, which means that the list box always appears to have no value and that also prevents the user from being able to submit the form because the list box appears never to have been filled (even though an item is clearly selected).

So the are three problems with the 8.1 sample form when it’s running in versions of Acrobat/Reader prior to 8.1:

  1. Although properly supported in Acrobat/Reader 8.0, radio button lists can’t be set to “required”;
  2. List boxes with Change event script containing a statement which sets a field’s mandatory property to “error” results in that field always being “required” (this strange issue is resolved in Acrobat/Reader 8.1); and
  3. List boxes with Change event script don’t commit their value to the Data DOM (this is also resolved in Acrobat/Reader 8.1).

Fortunately, issues #2 and #3 can be resolved fairly easily simply by not using the Change event. The only viable alternative I found was using the Exit event instead. (Note that in the Exit event, you have to use the list’s “rawValue” property to determine its value rather than using the “xfa.event.newText” property as in the original Change event script.)

Issue #1 (required radio button lists not supported) can also be resolved although it requires a little more work. One alternative is to use the “Two Button Submit” Technique I described on a previous post on Complex Validations, which is what I implemented in my 7.x sample form.

Download 7.x sample [pdf]

Minimum requirements: Designer 7.0, Acrobat/Reader 7.0


Posted by Stefan Cameron on August 7th, 2007
Filed under Acrobat,Bugs,Events,Scripting,Tutorials
Both comments and pings are currently closed.

35 Responses to “What About the Other Field?”

  1. Carey on August 15th, 2007

    Hello, I’m new to Live Cycle and need help figuring this out. I know you can format a text field so that when a large amount of text is entered the font will shrink to accommodate that amount of text. The only thing is that I don’t know how to actually set it up. I’ve been looking everywhere for the answer and can’t figure it out! Can you help? Please note that I am not referring to the option to allow the field to grow/expand but rather for the font to shrink. Thanks!

  2. Sven Pelta on August 22nd, 2007

    Carey,

    you need to set the font size of the field to 0. Make sure that you only set the size of the _value_ (meaning the part of the field where you enter stuff). If you try to set the caption size or value & caption to 0, it will switch back to your original size.

    Cheers,

    Sven

  3. Weilin on October 2nd, 2007

    Hi,
    i would like to ask how to high light the field that need to fill in when you click submit button.
    thanks
    send me your reply through e-mail

    yours sincerely
    weilin

  4. Stefan Cameron on October 14th, 2007

    Weilin,

    My Invalid Flashing Fields 2.0 tutorial will show you how to do that. It’ll even make the field flash but you can easily disable that part in the script if you don’t want it.

  5. Terri on March 10th, 2008

    I would like to be able to prevent the printing of a form if a required field is not filled. I’m currently using Livecycle 7.1 but will be upgrading to ES
    within the next few months. Thanks!

  6. Stefan Cameron on March 12th, 2008

    Terri,

    Unfortunately, while there are ways that you may be able to make the user think that they can’t print the form (you can show a print button on the form and display an error message, instead of printing, if a particular field isn’t filled all the way up to removing the print menu item in Acrobat) there will always be some other way for the user to print (e.g. there’s no way you can stop “Ctrl + P” from functioning).

    So my answer to this question is always that it just can’t be done reliably. If you like the idea of the print button, then I suggest you use the two button submit solution but use a print button instead of a submit button.

  7. Terri on March 20th, 2008

    Hi,

    While this might not be the proper post to place this, here goes.
    I would like to prevent text fields from scrolling when the user hits the bottom of the field. Setting maximum characters does not necessarily work, same as setting a message box on “Full”. I’ve been trying to work, unsuccessfully, with the following:

    var myDoc = event.target;
    var f = myDoc.getField(“Form.Page.Field”);
    f.doNotScroll = true;

    Any advice?

  8. Stefan Cameron on March 22nd, 2008

    Terri,

    If you’re using Designer 8+, there’s a new option for text fields in the Object palette’s Field tab called “limit length to visible area”. That should give you what you’re looking for.

  9. NP_Martin on April 29th, 2008

    Dear Mr Cameron,
    I’m a newcomer to using JavaScript objects in LiveCycle Designer 8, and would like to kindly ask you for some help.
    I’ve been wondering how to automate the filling of a text field based on some input from another field. I found a pretty good solution to this problem in the Purchase Order sample form that ships with LC, although in this the input field is a dropdown list. Anyway, I may say that I became familiar with its logic, as well as the scripting it involves.
    My question is how to achieve the same result if the input field is not a drop down list, but another text or a numeric field. If, for example, you’d like to automate the filling of the “City” field after entering the postal code as an input, the array for postal codes would obviously be too large to be contained in a drop down list. So, therefore the user enters the input by typing, and the result shows in the next field.
    Could you provide me with a clue as to how to start?
    Thanks in advance:
    Martin

  10. Stefan Cameron on May 6th, 2008

    NP_Martin,

    I think you would put script in the first field’s Exit event that would look at the field’s value, find the related city and set the city field’s value to the name of the city. For example, you could define an array of postal codes and city names in the Exit event like this (using JavaScript):

    function pair(postCode, city)
    {
        this.postCode = postCode;
        this.city = city;
    }
    
    var postCityArray = new Array();
    postCityArray.push(new pair("A1A1A1", "Name of City"));
    postCityArray.push(new pair("B1B1B1", "Name of Other City"));

    Then you would get the field’s value:

    var postCode = this.rawValue;

    Next, search the array for the city:

    var cityName = "";
    
    for (var i = 0; i < postCityArray.length; i++)
    {
        if (postCityArray[i].postCode == postCode)
        {
            cityName = postCityArray[i].city;
            break;
        }
    }

    Finally, set the city field's value:

    CityField.rawValue = cityName;

    Give that a try and see if it works.

  11. Sylvia on July 22nd, 2008

    Hello, I am new to lifecycle, reading this article has given me ideas on how to validate user required fields via submit button but unfortunately I am running out of ways to make sure user enter fields when certain field is entered. Currently I have many fields lets say field A, B, C, D… How do I make “only if field A and B are entered then user is required to fill in field C,D” automatically without any buttons? Thanks!

  12. Stefan Cameron on July 30th, 2008

    Sylvia,

    You can achieve this by using validation scripts on fields A and B that check for values in C and D. To do this, you have to understand that a validation script evaluates to either true or false and that the result of a validation script on an empty field (one that doesn’t contain a value) is ignored and considered true (i.e. Acrobat considers the validation to have succeeded).

    Knowing this information, you can define validation scripts for A and B that evaluate to true if the other one isn’t filled or if C and D are filled. On A, you would use the following JavaScript expression in the Validation event:

    B.rawValue == null || (C.rawValue != null && C.rawValue.length > 0 && D.rawValue != null && D.rawValue.length > 0)

    This says that A is valid if B isn’t filled or if both C and D are filled. On B, you would have the following expression:

    A.rawValue == null || (C.rawValue != null && C.rawValue.length > 0 && D.rawValue != null && D.rawValue.length > 0)

    This says that B is valid if A isn’t filled or if both C and D are filled.

    Remember that Acrobat ignores validation script results on empty fields. That means that if only A and C are filled, A’s validation script will succeed but B’s validation script will fail (because A is filled therefore C and D must be filled). BUT, Acrobat will ignore the fact that B’s validation script failed because B isn’t filled. Therefore, Acrobat will let the form submit. Of course if B and C are filled and A isn’t, the opposite occurs (A’s failed validation is ignored by Acrobat because A is empty and the form can still be submitted). Now if both A and B are filled and either C or D isn’t, Acrobat will not let the form be submitted because it will respect the failed validations on both A and B since they are filled.

    I know this will seem overly complex for something as simple as “if A and B are filled, C and D are required” but that’s the way script validations work.

    Another way to do it might be to script the Exit event of A and B and set C and D as mandatory if A and B are filled. For example, on A’s Exit event, you would use the following JavaScript:

    if (this.rawValue != null && this.rawValue.length > 0 && B.rawValue != null && B.rawValue.length > 0)
    {
        C.mandatory = "error";
        D.mandatory = "error";
    }
    else
    {
        C.mandatory = "disabled";
        D.mandatory = "disabled";
    }

    You would do something similar on B’s Exit event. The Exit event is fired after a user clicks out of a field so when the user clicks out of A, you check to see if A was filled and if B is filled as well, in which case you make C and D mandatory fields. Same thing for B when A is filled.

  13. Sylvia on August 4th, 2008

    Thanks Stefan for your explanation – I now have a working validation without submit buttons thanks to you!
    For the sample expression below, would you have the equivalent of JavaScript expression for the validate event or is there a simpler / better way?
    This works in checkbox A’s exit event:

    if(A.rawValue == “1″) {
    B.mandatory = “error”;
    B.mandatoryMessage = “Please fill in this field”;
    } else {
    B.mandatory = “disabled”;
    }

  14. TJ on August 7th, 2008

    I’m so confused. I’ve examined the sample documents for acrobat 8.1 and 7.x. In both cases the action script portion appears to be the same for making the “Please specify” text field appear and disappear. However, I cannot duplicate these results on my own using LiveCycle 8.05. These are the steps I have taken:
    Open a new blank document.
    Drag 3 radio buttons to the page and change the captions to “Single”, “Married” and “Other”, then uncheck the specify item values box.
    Drag a text field to the page and change the caption to “Please specify:”, then set the presence to invisible and the name to “RBLOther”.
    I copy the script section from your example:
    &ltevent activity=”click”>
    &ltscript contentType=”application/x-javascript”>if (“Other” == this.rawValue)
    {
    RBLOther.presence = “visible”;
    RBLOther.mandatory = “error”;
    }
    else
    {
    RBLOther.presence = “invisible”;
    RBLOther.mandatory = “disabled”;
    RBLOther.rawValue = “”; // remove the other value in case one was specified
    }&lt/script>
    &lt/event>
    &ltvalidate>
    &ltmessage>
    &lttext name=”nullTest”/>
    &lt/message>
    &lt/validate>
    I insert the script after the “&lt/field>” line for the Other radio button (where it is placed in your example) and then I go to Preview PDF and click on Other – nothing happens! What am I missing? My form properties are set to JavaScript, Interactive Form, Acrobat 8 (Dynamic) XML form.
    My goal here is to understand how to make a text field or drop-down list appear or disappear depending upon which radio button is selected from a group of radio buttons. The radio buttons don’t have to be mandatory, they just need to control the appearance or disappearance of the text filed or drop-down list. I know I’m missing something here since your examples clearly work. Please clue me in on the missed step. Thanks!

  15. TJ on August 7th, 2008

    One more thing…
    Just for grins, I started a new document and set the form properties. I opened your example, copied the entire set of code and pasted it to the new document, overwriting the default code that was already there. Guess what? Nothing happens when I click “Other”! This makes no sense to me. If I am using your entire set of code there should be no differences between the two documents and they should behave the same way, but they don’t. I am really confused now. What could possibly be the difference between the two? I looked everywhere I could think of for a setting that might be different, but I cannot find it. Any light you could shed on this would be most appreciated.

  16. Stefan Cameron on August 8th, 2008

    Sylvia,

    In that case, I think it might be as simple as using this little expression in A’s Validate event:

    this.rawValue == "0" || (B.rawValue != null && B.rawValue.length > 0)

    Note that checkbox fields always have a value (their “off” or “on” value — 0 or 1 by default, respectively) so the Validate event results are always “respected”, if you will, as opposed to a Validate event on a text field which is initially empty.

    The result will be that the validation will fail and you’ll get a “validation failed” error message the second you check A if B hasn’t been filled — not the nicest experience.

    Why not just leave it as you have it already with the Exit event on A? That seems like it would do the trick…

  17. Sylvia on August 12th, 2008

    Hi Stefan, many thanks once again – you’ve been a good teacher. The reason is because I am curious and would like to explore the possibilities of other more efficient method for future use, but as you say if it does the trick why not leave it :)

  18. Stefan Cameron on August 13th, 2008

    TJ,

    It looks like you’re doing everything correctly (although I would recommend you use the Script Editor palette to set the script on the radio button list’s Click event rather than copying and pasting XFA from one form to another). I followed the steps you outlined and it works just fine (though I was using Designer 8.2 and Acrobat 9).

    When you say that “nothing happens”, I assume you mean the “RBLOther” field doesn’t become visible when you select “Other” from the radio button list. The only thing I can think of is that while you’ve set form properties correctly, you may still be saving as a static PDF. As a sanity check, you could try creating a new form, dropping a text field on it, set its presence to “hidden” and set its initialize script to

    this.presence = "visible";

    Then preview the form using the “Preview PDF” tab. If the field isn’t visible, you’re previewing the form as a static PDF — which is likely your default save format. Static PDFs don’t support showing/hiding fields.

    Have a look at my article on previewing as Dynamic PDF to see if you’ve covered all the bases.

  19. TJ on August 14th, 2008

    Stefan,

    THANK YOU! I tried your ‘sanity check’ and that worked fine. I then tried entering the code via the Script Editor rather than the XML Source and it worked perfectly. Clearly I must have missed something when entering the code on the XML Source tab. I appreciate your response!

  20. Stefan Cameron on August 15th, 2008

    TJ,

    Awesome!

  21. Cindy on October 9th, 2008

    Hi,

    Do you know how to validate all the fields in JavaScript when the user clicks the Submit button so that if any required fields are empty, nothing (submission, JavaScript code, execute menu items, etc.) will be executed? I found something about execValidate() but it didn’t work for me. It wouldn’t do anything. I am using Adobe Acrobat Professional 8.0. Thank you!

  22. Stefan Cameron on October 14th, 2008

    Cindy,

    Unfortunately, validations in XFA forms don’t really work the way you would expect them to. At the moment, you’re still better-off implementing your own script to validate the fields you care about unless you only care about mandatory fields being empty or filled. If it’s that simple, then setting a field’s “Object palette > Value tab > Type property” to “User Entered – Required” will prevent the form from being submitted if that field is empty. If you want to prevent printing, saving or web service execution if form fields aren’t filled, then see my article on preventing a form from being printed.

    If you need to do something more complicated than that, then you’ll need to implement your own solution. I would start by implementing the two button submit technique on your form. Once you’ve done that, you’ll just need to iterate through all the fields on your form and make sure they’re filled. My Invalid Flashing Fields 2.0 tutorial is a great example of looking at all fields in a form and highlighting (flashing red) the first one found that isn’t valid filled.

  23. Melissa Templeton on October 21st, 2008

    Hi!

    I have an issue with coding a background color into a specific selection on a drop down menu within LiveCycle Designer 8.0. Could you please point me in the right direction?

    No
    Yes

    Upon selection of “Yes”, I would like the field background color and/or font color to change. I have tried several solutions, and I am unable to find any answers.

    Thanks!!

  24. Melissa Templeton on October 21st, 2008

    Of course pasted too quickly. Please see the script below:
    <field h=”1.8549mm” name=”DropDownList1″ w=”35.4598mm” x=”30.0253mm” y=”25mm”>
    <ui>
    <choiceList>
    <border hand=”right”>
    <edge presence=”hidden” cap=”butt”/>
    <corner presence=”hidden”/>
    </border>
    </choiceList>
    </ui>
    <font size=”6pt” typeface=”Myriad Pro”/>
    <para vAlign=”middle”/>
    <items save=”1″>
    <text>No
    <text>Yes
    </items>
    </field>

  25. Stefan Cameron on October 24th, 2008

    Melissa Templeton,

    Have a look at my article on setting the field background color.

  26. Melissa Templeton on October 24th, 2008

    Stefan,

    I looked over your article; however I am still unsure as to how to only fill the field when ‘Yes’ is selected. If ‘No’ is selected, I do not want the field to appear as colored.

    Maybe I am just having “a blonde moment”.

    Thanks!
    Melissa

  27. Stefan Cameron on October 24th, 2008

    Melissa Templeton,

    I see. What you need to do is handle the Change event on the drop down list. In the event, look at the xfa.event.newText property which will be set to the new selection. Note that if you list items have text and value data that differ and you need the value data, you’ll need to use the boundItem list function on the newText value to get it:

    var newSelection = xfa.event.newText;
    var boundValue = this.boundItem(newSelection); // to get the value data associated with the new selected item, if you need it
    
    if (boundValue == "yes")
        this.fillColor = "255,0,0";
    else
        this.fillColor = "255,255,255";
  28. Melissa Templeton on October 28th, 2008

    Thanks Stefan. I really apprecaite your assistance. =) Looks great!

  29. rpeterson on March 23rd, 2009

    Stefan,

    I have just found this site!! It appears to be equally informative when compared to the user forum for adobe. I am sooo jazzed!!

    I am fairly new to adobe/lc, and have absolutely no programming experience at all, but can learn from examples and reading reference materials.

    Now for my question…

    Can I set up a messageBox to give a list of radio buttons to allow a user to select from a list of statements, then once selected (click a radiobutton, then click OK) to provide that selection in a field that if it is too long to print on a single line to show wrapped?

    I tried using the messageBox to select a yes/no/cancel to have either a static text or text field show when either yes or no was selected, but somehow I do not have the experience to make it work. Do you have any suggestions? Any help at all would be really appreciated.

    Thanks, rpeterson

  30. Stefan Cameron on March 28th, 2009

    rpeterson,

    The messageBox function doesn’t let you add UI controls to it like radio buttons. If you want to use messageBox, then then best you can do is instruct the user to click ‘yes’ for one thing, ‘no’ for another and ‘cancel’ for the third option.

    In this case, you would use the following script:

    // JavaScript:
    switch (xfa.host.messageBox("Choose an option:\nyes: option 1\nno: option 2\ncancel: option 3", "Option Dialog", 2, 3)
    {
        case 4:
            // user clicked 'yes'
            break;
        case 3:
            // user clicked 'no'
            break;
        case 2:
            // user clicked 'cancel'
            break;
        default:
            break;
    }

    Another option is to use the xfa.host.response() function. In this case, you would instruct the user to enter the number corresponding to the option they want to select in the message box that appears (it’ll have a single entry field):

    // JavaScript:
    var answer = xfa.host.response("Choose an option by entering the corresponding number in the box below and pressing 'OK':\n1: option 1\n2: option 2\n3: option 3", "Option Dialog", "" /*can set default answer here*/, false);
    if (answer == null)
    {
        // user clicked 'cancel' instead of 'ok'
    }
    else
    {
        switch (parseInt(answer))
        {
            case 1:
                // user chose 1
                break;
            case 2:
                // user chose 2
                break;
            case 3:
                // user chose 3
                break;
            default:
                // invalid option!
                break;
        }
    }
  31. sblanco on April 3rd, 2009

    Hi Stefan,

    I’m new to LiveCycle…trying to create a form and I used one of your sample scripts (ProcessAllFields.js) in validating mandatory fields. It works good. I only have one problem… I have a subform that has a textfield that is mandatory, but this subform is hidden. This will only show if I select a checkbox..

    Example: if checkbox.rawvalue==1
    { subform.presence = “visible”;}
    else
    {subform.presence=”hidden”;}

    Now the sample script I used is also checking the textfield inside the subform even the subform is hidden. I tried adding in the script if there are any hidden fields or subform it will be skip… But I guess I do not have the experience to make it work. Do you have any suggestions? Any help at all would be really appreciated.

  32. Stefan Cameron on April 5th, 2009

    sblanco,

    In my ProcessAllFields script, just change the first part to this:

    if (oNode.className == "exclGroup" || oNode.className == "subform"  || oNode.className == "subformSet" || oNode.className == "area")
    {
        // Look for child fields unless it's a hidden subform.
        if (oNode.className == "subform" && oNode.presence != "visible")
            return;
    
        for (var i = 0; i < oNode.nodes.length; i++)
        {
            var oChildNode = oNode.nodes.item(i);
            ProcessAllFields(oChildNode);
        }
    }
    else if (oNode.className == "field")
    ...

    Notice the new statement inside the first IF that checks to see if the node is a subform and if it isn't visible (if those conditions are met, the function doesn't look inside).

  33. sblanco on April 8th, 2009

    Hi Stefan,

    Works great! I really appreciate your help “).

    Thank you very much!!

  34. Michael Newson on June 7th, 2010

    Quick question: I’m trying to do something very simple, but I’m having the hardest time figuring out how to do it correctly.

    I have a checkbox field that when checked, I would like a numerical field to go to zero. The complicated part is that this numerical field is a calculated field (it automatically calculates shipping cost), and if the customer doesn’t check the box, I would like the normal calculation to take place.

    I figured that I could use a simple “if…then” statment, but I think my programming skills are rusty, so I’m struggling.

    I’m trying to do this in Adobe LiveCycle Designer 8.0.

    Any suggestions?

  35. Stefan Cameron on June 16th, 2010

    @Michael Newson,

    I would suggest that you use an IF statement in the numeric field’s Calculate script:

    // JavaScript:
    if (CheckBox1.rawValue == "1")
    {
        this.rawValue = 0; // set to zero
    }
    else
    {
        // do the normal calculation here
    }