- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables
Class ::xowiki::formfield::reorder_box
::xowiki::formfield::reorder_box create ... \
[ -shuffle:boolean (default "true") ]
Class Relations
::xotcl::Class create ::xowiki::formfield::reorder_box \ -superclass ::xowiki::formfield::selectMethods (to be applied on instances)
answer_is_correct (scripted)
# # This method returns 0 (undecided), -1 (incorrect) or 1 (correct) # and sets as well the instance variable :correction with the # per-item correctness settings for correct/incorrect. # #:log "reorder_box CORRECT? ${:name} (value=[:value])" if {![info exists :answer]} { set result 0 } else { set value [:value] if {[llength $value] != [llength ${:answer}]} { error "list length of value <$value> and answer <${:answer}> must be equal (${:name})" } set result 1 set :correction {} set R 0; set W 0 foreach v $value a ${:answer} { set ok [expr {$v eq $a}] lappend :correction $ok if {$ok} { incr R } else { set result -1 incr W } } ns_log notice "${:name}: correction? have grading [info exists :grading]" set correct_relative {} # # Compare neighbors; when left neighbor is smaller, this is # counted as correct. Assumption: provided answer is ascending. # set Rr 0; set Wr 0 for {set i 1} {$i < [llength $value]} {incr i} { if {[lindex $value $i-1] < [lindex $value $i]} { incr Rr lappend correction_relative 1 } else { set result -1 incr Wr lappend correction_relative 0 } } # # We could provide a special correction based on the relative # data, but the rendering of this in e.g. the exam protocol is # would need more work (green and red should be between the # answer elements, not left of it). # #if {[info exists :grading] && ${:grading} eq "relative"} { # set :correction $correction_relative #} # # An empty value for grading is the same as grading "exact" # set exact [expr {$result == 1 ? 1.0 : 0.0}] set scores {} lappend scores exact $exact "" $exact position [:ggw $R $W] relative [:ggw $Rr $Wr] dict set :correction_data scores $scores #:log "${:name} reorder_box CORRECT? answers [llength ${:answer}] " "options [llength ${:options}] -> $result scores $scores" } return $resultinitialize (scripted)
# # The reorder_box must always be treated as a :multiple field # set :multiple 1 nextrender_input (scripted)
if {${:value} eq ""} { # # When we have no value, provide a start value. # if {${:shuffle}} { # # When :shuffle is set, provide a randomized start value. # set :value [::xowiki::randomized_indices -seed [xo::cc user_id] [llength ${:options}]] #ns_log notice "=== reorder_box value '${:value}' shuffle ${:shuffle} value ${:value}" } else { # # Otherwise, take the internal representations as :value # set :value [lmap o ${:options} {lindex $o 1}] } } # # Make sure that value is feasible and bail out, if not. # set c -1; set indices [lmap o ${:options} {incr c}] if {[lsort -integer ${:value}] ne $indices} { error "internal representation of options ${:options} must be subsequent integers starting with 0\nwe have: ${:value}\noptions: ${:options}" } # # Provide an HTML ID for ".sortable" compatible with jquery # regsub -all -- {[.]} "${:id}.sortable" - jqID set textAreaID ${:id}.text if {![:is_disabled]} { # # If not disabled, let people move around the elements. # ::xo::Page requireCSS urn:ad:css:jquery-ui ::xo::Page requireJS urn:ad:js:jquery-ui if {[::xo::cc mobile]} { ::xo::Page requireJS urn:ad:js:jquery-ui-touch-punch } template::add_body_script -script [subst { \$("#$jqID").sortable(); \$("#$jqID").on( "sortupdate", function( event, ui ) { var ul = event.target; var textarea = document.getElementById('$textAreaID'); var items = ul.getElementsByTagName('LI'); var internalRep = ""; for (var j = 0; j < items.length; j++) { internalRep += items\[j\].dataset.value + "\\n"; } textarea.value = internalRep; } ); }] } # # Make sure, we have :correction initialized, since the rendering # code below needs it. # if {![info exists :correction]} { set :correction {} } html::div -class reorder_box -id ${:id} { # # The input field of the internal representation. # ::html::textarea -id $textAreaID -name ${:name} { ::html::t [join ${:value} \n] } # # The box for reordering items. # ::html::div -class workarea { ::html::ul -class "list-group" -id $jqID { foreach v ${:value} c ${:correction} { set cl "list-group-item" lappend cl [expr {$c eq "1" ? "correct" : $c eq "0" ? "incorrect" : ""} ] ::html::li -class $cl -style "min-width:200px;" -data-value $v { ::html::t [lindex ${:options} $v 0] } } } } }shuffle (setter)
- Methods: All Methods Documented Methods Hide Methods
- Source: Display Source Hide Source
- Variables: Show Variables Hide Variables