Class ::xowiki::formfield::FormField (public)

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

Defined in

Testcases:
No testcase defined.
Source code:
namespace eval ::xowiki::formfield {}
::nsf::object::alloc ::xotcl::Class ::xowiki::formfield::FormField {set :__default_metaclass ::xotcl::Class
   set :__default_superclass ::xotcl::Object
   set :abstract 1
   set :cond_regexp {^([^=?]+)[?]([^:]*)[:](.*)$}}
::xowiki::formfield::FormField proc fc_decode string {
    return [string map [list __COMMA__ ,] $string]
  }
::xowiki::formfield::FormField proc interprete_condition {-package_id -object:object cond} {
    if {[::xo::cc info methods role=$cond] ne ""} {
      if {$cond eq "creator"} {
        set success [::xo::cc role=$cond  -object $object  -user_id [::xo::cc user_id]  -package_id $package_id]
      } else {
        set success [::xo::cc role=$cond  -user_id [::xo::cc user_id]  -package_id $package_id]
      }
    } else {
      set success [$object evaluate_form_field_condition $cond]
    }
    return $success
  }
::xowiki::formfield::FormField proc fc_encode string {
    return [string map [list , __COMMA__] $string]
  }
::xowiki::formfield::FormField proc get_from_name {object:object name} {
    #
    # Get a form field via name. The provided names are unique for a
    # form. If multiple forms should be rendered simultaneously, we
    # have to extend the addressing mechanism.
    #
    # todo: we could speed this up by an index if needed
    foreach f [::xowiki::formfield::FormField info instances -closure] {
      if {[$f name] eq $name} {
        if {![$f exists object]} {
          #ad_log warning "strange, $f [$f name] was created without object but fits name"
          return $f
        } elseif {$object eq [$f object]} {
          return $f
        }
      }
    }
    #:msg not-found-$object-$name
    return ""
  }
::xowiki::formfield::FormField proc get_single_spec {-package_id -object:object string} {
    if {[regexp ${:cond_regexp} $string _ condition true_spec false_spec]} {
      if {[:interprete_condition -package_id $package_id -object $object $condition]} {
        return [:get_single_spec -package_id $package_id -object $object $true_spec]
      } else {
        return [:get_single_spec -package_id $package_id -object $object $false_spec]
      }
    }
    return $string
  }
::xowiki::formfield::FormField instproc answer_check=answer_words {} {
    #
    # Correct, when the answer is equal to the provided (sequence of)
    # words, but white-space is ignored. When the first word is
    # "*lower*" then the provided answer of the student is converted
    # to lowercase before the comparison is performed; as a
    # consequence the comparison is not case sensitive. Note that the
    # answer_words have to be provided in lowercase as well.
    #
    set d [:process_correct_when_modifier]
    dict with d {
      return [expr {$value eq $words}]
    }
  }
::xowiki::formfield::FormField instproc render_error_msg {} {
    #ns_log notice "render_error_msg: field ${:name} has errorMsg (reported [info exists :error_reported]) '${:error_msg}'"
    if {${:error_msg} ne "" && ![info exists :error_reported]} {
      ::html::div -class form-error {
        set label ${:label} ;# needed for error_msg; TODO: we should provide a substitution_list similar to "_"
        ::html::t [::xo::localize ${:error_msg}]
        :render_localizer
        set :error_reported 1
      }
    }
  }
::xowiki::formfield::FormField instproc convert_to_internal {} {
    # To be overloaded.
  }
::xowiki::formfield::FormField instproc answer_check=contains-not {} {
    #
    # Correct, when answer does not contain any of the provided
    # words. Just a negation of "contains".
    #
    return [expr {[:answer_check=contains] ? 0 : 1}]
  }
::xowiki::formfield::FormField instproc escape_message_keys value {
    #
    # Can be overloaded, when e.g. no escaping of message keys or
    # other representations of message keys are desired.
    #
    return [xo::escape_message_keys $value]
  }
::xowiki::formfield::FormField instproc repeat range {
    if {[info exists :__initialized_repeat]} return

    set oldClass [:info class]
    :class ::xowiki::formfield::repeatContainer

    if {$oldClass ne [:info class]} {
      :reset_parameter
      set :__state reset
    }

    if {$range ne ""} {
      if {[regexp {^(\d*)[.][.](\d*)$} $range _ low high]} {
        if {$low ne ""}  {set :min $low}
        if {$high ne ""} {set :max $high}
        if {${:min} > ${:max}} {
          error "invalid range '$range' specified (lower limit ${:min} must not be larger than higher limit ${:max})"
        }
        if {${:min} < 0 || ${:max} < 1} {
          error "invalid range '$range' specified (max ${:max} must be at least 1) "
        }
      } else {
        error "invalid range '$range' specified (must be of form 'min..max')"
      }
    }
    :initialize
  }
::xowiki::formfield::FormField instproc answer_check=le {} {
    set d [:process_correct_when_modifier]
    dict with d {
      return [expr {$value ne "" && $value <= [lindex $words 0]}]
    }
  }
::xowiki::formfield::FormField instproc convert_to_external value {
    # To be overloaded.
    return $value
  }
::xowiki::formfield::FormField instproc render_word_statistics {} {
    #ns_log notice ":render_word_statistics: ${:word_statistics_option}"
    if {${:word_statistics_option} eq "word_cloud"} {
      # stopword list based on lucene, added a few more terms
      set stopWords {
        a about an and are as at be but by do does for from how if in into is it no not of on or
        such that the their then there these they this to vs was what when where who will with
      }
      set jsWords {}
      foreach {word freq} [lsort -decreasing -integer -stride 2 -index 1 ${:word_statistics}] {
        if {$word in $stopWords} continue
        lappend jsWords [subst {{text: "$word", weight: $freq}}]
      }
      set tsp [clock clicks -microseconds]
      set height [expr {(12*[llength $jsWords]/10)  + 250}]
      # set js [subst {
      #   var jqcloud_$tsp = \[
      #   [join $jsWords ",\n"]
      #   \];
      #   \$('#jqcloud_$tsp').jQCloud(jqcloud_$tsp, {autoResize: true, width: 500, steps: 5, height: $height});
      # }]
      set js [subst {
        var jqcloud_$tsp = \[
        [join $jsWords ",\n"]
        \];
        \$('#jqcloud_$tsp').jQCloud(jqcloud_$tsp, {autoResize: true, width: 500, height: $height});
      }]
      template::add_script -order 20 -src https://cdn.jsdelivr.net/npm/jqcloud2@2.0.3/dist/jqcloud.min.js
      template::head::add_css -href https://cdn.jsdelivr.net/npm/jqcloud2@2.0.3/dist/jqcloud.min.css
      security::csp::require script-src https://cdn.jsdelivr.net
      security::csp::require style-src  https://cdn.jsdelivr.net

      template::add_body_script -script $js
      ::html::div -class "jq-cloud" -id jqcloud_$tsp  {}
    } else {
      ::html::ul {
        foreach {word freq} [lsort -decreasing -integer -stride 2 -index 1 ${:word_statistics}] {
          html::li { html::t "$freq: $word" }
          lappend jsWords [subst {{text: "$word", weight: $freq}}]
        }
      }
    }
  }
