Class ::xowiki::formfield::CompoundField (public)

 ::xotcl::Class ::xowiki::formfield::CompoundField[i]

Defined in

Testcases:
No testcase defined.
Source code:
namespace eval ::xowiki::formfield {}
::nsf::object::alloc ::xotcl::Class ::xowiki::formfield::CompoundField {set :__default_metaclass ::xotcl::Class
   set :__default_superclass ::xotcl::Object}
::xowiki::formfield::CompoundField instproc check=compound value {
    #:msg "check compound in ${:components}"
    foreach c ${:components} {
      set error [$c validate [self]]
      if {$error ne ""} {
        set msg "[$c label]: $error"
        :uplevel [list set errorMsg $msg]
        #util_user_message -message "Error in compound field [$c name]: $error"
        return 0
      }
    }
    return 1
  }
::xowiki::formfield::CompoundField instproc specs_unmodified spec_list {
    expr {${:__state} eq "after_specs"
          && [info exists :structure] && ${:structure} eq $spec_list
        }
  }
::xowiki::formfield::CompoundField instproc reset_on_validation_error args {
    #
    # We actually want to reset all the leaf components
    #
    ns_log debug "reset_on_validation_error COMPOUND"
    foreach f [:leaf_components] {
      $f reset_on_validation_error {*}$args
    }
  }
::xowiki::formfield::CompoundField instproc set_is_repeat_template is_template {
    # :msg "${:name} set is_repeat_template $is_template"
    if {$is_template} {
      set :is_repeat_template true
    } else {
      unset -nocomplain :is_repeat_template
    }
    foreach c ${:components} {
      $c set_is_repeat_template $is_template
    }
  }
::xowiki::formfield::CompoundField instproc get_named_sub_component_value {-from_repeat:switch {-default ""} args} {
    if {[:exists_named_sub_component {*}$args]} {
      set result [[:get_named_sub_component {*}$args] value]
      if {$from_repeat} {
        if {[lindex [split [lindex $result 0] .] end] eq "0"} {
          set result [lrange $result 2 end]
        }
      }
    } else {
      set result $default
    }
    return $result
  }
::xowiki::formfield::CompoundField instproc named_sub_components {} {
    # Iterate along the argument list to check components of a deeply
    # nested structure.
    set component_names [array names :component_index]
    foreach c ${:components} {
      lappend component_names {*}[$c array names component_index]
    }
    return $component_names
  }
::xowiki::formfield::CompoundField instproc pretty_value v {
    #
    # Typically, subtypes of CompoundFields should define their own
    # "pretty_value". This is a simple renderer that provides a
    # default behavior.
    #
    set ff [dict create {*}$v]
    set html "<ul class='CompoundField'>\n"
    foreach c [lsort ${:components}] {
      set componentName [$c set name]
      if {[dict exists $ff $componentName]} {
        set componentLabel [string range $componentName [string length ${:name}]+1 end]
        append html "<li><span class='name'>$componentLabel:</span> "  "[$c pretty_value [dict get $ff $componentName]]</li>\n"
      }
    }
    append html "</ul>\n"
    return $html
  }
::xowiki::formfield::CompoundField instproc set_compound_value value {
    if {![string is list $value] || ([llength $value] % 2) == 1} {
      # this branch could be taken, when the field was retyped
      ns_log notice "CompoundField: value '$value' is not avalid dict"
      return
    }
    # set the value parts for each components
    foreach c ${:components} {
      # Set only those parts, for which attribute values pairs are
      # given.  Components might have their own default values, which
      # we do not want to overwrite ...
      set cname [$c name]
      if {[dict exists $value $cname]} {
        $c value [dict get $value $cname]
      }
    }
  }
::xowiki::formfield::CompoundField instproc has_instance_variable {var value} {
    set r [next]
    if {$r} {return 1}
    foreach c ${:components} {
      set r [$c has_instance_variable $var $value]
      if {$r} {return 1}
    }
    return 0
  }
::xowiki::formfield::CompoundField instproc leaf_components {} {
    set leaf_components {}
    foreach c ${:components} {
      if {[self class] in [[$c info class] info heritage]} {
        lappend leaf_components {*}[$c leaf_components]
      } else {
        lappend leaf_components $c
      }
    }
    return $leaf_components
  }
