Showing and hiding fields in an Adobe form based on a checkbox

One of the common tasks is to enable / disable or show / hide a form object based on the value in a related checkbox, or even a value in a drop down box. Unfortunately, there are not that many resources that walk you through this particular task, so the following article will discuss the steps involved, and highlight the Livecycle actions object.

First, start with a blank PDF like the one below and then drag a checkbox onto the page followed by the text box that you would like to connect to the checkbox. This could be any type of control, and in fact you will need to add a plain text item to the form in many cases so you have an area that will allow you to explain the action that you are performing. The image below shows the object library and highlights the objects that will be used.

Next, make sure the object explorer is open, to do this just click on view, and then object editor as in the image below.

The object explorer will appear with a heading of Object and a set of tabs named field, value, and binding. Clicking on the binding tab will display the object name. For this example change the object name to cb for your checkbox and tb for your textfield.

You change the control by clicking on the object in the design view panel.

After renaming the textbox to tb go ahead and click on the ‘Field’ tab of the textbox object and make this invisible by changing the value in the ‘Presence’ section to invisible.

Now that they are named something fairly easy to remember let’s add some interaction to the checkbox. To do this we need to look at the built in actions that adobe provides by right clicking on the object, which in this case is the check box. The image above shows the checkbox after we have left clicked on it (it should be highlighted in purple). The right click menu is shown below, select actions from the list then click on the add action button.

I have attached a screen shot of the box that pops up when you press this button below.

When dealing with a checkbox you have three choices in the top dropdown, is checked, is clicked, or is unchecked. In the bottom dropdown box you have a long list of prebuilt actions that you can apply to the condition in the top dropdown. To show or hide our textbox select Show or Hide Object from the list in the result box of the action builder. You will then see what looks like a hyperlink which allows you to select the object you want to hide or show and a dropdown to toggle between visible, hidden, or invisible.

Now remember when you select is checked and then change the object tb to visible in this example you have to also add an action that changes the object to invisible when the checkbox is unchecked. To do this select the new action button on the top of the add/edit action window. I have highlighted it in yellow in the image below

Finally, for the Pièce de résistance, all of this works great but what if a user saves the form with the checkbox checked and we have set our initial ‘Presence’ value for the textbox to invisible? That’s right the box will be checked and the textbox will not show since our action takes place on a click or change to the textbox. To correct this we need to now go further into the pdf and add some custom code that runs on form initialize.
In this case we have to now open the script editor and put some code in the form initialize event. The script editor window can be found under the window option on the top toolbar.

This window works just like any of the other windows in the application as the code changes depending on what object you have clicked in Livecycle. Before we get to the events let’s change to the correct object which is the form. In the hierarchy pane on the top left hand corner of Livecycle go ahead and click on the form.

Once you open the window you have to change a few settings to get to the right place in the document and also set the correct language. The image below shows the options that must be selected which I highlighted in yellow.

Now for the code:
Here’s a cut and paste version.

if (this.resolveNode("cb").rawValue == "0") {
  this.resolveNode("tb").presence = "invisible";
}
if (this.resolveNode("cb").rawValue == "1") {
  this.resolveNode("tb").presence = "visible";
}

Here’s what it looks like in Livecycle.

Blazing fast Adobe dropdown in a form with web like type ahead for very large lists

If you ever had to create adobe forms and used the drop down box that comes standard in Livecycle you may have noticed that it does not provide support for type ahead. If you have some data intensive form fields you may have already noticed that the fields which are scrollable using the bar seem to stop around 2000 entries and after that the user will have to know that they must click the small arrow and scroll through the records that way, both you and I know that this is not acceptable in real world production environments. I had a requirement to put over 3000 items in a dropdown in an adobe form, so when I found out that you can use Javascript in Livecycle I had to try and get this one working, you can see the result below. For those that want to try and replicate this I am sharing the source code and will provide an explanation, if this is not enough you can download the compiled adobe form with a compiled fragment so you can be up and running in no time here Type Ahead Sample PDF for free!

First, since there is a refresh problem with the dropdown control that prevents the list from being updated while it is opened we will have to construct a custom dropdown. This custom dropdown will be contain the following 4 objects:

1) A text field – this will be named typeAheadField

2) A list field – this will be named typeAheadList

3) A button – this will act as the trigger which toggles the visibility of the dropdown list, the button will be named typeAheadTrigger.

4) An image that will serve as the small triangle on the button face, the image takes the default name of Image1 in the fragment.

The list that we use for the sample data is the countries list that ships with adobe Livecycle in the custom section of the object library. You can download the text version of the list here
These objects will all be grouped together so that they remain in proportion to one another. Now the real fun begins, it’s time to throw some Javascript in the form. The first thing we need to do is capture the entire list in an array so that we can repopulate the list when the user clears the contents of the textfield, and also, so we can perform a search over the entire contents of the list and not the set of new values that you get when you start filtering. It is very important that this only take place once, otherwise you run the risk of filling your main list with a subset of items. The code that performs this is below:

form1.typeAheadDropDown.ta.typeAheadList::ready:form - (JavaScript, client)

