%3 ::xowiki::formfield::text ::xowiki::formfield::text add_statistics initialize render_input ::xowiki::formfield::FormField ::xowiki::formfield::FormField ::xowiki::formfield::text->::xowiki::formfield::FormField ::xowiki::formfield::numeric ::xowiki::formfield::numeric answer_check=eq check=numeric convert_to_external convert_to_internal convert_to_internal_value initialize pretty_value render_input ::xowiki::formfield::numeric->::xowiki::formfield::text ::xowiki::formfield::user_id ::xowiki::formfield::user_id initialize pretty_value ::xowiki::formfield::user_id->::xowiki::formfield::numeric ::xowiki::formfield::YYYY ::xowiki::formfield::YYYY check=YYYY ::xowiki::formfield::YYYY->::xowiki::formfield::numeric ::xowiki::formfield::author ::xowiki::formfield::author pretty_value ::xowiki::formfield::author->::xowiki::formfield::user_id ::xowiki::formfield::party_id ::xowiki::formfield::party_id check=party_id_check ::xowiki::formfield::party_id->::xowiki::formfield::user_id

Class ::xowiki::formfield::numeric

::xowiki::formfield::numeric[i] create ... \
           [ -connection_locale (default "1") ] \
           [ -format (default "%.2f") ] \
           [ -keep_string_rep (default "0") ] \
           [ -strict (default "0") ]

Field with numeric content. Depending on the format, the accepted value can be either an integer or a floating point number. The widget performs localization based on the setting of :locale. In case 'keep_string_rep' is not true, the widget converts the value to an internal representation to be able to evaluate numeric expressions by this. When 'keep_string_rep' is true, the original string representation is kept, and only validation is performed.
Documented Parameters:
format
format for output and determining integer property
connection_locale
when set, use the connection locale as source for internationalized input
strict
when set, use just use the locale for input checking. Otherwise, always accept as fallback what is accepted by en_US.
keep_string_rep
when true, do not convert from and to the internal representation, but preserve the original string.
Defined in packages/xowiki/tcl/form-field-procs.tcl

Class Relations

  • class: ::xotcl::Class[i]
  • superclass: ::xowiki::formfield::text[i]
  • subclass: ::xowiki::formfield::user_id[i], ::xowiki::formfield::YYYY[i]
::xotcl::Class create ::xowiki::formfield::numeric \
     -superclass ::xowiki::formfield::text

Methods (to be applied on instances)

  • answer_check=eq (scripted)

    try {
      set x [:convert_to_internal_value ${:value}]
      set y [:convert_to_internal_value [lindex ${:correct_when} 1]]
      #ns_log notice "numeric answer_check=eq "  "'[lindex ${:correct_when} 1]' with '${:value}'" "->"  "expr {$x == $y}"
      set result [expr {$x == $y}]
    } on error {errorMsg} {
      ns_log warning "numeric answer_check=eq received exception while comparing "  "'[lindex ${:correct_when} 1]' with '${:value}'"  $errorMsg
      set result 0
    }
    return $result
  • check=numeric (scripted)

    #ns_log notice "=== numeric: value '$value' locale '[:locale]' is_integer '${:is_integer}'"
    return [expr {[catch {:convert_to_internal_value $value}] == 0}]
  • connection_locale (setter)

  • convert_to_external (scripted)

    #ns_log notice "convert_to_external ${:name} keep_string_rep ${:keep_string_rep}"
    if {${:keep_string_rep}} {
      return $value
    }
    if {$value eq ""} {
      set result ""
    } else {
      ad_try {
        set value [lc_numeric $value ${:format} ${:locale}]
      } on error {errorMsg} {
        util_user_message -message "${:label}$errorMsg (locale=${:locale})"
      }
      #
      # Try to parse finally the value against the format
      #
      set converted_value $value
      ad_try {
        scan $value ${:format} result
      } on error {errMsg} {
        set result $value
      }
    }
    #ns_log notice "convert_to_external ${:name} keep_string_rep ${:keep_string_rep} -> $result"
    return $result
  • convert_to_internal (scripted)

    if {!${:keep_string_rep} && ${:value} ne ""} {
      #
      # The value has been already checked against the validator, so
      # the conversion should be smooth.
      #
      set :value [:convert_to_internal_value ${:value}]
      ${:object} set_property -new 1 ${:name} ${:value}
    }
  • convert_to_internal_value (scripted)

    #ns_log notice "convert_to_internal_value called with value '$value'"
    try {
      lc_parse_number $value ${:locale} ${:is_integer}
    } on ok {result} {
    } on error {errorMsg} {
      #ns_log notice "numeric instproc convert_to_internal <$value> ${:locale} -> $errorMsg ($::errorCode)"
      if {${:strict} == 0 && ${:locale} ne "en_US"} {
        try {
          lc_parse_number $value en_US ${:is_integer}
        } on ok {result} {
        }
      } else {
        throw $::errorInfo $errorMsg
      }
    }
    #ns_log notice "convert_to_internal_value called with value '$value' -> $result"
    return $result
  • format (setter)

  • initialize (scripted)

    next
    set :widget_type numeric
    # check, if we have an integer format
    set :is_integer [regexp {%[0-9.]*d} ${:format}]
    if {${:connection_locale} && [ns_conn isconnected]} {
      set :locale [ad_conn locale]
    }
  • keep_string_rep (setter)

  • pretty_value (scripted)

    return [:convert_to_external $value]
  • render_input (scripted)

    #
    # Prevent inserting invalid value; we allow currently just a
    # single dot, comma for floats or "-" to be entered.  Maybe some
    # of this functionality should be blocked conditionally. Paste
    # filtering is also currently just half-hearted but probably
    # sufficient.
    #
    set punctuation [expr {[string match %*f ${:format}] ? ",." : "" }]
    template::add_script -section body -script [subst -nocommands [ns_trim {
      var e = document.getElementById('${:id}');
      e.addEventListener('keypress', function (e) {
        if (!(/[0-9]|[.,]|-/.test(e.key))){
          e.preventDefault();
        } else if (/[$punctuation-]/.test(e.key) && e.target.value.includes(e.key)) {
          e.preventDefault();
        }
      });
      e.addEventListener('paste', function (e) {
        var pasted = e.clipboardData || window.clipboardData;
        var text = pasted.getData('Text');
        if (!text.match(/[0-9$punctuation]|-/)) {
          e.preventDefault();
        }
      });
    }]]
    next
  • strict (setter)

  • validator (setter)