From 0ad26a1921231532dde76c4cc6fc0328600ceed7 Mon Sep 17 00:00:00 2001 From: Patrick Donelan Date: Sun, 24 May 2009 09:59:43 +0000 Subject: [PATCH] Survey: more bug fixes Fixed invalid calendar markup so that Date question type works in IE Minor tweaks to ResponseJSON for more robustness Fixed Number question type javascript --- ...root_import_survey_default-questions.wgpkg | Bin 0 -> 4072 bytes docs/upgrades/packages-7.7.7/survey.css.wgpkg | Bin 0 -> 2212 bytes .../Asset/Wobject/Survey/ResponseJSON.pm | 20 ++++- lib/WebGUI/Asset/Wobject/Survey/Test.pm | 20 ++--- www/extras/wobject/Survey/administersurvey.js | 77 +++++++++++------- 5 files changed, 69 insertions(+), 48 deletions(-) create mode 100644 docs/upgrades/packages-7.7.7/root_import_survey_default-questions.wgpkg create mode 100644 docs/upgrades/packages-7.7.7/survey.css.wgpkg diff --git a/docs/upgrades/packages-7.7.7/root_import_survey_default-questions.wgpkg b/docs/upgrades/packages-7.7.7/root_import_survey_default-questions.wgpkg new file mode 100644 index 0000000000000000000000000000000000000000..7fcac5696c3411c87783284fbcf8453f99a7ac47 GIT binary patch literal 4072 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 aTfeK3QP*7WhBn2F=6(Q~&^-GRsH+ literal 0 HcmV?d00001 diff --git a/docs/upgrades/packages-7.7.7/survey.css.wgpkg b/docs/upgrades/packages-7.7.7/survey.css.wgpkg new file mode 100644 index 0000000000000000000000000000000000000000..e7169fa17adefcf02e7f95b38df383957fbf1d52 GIT binary patch literal 2212 zcmV;V2wV3biwFP!000001MOK`bK5o+_H%y)MxIWaOeB-K*`c27q;4{8J?_|PcXqW8 zyg(8X5@ZO_vZC>S-vb#~u(8-=Fxy0|G2h|5QSTC74!(QWRl!ufl)Y2PffC&f(|1g8siYw6%Wo z|5*R-dxQ5P=Z|D6NS}_!P2O!CVEX;>1UB3GpLpK*fIu{#{&}kW51!ui$I!6-0kY5& zGB3j=?U8`|=f5xXQc>mwEhVEut!gqw8J9GaG&$R-)!wM5iPc6L3i-=zk(aQ0s(E;o zru8;-nbh)oMHQt?tZ35ka=QMT@g!espf1j-z3#&5KMvJPv zp_@T0M6<`l8eMydm7v%jwpp|u z$8&*sYI>*_<;iB7h2@g*z?((TTq>|U>6f&C<`3|rzj3#UTrd^az$p$h?Ifeeze@ywv`k*g56NZ@BsSv=OaB1#L+sB-qTnfUFlvvikAI_vb_(d z(O}6I&&WhMM|f@`VO^P?faPf4WcX5f;TRxSRTgdIsuXz{ByBfdhnP6saodCmm?oQm=bS>0%oc>LyYsQ4Le+ujY%pF_ za*)MQC1uXHi=4~8fPM*l<+J{}#uP?*n#@$^_Y)e!sidn)>vbwI&Qply;Vb<(>Fku~ zEeZ-#w&Xz!q?YDSDFG0yupNKvm#6q#+Sk11iq+{V@{{FiHk5}=_dG#mPyFN z7pEl)(-&`OdP615l@|gEvJdACTg;4sdWN=oh-J{E4^`c=3=;;X_Lpfc#AZ z?WWF2n=YgW^1oAgPE5ZpRgQqV%b|eULy_?tFe>ST4<8_rby!rrG&4{e_tj~P@)Cwu zFaq5$V^~5CeX4$H`NYgxJE9%SjY083{n)wt=AX$c$u>bmU4;GxszpD|7=5E|*=3VMQghiG3M`!rUuCU&q7 zvNv|u5C}I^R}qbb@VmxCL?N24k{T3!gQC51En0dEx$cOx@+<@aBnfZ|%cq%24^i21 zAs!%VLxn9yu{q+2MqJLS!CgcHFO!1~{IZ6s3U;~=PYGgS81g#%o$gc_R1%!=P7El+ zjXExf&2X{qetpj4nw`r;BQ--;<29lI8?L%XD6zPWAaElMaw86OLq_YHL2$U}_=ezs zJn;Ik7s%;kw=-nG+>Qoofx&d&=+FKFusUilVKla_Yw+H^1{&D6vwu(etxf|1pTw`v zEgCb9or3wY;?z;y(?E|=D4k|&24?FZoAaaRfLB8~y{m>UzN!#}y=oQvRzqK6u#@#|VGx*Xi$Tl#y zEVc{I&)x1l)G*!BAX+CHuA?F|9TBzTk_E&F-oe@izQcHk@~SBSA^-q=rctT@ literal 0 HcmV?d00001 diff --git a/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm b/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm index 3783b1eaa..082b5f342 100644 --- a/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm +++ b/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm @@ -102,11 +102,11 @@ sub reset { startTime => time(), surveyOrder => undef, tags => {}, - - # And then data overrides - %{$data}, }; + # And then data overrides (via a hash slice) + @{$self->{_response}}{keys %{$data}} = values %{$data}; + # If first section is logical, process it immediately $self->checkForLogicalSection; return $self; @@ -1141,6 +1141,15 @@ sub nextQuestions { last; } + # In rare cases where you change the structure of your survey after + # someone has already started a response, it's possible for this + # to be triggered, in which case the easiest course of action is + # to just skip over the question. + if (!$self->survey->question( $address )) { + $self->session->log->debug("Unable to retrieve question for address $sIndex-$qIndex"); + next; + } + # Make a safe copy of the question my %questionCopy = %{$self->survey->question( $address )}; @@ -1190,7 +1199,10 @@ sub nextQuestions { } } else { for my $aIndex ( aIndexes($address) ) { - my %answerCopy = %{ $self->survey->answer( [ $sIndex, $qIndex, $aIndex ] ) }; + my %answerCopy + = %{ $self->survey->answer( [ $sIndex, $qIndex, $aIndex ] ) + || $self->survey->newAnswer # in case the lookup fails, use a default answer + }; # Do text replacement $answerCopy{text} = $self->getTemplatedText($answerCopy{text}, \%templateValues); diff --git a/lib/WebGUI/Asset/Wobject/Survey/Test.pm b/lib/WebGUI/Asset/Wobject/Survey/Test.pm index 7f376cb0f..3d42e2a3a 100644 --- a/lib/WebGUI/Asset/Wobject/Survey/Test.pm +++ b/lib/WebGUI/Asset/Wobject/Survey/Test.pm @@ -133,9 +133,6 @@ sub run { $self->session->db->write( 'delete from Survey_response where assetId = ? and userId = ?', [ $self->getId, $self->session->user->userId() ] ); - # disable cookies so that test code doesn't die - $survey->responseIdCookies(0); - # Start a response as current user my $responseId = $survey->responseId($self->session->user->userId) or return { tap => "Bail Out! Unable to start survey response" }; @@ -144,7 +141,6 @@ sub run { my $rJSON = $survey->responseJSON or return { tap => "Bail Out! Unable to get responseJSON" }; - my %validTargets = map { $_ => 1 } @{$survey->surveyJSON->getGotoTargets}; my $surveyOrder = $rJSON->surveyOrder; my $surveyOrderIndexByVariableName = $rJSON->surveyOrderIndexByVariableName; @@ -371,28 +367,24 @@ sub _setup { # Setup any fake data the user wants prior to the test if ($setup && ref $setup eq 'HASH') { - my %existingTags = %{$rJSON->tags}; - # Process tags - # N.B. Make sure we add to existing tags instead of overwriting + my %tags; if (ref $setup->{tag} eq 'HASH') { - # already a hash, so store it right away - $rJSON->tags( {%existingTags, %{$setup->{tag}} }); + %tags = %{$setup->{tag}}; } elsif (ref $setup->{tag} eq 'ARRAY') { - # turn array into hash before storing it - my $tags; for my $tag (@{$setup->{tag}}) { if (ref $tag eq 'HASH') { # Individual item is a single key/value hash my ($key, $value) = %$tag; - $tags->{$key} = $value; + $tags{$key} = $value; } else { # Individual item is a string, default to boolean truth flag - $tags->{$tag} = 1; # default to 1 + $tags{$tag} = 1; # default to 1 } } - $rJSON->tags( {%existingTags, %$tags }); } + # N.B. Make sure we add to existing tags instead of overwriting + @{$rJSON->tags}{keys %tags} = values %tags; } } diff --git a/www/extras/wobject/Survey/administersurvey.js b/www/extras/wobject/Survey/administersurvey.js index df1321c1b..512c48d9d 100644 --- a/www/extras/wobject/Survey/administersurvey.js +++ b/www/extras/wobject/Survey/administersurvey.js @@ -186,42 +186,59 @@ if (typeof Survey === "undefined") { anim.setAttribute = setAttr; anim.animate(); } - function numberHandler(event, objs){ var keycode = event.keyCode; - var value = this.value; + var value = parseFloat(this.value, 10); - //if starting a negative number, don't do anything - if(value == '' || value == "-"){return;} - - var step = objs.step ? objs.step : 1; - - if(!value){this.value = objs.min ? objs.min : 0;} - if(value % step > 0){ - this.value = +value + value % step; - } + // Keep a record of the original value entered + var originalValue = value; + + // Get the constraints + var min = parseFloat(objs.min, 10); + var max = parseFloat(objs.max, 10); + var step = parseFloat(objs.step, 10); + + // Response to up/down arrow keys + if (keycode == 38 || keycode == 40) { + // start at zero if we don't have a valid number + if (!YAHOO.lang.isNumber(value)) { + value = 0; + } - if(objs.min != '' && +value < +objs.min){ - this.value = objs.min; + // Default to 1 for increment steps + step = step ? step : 1; + + if (keycode == 38){ // up + value += step; + } + if (keycode == 40){ // down + value -= step; + } + } else { + // Apart from when we respond to up/down requests, if the input + // isn't a valid number it's best if we do nothing - the user + // might be half-way through entering something, and + // besides, validation will take care of it for us later + if (!YAHOO.lang.isNumber(value)) { + return; + } } - - else if(objs.max != '' && +value > objs.max){this.value = objs.max;} - else if(+keycode == 40){//key down - if(objs.min == ''){ - this.value = value - step; - } - else if((value - step) >= +objs.min){ - this.value = value - step; - } - }else if(+keycode == 38){//key up - if(objs.max == ''){ - this.value = value + step; - } - if(value + step <= objs.max){ - this.value = value + step; - } + + // Enforce max/min constraints + if (YAHOO.lang.isNumber(min) && value < min){ + value = min; + } + if (YAHOO.lang.isNumber(max) && value > max){ + value = max; + } + + // Only modify the value if the new numeric value + // is different from the original parsed value + // (so that "0.000" doesn't get turned into "0" etc..) + if (value != originalValue) { + this.value = value; } } @@ -733,7 +750,7 @@ if (typeof Survey === "undefined") { if (toValidate[q.id]) { toValidate[q.id].answers[q.answers[x1].id] = {'min':q.answers[x1].min,'max':q.answers[x1].max,'step':q.answers[x1].step}; } - YAHOO.util.Event.addListener(q.answers[x1].id, "keyup", numberHandler, q.answers[x1]); + YAHOO.util.Event.addListener(q.answers[x1].id, "keydown", numberHandler, q.answers[x1]); } } continue;