a  = xfa.resolveNodes("this.items[*]");
list 	= a.item(0).nodes; 		
	
list_bak = new Array();  

if(list_bak.length < 1){	
  for (i=0;i<list.length;i++){
      list_bak.push(list.item(i).value);
  }
} 

No we have created a Javascript array named list_bak that contains all of the list items. Now that we have some Javascript in the form we can start using the built in debugger to make sure that there are no errors in our code. To find the debugger just open your form using acrobat (pro) and click view in the toolbar then hover over tools and select ‘Javascript’ from the list that appears to the right (see the image below).

Once you have clicked JavaScript you should see a menu to the right of your document the console will appear, the image below shows both the console and the tab to the right that you must click to bring the console up.

Any errors in your JavaScript code will populate the console. In addition, the code below placed in your Livecycle form will print to the console.

console.println(‘something’);

Next, in keeping with the list control we have to make sure that the typeAheadField control is populated with the text from the list selection. To do this we need to add the following code on the change event:

form1.typeAheadDropDown.ta.typeAheadList::change - (JavaScript, client)
// Add the value to the textfield
this.resolveNode("typeAheadField").rawValue = ((xfa.host.version < 8.1 || xfa.host.version >= 9) ? ($.boundItem(xfa.event.newText)) : (xfa.event.newText));
// change the background color to white as a selection has been made
this.resolveNode("typeAheadField").ui.oneOfChild.border.fill.color.value = "255,255,255";

The last thing we want to control as far as the list portion of the control is to make sure that the list hides when the mouse is not over the list, otherwise we would be stuck with a dropdown that did indeed ‘drop down’ and never went back up. The following code in the mouseExit function will make sure that the list hides when it’s supposed to.

form1.typeAheadDropDown.ta.typeAheadList::mouseExit - (JavaScript, client)

this.resolveNode("typeAheadList").presence = "invisible";

Let’s move on to the actual text box that will take the input, obviously there are two important things to consider here, first, we have to filter the box based on the characters entered into the field, and second, we need to mark the box with a different color to indicate that the selection was not on the list, since one of the drawbacks of this approach is that you MUST have the fields set to user entered OPTIONAL in order for this to work.

Fisrt we’ll look at the code below that searches the list when the user pressed a key in the text field.

form1.typeAheadDropDown.ta.typeAheadField::change - (JavaScript, client)

pattern = xfa.event.newText;

match = new Array();

for (n=0; n < list_bak.length; n++){
 if(list_bak[n].toLowerCase().indexOf(pattern.toLowerCase())!= -1){
   match.push(list_bak[n]);
 }
}

if (xfa.event.newText == ""){
	this.resolveNode("typeAheadList").setItems( list_bak.toString(),1);
} else {
	this.resolveNode("typeAheadList").setItems( match.toString(),1);
}

this.resolveNode("typeAheadList").presence = "visible";

The code xfa.event.newText; will contain the value that has been entered into the text field. Remember the array list_bak, we will traverse the entire array looking for matches, the code we will use allows for a match anywhere in the text, working just like a SQL LIKE%% statement. When a match is found in the original list array the node is pushed into an array of matches and this array is written to the list. If the user clears the text field then we repopulate the field with the original list. The last line of code simply shows the list when the user starts typing.

Since we are forced to go the user entered optional route in the field settings we want to add some validation, right? I know that you probably aren’t using a list because you hoped that the user would just type in their own values. The code below will turn the text field a nice adobe form blue if the value is not on the list.

form1.typeAheadDropDown.ta.typeAheadField::validate - (JavaScript, client)


var v = this.resolveNode("typeAheadField").rawValue;

if (v == ""){
	 //	app.alert( this.resolveNode("typeAheadField.caption.value.#text").value + " is a required field and the value must be on the list.");
	 	this.resolveNode("typeAheadField").ui.oneOfChild.border.fill.color.value = "153,204,255";
	} else {
		
		match = new Array();

		for (n=0; n < list_bak.length; n++){
if(list_bak[n] == v){
match.push(list_bak[n]);
}
}

if(match.length){
this.resolveNode("typeAheadField").ui.oneOfChild.border.fill.color.value = "255,255,255";			
		} else {
this.resolveNode("typeAheadField").ui.oneOfChild.border.fill.color.value = "153,204,255";
		}		
}

The code that we need to place on the button is very simple, just one line that opens the drop down list.

form1.typeAheadDropDown.ta.typeAheadTrigger::click - (JavaScript, client)

this.resolveNode("typeAheadList").presence = "visible";

There you have it enough information to be dangerous and create your own adobe type ahead dropdown box like the one shown in the video.

If you do decide to use this Type Ahead Sample PDF adobe file instead of using the tutorial above to try your hand at recreating this object you will need to know the following:

  • This method relies on a list being pasted into the values section of the dropdown; it does not work on a form that is connected to a remote database, or an embedded XML file.
  • You will have to convert the fragment to an object to change the dimensions, data, etc. You can do this by right clicking on the fragment and choosing convert to embedded object.
  • Need support or want to hire me to create your adobe form just drop me a line at joshuamcdonald69124@gmail.com.