- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables
Class ::xowiki::formfield::CompoundField
::xowiki::formfield::CompoundField create ... \
[ -CSSclass (default "compound-field") ] \
[ -components (default "") ]
Defined in
Class Relations
- class: ::xotcl::Class
- superclass: ::xowiki::formfield::FormField
- subclass: ::xowiki::formfield::repeatContainer, ::xowiki::formfield::regression_test_mycompound, ::xowiki::formfield::text_fields, ::xowiki::formfield::regression_test_compound_with_repeat2, ::xowiki::formfield::mc_exercise, ::xowiki::formfield::date, ::xowiki::formfield::CalendarField, ::xowiki::formfield::repeattest, ::xowiki::formfield::mc_alternative, ::xowiki::formfield::FormGeneratorField, ::xowiki::formfield::regression_test_compound_with_repeat, ::xowiki::formfield::regression_test_compound_numeric, ::xowiki::formfield::comp_correct_when
::xotcl::Class create ::xowiki::formfield::CompoundField \ -superclass ::xowiki::formfield::FormFieldMethods (to be applied on instances)
CSSclass (setter)
add_component (scripted)
# # 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 $cadd_statistics (scripted)
foreach c ${:components} { $c add_statistics -options $options }check=compound (scripted)
#: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 1components (setter)
convert_to_external (scripted)
#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 $resultconvert_to_internal (scripted)
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]create_components (scripted)
#: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 }exists_named_sub_component (scripted)
# 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 1generate_fieldnames (scripted)
set names [list] for {set i 1} {$i <= $n} {incr i} {lappend names $prefix$i} return $namesget_component (scripted)
set key component_index(${:name}.$component_name) if {[info exists :$key]} { return [set :$key] } error "no component named $component_name of compound field ${:name}"get_compound_value (scripted)
# # 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 $valueget_named_sub_component (scripted)
# 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 $subget_named_sub_component_value (scripted, public)
<instance of xowiki::formfield::CompoundField> get_named_sub_component_value \ [ -from_repeat ] [ -default default ] args [ args... ]Return the value of a named subcomponent. When the named subcomponent is a repeated item, and the value of the 0th element of the repeat (the template element) is omitted from the returned value.
- Switches:
- -from_repeat (optional)
- skip template element from repeated values
- -default (optional)
- default value, when component is not found
- Parameters:
- args (required)
- space separated path of elements names in a potentially nested component structure (similar to dict)
- Testcases:
- create_test_items
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 $resulthas_instance_variable (scripted)
set r [next] if {$r} {return 1} foreach c ${:components} { set r [$c has_instance_variable $var $value] if {$r} {return 1} } return 0leaf_components (scripted)
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_componentsmake_correct (scripted)
foreach c ${:components} { $c make_correct }named_sub_components (scripted)
# 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_namesobject (scripted)
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" } }pretty_value (scripted)
# # 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 $htmlrender_input (scripted)
# # 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 } }reset_on_validation_error (scripted)
# # 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 }same_value (scripted)
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 1set_compound_value (scripted)
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] } }set_disabled (scripted)
#:msg "${:name} set disabled $disable" next foreach c ${:components} { $c set_disabled $disable }set_is_repeat_template (scripted)
# :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 }specs_unmodified (scripted)
expr {${:__state} eq "after_specs" && [info exists :structure] && ${:structure} eq $spec_list }validate (scripted)
# 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 ""validator (setter)
value (scripted)
if {[info exists value]} { #:msg "${:name}: setting compound value => '$value'" :set_compound_value $value } return [:get_compound_value]
- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables