\n"
+ }
+ } else {
+ set signatureString ""
+ }
+
+ set time [::xo::db::tcl_date [$i property _last_modified] tz_var]
+ set pretty_date [clock format [clock scan $time] -format "%Y-%m-%d %T"]
+
+ append HTML "\n
" \
+ "
$userName · $fullName · $pretty_date · IP [$i property ip]
" \
+ $signatureString \
+ $question_form \
+ "\n"
+ }
+ }
+
+ if {$HTML eq ""} {
+ set HTML "#xowiki.no_data#"
+ } else {
+ set HTML "
#xowf.online-exam-protocol#
$HTML"
+ }
+ set return_url [[$wf package_id] query_parameter local_return_url:localurl [:pretty_link]]
+ append HTML "
#xowiki.back#
\n"
+ ::xo::cc set_parameter template_file view-plain-master
+ ::xo::cc set_parameter MenuBar 0
+ xo::Page requireCSS /resources/xowf/test-item.css
+ :www-view $HTML
+ }
+
+ ########################################################################
+ # web-callable method "answer"
+ #
+ # Create or use an answering workflow for the current exam. This is
+ # a convenience routine to shorten the published URL.
+ #
+ :proc www-answer {} {
+ #
+ # Make sure that no-one tries to start the answer workflow in a
+ # state different to "published".
+ #
+ if {[:property _state] ne "published"} {
+ util_user_message -html -message "Cannot start answer workflow in this state"
+ } else {
+ set wf [xowf::test_item::answer_manager get_answer_wf [self]]
+ $wf www-create-or-use -parent_id [:item_id]
+ }
+ }
+
+ :proc www-qrcode {} {
+ set aLink [:pretty_link -absolute true -query m=answer]
+ set fn /tmp/qr-${:item_id}.png
+ exec qrencode -o $fn -l h $aLink
+ ns_returnfile 200 image/png $fn
+ ad_script_abort
+ }
+
+ ########################################################################
+ # AJAX call "poll"
+ #
+ # Return statistics about working and finished exams.
+ #
+ :proc www-poll {} {
+ set wf [xowf::test_item::answer_manager get_answer_wf [self]]
+ set answers [xowf::test_item::answer_manager get_answers $wf]
+ set answered [xowf::test_item::answer_manager get_answers -state done $wf]
+ ns_return 200 text/plain [llength $answered]/[llength $answers]
+ #ns_log notice "MASTER POLL [self] ${:name}, returned [llength $answered]/[llength $answers]"
+ ad_script_abort
+ }
+}
+
+#
+# Local variables:
+# mode: tcl
+# tcl-indent-level: 2
+# indent-tabs-mode: nil
+# End:
Index: openacs-4/packages/xowf/lib/inclass-quiz-answer.wf
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/Attic/inclass-quiz-answer.wf,v
diff -u -N -r1.1.2.5 -r1.1.2.6
--- openacs-4/packages/xowf/lib/inclass-quiz-answer.wf 5 Dec 2019 21:09:53 -0000 1.1.2.5
+++ openacs-4/packages/xowf/lib/inclass-quiz-answer.wf 21 Feb 2020 13:45:15 -0000 1.1.2.6
@@ -88,11 +88,6 @@
set more_ahead 1
set quiz_available 1
- #if {$parent_state eq "created" && [$obj property try_out_mode]} {
- # ns_log notice "FAKE state as published"
- # set parent_state "published"
- #}
-
switch $parent_state {
"published" {
#
@@ -105,7 +100,7 @@
set form_answer [xowf::test_item::renaming_form_loader answer_for_form \
$form_name \
[$obj instance_attributes]]
- ns_log notice "CURRENT answer '$form_answer' form_name $form_name"
+ #ns_log notice "CURRENT answer '$form_answer' form_name $form_name"
if {$form_answer eq ""} {
#
# It was not answered yet, show the question as 'waiting_form'
Index: openacs-4/packages/xowf/lib/inclass-quiz.wf
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/Attic/inclass-quiz.wf,v
diff -u -N -r1.1.2.10 -r1.1.2.11
--- openacs-4/packages/xowf/lib/inclass-quiz.wf 5 Feb 2020 20:48:42 -0000 1.1.2.10
+++ openacs-4/packages/xowf/lib/inclass-quiz.wf 21 Feb 2020 13:45:15 -0000 1.1.2.11
@@ -138,10 +138,11 @@
:proc load_form {ctx title} {
set obj [$ctx object]
set state [$obj property _state]
+ set wf [xowf::test_item::answer_manager get_answer_wf $obj]
switch $state {
"created" {
- set current_form_info [::xowf::test_item::question_manager combined_question_form \
+ set combined_form_info [::xowf::test_item::question_manager combined_question_form \
-with_numbers $obj]
}
default {
@@ -151,13 +152,12 @@
"results" {set title "#xowf.results_of#: $title"}
}
set current_question [xowf::test_item::question_manager current_question_obj $obj]
- set current_form_info [::xowf::test_item::question_manager current_question_form $obj]
+ set combined_form_info [::xowf::test_item::question_manager current_question_form $obj]
}
}
- set fullQuestionForm [dict get $current_form_info form]
- set full_fc [dict get $current_form_info disabled_form_constraints]
- set wf [xowf::test_item::answer_manager get_answer_wf $obj]
+ set fullQuestionForm [dict get $combined_form_info form]
+ set full_fc [dict get $combined_form_info disabled_form_constraints]
set qrCode ""
set answerStatus ""
@@ -174,7 +174,7 @@
"published" {
set src [$obj pretty_link -query m=qrcode]
- set qrCode [subst {
}]
+ set qrCode [subst {
}]
set answerStatus [xowf::test_item::answer_manager answers_panel \
-polling=${:live_updates} \
-manager_ob $obj \
@@ -185,12 +185,13 @@
"done" -
"results" {
[$ctx object] setCSSDefaults
- set marked [xowf::test_item::answer_manager marked_results $wf $current_form_info]
+ set marked [xowf::test_item::answer_manager marked_results -obj $obj -wf $wf $combined_form_info]
set answerStatus [xowf::test_item::answer_manager answers_panel \
-manager_ob $obj \
-wf $wf \
-current_question $current_question]
}
+
default {
:msg "not handled: state=$state"
}
Index: openacs-4/packages/xowf/lib/online-exam-answer.wf
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/online-exam-answer.wf,v
diff -u -N -r1.2.2.21 -r1.2.2.22
--- openacs-4/packages/xowf/lib/online-exam-answer.wf 3 Feb 2020 22:55:55 -0000 1.2.2.21
+++ openacs-4/packages/xowf/lib/online-exam-answer.wf 21 Feb 2020 13:45:15 -0000 1.2.2.22
@@ -56,18 +56,17 @@
# or closed it already). Only allow usage in the try-out-mode.
#
if {$parent_state ne "published" && [$obj property try_out_mode 0] == 0} {
- #:msg "LOCKED"
set current_state [$obj property _state]
- set lockin_state [expr {$current_state eq "initial" ? "initial" : "done"}]
- set lockin_msg(initial) "#xowf.online-exam-not-published#"
- set lockin_msg(done) "#xowf.online-exam-finished#"
+ set locking_state [expr {$current_state eq "initial" ? "initial" : "done"}]
+ set locking_msg(initial) "#xowf.online-exam-not-published#"
+ set locking_msg(done) "#xowf.online-exam-finished#"
- util_user_message -message $lockin_msg($lockin_state)
+ util_user_message -message $locking_msg($locking_state)
#
# Force the user in the done state. Alternatively, we could
# handle this in the provide a different form or push the user to some other state.
#
- [:wf_context] set_current_state $lockin_state
+ [:wf_context] set_current_state $locking_state
} else {
#:msg "not LOCKED"
@@ -114,7 +113,6 @@
-label #xowf.online-exam-submit# \
-proc activate {obj} {
[[$obj wf_context ] wf_container] addSignature $obj
- set pid [$obj package_id]
set try_out_mode [$obj property try_out_mode 0]
set return_url [$obj property return_url .]
#:msg "tryout $try_out_mode return_url $return_url"
@@ -214,7 +212,9 @@
}
#
-# Set "title" with question/user/IP information.
+# Set "title" with question/user/IP information. Note that the
+# "set_title" method is as well responsible for calling the rename
+# function via question_manager.
#
:proc set_title {
obj
@@ -232,7 +232,8 @@
-position $position \
-item_nr $item_nr \
$parent_obj]
- set titleString [dict get $form_info title_infos full_title]
+ set title_info [lindex [dict get $form_info title_infos] 0]
+ set titleString [dict get $title_info full_title]
set title [list [string trim $titleString]]
}
lappend title \
Index: openacs-4/packages/xowf/lib/online-exam.wf
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/online-exam.wf,v
diff -u -N -r1.6.2.21 -r1.6.2.22
--- openacs-4/packages/xowf/lib/online-exam.wf 15 Feb 2020 10:37:53 -0000 1.6.2.21
+++ openacs-4/packages/xowf/lib/online-exam.wf 21 Feb 2020 13:45:15 -0000 1.6.2.22
@@ -148,23 +148,32 @@
set pLink "."
set menu ""
} else {
+ #
+ # Always compute the testrun and answer link.
+ #
set wf_pretty_link [$wf pretty_link]
set tLink [export_vars -base $wf_pretty_link {
{m create-new} {p.return_url "[::xo::cc url]"} {p.try_out_mode 1} {title "[$obj title]"}
}]
- set lLink "$wf_pretty_link?m=list"
set aLink [$obj pretty_link -query m=answer]
- set pLink1 [$obj pretty_link -query m=print-answers]
- set pLink2 [$obj pretty_link -query m=print-answer-table]
- #util_user_message -html -message "$survey is available as
$pLink"
- # [
#xowf.refresh#,
- set menu "\["
- if {[acs_user::site_wide_admin_p -user_id [::xo::cc user_id]]} {
- append menu "
#xowf.online-exam-exam_instances#, "
+ #
+ # If there are answers, include the full menu.
+ #
+ set answers [xowf::test_item::answer_manager get_answers $wf]
+ if {[llength $answers] > 0} {
+
+ set lLink "$wf_pretty_link?m=list"
+ set pLink1 [$obj pretty_link -query m=print-answers]
+ set pLink2 [$obj pretty_link -query m=print-answer-table]
+
+ set menu "\["
+ if {[acs_user::site_wide_admin_p -user_id [::xo::cc user_id]]} {
+ append menu "
#xowf.online-exam-exam_instances#, "
+ }
+ append menu \
+ "
#xowf.online-exam-protocol#, " \
+ "
#xowf.online-exam-results-table#\]"
}
- append menu \
- "
#xowf.online-exam-protocol#, " \
- "
#xowf.online-exam-results-table#\]"
}
set extraAction ""
@@ -184,7 +193,7 @@
if {$state in {published done}} {
if {$state eq "done"} {
[$ctx object] setCSSDefaults
- set marked [xowf::test_item::answer_manager marked_results $wf $combined_form_info]
+ set marked [xowf::test_item::answer_manager marked_results -obj $obj -wf $wf $combined_form_info]
}
set answerStats [xowf::test_item::answer_manager answers_panel \
-heading "#xowf.online-exam-submitted_exams_heading#" \
Index: openacs-4/packages/xowf/tcl/test-item-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/tcl/test-item-procs.tcl,v
diff -u -N -r1.7.2.25 -r1.7.2.26
--- openacs-4/packages/xowf/tcl/test-item-procs.tcl 12 Feb 2020 12:43:26 -0000 1.7.2.25
+++ openacs-4/packages/xowf/tcl/test-item-procs.tcl 21 Feb 2020 13:45:15 -0000 1.7.2.26
@@ -149,7 +149,7 @@
set auto_correct ${:auto_correct}
set can_shuffle true
}
- ul { #
+ ul { #
set interaction_class upload_interaction
set options ""
set auto_correct false
@@ -854,11 +854,55 @@
#:msg "fc=$fc"
}
}
+############################################################################
+# Generic Assement interface
+############################################################################
namespace eval ::xowf::test_item {
- nx::Object create renaming_form_loader {
+ nx::Class create AssessmentInterface {
#
+ # Abstract class for common functionality
+ #
+ :method assert_assessment_container {o:object} {
+ set ok [expr {[$o is_wf_instance] == 0 && [$o is_wf] == 1}]
+ if {!$ok} {
+ ns_log notice "NO ASSESSMENT CONTAINER [$o title]"
+ ns_log notice "NO ASSESSMENT CONTAINER page_template [[$o page_template] title]"
+ ns_log notice "NO ASSESSMENT CONTAINER iswfi [$o is_wf_instance] iswf [$o is_wf]"
+ ns_log notice "[$o serialize]"
+ error "'[lindex [info level -1] 0]': not an assessment container"
+ }
+ }
+
+ :method assert_assessment {o:object} {
+ if {[llength [$o property question]] == 0} {
+ ns_log notice "NO ASSESSMENT [$o title]"
+ ns_log notice "NO ASSESSMENT page_template [[$o page_template] title]"
+ ns_log notice "NO ASSESSMENT iswfi [$o is_wf_instance] iswf [$o is_wf]"
+ ns_log notice "[$o serialize]"
+ error "'[lindex [info level -1] 0]': object has no questions"
+ }
+ }
+
+ :method assert_answer_instance {o:object} {
+ # we could include as well {[$o property answer] ne ""} in case we initialize it
+ set ok [expr {[$o is_wf_instance] == 1 && [$o is_wf] == 0}]
+ if {!$ok} {
+ ns_log notice "NO ANSWER [$o title]"
+ ns_log notice "NO ANSWER page_template [[$o page_template] title]"
+ ns_log notice "NO ANSWER iswfi [$o is_wf_instance] iswf [$o is_wf]"
+ ns_log notice "[$o serialize]"
+ error "'[lindex [info level -1] 0]': not an answer instance"
+ }
+ }
+
+ }
+}
+namespace eval ::xowf::test_item {
+
+ nx::Class create Renaming_form_loader -superclass AssessmentInterface {
+ #
# Form loader that renames "generic" form-field-names as provided
# by the test-item form-field classes (@answer@) into names based
# on the form name, such that multiple of these form names can be
@@ -873,7 +917,7 @@
# - rename_attributes
#
- :object method map_form_constraints {form_constraints oldName newName} {
+ :method map_form_constraints {form_constraints oldName newName} {
#
# Rename form constraints starting with $oldName into $newName.
# Handle as well "answer=$oldName" form constraint properties.
@@ -891,7 +935,7 @@
}]
}
- :public object method form_name_based_attribute_stem {formName} {
+ :public method form_name_based_attribute_stem {formName} {
#
# Produce from the provided 'formName' an attribute stem for the
# input fields of this form.
@@ -902,7 +946,7 @@
}
- :public object method answer_attributes {instance_attributes} {
+ :public method answer_attributes {instance_attributes} {
#
# Return all form-loader specific attributes from
# instance_attributes.
@@ -916,7 +960,7 @@
return $result
}
- :public object method answer_for_form {formName instance_attributes} {
+ :public method answer_for_form {formName instance_attributes} {
#
# Return answer for the provided formName from
# instance_attributes of a single object.
@@ -934,7 +978,7 @@
return $result
}
- :public object method answers_for_form {formName answers} {
+ :public method answers_for_form {formName answers} {
#
# Return a list of dicts for the provided formName from the
# answers (as returned from [answer_manager get_answers ...]).
@@ -954,7 +998,7 @@
return $result
}
- :public object method rename_attributes {form_obj:object} {
+ :public method rename_attributes {form_obj:object} {
set form [$form_obj get_property -name form]
set fc [$form_obj get_property -name form_constraints]
@@ -984,20 +1028,22 @@
return $form_obj
}
- :public object method get_form_object {{-set_title:boolean true} ctx:object form_name} {
- #ns_log notice "renaming_form_loader get_form_object for form_name <$form_name>"
+ :public method get_form_object {{-set_title:boolean true} ctx:object form_name} {
set form_id [$ctx default_load_form_id $form_name]
set obj [$ctx object]
set form_obj [::xo::db::CrClass get_instance_from_db -item_id $form_id]
return [:rename_attributes $form_obj]
}
}
+
+ Renaming_form_loader create renaming_form_loader
}
+
namespace eval ::xowf::test_item {
- nx::Object create answer_manager {
+ nx::Class create Answer_manager -superclass AssessmentInterface {
#
# Public API:
@@ -1010,10 +1056,10 @@
#
# - marked_results
# - answers_panel
- # - participant_result
# - result_table
#
- :public object method create_workflow {
+
+ :public method create_workflow {
{-answer_workflow /packages/xowf/lib/online-exam-answer.wf}
{-master_workflow en:Workflow.form}
parentObj:object
@@ -1090,7 +1136,7 @@
########################################################################
- :public object method delete_all_answer_data {obj:object} {
+ :public method delete_all_answer_data {obj:object} {
#
# Delete all instances of the answer workflow
#
@@ -1105,7 +1151,7 @@
########################################################################
- :public object method get_answer_wf {obj:object} {
+ :public method get_answer_wf {obj:object} {
#
# return the workflow denoted by the property wfName in obj
#
@@ -1118,12 +1164,14 @@
########################################################################
- :public object method get_wf_instances {
+ :public method get_wf_instances {
{-initialize false}
{-orderby ""}
wf:object
} {
# get_wf_instances: return the workflow instances
+ :assert_assessment_container $wf
+
return [::xowiki::FormPage get_form_entries \
-base_item_ids [$wf item_id] \
-form_fields "" \
@@ -1136,7 +1184,7 @@
########################################################################
- :public object method get_answers {{-state ""} wf:object} {
+ :public method get_answers {{-state ""} wf:object} {
set results {}
set items [:get_wf_instances $wf]
foreach i [$items children] {
@@ -1152,24 +1200,26 @@
########################################################################
- :object method participant_result {obj:object form_info} {
- #
- # In case, the passed-in obj modifies during rendering the
- # perconnection parameters, save and restore these.
- #
- set form_fields [:answer_form_field_objs -wf $obj]
- $obj form_field_index $form_fields
+ :method participant_result {
+ -obj:object
+ answerObj:object
+ form_info
+ form_field_objs
+ } {
- set instance_attributes [$obj instance_attributes]
- set answer [list item $obj]
+ :assert_answer_instance $answerObj
+ :assert_assessment $obj
- foreach f $form_fields {
+ set instance_attributes [$answerObj instance_attributes]
+ set answer [list item $answerObj]
+
+ foreach f $form_field_objs {
set att [$f name]
if {[dict exists $instance_attributes $att]} {
set value [dict get $instance_attributes $att]
#ns_log notice "### '$att' value '$value'"
- $obj combine_data_and_form_field_default 1 $f $value
+ $answerObj combine_data_and_form_field_default 1 $f $value
$f set_feedback 1
$f add_statistics -options {word_statistics word_cloud}
#
@@ -1189,7 +1239,7 @@
return $answer
}
- :object method answer_form_field_objs {-clear:switch -wf:object} {
+ :method answer_form_field_objs {-clear:switch -wf:object form_info} {
set key ::__test_item_answer_form_fields
if {$clear} {
#
@@ -1199,25 +1249,32 @@
#
unset $key
} else {
+ #ns_log notice "### key exists [info exists $key]"
if {![info exists $key]} {
- set form_info [::xowf::test_item::question_manager combined_question_form -with_numbers $wf]
+ #ns_log notice "form_info: $form_info"
+ set fc [dict get $form_info disabled_form_constraints]
set pc_params [::xo::cc perconnection_parameter_get_all]
+ #ns_log notice "### create_form_fields_from_form_constraints <$fc>"
set $key [$wf create_form_fields_from_form_constraints \
-lookup \
- [dict get $form_info disabled_form_constraints]]
+ [lsort -unique $fc]]
::xo::cc perconnection_parameter_set_all $pc_params
+ $wf form_field_index [set $key]
}
return [set $key]
}
}
- :public object method result_table {
+
+ :public method result_table {
-package_id:integer
-items:object,required
{-view_all_method print-answers}
wf:object
} {
- set answer_form_field_objs [:answer_form_field_objs -wf $wf]
+ #set form_info [:combined_question_form -with_numbers $wf]
+ set form_info [::xowf::test_item::question_manager combined_question_form $wf]
+ set answer_form_field_objs [:answer_form_field_objs -wf $wf $form_info]
set form_field_objs [$wf create_raw_form_field \
-name _online-exam-userName \
@@ -1302,17 +1359,21 @@
return $HTML
}
- :public object method marked_results {wf:object form_info} {
+ :public method marked_results {-obj:object -wf:object form_info} {
+ set form_field_objs [:answer_form_field_objs -wf $wf $form_info]
+
set items [:get_wf_instances $wf]
set results ""
foreach i [$items children] {
- set participantResult [:participant_result $i $form_info]
+ set participantResult [:participant_result -obj $obj $i $form_info $form_field_objs]
append results $participantResult \n
}
+
+ #ns_log notice "=== marked_results of [llength [$items children]] items => $results"
return $results
}
- :public object method answers_panel {
+ :public method answers_panel {
{-polling:switch false}
{-heading #xowf.submitted_answers#}
{-submission_msg #xowf.participants_answered_question#}
@@ -1372,28 +1433,60 @@
return $answerStatus
}
- }
-}
-namespace eval ::xowf::test_item {
- ::xotcl::Class create ::xowf::test_item::td_pretty_value \
- -superclass ::xowiki::formfield::FormField
+ :public method countdown_timer {
+ {-target_time:required}
+ {-id:required}
+ } {
+ # new Date('1995-12-17T03:24:00')
+ template::add_body_script -script [subst {
+ var countdown_target_date = new Date('$target_time').getTime();
+ var countdown_days, countdown_hours, countdown_minutes, countdown_seconds;
+ var countdown = document.getElementById('$id');
- ::xowf::test_item::td_pretty_value instproc pretty_value {value} {
- #ns_log notice "${:name} pretty_value [:info precedence]"
- if {"::xowiki::formfield::checkbox" in [:info precedence]} {
- set v ${value}
- } else {
- set v [next]
+ setInterval(function () {
+ var current_date = new Date().getTime();
+ var seconds_left = (countdown_target_date - current_date) / 1000;
+ var HTML = '';
+
+ countdown_days = parseInt(seconds_left / 86400);
+ seconds_left = seconds_left % 86400;
+ countdown_hours = parseInt(seconds_left / 3600);
+ seconds_left = seconds_left % 3600;
+ countdown_minutes = parseInt(seconds_left / 60);
+ countdown_seconds = parseInt(seconds_left % 60);
+
+ if (countdown_days != 0) {
+ HTML += '
' + countdown_days + ' '
+ + (countdown_days != 1 ? '[_ xowf.Days]' : '[_ xowf.Day]')
+ + ' ';
+ }
+ if (countdown_hours != 0 || countdown_days != 0) {
+ HTML += '
' + countdown_hours + ' '
+ + (countdown_hours != 1 ? '[_ xowf.Hours]' : '[_ xowf.Hour]')
+ + ' ';
+ }
+ HTML += '
' + countdown_minutes + ' '
+ + (countdown_minutes != 1 ? '[_ xowf.Minutes]' : '[_ xowf.Minute]')
+ + ' '
+ + '
' + countdown_seconds + ' '
+ + (countdown_seconds != 1 ? '[_ xowf.Seconds]' : '[_ xowf.Second]')
+ + ' [_ xowf.remaining]' ;
+
+ countdown.innerHTML = HTML;
+ }, 1000);
+ }]
+ return "
"
}
- return $v
}
+
+ Answer_manager create answer_manager
}
+
namespace eval ::xowf::test_item {
-
- nx::Object create question_manager {
+ nx::Class create Question_manager -superclass AssessmentInterface {
#
# This code manages questions and the information related to a
# current (selected) question via qthe "position" instance
@@ -1413,20 +1506,21 @@
# - question_objs
# - question_names
# - question_property
+ # - total_minutes
#
- :public object method goto_page {obj:object position} {
+ :public method goto_page {obj:object position} {
$obj set_property position $position
}
- :public object method more_ahead {{-position ""} obj:object} {
+ :public method more_ahead {{-position ""} obj:object} {
if {$position eq ""} {
set position [$obj property position]
}
set questions [dict get [$obj instance_attributes] question]
return [expr {$position + 1 < [llength $questions]}]
}
- :object method load_question_objs {obj names} {
+ :method load_question_objs {obj:object names} {
set questions [lmap ref $names {
if {![string match "*/*" $ref]} {
set ref [[$obj parent_id] name]/$ref
@@ -1438,21 +1532,22 @@
-package_id [$obj package_id] \
-default_lang [$obj lang] \
-forms $questionNames]
+
#ns_log notice "load_question_objs called with $obj $names -> $questionForms"
return $questionForms
}
- :public object method current_question_name {obj:object} {
+ :public method current_question_name {obj:object} {
set questions [dict get [$obj instance_attributes] question]
return [lindex [dict get [$obj instance_attributes] question] [$obj property position]]
}
- :public object method current_question_obj {obj:object} {
+ :public method current_question_obj {obj:object} {
return [:load_question_objs $obj [:current_question_name $obj]]
}
- :public object method shuffled_question_objs {obj:object shuffle_id} {
+ :public method shuffled_question_objs {obj:object shuffle_id} {
set form_objs [:question_objs $obj]
set result {}
foreach i [::xowiki::randomized_indices -seed $shuffle_id [llength $form_objs]] {
@@ -1461,7 +1556,7 @@
return $result
}
- :public object method shuffled_index {{-shuffle_id:integer -1} obj:object position} {
+ :public method shuffled_index {{-shuffle_id:integer -1} obj:object position} {
if {$shuffle_id > -1} {
set form_objs [:question_objs $obj]
set shuffled [::xowiki::randomized_indices -seed $shuffle_id [llength $form_objs]]
@@ -1470,7 +1565,8 @@
return $position
}
- :public object method question_objs {{-shuffle_id:integer -1} obj:object} {
+ :public method question_objs {{-shuffle_id:integer -1} obj:object} {
+ :assert_assessment $obj
set form_objs [:load_question_objs $obj [$obj property question]]
if {$shuffle_id > -1} {
set result {}
@@ -1482,18 +1578,18 @@
return $form_objs
}
- :public object method question_names {obj:object} {
+ :public method question_names {obj:object} {
return [$obj property question]
}
- :public object method nth_question_obj {obj:object position:integer} {
+ :public method nth_question_obj {obj:object position:integer} {
+ :assert_assessment $obj
set questions [dict get [$obj instance_attributes] question]
set result [:load_question_objs $obj [lindex $questions $position]]
- #ns_log notice "nth_question_obj called with $position -> $result"
return $result
}
- :object method question_info {
+ :method question_info {
{-numbers ""}
{-with_title:switch false}
{-with_minutes:switch false}
@@ -1503,6 +1599,7 @@
set full_fc {}
set full_disabled_fc {}
set title_infos {}
+
foreach form_obj $form_objs number $numbers {
set form_obj [::xowf::test_item::renaming_form_loader rename_attributes $form_obj]
set form_title [$form_obj title]
@@ -1520,11 +1617,10 @@
append full_form "
$title
\n"
append full_form [$form_obj property form] \n
- lappend title_infos \
- full_title $title \
- title $form_title \
- minutes $minutes \
- number $number
+ lappend title_infos [list full_title $title \
+ title $form_title \
+ minutes $minutes \
+ number $number]
lappend full_fc [$form_obj property form_constraints]
lappend full_disabled_fc [$form_obj property disabled_form_constraints]
}
@@ -1536,7 +1632,7 @@
}
- :public object method question_property {form_obj:object attribute {default ""}} {
+ :public method question_property {form_obj:object attribute {default ""}} {
#
# Get an attribute of the original question
#
@@ -1550,7 +1646,7 @@
return $value
}
- :public object method minutes_string {form_obj:object} {
+ :public method minutes_string {form_obj:object} {
#
# Get an attribute of the original question
#
@@ -1561,7 +1657,7 @@
}
}
- :public object method combined_question_form {
+ :public method combined_question_form {
{-with_numbers:switch false}
{-with_title:switch false}
{-with_minutes:switch false}
@@ -1585,15 +1681,25 @@
$form_objs]
}
- :public object method current_question_form {
+ :public method total_minutes {form_info} {
+ set minutes 0
+ foreach title_info [dict get $form_info title_infos] {
+ if {[dict exists $title_info minutes]} {
+ set minutes [expr {$minutes + [dict get $title_info minutes]}]
+ }
+ }
+ return $minutes
+ }
+
+ :public method current_question_form {
{-with_numbers:switch false}
{-with_title:switch false}
obj:object
} {
return [:nth_question_form -with_numbers=$with_numbers -with_title=$with_title $obj]
}
- :public object method nth_question_form {
+ :public method nth_question_form {
{-position:integer}
{-item_nr:integer}
{-with_numbers:switch false}
@@ -1621,33 +1727,40 @@
$form_objs]
}
- :public object method current_question_number {obj:object} {
+ :public method current_question_number {obj:object} {
return [expr {[$obj property position] + 1}]
}
- :public object method current_question_title {{-with_numbers:switch false} obj:object} {
+ :public method current_question_title {{-with_numbers:switch false} obj:object} {
if {$with_numbers} {
return "#xowf.question# [:current_question_number $obj]"
}
}
+ }
+ Question_manager create question_manager
- # :public object method set_page {obj increment} {
- # #set pages [$obj property pages]
- # set position [$obj property position 0]
- # incr position $increment
- # if {$position < 0} {
- # set position 0
- # } elseif {$position >= [llength $pages]} {
- # set position [expr {[llength $pages] - 1}]
- # }
- # $obj set_property position $position
- # #$obj set_property -new 1 current_form [lindex $pages $position]
- # }
- }
}
namespace eval ::xowf::test_item {
+ #
+ # Define handling of form-field "td_pretty_value"
+ #
+ ::xotcl::Class create ::xowf::test_item::td_pretty_value \
+ -superclass ::xowiki::formfield::FormField
+ ::xowf::test_item::td_pretty_value instproc pretty_value {value} {
+ #ns_log notice "${:name} pretty_value [:info precedence]"
+ if {"::xowiki::formfield::checkbox" in [:info precedence]} {
+ set v ${value}
+ } else {
+ set v [next]
+ }
+ return $v
+ }
+}
+
+
+namespace eval ::xowf::test_item {
#
# Copy the default policy (policy1) from xowiki and add elements for
# FormPages as needed by the demo workflows:
Index: openacs-4/packages/xowf/tcl/xowf-init.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/tcl/xowf-init.tcl,v
diff -u -N -r1.3.2.3 -r1.3.2.4
--- openacs-4/packages/xowf/tcl/xowf-init.tcl 14 Feb 2020 13:42:12 -0000 1.3.2.3
+++ openacs-4/packages/xowf/tcl/xowf-init.tcl 21 Feb 2020 13:45:15 -0000 1.3.2.4
@@ -4,6 +4,11 @@
::xowf::dav-todo register
#
+# Make sure, the site-wide pages are loaded
+#
+::xowf::Package require_site_wide_pages
+
+#
# Run the checker for the scheduled at-jobs.
#
# As we are trying to run as close as possible to the minute change,
Index: openacs-4/packages/xowf/tcl/xowf-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/tcl/xowf-procs.tcl,v
diff -u -N -r1.28.2.25 -r1.28.2.26
--- openacs-4/packages/xowf/tcl/xowf-procs.tcl 14 Feb 2020 13:42:12 -0000 1.28.2.25
+++ openacs-4/packages/xowf/tcl/xowf-procs.tcl 21 Feb 2020 13:45:15 -0000 1.28.2.26
@@ -16,6 +16,7 @@
::xo::db::require package xowiki
::xo::library require -package xowiki xowiki-procs
+::xo::library require -package xotcl-core 06-package-procs
namespace eval ::xowf {
#
@@ -44,6 +45,23 @@
parameter_page en:xowf-site-wide-parameter
}
+ Package site_wide_pages {
+ Workflow.form
+
+ TestItemText.form
+ TestItemShortText.form
+ TestItemMC.form
+ TestItemSC.form
+ TestItemUpload.form
+
+ online-exam.wf
+ inclass-quiz.wf
+ inclass-exam.wf
+
+ quiz-select_question.form
+ select_question.form
+ }
+
Package default_package_parameters {
parameter_page en:xowf-default-parameter
}
@@ -54,11 +72,46 @@
instance_attributes {
MenuBar t top_includelet none production_mode t with_user_tracking t with_general_comments f
with_digg f with_tags f
- ExtraMenuEntries {{entry -name New.Extra.Workflow -form /en:Workflow.form}}
+ ExtraMenuEntries {{entry -name New.Extra.Workflow -form en:Workflow.form}}
with_delicious f with_notifications f security_policy ::xowiki::policy1
}
}
+ Package ad_proc create_new_workflow_page {
+ -package_id:required
+ -parent_id:required
+ -name:required
+ -title:required
+ {-instance_attributes ""}
+ } {
+ Helper proc for loading workflow prototype page with less effort.
+ } {
+ #
+ # Load Workflow.form
+ #
+ xo::Package require $package_id
+ set item_ref_info [$package_id item_ref -use_site_wide_pages true -default_lang en \
+ -parent_id $parent_id \
+ en:Workflow.form]
+ set page_template [dict get $item_ref_info item_id]
+ if {$page_template != 0} {
+ #
+ # Create FormPage
+ #
+ set p [::xowiki::FormPage new \
+ -name $name \
+ -title $title \
+ -set text {} \
+ -instance_attributes $instance_attributes \
+ -page_template $page_template]
+ } else {
+ ns_log error "could not load Workflow form, therefore creation of workflow $name failed as well"
+ set p ""
+ }
+ return $p
+ }
+
+
Package ad_instproc initialize {} {
Add mixin ::xowf::WorkflowPage to every FormPage.
} {
@@ -99,6 +152,8 @@
next
}
+
+
# Package instproc delete {-item_id -name} {
# # Provide a method to delete the foreign key references, when
# # an item for an atjob is deleted. We do here the same magic
Index: openacs-4/packages/xowf/www/prototypes/TestItemMC.form.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/TestItemMC.form.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/TestItemMC.form.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,12 @@
+# -*- tcl-*-
+::xowiki::Form new \
+ -name en:TestItemMC.form \
+ -title "MC Item" \
+ -anon_instances f \
+ -text {} \
+ -form {{
} text/html} \
+ -form_constraints {
+ {question:test_item,question_type=mc2,grading=ggw wi1 wi2 exact,feedback_level=single,label=#xowf.mc_question#}
+ _description:omit _page_order:omit
+ }
+
Index: openacs-4/packages/xowf/www/prototypes/TestItemSC.form.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/TestItemSC.form.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/TestItemSC.form.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,14 @@
+# -*- tcl-*-
+::xowiki::Form new \
+ -name en:TestItemSC.form \
+ -title "SC Item" \
+ -anon_instances f \
+ -text {} \
+ -form {{
} text/html} \
+ -form_constraints {
+ question:test_item,question_type=sc,grading=exact,feedback_level=single,label=#xowf.sc_question#
+ _description:omit _page_order:omit
+ }
+
+
+
Index: openacs-4/packages/xowf/www/prototypes/TestItemShortText.form.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/TestItemShortText.form.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/TestItemShortText.form.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,14 @@
+# -*- tcl-*-
+::xowiki::Form new \
+ -name en:TestItemShortText.form \
+ -title "ShortTextItem" \
+ -anon_instances f \
+ -text {} \
+ -form {{
} text/html} \
+ -form_constraints {
+ question:test_item,question_type=st,grading=none,feedback_level=single,auto_correct=1,label=#xowf.short_text_question#
+ _description:omit _page_order:omit
+ }
+
+
+
Index: openacs-4/packages/xowf/www/prototypes/TestItemText.form.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/TestItemText.form.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/TestItemText.form.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,14 @@
+# -*- tcl-*-
+::xowiki::Form new \
+ -name en:TestItemText.form \
+ -title "TextItem" \
+ -anon_instances f \
+ -form {{
} text/html} \
+ -form_constraints {
+question:test_item,question_type=ot,grading=none,feedback_level=single,auto_correct=1,label=#xowf.text_question#
+_description:omit
+_page_order:omit
+}
+
+
+
Index: openacs-4/packages/xowf/www/prototypes/TestItemUpload.form.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/TestItemUpload.form.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/TestItemUpload.form.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,14 @@
+# -*- tcl-*-
+::xowiki::Form new \
+ -name en:TestItemUpload.form \
+ -title "File Submission Item" \
+ -anon_instances f \
+ -text {} \
+ -form {{
} text/html} \
+ -form_constraints {
+ {question:test_item,question_type=ul,feedback_level=single,label=#xowf.ul_question#}
+ _description:omit _page_order:omit
+ }
+
+
+
Index: openacs-4/packages/xowf/www/prototypes/assessment-index.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/assessment-index.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/assessment-index.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,17 @@
+::xowiki::Page new -title "Assessment Index" -text {
+
#xowf.Created_Questions#:
+
+
{{form-usages -title "Questions" -form en:TestItemText.form|en:TestItemShortText.form|en:TestItemMC.form|en:TestItemSC.form|en:TestItemUpload.form -buttons "edit duplicate slim_publish_status delete" -field_names "_title,_last_modified,_creation_user" -date_format "pretty-age" -csv false}}
+
+
#xowf.Created_Assessments#:
+
+
{{form-usages -title "Online Exams" -form en:online-exam.wf|en:inclass-quiz.wf|en:inclass-exam.wf -buttons "edit delete" -field_names "_title,_state,_last_modified,_creation_user" -date_format "pretty-age" -csv false}}
+
+{{set-parameter __no_footer 1}}
+
+
+}
+
+
+
+
Index: openacs-4/packages/xowf/www/prototypes/inclass-exam.wf.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/inclass-exam.wf.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/inclass-exam.wf.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,16 @@
+# -*- tcl-*-
+# The variable package_id and parent_id are provided via the caller context
+xowf::Package create_new_workflow_page \
+ -package_id $package_id \
+ -parent_id $parent_id \
+ -name en:inclass-exam.wf \
+ -title "In-class Exam Workflow" \
+ -instance_attributes {
+ workflow_definition {::xowf::include /packages/xowf/lib/inclass-exam.wf}
+ form_constraints {}
+ return_url {}
+ }
+
+
+
+
Index: openacs-4/packages/xowf/www/prototypes/inclass-quiz.wf.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/inclass-quiz.wf.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/inclass-quiz.wf.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,16 @@
+# -*- tcl-*-
+# The variable package_id and parent_id are provided via the caller context
+xowf::Package create_new_workflow_page \
+ -package_id $package_id \
+ -parent_id $parent_id \
+ -name en:inclass-quiz.wf \
+ -title "In-class Quiz Workflow" \
+ -instance_attributes {
+ workflow_definition {::xowf::include /packages/xowf/lib/inclass-quiz.wf}
+ form_constraints {}
+ return_url {}
+ }
+
+
+
+
Index: openacs-4/packages/xowf/www/prototypes/online-exam.wf.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/online-exam.wf.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/online-exam.wf.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,12 @@
+# -*- tcl-*-
+# The variable package_id and parent_id are provided via the caller context
+xowf::Package create_new_workflow_page \
+ -package_id $package_id \
+ -parent_id $parent_id \
+ -name en:online-exam.wf \
+ -title "Online Exam Workflow" \
+ -instance_attributes {
+ workflow_definition {::xowf::include /packages/xowf/lib/online-exam.wf}
+ form_constraints {}
+ return_url {}
+ }
Index: openacs-4/packages/xowf/www/prototypes/quiz-select_question.form.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/quiz-select_question.form.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/quiz-select_question.form.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,14 @@
+# -*- tcl-*-
+::xowiki::Form new \
+ -name quiz-select_question.form \
+ -title "Select Question" \
+ -anon_instances f \
+ -text {} \
+ -form {{
} text/html} \
+ -form_constraints {
+ @cr_fields:hidden
+ {_title:text,label=#xowf.inclass-quiz-name#,default=#xowf.inclass-quiz-default_name#}
+ {question:form_page,multiple=true,form=en:TestItemText.form|en:TestItemShortText.form|en:TestItemMC.form|en:TestItemSC.form,required,help_text=#xowf.select_question_help_text#,label=#xowiki.questions#}
+ _description:omit _page_order:omit
+ }
+
Index: openacs-4/packages/xowf/www/prototypes/select_question.form.page
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/prototypes/Attic/select_question.form.page,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowf/www/prototypes/select_question.form.page 21 Feb 2020 13:45:15 -0000 1.1.2.1
@@ -0,0 +1,16 @@
+# -*- tcl-*-
+::xowiki::Form new \
+ -name select_question.form \
+ -title "Select Question" \
+ -anon_instances f \
+ -text {} \
+ -form {{
} text/html} \
+ -form_constraints {
+ @cr_fields:hidden
+ {_title:text,label=#xowf.online-exam-name#,default=#xowf.online-exam-default_name#}
+ {question:form_page,multiple=true,form=en:TestItemText.form|en:TestItemShortText.form|en:TestItemMC.form|en:TestItemSC.form|en:TestItemUpload.form,required,help_text=#xowf.select_question_help_text#,label=#xowiki.questions#}
+ {shuffle_items:boolean,horizontal=true,label=#xowf.randomized_items#,help_text=#xowf.randomized_items_help_text#}
+ {signatur:boolean,horizontal=true,default=f,label=#xowf.signature#,help_text=#xowf.signature-help_text#}
+ _description:omit _page_order:omit
+ }
+
Index: openacs-4/packages/xowf/www/resources/test-item.css
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/resources/Attic/test-item.css,v
diff -u -N -r1.1.2.12 -r1.1.2.13
--- openacs-4/packages/xowf/www/resources/test-item.css 11 Feb 2020 21:26:04 -0000 1.1.2.12
+++ openacs-4/packages/xowf/www/resources/test-item.css 21 Feb 2020 13:45:15 -0000 1.1.2.13
@@ -192,3 +192,8 @@
height: auto; /* let the content decide it */
}
+
+div.xowiki-content h1 {
+ font-size: 24px;
+}
+