%3 ::xowiki::formfield::TestItemField ::xowiki::formfield::TestItemField QM attachments_widget comp_correct_when_from_value correct_when_spec correct_when_widget form_markup text_attachments twocol_layout ::xowiki::formfield::FormGeneratorField ::xowiki::formfield::FormGeneratorField pretty_value render_input ::xowiki::formfield::TestItemField->::xowiki::formfield::FormGeneratorField ::xowiki::formfield::CompoundField ::xowiki::formfield::CompoundField ::xowiki::formfield::FormGeneratorField->::xowiki::formfield::CompoundField ::xowiki::formfield::test_item ::xowiki::formfield::test_item feedback_definition initialize ::xowiki::formfield::test_item->::xowiki::formfield::TestItemField

Class ::xowiki::formfield::test_item

::xowiki::formfield::test_item[i] create ... \
           [ -grading (default "exact") ] \
           [ -nr_choices (default "5") ] \
           [ -question_type (default "mc") ]

Wrapper for composite test items, containing specification for minutes, grading scheme, feedback levels, handling different types of questions ("interactions" in the terminology of QTI). When such a question is saved, an HTML form is generated, which is used as a question.
Documented Parameters:
feedback_level
"full", "single", or "none"
grading
one of "exact", "none", or one of the partial grading schemes
nr_choices
number of choices
question_type
"mc", "sc", "ot", or "st"
Defined in /var/www/openacs.org/packages/xowf/tcl/test-item-procs.tcl

Class Relations

  • class: ::xotcl::Class[i]
  • superclass: ::xowiki::formfield::TestItemField[i]
::xotcl::Class create ::xowiki::formfield::test_item \
     -superclass ::xowiki::formfield::TestItemField

