%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::mc_interaction ::xowiki::formfield::mc_interaction convert_to_internal initialize set_compound_value ::xowiki::formfield::mc_interaction->::xowiki::formfield::TestItemField

Class ::xowiki::formfield::mc_interaction

::xowiki::formfield::mc_interaction[i] create ... \
           [ -multiple (default "true") ] \
           [ -nr_choices (default "5") ]

Class Relations

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

Methods (to be applied on instances)

  • convert_to_internal (scripted)

    #
    # Build a form from the components of the exercise on the fly.
    # Actually, this method computes the properties "form" and
    # "form_constraints" based on the components of this form field.
    #
    set form "<form>\n<table class='mchoice'>\n<tbody>"
    set fc "@categories:off @cr_fields:hidden\n"
    set intro_text [:get_named_sub_component_value text]
    append form "<tr><td class='text' colspan='2'><div class='question_text'>$intro_text</div></td></tr>\n"
    
    #:msg " input_field_names=${:input_field_names}"
    set mc [:get_named_sub_component_value -from_repeat mc]
    #ns_log notice "MC <$mc>"
    
    if {!${:multiple}} {
      set correct_field_name [:get_named_sub_component_value correct]
    }
    
    #set input_field_names [lmap {name .} $mc {set name}]
    set input_field_names {}
    foreach {name .} $mc {lappend input_field_names $name}
    
    foreach {input_field_name data} $mc {
      foreach f {text correct feedback_correct feedback_incorrect} {
        if {[dict exists $data $input_field_name.$f]} {
          set value($f) [dict get $data $input_field_name.$f]
        } else {
          set value($f""
        }
        #ns_log notice "$input_field_name: value($f) = <$value($f)>"
      }
      # skip empty entries
      if {$value(text) eq ""} continue
    
      regsub -all -- {[.:]} [${:object} name] "" form_name
      set input_field_name $form_name-[lindex [split $input_field_name .] end]
      #
      # fill values into form
      #
      if {${:multiple}} {
        set correct $value(correct)
        append form  "<tr><td class='selection'>"  "<input type='checkbox' id='$input_field_name' name='$input_field_name' value='$input_field_name'/>"  "</td>\n"  "<td class='value'><label for='$input_field_name'>$value(text)</label></td></tr>\n"
      } else {
        #:msg $correct_field_name,${:name},$input_field_name
        set correct [expr {"${:name}.$input_field_name" eq $correct_field_name}]
        append form  "<tr><td class='selection'>"  "<input id='$input_field_name' type='radio' name='radio' value='$input_field_name' /></td>\n"  "<td class='value'><label for='$input_field_name'>$value</label></td></tr>\n"
      }
      #ns_log notice "$input_field_name [array get value] corr=$correct"
      #:msg "[array get value] corr=$correct"
    
      #
      # build form constraints per input field
      #
      set if_fc [list]
      if {[string is true -strict $correct]} {
        lappend if_fc "answer=t" "options={{} $input_field_name}"
      } else {
        lappend if_fc "answer=f"
      }
      if {$value(feedback_correct) ne ""} {
        lappend if_fc "feedback_answer_correct=[::xowiki::formfield::FormField fc_encode $value(feedback_correct)]"
      }
      if {$value(feedback_incorrect) ne ""} {
        lappend if_fc "feedback_answer_incorrect=[::xowiki::formfield::FormField fc_encode $value(feedback_incorrect)]"
      }
      if {[llength $if_fc] > 0} {
        lappend fc [list $input_field_name:checkbox,[join $if_fc ,]]
      }
      #:msg "$input_field_name .correct = $value(correct)"
    }
    
    if {!${:multiple}} {
      regexp {[.]([^.]+)$} $correct_field_name _ correct_field_value
      lappend fc "radio:text,answer=$correct_field_value"
    }
    append form "</tbody></table></form>\n"
    ns_log notice FORM=$form\nFC=$fc
    ${:object} set_property -new 1 form $form
    ${:object} set_property -new 1 form_constraints $fc
    set anon_instances true ;# TODO make me configurable
    ${:object} set_property -new 1 anon_instances $anon_instances
    ${:object} set_property -new 1 auto_correct [[self class] set closed_question_type]
    ${:object} set_property -new 1 has_solution true
  • initialize (scripted)

    
    if {${:__state} ne "after_specs"} return
    
    #
    # build choices
    #
    if {!${:multiple}} {
      append choices "{correct radio,omit}\n"
    }
    #
    # create component structure
    #
    set widget [test_item set richtextWidget]
    :create_components [subst {
      {text  {$widget,required,height=150px,label=#xowf.exercise-text#}}
      {mc {mc_choice,feedback_level=${:feedback_level},label=#xowf.alternative#,multiple=${:multiple},repeat=1..${:nr_choices}}}
    }]
    set :__initialized 1
  • multiple (setter)

  • nr_choices (setter)

  • set_compound_value (scripted)

    set r [next]
    
    if {!${:multiple}} {
      # For single choice questions, we have a fake-field for denoting
      # the correct entry. We have to distribute this to the radio
      # element, which is rendered.
      set correct_field_name [:get_named_sub_component_value correct]
      if {$correct_field_name ne ""} {
        foreach c [:components] {
          if {[$c name] eq $correct_field_name} {
            ${c}::correct value $correct_field_name
          }
        }
      }
    }
    return $r