::xowiki::formfield::CompoundField instproc object args {
    set l [llength $args]
    switch $l {
      0 {
        #
        # Called without args, return the current value
        #
        return ${:object}
      }
      1 {
        #
        # Called with a single value, set object for all components
        #
        foreach c ${:components} {
          $c object [lindex $args 0]
        }

        set :object [lindex $args 0]
      }
      default {
        error "wrong number of arguments"
      }
    }
  }
::xowiki::formfield::CompoundField instproc exists_named_sub_component args {
    # Iterate along the argument list to check components of a deeply
    # nested structure. For example,
    #
    #    :check_named_sub_component a b
    #
    # returns 0 or one depending whether there exists a component "a"
    # with a subcomponent "b".
    set component_name ${:name}
    set sub [self]
    foreach e $args {
      append component_name .$e
      if {![$sub exists component_index($component_name)]} {
        return 0
      }
      set sub [$sub set component_index($component_name)]
    }
    return 1
  }
::xowiki::formfield::CompoundField instproc render_input {} {
    #
    # Render content within in a fieldset, but with labels etc.
    #
    :CSSclass_list_add CSSclass [namespace tail [:info class]]
    :CSSclass_list_add CSSclass "align-items-center"
    html::fieldset [:get_attributes id {CSSclass class}] {
      foreach c ${:components} { $c render }
    }
  }
::xowiki::formfield::CompoundField instproc make_correct {} {
    foreach c ${:components} {
      $c make_correct
    }
  }
::xowiki::formfield::CompoundField instproc convert_to_internal {} {
    foreach c ${:components} {
      $c convert_to_internal
    }
    # Finally, update the compound value entry with the compound
    # internal representation; actually we could drop the instance
    # atts of the components from the "instance_attributes" ...
    ${:object} set_property -new 1 ${:name} [:get_compound_value]
  }
::xowiki::formfield::CompoundField instproc get_compound_value {} {
    #
    # returns the internal representation based on the components values.
    #
    set cc [[${:object} package_id] context]

    set value [list]
    foreach c ${:components} {
      lappend value [$c name] [$c value]
    }
    #:log "${:name}: get_compound_value returns value=$value"
    return $value
  }
::xowiki::formfield::CompoundField instproc create_components spec_list {
    #:log "create_components $spec_list"

    #
    # Omit after specs for compound fields to avoid multiple
    # recreations.
    #
    if {[:specs_unmodified $spec_list]} {
      return
    }

    #
    # Build a component structure based on a list of specs
    # of the form {name spec}.
    #
    set :structure $spec_list
    set :components [list]
    foreach entry $spec_list {
      #:log "create_components creates form-field for spec '$entry'"
      lassign $entry name spec
      if {$name eq ""} {
        continue
      }
      #
      # create for each component a form field
      #
      set c [::xowiki::formfield::FormField create [self]::$name  -name ${:name}.$name -id ${:id}.$name  -locale [:locale] -object ${:object}  -spec $spec]
      set :component_index(${:name}.$name$c
      $c set parent_field [self]
      lappend :components $c
    }
  }
::xowiki::formfield::CompoundField instproc same_value {v1 v2} {
    if {$v1 eq $v2} {return 1}
    foreach {n1 value1} $v1 {n2 value2} $v2  {
      set f [set :component_index($n1)]
      if {![$f same_value $value1 $value2]} { return 0 }
    }
    return 1
  }
::xowiki::formfield::CompoundField instproc validate obj:object {
    # Delegate validate to the components. If a validation of a
    # component fails, report the error message back.
    foreach c ${:components} {
      set result [$c validate $obj]
      #ns_log notice "CompoundField validate on [$c name] returns '$result' [info exists errorMsg]"
      if {$result ne ""} {
        return $result
      }
    }
    return ""
  }
::xowiki::formfield::CompoundField instproc get_component component_name {
    set key component_index(${:name}.$component_name)
    if {[info exists :$key]} {
      return [set :$key]
    }
    error "no component named $component_name of compound field ${:name}"
  }
::xowiki::formfield::CompoundField instproc generate_fieldnames {{-prefix "v-"} n} {
    set names [list]
    for {set i 1} {$i <= $n} {incr i} {lappend names $prefix$i}
    return $names
  }
::xowiki::formfield::CompoundField instproc set_disabled disable {
    #:msg "${:name} set disabled $disable"
    next

    foreach c ${:components} {
      $c set_disabled $disable
    }
  }
::xowiki::formfield::CompoundField instproc add_component entry {
    #
    # Add a single component dynamically to the list of already
    # existing components and return the component as result.
    #
    lappend :structure $entry
    lassign $entry name spec
    set c [::xowiki::formfield::FormField create [self]::$name  -name ${:name}.$name -id ${:id}.$name  -locale [:locale] -object ${:object}  -spec $spec]
    set :component_index(${:name}.$name$c
    lappend :components $c
    return $c
  }
::xowiki::formfield::CompoundField instproc add_statistics {{-options ""}} {
    foreach c ${:components} {
      $c add_statistics -options $options
    }
  }
::xowiki::formfield::CompoundField instproc value value:optional {
    if {[info exists value]} {
      #:msg "${:name}: setting compound value => '$value'"
      :set_compound_value $value
    }
    return [:get_compound_value]
  }
::xowiki::formfield::CompoundField instproc convert_to_external internal {
    #ns_log notice "Compound ${:name} convert_to_external <$internal>"
    set result {}
    set c [lindex ${:components} 0]
    if {[$c is_repeat_template_p]} {
      foreach {name value} $internal {
        set value [$c convert_to_external [dict get $internal $name]]
        lappend result $name $value
      }
    } else {
      foreach c ${:components} {
        set name [$c name]
        if {[dict exists $internal $name]} {
          set value [$c convert_to_external [dict get $internal $name]]
        } else {
          set value ""
        }
        lappend result [$c name] $value
      }
    }
    #ns_log notice "Compound ${:name} convert_to_external -> $result"
    return $result
  }
::xowiki::formfield::CompoundField instproc get_named_sub_component args {
    # Iterate along the argument list to get components of a deeply
    # nested structure. For example,
    #
    #    :get_named_sub_component a b
    #
    # returns the object of the subcomponent "b" of component "a"
    set component_name ${:name}
    set sub [self]
    foreach e $args {
      append component_name .$e
      #:msg "check $sub set component_index($component_name)"
      set sub [$sub set component_index($component_name)]
    }
    return $sub
  }
::xowiki::formfield::CompoundField instparametercmd components
::xowiki::formfield::CompoundField instparametercmd validator
::xowiki::formfield::CompoundField instparametercmd CSSclass
::nsf::relation::set ::xowiki::formfield::CompoundField superclass ::xowiki::formfield::FormField

::nx::slotObj -container slot ::xowiki::formfield::CompoundField
::xowiki::formfield::CompoundField::slot eval {set :__parameter {
    {components ""}
    {CSSclass compound-field}
  }}

::nsf::object::alloc ::xotcl::Attribute ::xowiki::formfield::CompoundField::slot::validator {set :accessor public
   set :configurable true
   set :convert false
   set :default compound
   set :defaultmethods {}
   set :disposition alias
   set :domain ::xowiki::formfield::CompoundField
   set :incremental false
   set :manager ::xowiki::formfield::CompoundField::slot::validator
   set :methodname validator
   set :multiplicity 1..1
   set :name validator
   set :per-object false
   set :position 0
   set :required false
   set :substdefault 0b111
   set :trace none
   : init}

::nsf::object::alloc ::xotcl::Attribute ::xowiki::formfield::CompoundField::slot::components {set :accessor public
   set :configurable true
   set :convert false
   set :default {}
   set :defaultmethods {}
   set :disposition alias
   set :domain ::xowiki::formfield::CompoundField
   set :incremental 0
   set :manager ::xowiki::formfield::CompoundField::slot::components
   set :methodname components
   set :multiplicity 1..1
   set :name components
   set :per-object false
   set :position 0
   set :required false
   set :substdefault 0b111
   set :trace none
   : init}

::nsf::object::alloc ::xotcl::Attribute ::xowiki::formfield::CompoundField::slot::CSSclass {set :accessor public
   set :configurable true
   set :convert false
   set :default compound-field
   set :defaultmethods {}
   set :disposition alias
   set :domain ::xowiki::formfield::CompoundField
   set :incremental 0
   set :manager ::xowiki::formfield::CompoundField::slot::CSSclass
   set :methodname CSSclass
   set :multiplicity 1..1
   set :name CSSclass
   set :per-object false
   set :position 0
   set :required false
   set :substdefault 0b111
   set :trace none
   : init}
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: