Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
c-schmitz committed May 15, 2012
2 parents f67c115 + 4627d34 commit 0a086ac
Show file tree
Hide file tree
Showing 6 changed files with 12,343 additions and 52 deletions.
2 changes: 1 addition & 1 deletion admin/scripts/answers.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function addinput()
languages=langs.split(';');

sNextCode=getNextCode($(this).parent().parent().find('.code').val());
while ($(this).parent().parent().parent().find('input[value="'+sNextCode+'"]').length>0)
while ($(this).parent().parent().parent().find('input[value="'+sNextCode+'"]').length>0 && sNextCode!=$(this).parent().parent().find('.code').val())
{
sNextCode=getNextCode(sNextCode);
}
Expand Down
2 changes: 1 addition & 1 deletion admin/scripts/subquestions.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function addinput()
languages=langs.split(';');

nextcode=getNextCode($(this).parent().parent().find('.code').val());
while ($(this).parent().parent().parent().find('input[value="'+nextcode+'"]').length>0)
while ($(this).parent().parent().parent().find('input[value="'+nextcode+'"]').length>0 && nextcode!=$(this).parent().parent().find('.code').val())
{
nextcode=getNextCode(nextcode);
}
Expand Down
206 changes: 172 additions & 34 deletions classes/expressions/LimeExpressionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,12 @@ class LimeExpressionManager {
* @var array
*/
private $qrootVarName2arrayFilter = array();
/**
* Array, keyed on qid, to JavaScript needed to implement exclude_all_others_auto
* @var type
*/
private $qid2exclusiveAutoJS = array();


/**
* A private constructor; prevents direct creation of object
Expand Down Expand Up @@ -1154,6 +1160,7 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL)
}

// exclude_all_others
// If any excluded options are true (and relevant), then disable all other input elements for that question
if (isset($qattr['exclude_all_others']) && trim($qattr['exclude_all_others']) != '')
{
$exclusive_options = explode(';',$qattr['exclude_all_others']);
Expand Down Expand Up @@ -1208,7 +1215,64 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL)
}

// exclude_all_others_auto
// TODO
// if (count(this.relevanceStatus) == count(this)) { set exclusive option value to "Y" and call checkconditions() }
// However, note that would need to blank the values, not use relevance, otherwise can't unclick the _auto option without having it re-enable itself
if (isset($qattr['exclude_all_others_auto']) && trim($qattr['exclude_all_others_auto']) != ''
&& isset($qattr['exclude_all_others']) && count(explode(';',trim($qattr['exclude_all_others']))) == 1)
{
$exclusive_option = trim($qattr['exclude_all_others']);
if ($hasSubqs) {
$subqs = $qinfo['subqs'];
$sq_names = array();
foreach ($subqs as $sq) {
$sq_name = NULL;
switch ($type)
{
case 'M': //Multiple choice checkbox
if ($this->sgqaNaming)
{
$sq_name = substr($sq['jsVarName'],4);
}
else
{
$sq_name = $sq['varName'];
}
break;
default:
break;
}
if (!is_null($sq_name))
{
if ($sq['csuffix'] == $exclusive_option)
{
$eoVarName = substr($sq['jsVarName'],4);
}
else
{
$sq_names[] = $sq_name;
}
}
}
if (count($sq_names) > 0) {
$relpart = "LEMsum(LEMval('" . implode(".relevanceStatus'), LEMval('", $sq_names) . ".relevanceStatus'))";
$checkedpart = "LEMcount(LEMval('" . implode("'), LEMval('", $sq_names) . "'))";
$eoRelevantAndUnchecked = "(LEMval('" . $eoVarName . ".relevanceStatus') && LEMval('" . $eoVarName . "')=='')";
$eosaJS = "if (" . $eoRelevantAndUnchecked . " && (" . $relpart . " == " . $checkedpart . ")) {\n";
// Unset all checkboxes and hidden values for this question (irregardless of whether they are array filtered)
$eosaJS .=" $('#question" . $questionNum . " [type=checkbox]').attr('checked',false);\n";
$eosaJS .=" $('#java" . $qinfo['sgqa'] . "other').val('');\n";
$eosaJS .=" $('#answer" . $qinfo['sgqa'] . "other').val('');\n";
$eosaJS .=" $('[id^=java" . $qinfo['sgqa'] . "]').val('');\n";
$eosaJS .=" $('#answer" . $eoVarName . "').attr('checked',true);\n";
$eosaJS .=" $('#java" . $eoVarName . "').val('Y');\n";
$eosaJS .=" LEMrel" . $questionNum . "();\n";
$eosaJS .=" relChange" . $questionNum ."=true;\n";
$eosaJS .="}\n";

$this->qid2exclusiveAutoJS[$questionNum] = $eosaJS;
}
}
}

// min_answers
// Validation:= count(sq1,...,sqN) >= value (which could be an expression).
Expand Down Expand Up @@ -2236,37 +2300,39 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL)
$order=0;
foreach ($subQrels as $sq)
{
if (isset($rowdivids[$sq['rowdivid']]))
{
$backup = $rowdivids[$sq['rowdivid']];
$rowdivids[$sq['rowdivid']] = array(
'order'=>$backup['order'],
'qid'=>$sq['qid'],
'rowdivid'=>$sq['rowdivid'],
'type'=>$backup['type'] . ';' .$sq['type'],
'qtype'=>$sq['qtype'],
'sgqa'=>$sq['sgqa'],
'eqns' => array_merge($backup['eqns'],array($sq['eqn'])),
);
}
else
{
$rowdivids[$sq['rowdivid']] = array(
'order'=>$order++,
'qid'=>$sq['qid'],
'rowdivid'=>$sq['rowdivid'],
'type'=>$sq['type'],
'qtype'=>$sq['qtype'],
'sgqa'=>$sq['sgqa'],
'eqns'=>array($sq['eqn']),
);
}
$oldeqn = (isset($rowdivids[$sq['rowdivid']]['eqns']) ? $rowdivids[$sq['rowdivid']]['eqns'] : array());
$oldtype = (isset($rowdivids[$sq['rowdivid']]['type']) ? $rowdivids[$sq['rowdivid']]['type'] : '');
$neweqn = (($sq['type'] == 'exclude_all_others') ? array() : array($sq['eqn']));
$oldeo = (isset($rowdivids[$sq['rowdivid']]['exclusive_options']) ? $rowdivids[$sq['rowdivid']]['exclusive_options'] : array());
$neweo = (($sq['type'] == 'exclude_all_others') ? array($sq['eqn']) : array());
$rowdivids[$sq['rowdivid']] = array(
'order'=>$order++,
'qid'=>$sq['qid'],
'rowdivid'=>$sq['rowdivid'],
'type'=>$sq['type'] . ';' . $oldtype,
'qtype'=>$sq['qtype'],
'sgqa'=>$sq['sgqa'],
'eqns'=>array_merge($oldeqn, $neweqn),
'exclusive_options'=>array_merge($oldeo, $neweo),
);
}

foreach ($rowdivids as $sq)
{
$sq['eqn'] = '(' . implode(' and ', array_unique($sq['eqns'])) . ')'; // without array_unique, get duplicate of filters for question types 1, :, and ;
$result = $this->_ProcessSubQRelevance($sq['eqn'], $sq['qid'], $sq['rowdivid'], $sq['type'], $sq['qtype'], $sq['sgqa']);
$sq['eqn'] = implode(' and ', array_unique(array_merge($sq['eqns'],$sq['exclusive_options']))); // without array_unique, get duplicate of filters for question types 1, :, and ;
$eos = array_unique($sq['exclusive_options']);
$isExclusive = '';
$irrelevantAndExclusive = '';
if (count($eos) > 0)
{
$isExclusive = '!(' . implode(' and ', $eos) . ')';
$noneos = array_unique($sq['eqns']);
if (count($noneos) > 0)
{
$irrelevantAndExclusive = '(' . implode(' and ', $noneos) . ') and ' . $isExclusive;
}
}
$this->_ProcessSubQRelevance($sq['eqn'], $sq['qid'], $sq['rowdivid'], $sq['type'], $sq['qtype'], $sq['sgqa'], $isExclusive, $irrelevantAndExclusive);
}

foreach ($validationEqn as $qid=>$eqns)
Expand Down Expand Up @@ -3293,7 +3359,7 @@ private function _ProcessRelevance($eqn,$questionNum=NULL,$gseq=NULL,$jsResultVa
* @param <type> $type - the type of sub-question relevance (e.g. 'array_filter', 'array_filter_exclude')
* @return <type>
*/
private function _ProcessSubQRelevance($eqn,$questionNum=NULL,$rowdivid=NULL, $type=NULL, $qtype=NULL, $sgqa=NULL)
private function _ProcessSubQRelevance($eqn,$questionNum=NULL,$rowdivid=NULL, $type=NULL, $qtype=NULL, $sgqa=NULL, $isExclusive='', $irrelevantAndExclusive='')
{
// These will be called in the order that questions are supposed to be asked
if (!isset($eqn) || trim($eqn=='') || trim($eqn)=='1')
Expand All @@ -3320,6 +3386,20 @@ private function _ProcessSubQRelevance($eqn,$questionNum=NULL,$rowdivid=NULL, $t
$relevanceVars = implode('|',$this->em->GetJSVarsUsed());
$relevanceJS = $this->em->GetJavaScriptEquivalentOfExpression();

$isExclusiveJS='';
$irrelevantAndExclusiveJS='';
// Only need to extract JS, since will already have Vars and error counts from main equation
if ($isExclusive != '')
{
$this->em->ProcessBooleanExpression($isExclusive,$groupSeq, $questionSeq);
$isExclusiveJS = $this->em->GetJavaScriptEquivalentOfExpression();
}
if ($irrelevantAndExclusive != '')
{
$this->em->ProcessBooleanExpression($irrelevantAndExclusive,$groupSeq, $questionSeq);
$irrelevantAndExclusiveJS = $this->em->GetJavaScriptEquivalentOfExpression();
}

if (!isset($this->subQrelInfo[$questionNum])) {
$this->subQrelInfo[$questionNum] = array();
}
Expand All @@ -3336,6 +3416,8 @@ private function _ProcessSubQRelevance($eqn,$questionNum=NULL,$rowdivid=NULL, $t
'qtype'=>$qtype,
'sgqa'=>$sgqa,
'hasErrors'=>$hasErrors,
'isExclusiveJS'=>$isExclusiveJS,
'irrelevantAndExclusiveJS'=>$irrelevantAndExclusiveJS,
);
}
return $result;
Expand Down Expand Up @@ -3412,6 +3494,7 @@ static function StartProcessingPage($allOnOnePage=false,$rooturl=NULL, $initiali
$LEM->surveyOptions['rooturl'] = $rooturl;
$LEM->surveyOptions['hyperlinkSyntaxHighlighting']=true; // this will be temporary - should be reset in running survey
}
$LEM->qid2exclusiveAutoJS=array();

// $LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now));

Expand Down Expand Up @@ -5618,14 +5701,43 @@ static function GetRelevanceAndTailoringJavaScript()
foreach ($subqParts as $sq)
{
$rowdividList[$sq['rowdivid']] = $sq['result'];

$relParts[] = " if ( " . $sq['relevancejs'] . " ) {\n";
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . "').show();\n";
$relParts[] = " if ($('#relevance" . $sq['rowdivid'] . "').val()!='1') { relChange" . $arg['qid'] . "=true; }\n";
if ($sq['isExclusiveJS'] != '')
{
$relParts[] = " if ( " . $sq['isExclusiveJS'] . " ) {\n";
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . " :input:not(:hidden)').attr('disabled','disabled');\n";
$relParts[] = " }\n";
$relParts[] = " else {\n";
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . " :input:not(:hidden)').removeAttr('disabled');\n";
$relParts[] = " }\n";
}
$relParts[] = " relChange" . $arg['qid'] . "=true;\n";
$relParts[] = " $('#relevance" . $sq['rowdivid'] . "').val('1');\n";
$relParts[] = " }\n else {\n";
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . "').hide();\n";
$relParts[] = " if ($('#relevance" . $sq['rowdivid'] . "').val()=='1') { relChange" . $arg['qid'] . "=true; }\n";
if ($sq['isExclusiveJS'] != '')
{
if ($sq['irrelevantAndExclusiveJS'] != '')
{
$relParts[] = " if ( " . $sq['irrelevantAndExclusiveJS'] . " ) {\n";
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . " :input:not(:hidden)').attr('disabled','disabled');\n";
$relParts[] = " }\n";
$relParts[] = " else {\n";
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . " :input:not(:hidden)').removeAttr('disabled');\n";
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . "').hide();\n";
$relParts[] = " }\n";
}
else
{
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . " :input:not(:hidden)').attr('disabled','disabled');\n";
}
}
else
{
$relParts[] = " $('#javatbd" . $sq['rowdivid'] . "').hide();\n";
}
$relParts[] = " relChange" . $arg['qid'] . "=true;\n";
$relParts[] = " $('#relevance" . $sq['rowdivid'] . "').val('');\n";
switch ($sq['qtype'])
{
Expand Down Expand Up @@ -5927,6 +6039,19 @@ static function GetRelevanceAndTailoringJavaScript()
if ($_val==1)
{
$jsParts[] = " LEMrel" . $_qid . "(sgqa);\n";
if (isset($LEM->qattr[$_qid]['exclude_all_others_auto']) && $LEM->qattr[$_qid]['exclude_all_others_auto'] == '1'
&& isset($LEM->qid2exclusiveAutoJS[$_qid]) && strlen($LEM->qid2exclusiveAutoJS[$_qid]) > 0)
{
$jsParts[] = $LEM->qid2exclusiveAutoJS[$_qid];
}
if (isset($LEM->qattr[$_qid]['exclude_all_others']))
{
foreach (explode(';',trim($LEM->qattr[$_qid]['exclude_all_others'])) as $eo)
{
// then need to call the function twice so that cascading of array filter onto an excluded option works
$jsParts[] = " LEMrel" . $_qid . "(sgqa);\n";
}
}
}
}

Expand All @@ -5944,6 +6069,19 @@ static function GetRelevanceAndTailoringJavaScript()
if ($_val == 1)
{
$jsParts[] = " LEMrel" . $_qid . "(sgqa);\n";
if (isset($LEM->qattr[$_qid]['exclude_all_others_auto']) && $LEM->qattr[$_qid]['exclude_all_others_auto'] == '1'
&& isset($LEM->qid2exclusiveAutoJS[$_qid]) && strlen($LEM->qid2exclusiveAutoJS[$_qid]) > 0)
{
$jsParts[] = $LEM->qid2exclusiveAutoJS[$_qid];
}
if (isset($LEM->qattr[$_qid]['exclude_all_others']))
{
foreach (explode(';',trim($LEM->qattr[$_qid]['exclude_all_others'])) as $eo)
{
// then need to call the function twice so that cascading of array filter onto an excluded option works
$jsParts[] = " LEMrel" . $_qid . "(sgqa);\n";
}
}
}
}
}
Expand All @@ -5968,7 +6106,7 @@ static function GetRelevanceAndTailoringJavaScript()
$jsParts[] = " $('#relevanceG" . $gr['gseq'] . "').val(0);\n";
$jsParts[] = "}\n";
}

// now make sure any needed variables are accessible
$vars = explode('|',$gr['relevanceVars']);
if (is_array($vars))
Expand Down

0 comments on commit 0a086ac

Please sign in to comment.