Difference between revisions of "Widgets"
(Comments about defiencies in MkIV, information about JavaScript in Acrobat) |
m |
||
(19 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | < [[ | + | < [[Presentations]] | [[Basics|Text formatting]] | [[Interaction]] > |
You can find more about interactive form elements in [http://www.pragma-ade.com/general/manuals/mwidget-s.pdf Widgets uncovered]. It’s written for MkII, but still mostly valid. | You can find more about interactive form elements in [http://www.pragma-ade.com/general/manuals/mwidget-s.pdf Widgets uncovered]. It’s written for MkII, but still mostly valid. | ||
− | + | Most of the following examples are from <tt>mwidget</tt> manual. We will cook up our own later. | |
=JavaScript= | =JavaScript= | ||
Line 21: | Line 21: | ||
</texcode> | </texcode> | ||
− | + | In some versions of MkIV there was a bug that the JS code was only copied to the PDF if there was a \goto referencing one of the defined functions. Should be gone. | |
You can pass values to a JS function: | You can pass values to a JS function: | ||
Line 41: | Line 41: | ||
== Documentation == | == Documentation == | ||
− | JavaScript in Acrobat is different than in a web context. Documentation is even more sparse | + | JavaScript in Acrobat is different than in a web context. Documentation is even more sparse than on ConTeXt ;) |
Debugging is only possible in Acrobat Pro, and also there very inconvenient. | Debugging is only possible in Acrobat Pro, and also there very inconvenient. | ||
Additionally, Acrobat’s possibilities change with every version. | Additionally, Acrobat’s possibilities change with every version. | ||
Line 47: | Line 47: | ||
* [http://www.adobe.com/devnet/acrobat/javascript.html JavaScript documentation at Adobe’s] | * [http://www.adobe.com/devnet/acrobat/javascript.html JavaScript documentation at Adobe’s] | ||
* [http://help.adobe.com/livedocs/acrobat_sdk/9.1/Acrobat9_1_HTMLHelp/wwhelp/wwhimpl/js/html/wwhelp.htm?href=JS_Dev_Tools.72.1.html&accessible=true JavaScript API Reference for Acrobat 9] | * [http://help.adobe.com/livedocs/acrobat_sdk/9.1/Acrobat9_1_HTMLHelp/wwhelp/wwhimpl/js/html/wwhelp.htm?href=JS_Dev_Tools.72.1.html&accessible=true JavaScript API Reference for Acrobat 9] | ||
+ | * [https://acrobatusers.com/tutorials/javascript_console Tutorial on JS in Acrobat 11] | ||
+ | |||
+ | == Examples == | ||
+ | |||
+ | === Setting a default value === | ||
+ | |||
+ | Here we set a date field to the current date on opening the document. | ||
+ | Additionally we have a button that can hide/show a form field. | ||
+ | |||
+ | <texcode> | ||
+ | \starttext | ||
+ | \setupinteraction [state=start] | ||
+ | |||
+ | \startJSpreamble {EXAMPLE} used now | ||
+ | var d = new Date(); | ||
+ | var df = this.getField("CurDate"); | ||
+ | df.value = util.printd("dd.mm.yyyy", d); | ||
+ | |||
+ | function toggleField(){ | ||
+ | var f = this.getField("CurDate"); | ||
+ | f.display = ! f.display; | ||
+ | } | ||
+ | \stopJSpreamble | ||
+ | |||
+ | \setupfield[shortString][reset,horizontal][height=5mm, width=50mm, frame=off, bottomframe=on] | ||
+ | \definefield[CurDate][line][shortString][][JavaScript should replace this text with the current date] | ||
+ | |||
+ | Current date: \field[CurDate] | ||
+ | |||
+ | \stoptext | ||
+ | </texcode> | ||
+ | |||
+ | ===Setting the current date=== | ||
+ | Similar, but more usable than the example above: | ||
+ | |||
+ | <texcode> | ||
+ | \starttext | ||
+ | |||
+ | \setupinteraction [state=start] | ||
+ | |||
+ | \startJSpreamble {EXAMPLE} used now | ||
+ | function Dummy(){ | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | function setCurrentDate(fieldname) { | ||
+ | var f = this.getField(fieldname); | ||
+ | f.value = util.printd("yyyy-mm-dd", new Date()); | ||
+ | } | ||
+ | |||
+ | setCurrentDate("myDateField"); | ||
+ | \stopJSpreamble | ||
+ | |||
+ | \setupfield[dateString][reset,horizontal][width=5em,option=printable] | ||
+ | \definefield[myDateField][line][dateString][][JavaScript should replace this text with the current date] | ||
+ | |||
+ | Current date: \field[myDateField] | ||
+ | \stoptext | ||
+ | </texcode> | ||
+ | |||
=Fields= | =Fields= | ||
Line 56: | Line 116: | ||
* {{cmd|definefield|[name][type][setup name][content values][default content]}} | * {{cmd|definefield|[name][type][setup name][content values][default content]}} | ||
* {{cmd|field|[name]}} | * {{cmd|field|[name]}} | ||
− | |||
* {{cmd|fillinline}} | * {{cmd|fillinline}} | ||
* {{cmd|fillintext}} | * {{cmd|fillintext}} | ||
* {{cmd|fillinrules}} | * {{cmd|fillinrules}} | ||
+ | * {{cmd|fillinfield}} (defined in the {{src|m-fields.mkiv|fields}} module, broken) | ||
Field types: | Field types: | ||
Line 66: | Line 126: | ||
* radio: radiobutton (only one of a group can be active) | * radio: radiobutton (only one of a group can be active) | ||
* check: checkbox | * check: checkbox | ||
+ | * signature: electronic signature (since ConTeXt beta of 2016-03-11) | ||
Beware, for fillinfields in MkIV you need {{code|\usemodule[fields]}}! | Beware, for fillinfields in MkIV you need {{code|\usemodule[fields]}}! | ||
They’re meant for clozes (texts with gaps, like in questionnaires). | They’re meant for clozes (texts with gaps, like in questionnaires). | ||
− | In MkIV (as of 2015-04-01) default values are always used verbatim, i.e. JS() doesn’t work. | + | In MkIV (as of 2015-04-01) default values are always used verbatim, i.e. JS() doesn’t work. (Check: other bug is gone, maybe this also?) |
Other fields you must first define and then use. That might look complicated, but you can use the same field several times, and the contents will automatically repeat themselves if you need the same content at several places, even on different pages. | Other fields you must first define and then use. That might look complicated, but you can use the same field several times, and the contents will automatically repeat themselves if you need the same content at several places, even on different pages. | ||
Line 80: | Line 141: | ||
</texcode> | </texcode> | ||
− | + | If you use this command in MkIV, avoid using default validation with <tt>\setupfieldcategory[fillinfield][validate=]</tt>. The default validation removes the contents from field. | |
<context source=yes> | <context source=yes> | ||
− | \setupfield[ShortLine][horizontal][width=2cm] | + | \setupfield[ShortLine][horizontal][width=2cm,height=2em] |
\definefield [Email] [line] [ShortLine] [] [sample@contextgarden.net] | \definefield [Email] [line] [ShortLine] [] [sample@contextgarden.net] | ||
\field [Email] [your email] | \field [Email] [your email] | ||
Line 90: | Line 151: | ||
==Radiobuttons== | ==Radiobuttons== | ||
− | + | Example from the manual: | |
<texcode> | <texcode> | ||
Line 97: | Line 158: | ||
height=4cm, | height=4cm, | ||
frame=off, | frame=off, | ||
− | background= | + | background=color, |
+ | backgroundcolor=lightgray] | ||
\definefield[Logos] [radio] [LogoSetup][ConTeXt,PPCHTEX,TeXUtil] [PPCHTEX] | \definefield[Logos] [radio] [LogoSetup][ConTeXt,PPCHTEX,TeXUtil] [PPCHTEX] | ||
Line 110: | Line 172: | ||
\hbox to \hsize{\hss\field[ConTeXt]\hss\field[PPCHTEX]\hss\field[TeXUtil]\hss} | \hbox to \hsize{\hss\field[ConTeXt]\hss\field[PPCHTEX]\hss\field[TeXUtil]\hss} | ||
+ | </texcode> | ||
+ | |||
+ | As usual, first you need to define a class of fields ({{cmd|setupfield}}). Then you define the (invisible) group of radio buttons ({{cmd|definefield}} with "radio"). At last you define the single radio buttons with {{cmd|definesubfield}}. | ||
+ | |||
+ | Arguments of {{cmd|definefield}}: | ||
+ | # field name | ||
+ | # field type "radio" | ||
+ | # setup class, as defined by {{cmd|setupfield}} | ||
+ | # list of field names that should be part of the group | ||
+ | # name of default (activated) button | ||
+ | |||
+ | Arguments of {{cmd|definesubfield}}: | ||
+ | # field name | ||
+ | # setup class (default is inherited, but you can use a different one) | ||
+ | # content symbol, defined by {{cmd|definesymbol}} | ||
+ | |||
+ | ===Setup for questionnaire=== | ||
+ | |||
+ | If you need a lot of similar radiobuttons, like in a questionnaire where you answer every question with a range choice, a meta definition makes sense. Fortunately it’s quite easy: | ||
+ | |||
+ | <texcode> | ||
+ | \setupfield [ChoiceSetup][width=1em,height=1em,corner=00] | ||
+ | |||
+ | \definesymbol[X][X] % replace with dingbat symbol | ||
+ | |||
+ | \def\Choice#1{\definefield[#1:main][radio][ChoiceSetup][#1:1,#1:2,#1:3,#1:4,#1:5,#1:0][#1:0]% | ||
+ | \definesubfield [#1:1][][X]% | ||
+ | \definesubfield [#1:2][][X]% | ||
+ | \definesubfield [#1:3][][X]% | ||
+ | \definesubfield [#1:4][][X]% | ||
+ | \definesubfield [#1:5][][X]% | ||
+ | \definesubfield [#1:0][][X]% | ||
+ | \field[#1:1]\,\field[#1:2]\,\field[#1:3]\,\field[#1:4]\,\field[#1:5]\hskip1em\field[#1:0]} | ||
+ | |||
+ | \def\ChoiceTitle{\hfill$-$\hskip4em$+$\hskip1.25em?\ \strut\par} | ||
+ | |||
+ | \def\Question{\dosingleempty\doQuestion} | ||
+ | % We need the "optional" parameter as reference | ||
+ | \def\doQuestion[#1]#2{% | ||
+ | \iffirstargument | ||
+ | #2\dotfill\Choice{#1}\par | ||
+ | \else | ||
+ | #2\par | ||
+ | \fi | ||
+ | } | ||
+ | |||
+ | \starttext | ||
+ | |||
+ | \ChoiceTitle | ||
+ | \Question[q:ctx]{How much do you love \CONTEXT?} | ||
+ | \Question[q:lua]{How are your Lua skills?} | ||
+ | \Question[q:xml]{How often do you dream in XML?} | ||
+ | |||
+ | \stoptext | ||
</texcode> | </texcode> | ||
Line 125: | Line 241: | ||
</texcode> | </texcode> | ||
− | =Tricks= | + | =Tricks and Traps= |
− | This helps debugging | + | ==MkIV== |
+ | |||
+ | * JS code is only copied to the PDF if there is a {{cmd|goto}} referencing one of the defined functions! – This is actually a feature, you can get your JS without {{cmd|goto}}, using the magic incantation <code>used now</code>, as in the default value example. | ||
+ | |||
+ | * JS code for default values doesn’t work (reported 2015-04-01, still true 2015-10-07). | ||
+ | |||
+ | * There is no {{cmd|setupfields}} (plural)! | ||
+ | |||
+ | ==MkII== | ||
+ | |||
+ | This helps debugging: | ||
<texcode> | <texcode> | ||
Line 138: | Line 264: | ||
* [[Midgard PC sheet]] (RPG character sheet with lots of text fields in tables) | * [[Midgard PC sheet]] (RPG character sheet with lots of text fields in tables) | ||
+ | |||
+ | [[Category:Interaction]] | ||
+ | [[Category:PDF]] |
Revision as of 18:14, 8 June 2020
< Presentations | Text formatting | Interaction >
You can find more about interactive form elements in Widgets uncovered. It’s written for MkII, but still mostly valid.
Most of the following examples are from mwidget manual. We will cook up our own later.
Contents
JavaScript
If you need to check or otherwise process the input of your forms, you need JavaScript to handle interaction. For simple forms without input validation, you can skip this section.
\startJSpreamble {name} MyCounter = 0 ; \stopJSpreamble \startJScode {increment} MyCounter = MyCounter + 1 ; // or: ++MyCounter ; \stopJScode \goto {advance by one} [JS(increment)]
In some versions of MkIV there was a bug that the JS code was only copied to the PDF if there was a \goto referencing one of the defined functions. Should be gone.
You can pass values to a JS function:
\startJScode {increment} MyCounter = MyCounter + JS_V_1 ; \stopJScode \goto {advance by five} [JS(increment{V{5}})]
- V{} is verbose, defaults to string
- S{} = as string
- R{} = as reference
- JS_V_n, JS_S_n, JS_R_n are the names of the variables
- JS_N keeps the number of arguments
Documentation
JavaScript in Acrobat is different than in a web context. Documentation is even more sparse than on ConTeXt ;) Debugging is only possible in Acrobat Pro, and also there very inconvenient. Additionally, Acrobat’s possibilities change with every version.
- JavaScript documentation at Adobe’s
- JavaScript API Reference for Acrobat 9
- Tutorial on JS in Acrobat 11
Examples
Setting a default value
Here we set a date field to the current date on opening the document. Additionally we have a button that can hide/show a form field.
\starttext \setupinteraction [state=start] \startJSpreamble {EXAMPLE} used now var d = new Date(); var df = this.getField("CurDate"); df.value = util.printd("dd.mm.yyyy", d); function toggleField(){ var f = this.getField("CurDate"); f.display = ! f.display; } \stopJSpreamble \setupfield[shortString][reset,horizontal][height=5mm, width=50mm, frame=off, bottomframe=on] \definefield[CurDate][line][shortString][][JavaScript should replace this text with the current date] Current date: \field[CurDate] \stoptext
Setting the current date
Similar, but more usable than the example above:
\starttext \setupinteraction [state=start] \startJSpreamble {EXAMPLE} used now function Dummy(){ return 0; } function setCurrentDate(fieldname) { var f = this.getField(fieldname); f.value = util.printd("yyyy-mm-dd", new Date()); } setCurrentDate("myDateField"); \stopJSpreamble \setupfield[dateString][reset,horizontal][width=5em,option=printable] \definefield[myDateField][line][dateString][][JavaScript should replace this text with the current date] Current date: \field[myDateField] \stoptext
Fields
Someone thinks this entry needs some more explanation. | (See: Needs Explanation?, To-Do List.) |
Relevant commands:
- \setupfield, \setupfields
- \definefield[name][type][setup name][content values][default content]
- \field[name]
- \fillinline
- \fillintext
- \fillinrules
- \fillinfield (defined in the fields module, broken)
Field types:
- line: one line of text
- text: more lines of text
- radio: radiobutton (only one of a group can be active)
- check: checkbox
- signature: electronic signature (since ConTeXt beta of 2016-03-11)
Beware, for fillinfields in MkIV you need \usemodule[fields]
!
They’re meant for clozes (texts with gaps, like in questionnaires).
In MkIV (as of 2015-04-01) default values are always used verbatim, i.e. JS() doesn’t work. (Check: other bug is gone, maybe this also?)
Other fields you must first define and then use. That might look complicated, but you can use the same field several times, and the contents will automatically repeat themselves if you need the same content at several places, even on different pages.
Text Entries
\fillinfield[name]{text that defines field length}
If you use this command in MkIV, avoid using default validation with \setupfieldcategory[fillinfield][validate=]. The default validation removes the contents from field.
\setupfield[ShortLine][horizontal][width=2cm,height=2em] \definefield [Email] [line] [ShortLine] [] [sample@contextgarden.net] \field [Email] [your email]
Radiobuttons
Example from the manual:
\setupfield [LogoSetup] [width=4cm, height=4cm, frame=off, background=color, backgroundcolor=lightgray] \definefield[Logos] [radio] [LogoSetup][ConTeXt,PPCHTEX,TeXUtil] [PPCHTEX] \definesubfield [ConTeXt] [] [ConTeXtLogo] \definesubfield [PPCHTEX] [] [PPCHTEXLogo] \definesubfield [TeXUtil] [] [TeXUtilLogo] \definesymbol [ConTeXtLogo] [{\externalfigure[mpcont.502]}] \definesymbol [PPCHTEXLogo] [{\externalfigure[mpcont.503]}] \definesymbol [TeXUtilLogo] [{\externalfigure[mpcont.504]}] \hbox to \hsize{\hss\field[ConTeXt]\hss\field[PPCHTEX]\hss\field[TeXUtil]\hss}
As usual, first you need to define a class of fields (\setupfield). Then you define the (invisible) group of radio buttons (\definefield with "radio"). At last you define the single radio buttons with \definesubfield.
Arguments of \definefield:
- field name
- field type "radio"
- setup class, as defined by \setupfield
- list of field names that should be part of the group
- name of default (activated) button
Arguments of \definesubfield:
- field name
- setup class (default is inherited, but you can use a different one)
- content symbol, defined by \definesymbol
Setup for questionnaire
If you need a lot of similar radiobuttons, like in a questionnaire where you answer every question with a range choice, a meta definition makes sense. Fortunately it’s quite easy:
\setupfield [ChoiceSetup][width=1em,height=1em,corner=00] \definesymbol[X][X] % replace with dingbat symbol \def\Choice#1{\definefield[#1:main][radio][ChoiceSetup][#1:1,#1:2,#1:3,#1:4,#1:5,#1:0][#1:0]% \definesubfield [#1:1][][X]% \definesubfield [#1:2][][X]% \definesubfield [#1:3][][X]% \definesubfield [#1:4][][X]% \definesubfield [#1:5][][X]% \definesubfield [#1:0][][X]% \field[#1:1]\,\field[#1:2]\,\field[#1:3]\,\field[#1:4]\,\field[#1:5]\hskip1em\field[#1:0]} \def\ChoiceTitle{\hfill$-$\hskip4em$+$\hskip1.25em?\ \strut\par} \def\Question{\dosingleempty\doQuestion} % We need the "optional" parameter as reference \def\doQuestion[#1]#2{% \iffirstargument #2\dotfill\Choice{#1}\par \else #2\par \fi } \starttext \ChoiceTitle \Question[q:ctx]{How much do you love \CONTEXT?} \Question[q:lua]{How are your Lua skills?} \Question[q:xml]{How often do you dream in XML?} \stoptext
Checkboxes
\setupfield[setup 3] [width=2cm, height=2cm, rulethickness=3pt, corner=round, framecolor=red] \definesymbol [yes] [{\externalfigure[mpcont.502]}] \definesymbol [no] [] \definefield [checkme][check] [setup 3] [yes,no] [no] \field[checkme]
Tricks and Traps
MkIV
- JS code is only copied to the PDF if there is a \goto referencing one of the defined functions! – This is actually a feature, you can get your JS without \goto, using the magic incantation
used now
, as in the default value example.
- JS code for default values doesn’t work (reported 2015-04-01, still true 2015-10-07).
- There is no \setupfields (plural)!
MkII
This helps debugging:
\tracefieldstrue \showfields % typeset a table of field relations \logfields % logs field descriptions to a file fields.log
Samples
- Midgard PC sheet (RPG character sheet with lots of text fields in tables)