class HexaPDF::Type::AcroForm::ChoiceField
AcroForm
choice fields contain multiple text items of which one (or, if so flagged, more) may be selected.
They are divided into scrollable list boxes and combo boxes. To create a list or combo box, use the appropriate convenience methods on the main Form
instance (HexaPDF::Document#acro_form
). By using those methods, everything needed is automatically set up.
Type
Specific Field
Flags¶ ↑
- :combo
-
If set, the field represents a comb box.
- :edit
-
If set, the combo box includes an editable text box for entering arbitrary values. Therefore the 'combo' flag also needs to be set.
- :sort
-
The option items have to be sorted alphabetically. This flag is intended for PDF writers, not readers which should display the items in the order they appear.
- :multi_select
-
If set, more than one item may be selected.
- :do_not_spell_check
-
The text should not be spell-checked.
- :commit_on_sel_change
-
If set, a new value should be commited as soon as a selection is made.
See: PDF1.7 s12.7.4.4
Constants
- FLAGS_BIT_MAPPING
Updated list of field flags.
Public Instance Methods
Returns true
if this choice field represents a combo box.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 111 def combo_box? flagged?(:combo) end
Returns the concrete choice field type, either :list_box, :combo_box or :editable_combo_box.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 209 def concrete_field_type if combo_box? flagged?(:edit) ? :editable_combo_box : :combo_box else :list_box end end
Creates appropriate appearances for all widgets if they don't already exist.
For information on how this is done see AppearanceGenerator
.
Note that no new appearances are created if the dictionary fields involved in the creation of the appearance stream have not been changed between invocations.
By setting force
to true
the creation of the appearances can be forced.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 225 def create_appearances(force: false) current_appearance_state = [self[:V], self[:I], self[:Opt], self[:TI]] appearance_generator_class = document.config.constantize('acro_form.appearance_generator') each_widget do |widget| next if !force && widget.cached?(:appearance_state) && widget.cache(:appearance_state) == current_appearance_state widget.cache(:appearance_state, current_appearance_state, update: true) if combo_box? appearance_generator_class.new(widget).create_combo_box_appearances else appearance_generator_class.new(widget).create_list_box_appearances end end end
Returns the default field value.
See: field_value
# File lib/hexapdf/type/acro_form/choice_field.rb, line 147 def default_field_value process_value(self[:DV]) end
Sets the default field value.
See: field_value=
# File lib/hexapdf/type/acro_form/choice_field.rb, line 154 def default_field_value=(value) items = option_items self[:DV] = if [value].flatten.all? {|v| items.include?(v) } value else @document.config['acro_form.on_invalid_value'].call(self, value) end end
Returns the export values of the option items.
If you need the display strings (as in most cases), use the option_items
method.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 174 def export_values key?(:Opt) ? process_value(self[:Opt].map {|i| i.kind_of?(Array) ? i[0] : i }) : [] end
Returns the field value which represents the currently selected item(s).
If no item is selected, nil
is returned. If multiple values are selected, the return value is an array of strings, otherwise it is just a string.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 119 def field_value process_value(self[:V]) end
Sets the field value to the given string or array of strings.
The dictionary field /I is also modified to correctly represent the selected item(s).
# File lib/hexapdf/type/acro_form/choice_field.rb, line 126 def field_value=(value) items = option_items array_value = [value].flatten all_included = array_value.all? {|v| items.include?(v) } self[:V] = if (combo_box? && value.kind_of?(String) && (flagged?(:edit) || all_included)) delete(:I) value elsif list_box? && all_included && (value.kind_of?(String) || flagged?(:multi_select)) self[:I] = array_value.map {|val| items.index(val) }.sort! array_value.length == 1 ? value : array_value else @document.config['acro_form.on_invalid_value'].call(self, value) end update_widgets end
Initializes the button field to be a combo box.
This method should only be called directly after creating a new choice field because it doesn't completely reset the object.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 100 def initialize_as_combo_box self[:V] = nil flag(:combo) end
Initializes the choice field to be a list box.
This method should only be called directly after creating a new choice field because it doesn't completely reset the object.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 91 def initialize_as_list_box self[:V] = nil unflag(:combo) end
Returns true
if this choice field represents a list box.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 106 def list_box? !combo_box? end
Returns the index of the first visible option item of a list box.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 194 def list_box_top_index self[:TI] end
Makes the option item referred to via the given index
the first visible option item of a list box.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 200 def list_box_top_index=(index) if index < 0 || !key?(:Opt) || index >= self[:Opt].length raise ArgumentError, "Index out of range for the set option items" end self[:TI] = index end
Returns the array with the available option items.
Note that this only returns the option items themselves! For getting the export values, the export_values
method has to be used.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 167 def option_items key?(:Opt) ? process_value(self[:Opt].map {|i| i.kind_of?(Array) ? i[1] : i }) : [] end
Sets the array with the available option items to the given value.
Each entry in the array may either be a string representing the text to be displayed. Or an array of two strings where the first describes the export value (to be used when exporting form field data from the document) and the second is the display value.
See: option_items
, export_values
# File lib/hexapdf/type/acro_form/choice_field.rb, line 185 def option_items=(value) self[:Opt] = if flagged?(:sort) value.sort_by {|i| process_value(i.kind_of?(Array) ? i[1] : i) } else value end end
Updates the widgets so that they reflect the current field value.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 243 def update_widgets create_appearances end
Private Instance Methods
Uses the HexaPDF::DictionaryFields::StringConverter
to process the value (a string or an array of strings) so that it contains only normalized strings.
# File lib/hexapdf/type/acro_form/choice_field.rb, line 251 def process_value(value) value = value.value if value.kind_of?(PDFArray) if value.kind_of?(Array) value.map! {|item| DictionaryFields::StringConverter.convert(item, nil, nil) || item } else DictionaryFields::StringConverter.convert(value, nil, nil) || value end end