%3 ::xowiki::formfield::CompoundField ::xowiki::formfield::CompoundField add_component add_statistics check=compound convert_to_external convert_to_internal create_components exists_named_sub_component generate_fieldnames get_component get_compound_value get_named_sub_component get_named_sub_component_value has_instance_variable leaf_components make_correct named_sub_components object pretty_value render_input reset_on_validation_error same_value set_compound_value set_disabled set_is_repeat_template specs_unmodified validate value ::xowiki::formfield::FormField ::xowiki::formfield::FormField → fc_decode → fc_encode → get_from_name → get_single_spec → interprete_condition CSSclass_list_add add_statistics answer_check=AND answer_check=answer_words answer_check=btwn answer_check=contains answer_check=contains-not answer_check=eq answer_check=ge answer_check=gt answer_check=in answer_check=le answer_check=lt answer_check=match answer_is_correct asWidgetSpec behavior booleanAttributes config_from_spec convert_to_external convert_to_internal describe dict_to_fc dict_to_spec dict_value escape_message_keys field_value handle_transmit_always has_instance_variable init initialize interprete_single_spec is_disabled is_repeat_template_p leaf_components localize make_correct pretty_image pretty_value process_correct_when_modifier remove_omit render render_answer_statistics render_collapsed render_disabled_as_div render_error_msg render_form_widget render_help_text render_input render_item render_localizer render_modal render_result_statistics render_word_statistics repeat repeat_add_label resetBooleanAttributes reset_on_validation_error reset_parameter same_value set_disabled set_feedback set_is_repeat_template stats_record_count validate validation_check value_if_nothing_is_returned_from_form word_statistics ::xowiki::formfield::CompoundField->::xowiki::formfield::FormField ::xo::tdom::Object ::xo::tdom::Object ::xowiki::formfield::FormField->::xo::tdom::Object ::xowiki::formfield::date ::xowiki::formfield::date convert_to_external get_compound_value initialize pretty_value render_input same_value set_compound_value ::xowiki::formfield::date->::xowiki::formfield::CompoundField

Class ::xowiki::formfield::date

::xowiki::formfield::date[i] create ... \
           [ -display_format (default "%Y-%m-%d %T") ] \
           [ -format (default "DD MONTH YYYY") ]

Class Relations

  • class: ::xotcl::Class[i]
  • superclass: ::xowiki::formfield::CompoundField[i]
::xotcl::Class create ::xowiki::formfield::date \
     -superclass ::xowiki::formfield::CompoundField

Methods (to be applied on instances)

  • convert_to_external (scripted)

    #
    # For the date formfield, the internal representation does not
    # need conversion to external.
    #
    return $internal
  • display_format (setter)

  • format (setter)

  • get_compound_value (scripted)

    # Set the internal representation of the date based on the components values.
    # Internally, the ansi date format is used.
    set year ""set month ""set day ""set hour ""set min ""set sec ""
    if {[nsf::is object [self]::YYYY]}  {set year  [[self]::YYYY  value]}
    if {[nsf::is object [self]::month]} {set month [[self]::month value]}
    if {[nsf::is object [self]::mon]}   {set month [[self]::mon   value]}
    if {[nsf::is object [self]::MM]}    {set month [[self]::MM    value]}
    if {[nsf::is object [self]::DD]}    {set day   [[self]::DD    value]}
    if {[nsf::is object [self]::HH24]}  {set hour  [[self]::HH24  value]}
    if {[nsf::is object [self]::MI]}    {set min   [[self]::MI    value]}
    if {[nsf::is object [self]::SS]}    {set sec   [[self]::SS    value]}
    if {"$year$month$day$hour$min$sec" eq ""} {
      return ""
    }
    # Validation happens after the value is retrieved.
    # To avoid errors in "clock scan", fix the year if necessary
    if {![nsf::is integer $year]} {
      set year 0
    }
    
    foreach v [list year month day hour min sec] {
      if {[set $v] eq ""} {
        set $v [set :defaults($v)]
      }
    }
    #:msg "$year-$month-$day ${hour}:${min}:${sec}"
    if {[catch {set ticks [clock scan "$year-$month-$day ${hour}:${min}:${sec}"]}]} {
      set ticks 0 ;# we assume that the validator flags these values
    }
    # TODO: TZ???
    #:msg "DATE ${:name} get_compound_value returns [clock format $ticks -format {%Y-%m-%d %T}]"
    return [clock format $ticks -format "%Y-%m-%d %T"]
  • initialize (scripted)

    #:msg "DATE has value [:value]//d=[:default] format=${:format} disabled?[info exists :disabled]"
    set :widget_type date
    set :format [string map [list _ " "${:format}]
    array set :defaults {year 2000 month 01 day 01 hour 00 min 00 sec 00}
    array set :format_map {
      SS    {SS    %S 1}
      MI    {MI    %M 1}
      HH24  {HH24  %H 1}
      DD    {DD    %e 0}
      MM    {MM    %m 1}
      MON   {mon   %m 1}
      MONTH {month %m 1}
      YYYY  {YYYY  %Y 0}
    }
    #:msg "${:name} initialize date, format=${:format} components=${:components}"
    foreach c ${:components} {$c destroy}
    :components {}
    
    foreach element [split ${:format}] {
      if {![info exists :format_map($element)]} {
        #
        # We add undefined formats as literal texts in the edit form
        #
        set name $element
        set c [::xowiki::formfield::label create [self]::$name  -name ${:name}.$name -id ${:id}.$name  -locale [:locale] -object ${:object}  -value $element]
        $c set_disabled 1; # this is a dummy field, never query for its value
        if {$c ni ${:components}} {lappend :components $c}
        continue
      }
      lassign [set :format_map($element)] class code trim_zeros
      #
      # create for each component a form field
      #
      set name $class
      set c [::xowiki::formfield::$class create [self]::$name  -name ${:name}.$name -id ${:id}.$name  -locale [:locale] -object ${:object}]
      #:msg "creating ${:name}.$name"
      $c set_disabled [:is_disabled]
      $c set code $code
      $c set trim_zeros $trim_zeros
      if {$c ni ${:components}} {lappend :components $c}
    }
  • pretty_value (scripted)

    #
    # Internally, we use the ansi date format. For displaying the date,
    # use the specified display format and present the time localized.
    #
    # Drop of the value after the "." we assume to have a date in the local zone
    regexp {^([^.]+)[.]} $v _ v
    #return [clock format [clock scan $v] -format [string map [list _ " "] ${:display_format}]]
    if {${:display_format} eq "pretty-age"} {
      return [::xowiki::utility pretty_age -timestamp [clock scan $v] -locale [:locale]]
    } else {
      return [lc_time_fmt $v [string map [list _ " "${:display_format}] [:locale]]
    }
  • render_input (scripted)

    #
    # render the content inline within a fieldset, without labels etc.
    #
    set :style "margin: 0px; padding: 0px;"
    html::fieldset [:get_attributes id style] {
      foreach c ${:components} { $c render_input }
    }
  • same_value (scripted)

    if {$v1 eq $v2} {return 1}
    return 0
  • set_compound_value (scripted)

    #:log "${:name} original value '[:value]' // passed='$value' disa?[info exists :disabled]"
    if { $value eq {} } {
      # We need to reset component values so that
      # instances of this class can be used as flyweight
      # objects. Otherwise, we get side-effects when
      # we render the input widget.
      foreach c ${:components} {
        $c value ""
      }
      return
    }
    set value [::xo::db::tcl_date $value tz]
    if {$value ne ""} {
      #ns_log notice "DATE date tries to scan '$value' // <[string map [list _ " "] $value]>"
      set ticks [clock scan [string map [list _ " "$value]]
    } else {
      error "date: the parsed database value must not be empty"
    }
    set :defaults(year)  [clock format $ticks -format %Y]
    set :defaults(month) [clock format $ticks -format %m]
    set :defaults(day)   [clock format $ticks -format %e]
    set :defaults(hour)  [clock format $ticks -format %H]
    set :defaults(min)   [clock format $ticks -format %M]
    #set :defaults(sec)   [clock format $ticks -format %S]
    
    # set the value parts for each components
    foreach c ${:components} {
      if {[$c istype ::xowiki::formfield::label]} continue
      if {$ticks ne ""} {
        set value_part [string trim [clock format $ticks -format [$c set code]]]
        if {[$c set trim_zeros]} {
          set value_part [string trimleft $value_part 0]
          if {$value_part eq ""} {
            set value_part 0
          }
        }
      } else {
        set value_part ""
      }
      #:msg "ticks=$ticks $c value $value_part"
      $c value $value_part
    }