Populating list boxes

One of the Reader 9 enhancements was a new API call to populate list boxes: field.setItems(). The motivation for the new API is to provide better performance for populating lists.

Prior to Reader 9, the standard way to populate a list box is to call:

field.addItem(displayValue [, boundValue])

for each item in the list.  The new API looks like:

field.setItems(itemListString [, numColumns])

The first parameter is a comma-separated list of values, the second parameter is an integer telling the field how many columns are in the data (defaults to one).  The second parameter is designed for future extensibility if we choose to some day implement a multi-column list box.

Examples

A call to populate a listbox with currencies might look like:

Currency.setItems(
  "US Dollar,Canadian Dollar,Euro,United Kingdom Pounds");

Or if there were a bound value, it would look like:

Currency.setItems("US Dollar,USD,Canadian Dollar,CAD,Euro,EUR,United Kingdom Pounds,GBP", 2);

Prior to Reader 9, this second variation would have been coded as:

Currency.clearItems();
Currency.addItem("US Dollar", "USD");
Currency.addItem("Canadian Dollar", "CAD");
Currency.addItem("Euro", "EUR");
Currency.addItem("United Kingdom Pounds", "GBP");

Alternative

There is a 3rd method for populating listboxes: binding them to data.  Designer allows you to point your field at a location in your instance data where list box contents will be stored.  While this method has very good performance, it has the disadvantages that a) your data is not always in the correct format for binding, b) the listbox gets populated from data only during the initial data load.

Performance

If you are using listboxes only casually you probably will not notice the difference in performance between the two methods. But if you are using listboxes intensively, the new method is a life-saver.

I have attached a form where I compare the old performance to the new. On my laptop, I populate a listbox with 500 items in 125 milliseconds using addItem() calls, and in 16 milliseconds using setItems(). Neither of these numbers may seem significant, but we have customers with forms containing many list boxes with many, many entries where the difference in performance is critical.

Compatibility

If you are designing a form to use this new API, be sure and set your target version (in Form Properties/Default) to "Acrobat and Adobe Reader 9.0 or later".  Unless you do this, calls to setItems() will not work — even though you might open the form in Reader 9.

9 Responses to Populating list boxes

  1. John Ingles says:

    Thank you for the post. I am new to building forms in pdfs and your site is a great resource.Question. How do you deal with data entries that contain commas when using setItems()?The whole list is quoted, not the individual list items. So, commas within the data cause the those items to be broken into multiple items.Example: “My Company Name ,Inc.” would become 2 items “My Company Name ” and “Inc.”Can an escape char be used?I tried the \ char with no success.

  2. John:When you put a backslash in a literal string, it escapes the next character. e.g. the literal: “quote\”char” will yield the string quote”char.But you need the backslash to be preserved for the call to setItems. This means you have to double it: “My Company Name\\, inc”. That way the API receives the string:My Company Name\, incGood luckJohn

  3. John Ingles says:

    The double-backslash worked.I can’t thank you enough for the quick response. It was unexpected, but truly appreciated.Thank you.

  4. John Ingles says:

    I have multiple listboxes that need to be populated with the same data. The data is static and will not change once the pdf is released.I want to avoid hard coding each listbox as there are up to 120 on this form. There will be up to 20 different sets of data lists with a range of 5-600 items that will populate the listboxes. My hope was to create a variable for each set of data that would contain the comma delimited string, then reference that variable using setItems(myDelList, 1).I have not figured out how to make a variable global and access(path to) it from within the listbox. I have to assume there is a way as I have seen posts on this topic, but I have just failed to achieve it.Another idea… Would it be better/possible to hard code the list in one listbox, then have other listboxes using the same date reference that first box?The pdf must populate offline and without the use of external files, so data must be hard-coded in the pdf itself.Two Questions:What is the best method for populating the listboxes with hundreds of items if the data is static and the data is repeated in several listboxes?Will Acrobat handle this amount of data?

  5. John:There are a bunch of places where you could squirrel away some strings to use in your list boxes.My first choice would probably be a variable in a script object:fields.#variables[0].listboxes – (JavaScript, client)var listData = “one,1,two,2,three,3”;Then references it in your list box initialization script:fields.#subform[0].f.DropDownList1::initialize – (JavaScript, client)this.setItems(listboxes.listData,2);In order to accomodate multiple sets of listbox data you can either create multiple variables or make your variable an array of strings.As for whether Reader can handle this amount of data, I think that under normal cirumstances it shouldn’t be a problem.Good Luck.John

  6. John Ingles says:

    Thanks John.This is how I ended up doing it and it works great.I have a new question related to this document, but off-topic. I didn’t find any posts related to my question, so I’m asking here.This happens with this form and a different multi-page order form with standard text fields for shipping/billing information and approximately 100 quantity fields. This form was created with LiveCycle also.They both load within a few seconds in almost all cases.Window XP/Vista with Reader 7,8,9MacOS(PPC/Intel) 10.4-5 with Reader 7,8The one exception is Reader 9.2 on Mac which takes several minutes(4-7). Why do files created in LiveCycle take so long to open with Reader 9.2 on Mac?Is there something I can do to fix this?I have tried re-saving the file from Acrobat Pro 9 on both Mac and Windows versions with the same results.If I open the file in Preview 5 that comes with Mac 10.6(Snow Leopard), it opens immediately with the form intack, then do a saveAs. The re-saved file now opens in Mac Reader 9.2 in seconds.The problem is that the submit button no longer works, and if I take it back into LiveCycle to fix it, the Mac issue reappears.Any suggestions?

  7. John:Interesting. I can’t remember ever encountering any forms issues (performance or otherwise) that are MacOS-specific.Is your form rights-enabled or certified? How big is the PDF/XDP?What event(s) are you using to populate the list boxes? Have you checked that these scripts are not firing too often?If the listbox population is accounting for a large part of the open-processing, then you should consider moving the scripts to the preOpen event. That way none of the list box population happens during form open.Good luck.John

  8. John Ingles says:

    Answers to your questions.1. It is rights-enabled.2. PDF is 1.9MB.3. Populating the boxes from the initialize event.4. I’m not sure how to tell if the scripts are firing too often.Sorry, I am new to working with LiveCycle and forms and there is a good chance I’m making some rookie mistakes setting these file up.I will move the scripts to the preOpen event as you suggested to see if that makes a difference. I did find your post on using the preOpen event.I will post the results here, probably next week because I have a couple of other fire to put out today.Thanks again.

  9. John:Is this a dynamic form? A 1.9 MB dynamic form seems very large. Are there a lot of images? Or just lots of content?It would also be interesting to compare form open performance without rights-enabling. When Reader opens a rights-enabled PDF, it does a check to make sure the template has not been modified. The performance of this check is proportionate to the size of the PDF.good luck.John