Skip to content

Commit

Permalink
Fixed issue #05943: exclusive option in multiple choice hide all othe…
Browse files Browse the repository at this point in the history
…r answer options
  • Loading branch information
TMSWhite committed May 15, 2012
1 parent ae7e851 commit c16bb49
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 32 deletions.
128 changes: 97 additions & 31 deletions application/helpers/expressions/em_manager_helper.php
Expand Up @@ -1167,6 +1167,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 @@ -1221,6 +1222,8 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL)
}

// exclude_all_others_auto
// 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
// TODO

// min_answers
Expand Down Expand Up @@ -2252,37 +2255,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 @@ -3300,7 +3305,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 @@ -3327,6 +3332,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 @@ -3343,6 +3362,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 @@ -5626,11 +5647,40 @@ static function GetRelevanceAndTailoringJavaScript()

$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 @@ -5931,6 +5981,14 @@ static function GetRelevanceAndTailoringJavaScript()
if ($_val==1)
{
$jsParts[] = " LEMrel" . $_qid . "(sgqa);\n";
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 @@ -5948,6 +6006,14 @@ static function GetRelevanceAndTailoringJavaScript()
if ($_val == 1)
{
$jsParts[] = " LEMrel" . $_qid . "(sgqa);\n";
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 Down
27 changes: 26 additions & 1 deletion application/helpers/qanda_helper.php
Expand Up @@ -888,7 +888,32 @@ function return_array_filter_strings($ia, $aQuestionAttributes, $thissurvey, $an
$htmltbody2 .= ($class !== null) ? " class='$class'": "";
if (isset($_SESSION['relevanceStatus'][$rowname]) && !$_SESSION['relevanceStatus'][$rowname])
{
$htmltbody2 .= " style='display: none'";
// If using exclude_all_others, then need to know whether irrelevant rows should be hidden or disabled
if (isset($aQuestionAttributes['exclude_all_others']))
{
$disableit=false;
foreach(explode(';',trim($aQuestionAttributes['exclude_all_others'])) as $eo)
{
$eorow = $ia[1] . $eo;
if ((!isset($_SESSION['relevanceStatus'][$eorow]) || $_SESSION['relevanceStatus'][$eorow])
&& (isset($_SESSION[$eorow]) && $_SESSION[$eorow] == "Y"))
{
$disableit = true;
}
}
if ($disableit)
{
$htmltbody2 .= " disabled='disabled'";
}
else
{
$htmltbody2 .= " style='display: none'";
}
}
else
{
$htmltbody2 .= " style='display: none'";
}
}
$htmltbody2 .= ">\n";
return array($htmltbody2, "");
Expand Down

0 comments on commit c16bb49

Please sign in to comment.