Class ::xowiki::formfield::text_fields

::xowiki::formfield::text_fields[i] create ... \
           [ -descriptions (default "") ] \
           [ -paste:boolean (default "true") ] \
           [ -spellcheck:boolean (default "true") ] \
           [ -substvalues substvalues ]

Provide multiple text and short text entries. This field is a compound field which create for every text field a sub component. When the components are rendered, the items can be shuffled.
Defined in packages/xowiki/tcl/form-field-procs.tcl

Class Relations

  • class: ::xotcl::Class[i]
  • superclass: ::xowiki::formfield::CompoundField[i], ::xowiki::formfield::ShuffleField[i]
::xotcl::Class create ::xowiki::formfield::text_fields \
     -superclass {::xowiki::formfield::CompoundField ::xowiki::formfield::ShuffleField}

Methods (to be applied on instances)

  • answer_is_correct (scripted)

    #:log "text_fields  CORRECT? ${:name}"
    
    set feedback_mode [expr {[${:object} exists __feedback_mode]
                             ? [${:object} set __feedback_mode]
                             : 0}]
    set results {}
    set :correction {}
    foreach c [lsort ${:components}] {
      set correct [$c set_feedback $feedback_mode]
      lappend results $correct
      lappend :correction [expr {$correct eq "correct"}]
    }
    set feedback "Subquestions correct ${:correction}"
    
    set nr_correct [llength [lmap c ${:correction} { if {!$c} continue; set _ 1}]]
    set :grading_score [format %.2f [expr {$nr_correct*100.0/[llength ${:correction}]}]]
    
    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 " points: $points of [format %.2f ${:test_item_points}]"
    }
    append :grading_score *
    
    #:log "text_fields CORRECT? ${:name} results $results :correction ${:correction} -> ${:grading_score}"
    
    dict set :correction_data scores [list "" ${:grading_score}]
    set :help_text $feedback
    
    #
    # Return "0" to avoid double feedback via the info text per
    # subquestion and on the top-level.
    #
    return 0
  • descriptions (setter)

  • get_text_entry (scripted)

    set wantedRep [lindex [split $componentName .] end]
    foreach option ${:options} {
      lassign $option text rep
      if {$rep eq $wantedRep} {
        return $text
      }
    }
    return ""
  • initialize (scripted)

    # The value of ":multiple" has to be true for shuffling.
    set :multiple true
    next
    
    #
    # Properties for all fields
    #
    dict set fc_dict disabled [:is_disabled]
    dict set fc_dict disabled_as_div [info exists :disabled_as_div]
    dict set fc_dict label ""
    
    set fields {}
    set answers [expr {[info exists :answer] ? ${:answer} : ""}]
    
    foreach option ${:options} a $answers render_hints_dict ${:render_hints} {
      #
      # Properties for a single fields
      #
      set field_fc_dict $fc_dict
    
      if {[dict exists $render_hints_dict words]} {
        dict set field_fc_dict placeholder #xowiki.[dict get $render_hints_dict words]#
      }
      dict set field_fc_dict correct_when $a
    
      lassign $option text rep
      set render_hints [dict get $render_hints_dict words]
    
      #
      # Convert render hints to the form-field type used for
      # rendering. We might use here
      #
      #     number { set type numeric }
      #
      # but this has the consequence that the original string
      # representation might be lost.
    
      switch $render_hints {
        multiple_lines {
          set type textarea
          dict set field_fc_dict rows [dict get $render_hints_dict lines]
          dict set field_fc_dict autosave true
          if {!${:paste}} {
            dict set field_fc_dict paste false
          }
          if {!${:spellcheck}} {
            dict set field_fc_dict spellcheck false
          }
        }
        number      { set type numeric; dict set field_fc_dict keep_string_rep 1 }
        file_upload { set type file    }
        default     { set type text    }
      }
      lappend fields [list $rep [:dict_to_fc -type $type $field_fc_dict]]
    }
    
    :create_components $fields
    
    foreach c [:components] {
      :log "... $c [$c name] [$c info class]"
    }
  • paste (setter)

  • pretty_value (scripted)

    set result ""
    set ff [dict create {*}$v]
    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 result $componentLabel: " " [$c pretty_value [dict get $ff $componentName]] \n
      }
    }
    return $result
  • render_help_text (scripted)

    #
    # In case, all the components have no correct_when conditions,
    # omit the help text ("subquestion" summary).
    #
    set joined_conditions [join [lmap c ${:components} {set _ [$c set correct_when]}] ""]
    if {$joined_conditions ne ""} {
      next
    }
  • render_input (scripted)

    #
    # Render content within in a fieldset, but with labels etc.
    #
    html::ul [:get_attributes id {CSSclass class}] {
      #
      # Descriptions are currently handled outside of the
      # component. It might be possible to handle these on the
      # subcomponent level, but for now we want to keep the changes as
      # local as possible.
      #
      foreach c ${:components} description ${:descriptions} {
        if {$c eq ""} {
          ns_log bug "text_fields ${:name}: no component for description $description"
          continue
        }
        html::li {
          html::t -disableOutputEscaping [:get_text_entry [$c name]]
          $c render
          #
          # Display descriptions only for the "incorrect" cases.
          #
          if {[info exists :evaluated_answer_result]
              && ${:evaluated_answer_result} eq "incorrect"
              && $description ne ""
            } {
            html::div -class "help-block description" {
              html::t $description
            }
          }
          $c render_result_statistics
        }
      }
    }
  • set_feedback (scripted)

    next
    #
    # Mark result as (fully) correct, when all sub-questions are
    # (fully) correct.
    #
    set :evaluated_answer_result [expr {"0" in ${:correction} ? "incorrect" : "correct"}]
    #ns_log notice "set_feedback correction ${:correction} -> ${:evaluated_answer_result}"
    return ${:evaluated_answer_result}
  • spellcheck (setter)

  • substvalues (setter)

  • td_pretty_value (scripted)

    set result ""
    foreach {key value} $v {
      set componentLabel [string range $key [string length ${:name}]+1 end]
      append result $componentLabel: " " $value \n
    }
    return $result