diff --git a/application/helpers/SurveyRuntimeHelper.php b/application/helpers/SurveyRuntimeHelper.php index 0ffdb1a8476..b2bb1bd2dc6 100644 --- a/application/helpers/SurveyRuntimeHelper.php +++ b/application/helpers/SurveyRuntimeHelper.php @@ -975,78 +975,14 @@ function run($surveyid,$args) { // the runonce element has been changed from a hidden to a text/display:none one // in order to workaround an not-reproduced issue #4453 (lemeur) - echo " - - -END; $showpopups=Yii::app()->getConfig('showpopups'); //Display the "mandatory" message on page if necessary if (!$showpopups && $stepInfo['mandViolation'] && $okToShowErrors) diff --git a/application/helpers/expressions/em_core_helper.php b/application/helpers/expressions/em_core_helper.php index d3dea71d4fd..f28f938890d 100644 --- a/application/helpers/expressions/em_core_helper.php +++ b/application/helpers/expressions/em_core_helper.php @@ -268,14 +268,22 @@ private function RDP_EvaluateBinary(array $token) $this->RDP_AddError(gT("Invalid value(s) on the stack"), $token); return false; } - // TODO: try to determine datatype? - $bNumericArg1 = is_numeric($arg1[0]) || $arg1[0] == ''; - $bNumericArg2 = is_numeric($arg2[0]) || $arg2[0] == ''; + // Set bothnumeric only if set to numeric + // Not sure if needed to test if [2] is set. : TODO review + $bNumericArg1 = ((is_numeric($arg1[0]) || $arg1[0] == '') && (!isset($arg1[2]) || $arg1[2]=='NUMBER')); + $bNumericArg2 = ((is_numeric($arg2[0]) || $arg2[0] == '') && (!isset($arg2[2]) || $arg2[2]=='NUMBER')); $bStringArg1 = !$bNumericArg1 || $arg1[0] == ''; $bStringArg2 = !$bNumericArg2 || $arg2[0] == ''; $bBothNumeric = ($bNumericArg1 && $bNumericArg2); $bBothString = ($bStringArg1 && $bStringArg2); - $bMismatchType = (!$bBothNumeric && !$bBothString); + $bMismatchType=(!$bBothNumeric && !$bBothString); + if($bMismatchType){// Try same than JS: if can be numeric: convert to numeric else false + if((is_numeric($arg1[0]) || $arg1[0] == '') && (is_numeric($arg2[0]) || $arg2[0] == '')) + { + $bBothNumeric=true; + $bMismatchType=false; + } + } switch(strtolower($token[0])) { case 'or': @@ -296,7 +304,7 @@ private function RDP_EvaluateBinary(array $token) break; case '<': case 'lt': - if ($bMismatchType) { + if ($bMismatchType && false) { $result = array(false,$token[1],'NUMBER'); } else { @@ -335,7 +343,7 @@ private function RDP_EvaluateBinary(array $token) break; case '>='; case 'ge': - if ($bMismatchType) { + if ($bMismatchType && false) { $result = array(false,$token[1],'NUMBER'); } else { @@ -565,7 +573,8 @@ private function RDP_EvaluateConstantVarOrFunction() } if ($relStatus==1) { - $result = array($this->GetVarAttribute($token[0],NULL,''),$token[1],'NUMBER'); + $argtype=($this->GetVarAttribute($token[0],'onlynum'))?"NUMBER":"WORD"; + $result = array($this->GetVarAttribute($token[0],NULL,''),$token[1],$argtype); } else { diff --git a/application/helpers/expressions/em_manager_helper.php b/application/helpers/expressions/em_manager_helper.php index 9f36a43869c..347ef2d968d 100644 --- a/application/helpers/expressions/em_manager_helper.php +++ b/application/helpers/expressions/em_manager_helper.php @@ -1304,6 +1304,33 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL) // Default validation for question type switch ($type) { + case 'N': //NUMERICAL QUESTION TYPE + case 'K': //NUMERICAL QUESTION TYPE + if ($hasSubqs) { + $subqs = $qinfo['subqs']; + $sq_equs=array(); + foreach($subqs as $sq) + { + $sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK"; + if(($qinfo['mandatory']=='Y')){ + $sq_equs[] = 'is_numeric('.$sq_name.')'; + }else{ + $sq_equs[] = '( is_numeric('.$sq_name.') || is_empty('.$sq_name.') )'; + } + } + if (!isset($validationEqn[$questionNum])) + { + $validationEqn[$questionNum] = array(); + } + $validationEqn[$questionNum][] = array( + 'qtype' => $type, + 'type' => 'default', + 'class' => 'default', + 'eqn' => implode(' and ',$sq_equs), + 'qid' => $questionNum, + ); + } + break; case 'R': if ($hasSubqs) { $subqs = $qinfo['subqs']; @@ -1927,6 +1954,60 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL) $max_num_value_n=''; } + // num_value_int_only + // Validation fixnum(sqN)==int(fixnum(sqN)) : fixnum or not fix num ..... 10.00 == 10 + if (isset($qattr['num_value_int_only']) && trim($qattr['num_value_int_only']) == "1") + { + $num_value_int_only="1"; + if ($hasSubqs) { + $subqs = $qinfo['subqs']; + $sq_eqns = array(); + $subqValidEqns = array(); + foreach ($subqs as $sq) { + $sq_eqn=null; + switch ($type) + { + case 'N': //NUMERICAL QUESTION TYPE + case 'K': //MULTI NUMERICAL QUESTION TYPE (Need a attribute, not set in 131014) + $sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK"; + if(($qinfo['mandatory']=='Y')){ + $sq_eqn = 'is_int('.$sq_name.')'; + }else{ + $sq_eqn = 'is_int('.$sq_name.') || is_empty('.$sq_name.')'; + } + break; + default: + break; + } + if (!is_null($sq_eqn)) { + $sq_eqns[] = $sq_eqn; + $subqValidEqns[$subqValidSelector] = array( + 'subqValidEqn' => $sq_eqn, + 'subqValidSelector' => $subqValidSelector, + ); + } + } + if (count($sq_eqns) > 0) { + if (!isset($validationEqn[$questionNum])) + { + $validationEqn[$questionNum] = array(); + } + $validationEqn[$questionNum][] = array( + 'qtype' => $type, + 'type' => 'num_value_int_only', + 'class' => 'value_integer', + 'eqn' => implode(' and ', $sq_eqns), + 'qid' => $questionNum, + 'subqValidEqns' => $subqValidEqns, + ); + } + } + } + else + { + $num_value_int_only=''; + } + // min_num_value // Validation:= sum(sq1,...,sqN) >= value (which could be an expression). if (isset($qattr['min_num_value']) && trim($qattr['min_num_value']) != '') @@ -2557,6 +2638,12 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL) // Default validation qtip without attribute switch ($type) { + case 'N': + $qtips['default']=$this->gT("Only numbers may be entered in this field."); + break; + case 'K': + $qtips['default']=$this->gT("Only numbers may be entered in these fields."); + break; case 'R': $qtips['default']=$this->gT("All your answers must be different."); break; @@ -2607,6 +2694,12 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL) "{if(!is_empty($_minV) && !is_empty($_maxV) && ($_minV) != ($_maxV), sprintf('".$this->gT("Each answer must be between %s and %s")."', fixnum($_minV), fixnum($_maxV)), '')}"; } + // integer for numeric + if ($num_value_int_only!='') + { + $qtips['value_integer']=$this->gT("Only integer value"); + } + // min/max value for each numeric entry - for multi-flexible question type if ($multiflexible_min!='' || $multiflexible_max!='') { @@ -7733,17 +7826,17 @@ static function ProcessCurrentResponses() } $aDateFormatData=getDateFormatDataForQID($aAttributes[$qid],$LEM->surveyOptions); $oDateTimeConverter = new Date_Time_Converter($value, $aDateFormatData['phpdate']); - $value=$oDateTimeConverter->convert("Y-m-d H:i"); + $value=$oDateTimeConverter->convert("Y-m-d H:i"); // TODO : control if inverse function original value } break; - case 'N': //NUMERICAL QUESTION TYPE - case 'K': //MULTIPLE NUMERICAL QUESTION - if (trim($value)=="") { - $value = ""; - } - else { - $value = sanitize_float($value); - } +# case 'N': //NUMERICAL QUESTION TYPE +# case 'K': //MULTIPLE NUMERICAL QUESTION +# if (trim($value)=="") { +# $value = ""; +# } +# else { +# $value = sanitize_float($value); +# } break; case '|': //File Upload if (!preg_match('/_filecount$/', $sq)) @@ -8116,6 +8209,9 @@ private function _GetVarAttribute($name,$attr,$default,$gseq,$qseq) $qrel = (isset($_SESSION[$this->sessid]['relevanceStatus'][$qid]) ? $_SESSION[$this->sessid]['relevanceStatus'][$qid] : 0); $sqrel = (isset($_SESSION[$this->sessid]['relevanceStatus'][$rowdivid]) ? $_SESSION[$this->sessid]['relevanceStatus'][$rowdivid] : 1); // true by default - only want false if a subquestion is irrelevant return ($grel && $qrel && $sqrel); + case 'onlynum': + return (isset($var[$attr])) ? $var[$attr] : $default; + break; default: print 'UNDEFINED ATTRIBUTE: ' . $attr . "
\n"; return $default; @@ -8224,7 +8320,7 @@ static public function ShowSurveyLogicFile($sid, $gid=NULL, $qid=NULL,$LEMdebugL $LEM =& LimeExpressionManager::singleton(); - $aSurveyInfo=getSurveyInfo($sid, $_SESSION['LEMlang']); + $aSurveyInfo=getSurveyInfo($sid,$_SESSION['LEMlang']); $allErrors = array(); $warnings = 0; diff --git a/application/helpers/qanda_helper.php b/application/helpers/qanda_helper.php index 29419eb9184..bd47abb471b 100644 --- a/application/helpers/qanda_helper.php +++ b/application/helpers/qanda_helper.php @@ -3251,10 +3251,6 @@ function do_multiplenumeric($ia) $inputnames[]=$myfname; } $question_tip = ''; - if(!$hidetip) - { - $question_tip .= '

'.$clang->gT('Only numbers may be entered in these fields')."

\n"; - } if (trim($aQuestionAttributes['equals_num_value']) != '' || trim($aQuestionAttributes['min_num_value']) != '' @@ -3394,7 +3390,7 @@ function do_numerical($ia) $answertypeclass .= " integeronly"; if(is_numeric($fValue)) { - $fValue=number_format($fValue, 0, '', ''); + //$fValue=number_format($fValue, 0, '', ''); } $integeronly=1; } @@ -3407,6 +3403,7 @@ function do_numerical($ia) $sSeparator = getRadixPointData($thissurvey['surveyls_numberformat']); $sSeparator = $sSeparator['separator']; + $fValue = rtrim(trim($fValue,"0"),"."); $fValue = str_replace('.',$sSeparator,$fValue); if ($thissurvey['nokeyboard']=='Y') @@ -3425,10 +3422,6 @@ function do_numerical($ia) . "gT('Only numbers may be entered in this field.')."\" " . "id=\"answer{$ia[1]}\" value=\"{$fValue}\" onkeyup=\"{$checkconditionFunction}(this.value, this.name, this.type,'onchange',{$integeronly})\" " . " {$maxlength} />\t{$suffix}\n

\n"; - if ($aQuestionAttributes['hide_tip']==0) - { - $answer .= "

".$clang->gT('Only numbers may be entered in this field.')."

\n"; - } // --> END NEW FEATURE - SAVE $inputnames[]=$ia[1]; diff --git a/scripts/expressions/em_javascript.js b/scripts/expressions/em_javascript.js index 108362cf4da..71c817a515e 100644 --- a/scripts/expressions/em_javascript.js +++ b/scripts/expressions/em_javascript.js @@ -356,6 +356,7 @@ function LEMval(alias) var str = new String(alias); var varName = alias; var suffix = 'code'; // the default + if(typeof bNumRealValue == 'undefined'){bNumRealValue=false;} // Allow to update {QCODE} even with text /* If passed a number, return that number */ if (str == '') return ''; @@ -570,15 +571,35 @@ function LEMval(alias) break; } } - if (typeof attr.onlynum !== 'undefined' && attr.onlynum==1) { - newval = value; + if(value=="") + { + return ""; + } if (LEMradix === ',') { - newval = value.split(',').join('.'); + var regValidateNum = /^-?\d*\,?\d*$/; + }else{ + var regValidateNum = /^-?\d*\.?\d*$/; } - if (newval != parseFloat(newval)) { - newval = ''; + if(!regValidateNum.test(value)) + { + if(bNumRealValue) + { + return value; + } + else + { + return ''; + } } + newval=value; + if (LEMradix === ',') { + newval = value.split(',').join('.'); + } +// Already sone with regValidateNum.test(value) +// if (newval != parseFloat(newval)) { +// return ''; +// } return +newval; } else if (isNaN(value)) { @@ -591,7 +612,7 @@ function LEMval(alias) if (value.length > 0 && value[0]==0) { return value; // so keep 0 prefixes on numbers } - return +value; // convert it to numeric return type + return ''+value; // convert it to string return type: because we need string compare } } case 'rowdivid': @@ -614,7 +635,9 @@ function LEMfixnum(value) } if (LEMradix===',') { newval = newval.split('.').join(','); - return newval; + if (parseFloat(newval) != value) { + return value; // unchanged + } } return value; } diff --git a/scripts/survey_runtime.js b/scripts/survey_runtime.js index e941461dabf..e1b67b433f1 100644 --- a/scripts/survey_runtime.js +++ b/scripts/survey_runtime.js @@ -106,6 +106,88 @@ function needConfirmHandler(){ }); }); } +/** + * checkconditions : javascript function attach to some element + * Launch ExprMgr_process_relevance_and_tailoring with good value + */ +function checkconditions(value, name, type, evt_type) +{ + if (typeof evt_type === 'undefined') + { + evt_type = 'onchange'; + } + if (type == 'radio' || type == 'select-one') + { + $('#java'+name).val(value); + } + else if (type == 'checkbox') + { + if ($('#answer'+name).is(':checked')) + { + $('#java'+name).val('Y'); + } else + { + $('#java'+name).val(''); + } + } + else if (type == 'text' && name.match(/other$/)) + { + $('#java'+name).val(value); + } + if($.isFunction(window.ExprMgr_process_relevance_and_tailoring )) + ExprMgr_process_relevance_and_tailoring(evt_type,name,type); +} +/** + * fixnum_checkconditions : javascript function attach to some element + * Update the answer of the user to be numeric and launch checkconditions + */ +function fixnum_checkconditions(value, name, type, evt_type, intonly) +{ + if(typeof bFixNumAuto == 'undefined'){bFixNumAuto=true;} // Allow deactivate fixnum in template or in Plugin + if(typeof bNumRealValue == 'undefined'){bNumRealValue=false;} // Allow to update {QCODE} even with text + + newval = new String(value); + if (typeof intonly !=='undefined' && intonly==1) { + newval = newval.replace(intRegex,''); + } + else { + newval = newval.replace(numRegex,''); + } + aNewval = newval.split(LEMradix); + if(aNewval.length>0){ + newval=aNewval[0]; + } + if(aNewval.length>1){ + newval=newval+"."+aNewval[1]; + } + if (newval != '-' && newval != '.' && newval != '-.' && newval != parseFloat(newval)) {// Todo : do it in reg + newval = ''; + } + if(bFixNumAuto) + { + displayVal = newval; + if (LEMradix === ',') { + displayVal = displayVal.split('.').join(','); + } + if (name.match(/other$/)) { + $('#answer'+name+'text').val(displayVal); + } + $('#answer'+name).val(displayVal); + } + if (typeof evt_type === 'undefined') + { + evt_type = 'onchange'; + } + console.log(newval); + if(bNumRealValue) + { + checkconditions(value, name, type, evt_type); + } + else + { + checkconditions(newval, name, type, evt_type); + } +} // Set jquery-ui to LS Button function navbuttonsJqueryUi(){