diff --git a/application/helpers/expressions/em_manager_helper.php b/application/helpers/expressions/em_manager_helper.php index 4f2a2cd6259..fafebf76d58 100644 --- a/application/helpers/expressions/em_manager_helper.php +++ b/application/helpers/expressions/em_manager_helper.php @@ -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']); @@ -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 @@ -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) @@ -3300,7 +3305,7 @@ private function _ProcessRelevance($eqn,$questionNum=NULL,$gseq=NULL,$jsResultVa * @param $type - the type of sub-question relevance (e.g. 'array_filter', 'array_filter_exclude') * @return */ - 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') @@ -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(); } @@ -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; @@ -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']) { @@ -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"; + } + } } } @@ -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"; + } + } } } } diff --git a/application/helpers/qanda_helper.php b/application/helpers/qanda_helper.php index d0bf6a2e9fa..af1651f86d5 100644 --- a/application/helpers/qanda_helper.php +++ b/application/helpers/qanda_helper.php @@ -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, "");