Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Updating a ComboBox options list

Community Beginner ,
Dec 14, 2017 Dec 14, 2017

I created a PDF with two ComboBoxes, call them A and B. I want the selection of A to alter the content of B. I have some other (hidden) ComboBoxes, whose names correspond to the values of A, and when the user selects a value in A, that ComboBox's options list should be copied to the B.

The Javascript I use (when a selection in A is made) is:

var Val = this.getField("A").value;

var c1 = this.getField(Val);

var B = this.getField("B");

B.clearItems();

for (var i=0; i < c1.numItems; i++) {

  B.insertItemAt ( c1.getItemAt(i, false), c1.getItemAt(i, true), -1 );

}

(I would have been simpler to use B.SetItems(c1.getItems)  or something like that, but I don't think there's a method like getItems, right?)

The lists are about 2000 items longs, and each time I select a value in A, Acrobat gets stuck for about a minute or more. Except that it works fine.

Is there any way to speed tup the process?

Thanks!

TOPICS
PDF forms
3.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
1 ACCEPTED SOLUTION
Community Expert ,
Dec 14, 2017 Dec 14, 2017

Have you seen this article:

https://acrobatusers.com/tutorials/js_list_combo_livecycle

It uses a document level object to store list data.

Thom Parker - Software Developer at PDFScripting
Use the Acrobat JavaScript Reference early and often

View solution in original post

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 14, 2017 Dec 14, 2017

Instead of inserting the items one by one I would save them into an array

and then use the setItems method to apply them all at once.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 14, 2017 Dec 14, 2017

Thanks. There is a considerable improvement - it now takes only about 15 seconds.

But it's still a long time. Any way to further speed things up?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 14, 2017 Dec 14, 2017

The data is saved in other ComboBoxes only for conveniece. The user doesn't really see them (they're hidden). Perhaps there's a different, more effective way to store the data?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 14, 2017 Dec 14, 2017

You can use a doc-level variable.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 14, 2017 Dec 14, 2017

Have you seen this article:

https://acrobatusers.com/tutorials/js_list_combo_livecycle

It uses a document level object to store list data.

Thom Parker - Software Developer at PDFScripting
Use the Acrobat JavaScript Reference early and often

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 26, 2017 Dec 26, 2017

It seems a good idea... however when testing it, it failed. After many experiments, I think I found the problem: my data is utf. I encode it as UTF-16, as I understand that that's what PDF uses. However, when the strings contain a null character (as is the case when utf-16-encoding spaces or _ etc.), it is interpreted as a line terminator.

The code is as follows:

var Ravs = {

English: [["<FE><FF>^E<E0>","1831"]],

OtherLang: [["<FE><FF>^@_","0745"]],

French: [["<FE><FF>^@_","0512"]],

Spanish: [["<FE><FF>^@_","8027"]]

};

For simplicity, I omitted most of my data. Now each element contains only one arrays elements, which is a string with the char _ encoded in UTF-16 (except the first element, the "English"). When I execute the file, the console prints

SyntaxError: unterminated string literal

3:Document-Level:0000000000000000

ReferenceError: Ravs is not defined

8:Field:Blur

(Actually the second console error, the 'Ravs is not defined', happens later when other code tries to access Ravs).

The PDF is generated by a Perl script, if it matters. When using spaces instead of _'s, the same error occurs (spaces are "^@ ", and it's this null char ^@ that seems to be the problem).

Any help, please?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 26, 2017 Dec 26, 2017

I would recommend you put double-quotes around the names of the languages as well, especially if they contain UTF-16 characters.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 26, 2017 Dec 26, 2017

Okay, I double-quotes the langage names, although they don't contain UTF-16 chars. The code now is:

var Ravs = {

"English": [["<FE><FF>^E<E0>","1831"]],

"OtherLang": [["<FE><FF>^@_","0745"]],

"French": [["<FE><FF>^@_","0512"]],

"Spanish": [["<FE><FF>^@_","8027"]]

};

It still generates the same error.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 26, 2017 Dec 26, 2017

Works fine for me:

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 26, 2017 Dec 26, 2017

Typing it in the console works for me, too. I think that when you type in the literal ^@ in the console, it isn't interpreted as the null character.

The definition of Ravs I posted came from the output of the Unix 'less' command. There, when it prints ^@, it really means the null char.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 27, 2017 Dec 27, 2017

Then you need to replace or remove this combination before using it as code.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 27, 2017 Dec 27, 2017

It looks to me as if one of your quotes is not an ASCII quote. While JavaScript is Unicode based, All special characters are ASCII, i.e. they use the 0x00 prefix.  This is why typing it in works, because the quote on your keyboard is interpreted in the console as the ASCII quote, but pasting carries the original UTF-16 encoding. The issue has literally nothing to do with the ^@, which means nothing in the JavaScript world.

You know that you are writing in JavaScript, so all characters are interpreted in the JavaScript encoding of such things. Look up strings in the Core JavaScript reference.