Methods (to be applied on instances)

  • feedback_definition (scripted)

    #
    # Return the definition of the feed_back widgets depending on the
    # value of :feedback_level.
    #
    set widget [test_item set richtextWidget]
    
    switch ${:feedback_level} {
      "none" {
        set definition ""
      }
      "single" {
        set definition [subst {
          {feedback_correct   {$widget,height=150px,label=#xowf.feedback#}}
        }]
      }
      "full" {
        set definition [subst {
          {feedback_correct   {$widget,height=150px,label=#xowf.feedback_correct#}}
          {feedback_incorrect {$widget,height=150px,label=#xowf.feedback_incorrect#}}
        }]
      }
    }
    if {${:with_correction_notes}} {
      append definition [subst {
        {correction_notes  {$widget,height=150px,label=#xowf.Correction_notes#}}
      }]
    }
    
    return $definition
  • grading (setter)

  • initialize (scripted)

    if {${:__state} ne "after_specs"} {
      return
    }
    set options ""
    set typeSpecificComponentSpec ""
    #
    # Provide some settings for name short-cuts
    #
    switch -- ${:question_type} {
      mc { # we should support as well: minChoices, maxChoices
        #
        # Old style, kept just for backwards compatibility for the
        # time being. One should use "mc2" instead.
        #
        set interaction_class mc_interaction
        set options nr_choices=[:nr_choices]
        set options ""
        set auto_correct true
        set can_shuffle false
      }
      sc { # we should support as well: minChoices, maxChoices
        set interaction_class mc_interaction2
        set options multiple=false
        set auto_correct true
        set can_shuffle true
      }
      mc2 { # we should support as well: minChoices, maxChoices
        set interaction_class mc_interaction2
        set options ""
        set auto_correct true
        set can_shuffle true
      }
      ot {
        set interaction_class text_interaction
        set auto_correct ${:auto_correct}
        set can_shuffle false
      }
      ro {
        set interaction_class reorder_interaction
        set auto_correct ${:auto_correct}
        set can_shuffle false
      }
      te -
      st {
        set interaction_class short_text_interaction
        #set options nr_choices=[:nr_choices]
        set auto_correct ${:auto_correct}
        set can_shuffle true
      }
      ul { #
        set interaction_class upload_interaction
        set options ""
        set auto_correct false
        set can_shuffle false
        set typeSpecificComponentSpec {{max_nr_submission_files {number,form_item_wrapper_CSSclass=form-inline,min=1,default=1,label=Maximale Anzahl von Abgaben}}}
      }
      section -
      case {
        set interaction_class test_section
        set options ""
        set auto_correct false
        set can_shuffle false
      }
      pool {
        set interaction_class pool_question
        set options ""
        set auto_correct false
        set can_shuffle false
      }
      default {error "unknown question type: ${:question_type}"}
    }
    #:log test_item-auto_correct=$auto_correct
    
    #
    # Handle feedback_level (typically defined in "TestItem*.form.page")
    #
    # The object might be a form, just use the property, if we are on
    # a FormPage.
    #
    if {[${:object} istype ::xowiki::FormPage]} {
      set feedback_level_property [${:object} property feedback_level]
      if {$feedback_level_property ne ""} {
        set :feedback_level $feedback_level_property
      }
    }
    #set :feedback_level "full"
    
    if {${:grading} ne "none" && [llength ${:grading}] >1} {
      set grading_dict {_name grading _type select}
      dict set grading_dict default [lindex ${:grading} 0]
      dict set grading_dict options {}
      foreach o ${:grading} {
        dict lappend grading_dict options [list $o $o]
      }
      dict set grading_dict form_item_wrapper_CSSclass form-inline
      dict set grading_dict label #xowf.Grading-Scheme#
      dict set grading_dict required true
      set gradingSpec [list [:dict_to_spec -aspair $grading_dict]]
    } else {
      set gradingSpec ""
    }
    
    if {$can_shuffle} {
      set shuffle_dict {_name shuffle _type radio}
      dict set shuffle_dict horizontal true
      dict set shuffle_dict form_item_wrapper_CSSclass form-inline
      dict set shuffle_dict form_widget_CSSclass form-check
      dict set shuffle_dict default peruser
      dict set shuffle_dict label #xowf.Shuffle#
      dict set shuffle_dict options  "{#xowf.shuffle_none# none} {#xowf.shuffle_peruser# peruser} {#xowf.shuffle_always# always}"
      set shuffleSpec [subst {
        [list [:dict_to_spec -aspair $shuffle_dict]]
        {show_max {number,form_item_wrapper_CSSclass=form-inline,min=1,label=#xowf.show_max#}}
      }]
    } else {
      set shuffleSpec ""
    }
    
    #
    # Default twocol spec
    #
    set twocolDict {
      _name twocol
      _type boolean_checkbox
      label #xowf.Twocol_layout#
      default f
      form_item_wrapper_CSSclass form-inline
    }
    
    if {${:question_type} in {section case}} {
      #
      # Don't show "minutes" and "points" in the full composite test
      # item form but still define it, such we can compute and update
      # it in convert_to_internal with little effort, since all
      # "question" content is built based on included form fields.
      #
      set pointsSpec {
        {minutes hidden}
        {points hidden}
      }
      set typeSpecificComponentSpec {
        {show_minutes boolean_checkbox,form_item_wrapper_CSSclass=form-inline,default=t,label=#xowf.Composite_Show_minutes#}
        {show_points boolean_checkbox,form_item_wrapper_CSSclass=form-inline,default=f,label=#xowf.Composite_Show_points#}
        {show_title boolean_checkbox,form_item_wrapper_CSSclass=form-inline,default=f,label=#xowf.Composite_Show_title#}
      }
      #
      # Things different between "section" and "case".
      #
      switch ${:question_type} {
        "section" {}
        "case" {
          dict set twocolDict default t
        }
        default {error "this can't happen"}
      }
    } else {
      set pointsSpec {
        {minutes number,form_item_wrapper_CSSclass=form-inline,min=0,default=2,step=0.1,label=#xowf.Minutes#}
        {points number,form_item_wrapper_CSSclass=form-inline,min=0.0,step=0.1,label=#xowf.Points#}
      }
    }
    if {${:question_type} eq "pool"} {
      set twocolDict ""
    }
    
    :create_components [subst {
      $pointsSpec
      $shuffleSpec
      $gradingSpec
      $typeSpecificComponentSpec
      [list [:dict_to_spec -aspair $twocolDict]]
      {interaction {$interaction_class,$options,feedback_level=${:feedback_level},auto_correct=${:auto_correct},label=}}
      [:feedback_definition]
    }]
    set :__initialized 1
  • nr_choices (setter)

  • question_type (setter)