::xowiki::formfield::FormField instproc repeat_add_label label {
    if {[info exists :__initialized_repeat]} return
    set :repeat_add_label $label
  }
::xowiki::formfield::FormField instproc render_answer_statistics {} {
    #ns_log notice ":answer_statistics: ${:answer_statistics}"
    ::html::ul {
      foreach {answer freq} [lsort -decreasing -integer -stride 2 -index 1 ${:answer_statistics}] {
        html::li { html::t "$freq: $answer" }
      }
    }
  }
::xowiki::formfield::FormField 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 :is_repeat_template
    }
  }
::xowiki::formfield::FormField instproc resetBooleanAttributes atts {
    #
    # Unset the temporary boolean attributes which were set by method
    # "booleanAttributes".
    #
    foreach att $atts {
      lassign $att var value
      if {[info exists :$var]} {unset :$var}
    }
  }
::xowiki::formfield::FormField instproc CSSclass_list_add {attrName value} {
    #
    # Convenience function to add a CSS class to the existing values
    # in "attrName". The function is named somewhat similar to the
    # JavaScript function "classList.add"
    #
    if {$value ne ""} {
      if {[info exists :$attrName]} {
        append :$attrName " " $value
      } else {
        set :$attrName $value
      }
    }
  }
::xowiki::formfield::FormField instproc config_from_spec spec {
    #:log "config_from_spec ${:name} spec <$spec> [:info class] [[:info class] exists abstract]"
    if {[[:info class] exists abstract]} {
      # had earlier here: [:info class] eq [self class]
      # Check, whether the actual class is a concrete class (mapped to
      # concrete field type) or an abstract class.  Since
      # config_from_spec can be called multiple times, we want to do
      # the reclassing only once.
      if {[:isclass ::xowiki::formfield::${:type}]} {
        :class ::xowiki::formfield::${:type}
      } else {
        :class ::xowiki::formfield::text
      }
      # set missing instance vars with defaults
      :set_instance_vars_defaults
    }
    regsub -all -- {,\s+} $spec , spec
    foreach s [split $spec ,] {
      :interprete_single_spec [FormField fc_decode $s]
    }

    #:msg "${:name}: after specs"
    set :__state after_specs
    #:log "INITIALIZE ${:name} due to config_from_spec"
    :initialize

    #
    # It is possible, that a default value of a form field is changed through a spec.
    # Since only the configuration might set values, checking value for "" seems safe here.
    #
    if {[:value] eq "" && [info exists :default] && ${:default} ne ""} {
      #:msg "+++ reset value to [:default]"
      :value ${:default}
    }

    if {[lang::util::translator_mode_p]} {
      :mixin add "::xo::TRN-Mode"
    }

  }
::xowiki::formfield::FormField instproc pretty_value v {
    #:log "mapping $v"
    return [string map [list & "&amp;" < "&lt;" > "&gt;" \" "&quot;" ' "&#39;" @ "&#64;"$v]
  }
::xowiki::formfield::FormField instproc render_collapsed {-id:required {-label ""} -inner_method} {
    ::xowiki::BootstrapCollapseButton new -id $id -label $label -toggle "collapse" -direction "down"
    ::html::div -id "$id" -class "collapse" {
      :$inner_method
    }
  }
::xowiki::formfield::FormField instproc render_item {} {
    ::html::div [:get_attributes {form_item_wrapper_CSSclass class}] {
      if {[:error_msg] ne ""} {
        set CSSclass form-label-error
      } else {
        set CSSclass form-label
      }
      if {[::template::CSS toolkit] eq "bootstrap5"} {
        ::html::label -class "${:form_label_CSSclass} [lindex [split ${:name} .] end]" -for ${:id} {
          ::html::t ${:label}
        }
        if {${:required} && ${:mode} eq "edit"} {
          ::html::div -class form-required-mark {
            ::html::t " (#acs-templating.required#)"
          }
        }
      } else {
        ::html::div -class $CSSclass {
          ::html::label -class "${:form_label_CSSclass} [lindex [split ${:name} .] end]" -for ${:id} {
            ::html::t ${:label}
          }
          if {${:required} && ${:mode} eq "edit"} {
            ::html::div -class form-required-mark {
              ::html::t " (#acs-templating.required#)"
            }
          }
        }
      }
      :render_form_widget
      :render_help_text
      :render_error_msg
      html::t \n
    }
  }
::xowiki::formfield::FormField instproc make_correct {} {
    #
    # Set the form_field to a correct value, currently based on
    # :correct_when.  We could use here :answer when available.
    # Modified instance variables
    #
    # - :help_text is cleared to avoid stray per-user-feedback,
    #    We could as well provide teacher-level feedback here.
    # - :form_widget_CSSclass is altered to "correct" or "unknown".
    #
    #ns_log notice "FormField make_correct ${:name}: [info exists :answer] [info exists :correct_when]"

    set :form_widget_CSSclass unknown
    if {[info exists :correct_when]} {
      #
      # Try to get a correct value from the correct_when spec
      #
      set predicate [lindex ${:correct_when} 0]
      set args [lrange ${:correct_when} 1 end]
      switch $predicate {
        "match"    {set correct $args}
        "eq"       {set correct $args}
        "gt"       {set correct "> $args"}
        "ge"       {set correct ">= $args"}
        "lt"       {set correct "< $args"}
        "le"       {set correct "<= $args"}
        "contains" {set correct "... [join $args { ... }] ..."}
        "answer_words" {set correct "... [join $args { ... }] ..."}
        "in"       {set correct "... [join args { OR }] ..."}
        "btwn"     {set correct "[lindex $args 0] <= X <= [lindex $args 1]"}

      }
      if {[info exists correct]} {
        :value $correct
        set :form_widget_CSSclass correct
        #ns_log notice "FormField make_correct ${:name}: value '${:value}'"
      } else {
        ns_log notice "FormField make_correct ${:name}: not handled: correct_when '${:correct_when}' "
      }
    } else {
      ns_log notice "FormField make_correct ${:name}: not handled: answer? [info exists :answer]"
    }
    set :help_text "" ;# we could provide a teacher-level feedback here.
  }
::xowiki::formfield::FormField instproc answer_check=eq {} {
    set d [:process_correct_when_modifier]
    dict with d {
      return [expr {$value eq [lindex $words 0]}]
    }
  }
::xowiki::formfield::FormField instproc answer_check=contains {} {
    #
    # Correct, when answer contains any of the provided words.
    #
    set d [:process_correct_when_modifier]
    foreach word [dict get $d words] {
      if {[string match *$word* [dict get $d value]]} {
        return 1
      }
    }
    return 0
  }
::xowiki::formfield::FormField instproc pretty_image {-parent_id:required {-revision_id ""} entry_name} {
    if {$entry_name eq "" || ${:value} eq ""} return

    set item_ref [${:object} item_ref -default_lang [${:object} lang] -parent_id $parent_id $entry_name]

    set label ${:label} ;# the label is used for alt and title
    if {$label eq [dict get $item_ref stripped_name]} {
      #
      # The label is apparently the default. For Photo.form instances,
      # this is always "image". In such cases, use the title of the
      # parent object as label.
      #
      set label [${:object} title]
    }
    set l [::xowiki::Link create new  -page ${:object} -type "image"  -lang [dict get $item_ref prefix]  -stripped_name [dict get $item_ref stripped_name]  -label $label  -parent_id [dict get $item_ref parent_id]  -item_id [dict get $item_ref item_id]  -destroy_on_cleanup]

    if {[:istype file]} {
      if {$revision_id ne ""} {
        $l revision_id $revision_id
      }
    }

    foreach option {
      href cssclass
      float width height
      padding padding-right padding-left padding-top padding-bottom
      margin margin-left margin-right margin-top margin-bottom
      border border-width position top bottom left right
      geometry
    } {
      if {[info exists :$option]} {$l set $option [set :$option]}
    }
    set html [$l render]
    return $html
  }
::xowiki::formfield::FormField instproc answer_check=lt {} {
    set d [:process_correct_when_modifier]
    dict with d {
      return [expr {$value ne "" && $value < [lindex $words 0]}]
    }
  }
::xowiki::formfield::FormField instproc validate obj:object {
    # use the 'value' method to deal e.g. with compound fields
    set value [:value]
    #:msg "[:info class] value=$value req=${:required} // ${:value} //"

    if {${:required}
        && $value eq ""
        && ![:istype ::xowiki::formfield::hidden]
      } {
      return [_ acs-templating.Element_is_required [list label ${:label}]]
    }
    #
    #:log "++ ${:name} [:info class] validator=[:validator] ([llength [:validator]]) value=$value"
    foreach validator [:validator] {
      set errorMsg ""
      #
      # The validator might set the variable errorMsg in this scope.
      #
      set success 1
      set validator_method check=$validator
      set proc_info [:procsearch $validator_method]
      #:log "++ ${:name}: field-level validator exists '$validator_method' ? [expr {$proc_info ne {}}]"
      if {$proc_info ne ""} {
        #
        # We have a slot checker, call it.
        #
        #:msg "++ call-field level validator $validator_method '$value'"
        set success [:validation_check $validator_method $value]
      }
      #:log "++ ${:name} [:info class] validator=[:validator] ([llength [:validator]]) value=$value -> $success"
      if {$success == 1} {
        #
        # The previous check was ok, check now for a validator on the
        # object level.
        #
        set validator_method validate=$validator
        set proc_info [$obj procsearch $validator_method]
        #:log "++ ${:name}: page-level validator exists ? [expr {$proc_info ne {}}]"
        if {$proc_info ne ""} {
          set success [$obj $validator_method $value]
          #:msg "++ call page-level validator $validator_method '$value' returns $success"
        }
      }
      if {$success == 0} {
        #
        # We have an error message. Get the class name from procsearch and construct
        # a message key based on the class and the name of the validator.
        #
        set cl [namespace tail [lindex $proc_info 0]]
        #:msg "__langPkg?[info exists __langPkg]"
        if {![info exists __langPkg]} {
          set __langPkg "xowiki"
        }
        #:log "calling $__langPkg.$cl-validate_$validator with [list value $value errorMsg $errorMsg] on level [info level]"
        set msg [_ $__langPkg.$cl-validate_$validator [list value $value errorMsg $errorMsg]]
        if {$msg eq ""} {
          set msg  "validation of field '$validator' failed, '$errorMsg', no message key '$__langPkg.$cl-validate_$validator' provided"
          :log "++ ${:name}: VALIDATION FAILED <$msg>"
        }
        return $msg
      }
    }
    return ""
  }
::xowiki::formfield::FormField instproc same_value {v1 v2} {
    if {$v1 eq $v2} {return 1}
    return 0
  }
::xowiki::formfield::FormField instproc localize v {
    # We localize in pretty_value the message keys in the
    # language of the item (not the connection item).
    if {[regexp "^#(.*)#$" $v _ key]} {
      return [lang::message::lookup ${:locale} $key]
    }
    return $v
  }
::xowiki::formfield::FormField instproc is_disabled {} {
    return [expr {[info exists :disabled] && [string is true -strict ${:disabled}]}]
  }
::xowiki::formfield::FormField instproc set_disabled disable {
    #:msg "${:name} set disabled $disable"
    if {$disable} {
      set :disabled true
    } else {
      unset -nocomplain :disabled
    }
  }
::xowiki::formfield::FormField instproc answer_check=btwn {} {
    set d [:process_correct_when_modifier]
    dict with d {
      return [expr {$value >= [lindex $words 0] && $value <= [lindex $words 1]}]
    }
  }
::xowiki::formfield::FormField instproc answer_check=ge {} {
    set d [:process_correct_when_modifier]
    dict with d {
      return [expr {$value >= [lindex $words 0]}]
    }
  }
::xowiki::formfield::FormField instproc process_correct_when_modifier {} {
    #
    # Return a dict containing "words", "value" and "modifier",
    # skipping and processing optional parameters (just "-nocase" for
    # now). When "-nocase" is used, "value" and "words" are translated
    # to lowercase such that the result comparison is not case
    # sensitive.
    #
    set value [string trim [regsub -all -- {[ ]+} ${:value} " "]]
    set firstword [lindex ${:correct_when} 1]
    if {$firstword eq "-nocase" || [string match "*lower*" $firstword]} {
      set value [string tolower $value]
      set words [string tolower [lrange ${:correct_when} 2 end]]
      set modifier nocase
    } else {
      set words [lrange ${:correct_when} 1 end]
      set modifier ""
    }
    return [list op [lindex ${:correct_when} 0] words $words value $value modifier $modifier]
  }
::xowiki::formfield::FormField instproc field_value v {
    if {[info exists :show_raw_value]} {
      return $v
    } else {
      return [:pretty_value $v]
    }
  }
::xowiki::formfield::FormField instproc validation_check {validator_method value} {
    return [:uplevel [list :$validator_method $value]]
  }
::xowiki::formfield::FormField instproc reset_on_validation_error args {
    #
    # We don't actually do anything here, but subclassess can overload it.
    #
  }
::xowiki::formfield::FormField instproc render_disabled_as_div CSSclass {
    set attributes [:get_attributes id]
    lappend attributes class $CSSclass
    ::html::div $attributes {
      if {[info exists :value_with_markup]} {
        ::html::t -disableOutputEscaping ${:value_with_markup}
      } else {
        ::html::t [:value]
      }
    }
  }
::xowiki::formfield::FormField instproc answer_is_correct {} {
    #
    # Return correctness of the answer based on the instance variables
    # ":correct_when" and ":answer". Possible results are
    #
    #  -  1: correct
    #  - -1: incorrect
    #  -  0: can't say (or report back, that no evaluation should be
    #        provided for this field)
    #
    #  This method is free of side-effects (no instance variables are updated).
    #
    #:log "CORRECT? ${:name} ([:info class]): value=${:value}, answer=[expr {[info exists :answer]?${:answer}:{NONE}}]"
    if {[info exists :correct_when] && ${:correct_when} ne ""} {
      set op [lindex ${:correct_when} 0]
      #:log "CORRECT? ${:name} with op=$op '${:correct_when}'"
      if {[:procsearch answer_check=$op] ne ""} {
        set r [:answer_check=$op]
        if {$r == 0} {
          return -1
        } {
          return 1
        }
      } elseif$op eq ""} {
        return 0
      } else {
        error "invalid operator '$op'"
      }
    } elseif {![info exists :answer]} {
      return 0
    } elseif {${:value} ne ${:answer}} {
      #:msg "v='${:value}' NE a='[:answer]'"
      #:log "... answer_is_correct value comparison '${:value}' NE a='${:answer}'"
      return -1
    } else {
      #:log "... answer_is_correct value comparison OK"
      return 1
    }
  }
::xowiki::formfield::FormField instproc render_localizer {} {
    # Just an empty fall-back method.
    # This method will be overloaded in trn mode by a mixin.
  }
::xowiki::formfield::FormField instproc stats_record_count {} {
    #
    # This method is just called in situation, where the parent_id is
    # an instantiated object (via answer_is_correct). The parent
    # object is the actual workflow.
    #
    set reporting_obj ::[${:object} parent_id]
    $reporting_obj stats_record_count ${:name}
  }
::xowiki::formfield::FormField instproc has_instance_variable {var value} {
    if {[info exists :$var] && [set :$var] eq $value} {return 1}
    return 0
  }
::xowiki::formfield::FormField instproc leaf_components {} {
    #
    # We want to be able to be able to call leaf_components on
    # arbitrary form-fields, so return for non-composite fields just a
    # list with a single element.
    #
    return [list [self]]
  }
::xowiki::formfield::FormField instproc answer_check=match {} {
    set d [:process_correct_when_modifier]
    dict with d {
      return [string match [lindex $words 0] $value]
    }
  }
::xowiki::formfield::FormField instproc render_input {} {
    #
    # This is the most general widget content renderer.
    # If no special renderer is defined, we fall back to this one,
    # which is in most cases  a simple input field of type string.
    #
    set value [:value]
    if {${:mode} ne "edit"} {
      html::t -disableOutputEscaping [:pretty_value $value]
      return
    }
    if {[info exists :validate_via_ajax] && [:validator] ne ""} {
      set ajaxhelper 1
      ::xowiki::Includelet require_YUI_JS -ajaxhelper 0 "yahoo/yahoo-min.js"
      ::xowiki::Includelet require_YUI_JS -ajaxhelper 0 "dom/dom-min.js"
      ::xowiki::Includelet require_YUI_JS -ajaxhelper 0 "event/event-min.js"
      ::xowiki::Includelet require_YUI_JS -ajaxhelper 0 "connection/connection-min.js"
      ::xo::Page requireJS  "/resources/xowiki/yui-form-field-validate.js"
      set package_url [[${:object} package_id] package_url]
      ::xo::Page requireJS  "YAHOO.xo_form_field_validate.add('${:id}','$package_url');"
    }

    set booleanAtts [:booleanAttributes required readonly disabled multiple  formnovalidate autofocus]
    #
    # We do not want i18n substitutions in the input fields. So, save
    # away the original value and pass the escaped value to the tDOM
    # renderer.
    #
    set old_value ${:value}
    set :value [:escape_message_keys $old_value]
    ::html::input [:get_attributes type size maxlength id name value style  autocomplete pattern placeholder {CSSclass class} {*}$booleanAtts] {}
    #
    # Reset values to original content
    #
    :resetBooleanAttributes $booleanAtts
    set :value $old_value

    :handle_transmit_always $value

    set :__rendered 1
  }
::xowiki::formfield::FormField instproc booleanAttributes args {
    #
    # Special handling of HTML boolean attributes, since they require a
    # different coding; it would be nice, if tDOM would care for this.
    #
    set pairs ""
    foreach att $args {
      if {[info exists :$att] && [set :$att]} {
        set :__#$att $att
        lappend pairs [list __#$att $att]
      }
    }
    return $pairs
  }
::xowiki::formfield::FormField instproc render_result_statistics {} {
    #
    # In case, there are result_statistics, use a "progress bar" to
    # visualize correct answers.
    #
    # Currently, this is bootstrap only, unless pie charts are used.
    #
    if {[info exists :result_statistics] && [dict exists ${:result_statistics} count]} {
      set result_count [dict get ${:result_statistics} count]
      #ns_log notice "??? render_result_statistics: ${:name}: ${:result_statistics}"
      if {$result_count > 0} {
        ::html::div -class "progress" {
          set correctCount [expr {[dict exists ${:result_statistics} correct] ? [dict get ${:result_statistics} correct] : 0}]
          set percentage [format %2.0f [expr {$correctCount * 100.0 / $result_count}]]
          ::html::div -class "progress-bar progress-bar-success" -role "progressbar"  -aria-valuenow $percentage -aria-valuemin "0" -aria-valuemax "100" -style "width:$percentage%" {
                ::html::t "$percentage %"
              }
        }
      }
    }
    if {[info exists :answer_statistics]} {
      :render_collapsed  -id answers-[clock clicks -microseconds]  -label "#xowiki.answers#"  -inner_method render_answer_statistics
    }
    if {[info exists :word_statistics]} {
      ns_log notice ":word_statistics: ${:word_statistics}"
      if {${:word_statistics_option} eq "word_cloud"} {
        :render_modal  -id words-[clock clicks -microseconds]  -label "#xowiki.words#"  -inner_method render_word_statistics
      } else {
        #
        # The following is not used for the word cloud, since the
        # placement of the words in the word cloud does not work in
        # collapsed mode.
        #
        :render_collapsed  -id words-[clock clicks -microseconds]  -label "#xowiki.words#"  -inner_method render_word_statistics
      }
    }
  }
::xowiki::formfield::FormField instproc set_feedback feedback_mode {
    #
    # Set instance variables based on correctness of an answer.
    #
    #   - :form_widget_CSSclass
    #   - :evaluated_answer_result
    #   - :value (highlights potentially partial results, e.g. "contains")
    #   - :help_text
    #
    set correct [:answer_is_correct]
    #:log "${:name} [:info class]: correct? $correct"
    switch -- $correct {
      0  { set result "unknown" }
      -1 { set result "incorrect"}
      1  { set result "correct"  }
    }
    :form_widget_CSSclass $result
    set :evaluated_answer_result $result

    if {$correct == 0} {
      return ${:evaluated_answer_result}
    }

    set feedback ""
    if {[info exists :feedback_answer_$result]} {
      set feedback [set :feedback_answer_$result]
    } else {
      set feedback [_ xowf.answer_$result]
    }

    if {$feedback_mode > 1} {
      #ns_log notice "${:name} set_feedback $feedback_mode=[info exists :correct_when] "  "correction?[info exists :correction] "  "correction_data?[info exists :correction_data] "  "============"
      if {[info exists :correct_when]} {
        append feedback ${:correct_when}"
      } elseif {[info exists :correction]} {
        append feedback ${:correction}"
        if {[info exists :correction_data]} {
          #append feedback " ${:correction_data}"
          if {[info exists :grading]} {
            if {${:grading} in  {"" "exact"}} {
              set score [expr {${:evaluated_answer_result} eq "correct" ? 100.0 : 0.0}]
              dict set :correction_data scores ${:grading} $score
            }
            if {[dict exists ${:correction_data} scores ${:grading}] } {
              #
              # We end up here for
              #   - MC (xowiki::formfield::checkbox) and
              #   - SC (xowiki::formfield::radio)
              #   - Reorder (::xowiki::formfield::reorder_box)
              #
              set grading_score [dict get ${:correction_data} scores ${:grading}]
              if {$grading_score < 0} {
                set grading_score 0.0
              }
              #:log "=== ${:name} grading '${:grading}' => $grading_score"
              if {[info exists :test_item_points] && ${:test_item_points} ne ""} {
                set points [format %.2f [expr {${:test_item_points} * $grading_score / 100.0}]]
                dict set :correction_data points $points
                #append feedback " correct: $grading_score "
                append feedback " points: $points of [format %.2f ${:test_item_points}]"
              } else {
                append feedback " grading_score $grading_score"
              }
              #${:object} set_property -new 1 grading_score $grading_score
              set :grading_score $grading_score
              #ns_log notice "=== ${:name} SET GRADING score $grading_score"
            } else {
              ns_log notice "=== ${:name} == no scores for grading '${:grading}': ${:correction_data}"
            }
          } else {
            set :grading_score ""
            ns_log notice "=== ${:name} == no grading available"
          }
        } else {
          ns_log notice "=== ${:name} NO correction_data available"
        }
      } else {
        ns_log notice "=== ${:name} NO correct_when and no :correction"
      }
      #
      # When the widget class supports "disabled_as_div", we
      # can try to highlight matches from :correct_when.
      #
      if {[info exists :disabled_as_div] && [info exists :correct_when]} {
        #
        # When render_as_div might or might not require output
        # escaping. When we have a markup produced form match
        # highlighting, the code sets :value_with_markup for
        # rendering. Otherwise, the plain :value is used.
        #
        #ns_log notice "CHECK matches in ${:name} '${:correct_when}'"

        set :value [ns_quotehtml ${:value}]
        set saved_correct_when ${:correct_when}

        set op [lindex ${:correct_when} 0]
        if {$op in {contains contains-not}} {
          set :correct_when "AND [list ${:correct_when}]"
          set op AND
        }
        set dicts {}
        if {$op eq "AND"} {
          foreach clause [lrange ${:correct_when} 1 end] {
            set :correct_when $clause
            lappend dicts [:process_correct_when_modifier]
          }
        }
        set :correct_when $saved_correct_when

        set annotated_value ${:value}
        #ns_log notice "CHECK matches in ${:name} dicts <$dicts>"

        foreach d $dicts {
          if {[dict get $d op] in {contains contains-not}} {
            set CSSclass [dict get $d op]
            #
            # Mark matches in the div element.
            #
            set nocase [expr {[dict get $d modifier] eq "nocase" ? "-nocase" : ""}]
            #ns_log notice "CHECK matches in ${:name} nocase=$nocase words=[dict get $d words]"

            foreach word [dict get $d words] {
              #
              # We need here probably more escapes, or we should be more
              # restrictive on allowed content in the "contains" clause.
              #
              set word [string map {* \\* ( \\( ) \\)} $word]
              set nrSubst [regsub -all {*}$nocase -- [ns_quotehtml $word]  $annotated_value  "<span class='match-$CSSclass'>&</span>"  annotated_value ]
              #ns_log notice "MATCH $word -> $nrSubst"
            }
          }
        }
        if {$annotated_value ne ${:value}} {
          set :value_with_markup $annotated_value
        }
      }
    }
    #:log "==== ${:name} setting feedback $feedback"
    set :help_text $feedback
    return ${:evaluated_answer_result}
  }
::xowiki::formfield::FormField instproc render {} {
    #
    # In case, we use an asHTML of a FormField, we use this
    # render definition.
    #
    if {${:inline}} {
      # with label, error message, help text
      :render_form_widget
    } else {
      # without label, error message, help text
      :render_item
    }
    set :__rendered 1
  }
::xowiki::formfield::FormField instproc behavior mixin {
    #
    # Specify the behavior of a form field via
    # per object mixins
    #
    set pkgctx [[${:object} package_id] context]
    if {[$pkgctx exists embedded_context]} {
      set ctx [$pkgctx set embedded_context]
      set classname ${ctx}::$mixin
      #:msg ctx=$ctx-viewer=$mixin,found=[:isclass $classname]
      # TODO: search different places for the mixin. Special namespace?
      if {[:isclass $classname]} {
        if {[info exists :per_object_behavior]} {
          :mixin delete ${:per_object_behavior}
        }
        :mixin add $classname
        set :per_object_behavior $classname
      } else {
        :msg "Could not find mixin '$mixin'"
      }
    }
  }
::xowiki::formfield::FormField instproc asWidgetSpec {} {
    set spec ${:widget_type}
    if {[info exists :spell]} {
      append spec ",[expr {${:spell} ? {} : {no}}]spell"
    }

    if {!${:required}} {
      append spec ",optional"
    }
    if {[info exists :editor]} {
      append spec " {options {editor ${:editor}}} "
    }
    append spec " {label " [list ${:label}"} "

    if {[string match "*bootstrap*" [subsite::get_theme]]} {
      # TODO: we need a better solution for this
      if {[::template::CSS toolkit] eq "bootstrap5"
          && ([:hasclass ::xowiki::formfield::radio] || [:hasclass ::xowiki::formfield::checkbox])
        } {
        array set :html {class "form-check-input"}
      } else {
        array set :html {class "form-control"}
      }
    }

    if {[info exists :html]} {
      append spec " {html {"
      foreach {key value} [array get :html] {
        append spec $key " " [list $value" "
      }
      append spec "}} "
    }

    if {[info exists :options]} {
      append spec " {options " [list ${:options}"} "
    }
    if {[info exists :format]} {
      append spec " {format " [list ${:format}"} "
    }

    if {${:help_text} ne ""} {
      if {[string match "#*#" ${:help_text}]} {
        set internationalized [:localize ${:help_text}]
        append spec " {help_text {$internationalized}}"
      } else {
        append spec " {help_text {${:help_text}}}"
      }
    }
    #ns_log notice "${:name} === asWidgetSpec return $spec"
    return $spec
  }
::xowiki::formfield::FormField instproc add_statistics {{-options ""}} {
    #
    # The FormField based incremental statistic counter is deprecated,
    # since for randomization, it is necessary to reinitialized
    # form-fields of an exam multiple times (different students have
    # different alternatives, etc.).  Therefore, statistics have to be
    # collected in general on the level of the workflow object (via
    # $reporting_obj stats_record_*).
    #
    dict incr :result_statistics count
    #ns_log notice "[self] enumeration add_statistics count -> [dict get ${:result_statistics} count]"
    if {[info exists :evaluated_answer_result] && ${:evaluated_answer_result} eq "correct"} {
      #ns_log notice "[self] enumeration add_statistics count -> [dict get ${:result_statistics} count] correct"
      dict incr :result_statistics correct
      #ns_log notice "??? add_statistics ${:name}: ${:result_statistics}"
    }
    dict incr :answer_statistics ${:value}
  }
::nsf::method::property ::xowiki::formfield::FormField  add_statistics deprecated true
::xowiki::formfield::FormField instproc answer_check=gt {} {
    set d [:process_correct_when_modifier]
    dict with d {
      return [expr {$value > [lindex $words 0]}]
    }
  }
::xowiki::formfield::FormField instproc value_if_nothing_is_returned_from_form default {
    return $default
  }
::xowiki::formfield::FormField instproc init {} {
    if {![info exists :label]} {
      set :label [string totitle ${:name}]
    }
    if {![info exists :id]} {
      set :id ${:name}
    }
    set :html(id) ${:id}
    #if {[info exists :default]} {set :value [:default]}
    :config_from_spec ${:spec}
  }
::xowiki::formfield::FormField instproc render_help_text {} {
    if {${:help_text} ne ""} {
      html::div -class [:form_help_text_CSSclass] {
        html::span -class "info-sign" { }
        html::t ${:help_text}
      }
    }
  }
::xowiki::formfield::FormField instproc interprete_single_spec s {
    if {$s eq ""} return

    #ns_log notice "${:name} interprete_single_spec '$s'"
    set package_id [${:object} package_id]
    set s [::xowiki::formfield::FormField get_single_spec -object ${:object} -package_id $package_id $s]

    switch -glob -- $s {
      optional    {set :required false}
      required    {set :required true; :remove_omit}
      omit        {:mixin add ::xowiki::formfield::omit}
      noomit      {:remove_omit}
      disabled    {:set_disabled true}
      readonly    {:readonly true}
      enabled     {:set_disabled false}
      label=*     {:label     [lindex [split $s =] 1]}
      help_text=* {:help_text [lindex [split $s =] 1]}
      *=*         {
        set p [string first = $s]
        set attribute [string range $s 0 $p-1]
        set value [string range $s $p+1 end]
        set definition_class [lindex [:procsearch $attribute] 0]
        set method [:info methods $attribute]
        if {[string match "::xotcl::*" $definition_class] || $method eq ""} {
          error [_ xowiki.error-form_constraint-unknown_attribute [list class [:info class] name ${:name} entry $attribute]]
        }
        ad_try {
          #
          # We want to allow a programmer to use e.g. options=[xowiki::locales]
          #
          # Note: do not allow users to use [] via forms, since they might
          # execute arbitrary commands. The validator for the form fields
          # makes sure that the input specs are free from square brackets.
          #
          if {[string match {\[*\]} $value]} {
            set value [subst $value]
          }
          :$attribute $value
        } on error {errMsg} {
          error "Error during setting attribute '$attribute' to value '$value': $errMsg"
        }
      }
      default {
        # Check, if the spec value $s is a class.
        set old_class [:info class]
        # Don't allow one to use namespaced values, since we would run
        # into a recursive loop for richtext::wym (could be altered there as well).
        if {[:isclass ::xowiki::formfield::$s] && ![string match "*:*" $s]} {
          :class ::xowiki::formfield::$s
          :remove_omit
          if {$old_class ne [:info class]} {
            #:msg "${:name}: reset class from $old_class to [:info class]"
            :reset_parameter
            set :__state reset
            #:log "INITIALIZE ${:name} due to reclassing old $old_class to new [:info class]"
            :initialize
          }
        } else {
          if {$s ne ""} {
            error [_ xowiki.error-form_constraint-unknown_spec_entry  [list name ${:name} entry $s x "Unknown spec entry for entry '$s'"]]
          }
        }
      }
    }
  }
::xowiki::formfield::FormField instproc handle_transmit_always value {
    #
    # Disabled fields are not returned by the browsers. For some
    # fields, we require to be sent. Therefore, we include in these
    # cases the value in an additional hidden field. Maybe we should
    # change in the future the "name" of the disabled entry to keep
    # some hypothetical html-checker quiet.
    #
    if {[:is_disabled] && [info exists :transmit_field_always]} {
      ::html::div {
        ::html::input [list type hidden name ${:name} value $value] {}
      }
    }
  }
::xowiki::formfield::FormField instproc render_form_widget {} {
    # This method provides the form-widget wrapper
    if {0} {
      # no wrapper for form-widget (label + input)
      :render_input
    } else {
      set CSSclass [expr {[info exists :form_widget_CSSclass] ? ${:form_widget_CSSclass} : ""}]
      if {${:error_msg} ne ""} {
        append CSSclass " form-widget-error"
      }
      set atts [list class $CSSclass]
      if {${:inline}} {
        lappend atts style "display: inline;"
      }
      ::html::div $atts { :render_input }
    }
  }
::xowiki::formfield::FormField instproc is_repeat_template_p {} {
    return [expr {[info exists :is_repeat_template] && ${:is_repeat_template} == "true"}]
  }
::xowiki::formfield::FormField instproc answer_check=in {} {
    #
    # Correct, when answer is in the given set.
    #
    set d [:process_correct_when_modifier]
    dict with d {
      return [expr {$value in $words}]
    }
  }
::xowiki::formfield::FormField instproc describe {{-field_name ""}} {
    set d ""
    #
    # The dict keys of the result should correspond as far as possible
    # to message keys to ease multi-language communication.
    #
    set qa [${:object} property question]
    #ns_log notice "FormField describe gets question attributes <$qa> from ${:object}"

    foreach {key name} {
      question.minutes Minutes
      question.points Points
      question.grading grading
      question.show_max show_max
    } {
      if {[dict exists $qa $key]} {
        dict set d $name [dict get $qa $key]
      }
    }
    switch [:info class] {
      ::xowiki::formfield::radio -
      ::xowiki::formfield::checkbox {
        # mc and sc interaction
        set type [expr {[:info class] eq "::xowiki::formfield::checkbox" ? "MC" : "SC"}]
        #
        # The factual (displayed) answer is in ${:answer}, but we want
        # to see the list of possibilities, so use the data from the
        # original spec.
        #
        foreach s [split ${:spec} ,] {
          if {[regexp {^answer=(.*)$} $s . answer]} {
            break
          }
        }
        dict set d choice_options [llength ${answer}]
        dict set d nrcorrect [llength [lsearch -exact -all ${answer} t]]
        dict set d shuffle ${:shuffle_kind}
        #dict set d all [:serialize]
      }
      ::xowiki::formfield::text_fields {
        set type ShortText
        # short text interaction
        #
        # The factual (displayed) answer is in ${:answer}, but we want
        # to see the list of possibilities, so use the data from the
        # original spec (here in $options)
        #
        foreach s [split ${:spec} ,] {
          #ns_log warning "s=$s"
          if {[regexp {^options=(.*)$} $s . options]} {
            break
          }
        }
        dict set d all ${:spec}
        dict set d sub_questions [llength ${options}]
        dict set d shuffle ${:shuffle_kind}
      }
      ::xowiki::formfield::textarea {
        set type Text
      }
      ::xowiki::formfield::pool_question_placeholder {
        set type PoolQuestion
        set item_dict [:QM get_pool_questions  -field_name $field_name ${:object} ""]

        set counts ""
        foreach {key value} $item_dict {
          dict incr counts [dict get $item_dict $key item_type]
        }

        dict set d available_pool_items [dict size $item_dict]
        dict set d available_pool_item_stats $counts
      }
      ::xowiki::formfield::reorder_box {
        set type Reorder
      }
      ::xowiki::formfield::file {
        set type Upload
      }
      ::xowiki::formfield::form_page {
        set type Composite
      }

      default {
        set type [:info class]
        ns_log warning "describe: class [:info class] not handled"
      }
    }
    dict set d type $type
    #ns_log notice "describe [:info class] [${:object} name] -> $d"
    dict set d question_title [${:object} title]

    return $d
  }
::xowiki::formfield::FormField instproc initialize {} next
::xowiki::formfield::FormField instproc reset_parameter {} {
    # reset application specific parameters (defined below ::xowiki::formfield::FormField)
    # such that searchDefaults will pick up the new defaults, when a form field
    # is reclassed.

    if {[info exists :per_object_behavior]} {
      # remove per-object mixin from the "behavior"
      :mixin delete ${:per_object_behavior}
      unset :per_object_behavior
    }

    #:msg "reset along [:info precedence]"
    foreach c [:info precedence] {
      if {$c eq "::xowiki::formfield::FormField"} break
      foreach s [$c info slots] {
        if {![$s exists default]} continue
        set var [$s name]
        set key processed($var)
        if {[info exists $key]} continue
        set :$var [$s default]
        set $key 1
      }
    }
    :set_disabled false
  }
::xowiki::formfield::FormField instproc render_modal {-id:required {-label ""} -inner_method} {
    ::xowiki::BootstrapCollapseButton new -id $id -label $label -toggle "modal" -direction "down"
    ::html::div -id "$id" -class "modal fade" -tabindex -1 -role dialog aria-hidden "true" {
      ::html::div -class "modal-dialog" -role document {
        ::html::div -class "modal-content" {
          ::html::div -class "modal-header" {
            ::html::h5 -class "modal-title" { ::html::t $label }
            ::html::button -type "button" -class "close" -data-dismiss "modal" -aria-label "Close" {
              ::html::span -aria-hidden "true" { ::html::t -disableOutputEscaping "&times;" }
            }
            ::html::div -class "modal-body" {
              #::html::t ...
              :$inner_method
            }
            ::html::div -class "modal-footer" {
              ::html::button -type "button" -class "btn [::template::CSS class btn-default]" -data-dismiss "modal" {
                ::html::t Close
              }
            }
          }
        }
      }
    }
  }
::xowiki::formfield::FormField instproc answer_check=AND {} {
    set results ""
    #
    # The AND clause iterates over the list elements and reduces the
    # composite AND into multiple simple clauses and overwrites (!
    # danger) these in the instance variable "correct_when", but
    # resets these at the end.
    #
    set composite_correct_when ${:correct_when}
    ns_log notice "${:name} ... answercheck ${:correct_when}"
    foreach clause [lrange ${:correct_when} 1 end] {
      set :correct_when $clause
      ns_log notice "${:name} ... AND '$clause' for '${:value}' -> [:answer_is_correct]"
      lappend results [:answer_is_correct]
    }
    set :correct_when $composite_correct_when
    ns_log notice  "${:name} $composite_correct_when => $results"
    if {0 in $results} {
      #
      # When one element is undecided, all is undecided.
      #
      return 0
    }
    #
    # If one element is wrong, all is wrong
    #
    return [expr {-1 ni $results}]
  }
::xowiki::formfield::FormField instproc remove_omit {} {
    set m ::xowiki::formfield::omit
    if {[:ismixin $m]} {:mixin delete $m}
  }
::xowiki::formfield::FormField instproc word_statistics flavor {
    #
    # Word statistics based on :value. It is assumed here, that the
    # value is basically a string with whitespace.
    #
    regsub -all -- {\s} ${:value} " " value
    foreach w [split $value " "] {
      dict incr :word_statistics [string tolower $w]
    }
    set :word_statistics_option $flavor
  }
::xowiki::formfield::FormField instforward dict_value ::xowiki::formfield::dict_value
::xowiki::formfield::FormField instforward dict_to_spec ::xowiki::formfield::dict_to_spec
::xowiki::formfield::FormField instforward dict_to_fc ::xowiki::formfield::dict_to_fc
::xowiki::formfield::FormField instparametercmd slot
::xowiki::formfield::FormField instparametercmd correct_when
::xowiki::formfield::FormField instparametercmd form_help_text_CSSclass
::xowiki::formfield::FormField instparametercmd inline
::xowiki::formfield::FormField instparametercmd error_msg
::xowiki::formfield::FormField instparametercmd autofocus
::xowiki::formfield::FormField instparametercmd test_item_points
::xowiki::formfield::FormField instparametercmd multiple
::xowiki::formfield::FormField instparametercmd readonly
::xowiki::formfield::FormField instparametercmd show_raw_value
::xowiki::formfield::FormField instparametercmd feedback_answer_incorrect
::xowiki::formfield::FormField instparametercmd validate_via_ajax
::xowiki::formfield::FormField instparametercmd id
::xowiki::formfield::FormField instparametercmd disabled_as_div
::xowiki::formfield::FormField instparametercmd CSSclass
::xowiki::formfield::FormField instparametercmd answer
::xowiki::formfield::FormField instparametercmd title
::xowiki::formfield::FormField instparametercmd test_item_minutes
::xowiki::formfield::FormField instparametercmd spec
::xowiki::formfield::FormField instparametercmd value
::xowiki::formfield::FormField instparametercmd label
::xowiki::formfield::FormField instparametercmd style
::xowiki::formfield::FormField instparametercmd placeholder
::xowiki::formfield::FormField instparametercmd form_button_CSSclass
::xowiki::formfield::FormField instparametercmd pattern
::xowiki::formfield::FormField instparametercmd object
::xowiki::formfield::FormField instparametercmd form_item_wrapper_CSSclass
::xowiki::formfield::FormField instparametercmd locale
::xowiki::formfield::FormField instparametercmd form_label_CSSclass
::xowiki::formfield::FormField instparametercmd name
::xowiki::formfield::FormField instparametercmd required
::xowiki::formfield::FormField instparametercmd display_field
::xowiki::formfield::FormField instparametercmd autocomplete
::xowiki::formfield::FormField instparametercmd formnovalidate
::xowiki::formfield::FormField instparametercmd mode
::xowiki::formfield::FormField instparametercmd td_CSSclass
::xowiki::formfield::FormField instparametercmd label_noquote
::xowiki::formfield::FormField instparametercmd type
::xowiki::formfield::FormField instparametercmd form_button_wrapper_CSSclass
::xowiki::formfield::FormField instparametercmd form_widget_CSSclass
::xowiki::formfield::FormField instparametercmd default
::xowiki::formfield::FormField instparametercmd help_text
::xowiki::formfield::FormField instparametercmd validator
::xowiki::formfield::FormField instparametercmd disabled
::xowiki::formfield::FormField instparametercmd test_item_in_position
::xowiki::formfield::FormField instparametercmd in_position
::xowiki::formfield::FormField instparametercmd grading
::xowiki::formfield::FormField instparametercmd feedback_answer_correct
::xowiki::formfield::FormField instparametercmd hide_value
::nsf::relation::set ::xowiki::formfield::FormField superclass ::xo::tdom::Object

::nx::slotObj -container slot ::xowiki::formfield::FormField
::xowiki::formfield::FormField::slot eval {set :__parameter {
                        {CSSclass form-control}
                        {form_item_wrapper_CSSclass form-group}
                        {form_label_CSSclass ""}
                        {form_widget_CSSclass ""}
                        {form_button_CSSclass "btn btn-default"}
                        {form_button_wrapper_CSSclass ""}
                        {form_help_text_CSSclass help-block}
                    }}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

::nsf::object::alloc ::xotcl::Attribute ::xowiki::formfield::FormField::slot::CSSclass {set :accessor public
   set :configurable true
   set :convert false
   set :default form-control
   set :defaultmethods {}
   set :disposition alias
   set :domain ::xowiki::formfield::FormField
   set :incremental 0
   set :manager ::xowiki::formfield::FormField::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}

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

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

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

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

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

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

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

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

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

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

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

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

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

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