Thom Parker - Software Developer at PDFScripting
Use the Acrobat JavaScript Reference early and often

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 01, 2018 Jan 01, 2018

I didn't use the console at all before you, try67, mentioned it. As I said, I create my PDF (from a template) using a Perl script, I create some document-level variables and they have to contain utf characters. I need to know the correct way to encode them. For example, when I create a ComboBox with utf values, and then view the PDF in some editor (unix's 'less', or any other editor), I see the strings are encoded as UTF-16. When I create my file (with the perl script) and insert UTF-16 strings as the ComboBox values, it works. But for the document-level variables, it doesn't. Maybe the inner representation of ComboBox values are strings delimited by (), while document-level varialbles are delimited by quotes? does it make any difference?

After I create my document, which doesn't work, I try to debug it in the console. Here is what I get:

Ravs["English"][0][0]

þÿ Ô è abc

This seems to be correct. My string is really some UTF-16 data with " abc" appended to it. The þÿ prefix is the UTF-16's BOM. Using my editor (unix's 'less'), the first line of the assignment looks like:

var Ravs = {

"English": [["<FE><FF>^E<D4>^E<E8>" + " abc","1831"]],

One can verify that these strings match. That is, what less shows as <FE><FF>^E etc, the cosole shows as þÿ etc.

On with the cosole:

this.getField("Title").value =

Ravs["English"][0][0].match(/ .*$/)

abc

That really works. It sets the value of the Title field correctly. But now:

this.getField("Title").value =

Ravs["English"][0][0]

InvalidSetError: Set not possible, invalid or unknown.

Field.value:2:Console undefined:Exec

undefined

So the utf chars seem to confuse my Reader. Let's sum up: if the string is utf-16 encoded and contains no null bytes (that is, no ASCII chars were in the original string that was utf-16 encoded), all works fine. If it's a utf-16 string with some null bytes in it, the PDF doesn't run, and upon execution the console prints "SyntaxError: unterminated string literal". If the string is utf-16 with no nulls with ascii appended ("þÿ Ô è" + " abc"), it compiles but assignments (and the funtion setItems) don't work, as seen above. If the string is "þÿ Ô è" + " abc" and I assign something like Ravs["English"][0][0].match(/^[^ ]*/), which should be only the utf-16 with no null bytes, it gives the same error as above ("Set not possible").

So, what is the correct way to create document-level variables with utf chars? can you show me such a pdf that works (and then I'll use it as a template or duplicate it)?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 01, 2018 Jan 01, 2018

So I think your Perl code is creating the correct strings in the PDF.  You've done nothing wrong on this point. I was a bit confused because your post mixes notations.

That said, if I was to create a Unicode string for some JavaScript code (which I've done a lot from C++ and PHP (but not Perl).  I'd create the string with the "\u####"  notation. In your case these characters are still within the ANSI set so you could use the  "\x##" notation for specifying 1 byte characters.

Here is your string using both notations.

var MyVar1 = "\u00fe\u00ff\u0020\u00d4\u0020\u00e8";

var MyVar2 = "\xfe\xff\x20\xd4\x20\xe8";

Here's an article on the topic:

https://acrobatusers.com/tutorials/using_unicode_text

However, you have another issue, which may be the root of the problem.  Unicode strings are usually prefixed with a byte order indicator, in their raw form.  JavaScript handles this level of detail for the user, so the byte order indicator is not used when creating a JavaScript string. So is your string intending to setup a byte order? or do you really want the "þÿ" characters up front? Because these characters look exactly like a byte order prefix, and I believe they are confusing Acrobat.

I'm quite sure that it will all work if you either remove these characters or start the string with another character, like a space.

Thom Parker - Software Developer at PDFScripting
Use the Acrobat JavaScript Reference early and often

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 02, 2018 Jan 02, 2018

I think you might be making a big assumption that, because JavaScript strings can represent Unicode, that you can use a particular Unicode representation between quotes (UTF-16BE with BOM). PDF indeed uses UTF-16BE with BOM but JavaScript may be different as it has a different history.  Here is an article on using Unicode with JavaScript: JavaScript has a Unicode problem · Mathias Bynens

Above all never put binary zero in a string constant even if that’s what you need.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 11, 2018 Jan 11, 2018
LATEST

Thom - unfortunately both your ideas didn't work. The BOM wasn't the problem. I removed it (simply by encoding the string as UTF-16BE instead of UTF-16) and it made no difference.

Also your "\u00fe\u00ff\u0020\u00d4\u0020\u00e8" idea didn't work. Eventually I understood why. You wrote the Unicode codepoints of the string that was already UTF-16 encoded...

The article linked to by Test Screen Name hinted my. I had to omit the UTF-16 encoding, and simply represent the original unicode string as its code points:

"\u05d0\u05d1\u05d2"

for example, to show the first three Hebrew letters. So now it works perfectly.

Thank you all!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines