getDocument()->getWebAssetManager(); $visforms = $displayData['visforms']; $vfObjForJs = new stdClass(); $vfObjForJs->fid = $visforms->id; $textareaRequired = $displayData['textareaRequired']; $hasHTMLEditor = $displayData['hasHTMLEditor']; $vfObjForJs->initEditor = ($displayData['textareaRequired'] == true || $displayData['hasHTMLEditor'] == true) ? true : false; $parentFormId = $displayData['parentFormId']; $vfObjForJs->parentFormId = $displayData['parentFormId']; $steps = $displayData['steps']; $vfObjForJs->steps = $displayData['steps']; $nbFields = count($visforms->fields); $vfObjForJs->nbFields = count($visforms->fields); $vfObjForJs->summaryLayout = (!empty($visforms->summarytag)) ? $visforms->summarytag: 'table' ; $vfObjForJs->summaryLayoutClass = (!empty($visforms->summarylayoutclass)) ? (($vfObjForJs->summaryLayout == 'table') ? $visforms->summarylayoutclass . ' table' : $visforms->summarylayoutclass) : (($vfObjForJs->summaryLayout == 'table') ? 'table' : ''); $summaryRowLayout = 'tr'; $oSummaryFirstElementLayout = ''; $cSummaryFirstElementLayout = ''; $oSummarySecondElementLayout = ''; $cSummarySecondElementLayout = ''; if ((!empty($visforms->summarytag))) { switch ($visforms->summarytag) { case 'dl' : $summaryRowLayout = ''; $oSummaryFirstElementLayout = '
'; $cSummaryFirstElementLayout = '
'; $oSummarySecondElementLayout = '
'; $cSummarySecondElementLayout = '
'; break; case 'ul' : case 'ol' : $summaryRowLayout = 'li'; $oSummaryFirstElementLayout = ''; $cSummaryFirstElementLayout = ''; $oSummarySecondElementLayout = ''; $cSummarySecondElementLayout = ''; break; case 'div' : $summaryRowLayout = 'p'; $oSummaryFirstElementLayout = ''; $cSummaryFirstElementLayout = ''; $oSummarySecondElementLayout = ''; $cSummarySecondElementLayout = ''; break; default : break; } } $vfObjForJs->summaryRowLayout = $summaryRowLayout; $vfObjForJs->oSummaryFirstElementLayout = $oSummaryFirstElementLayout; $vfObjForJs->cSummaryFirstElementLayout = $cSummaryFirstElementLayout; $vfObjForJs->oSummarySecondElementLayout = $oSummarySecondElementLayout; $vfObjForJs->cSummarySecondElementLayout = $cSummarySecondElementLayout; $vfObjForJs->displaysummarypage = (!empty($visforms->displaysummarypage)) ? true : false; $vfObjForJs->hideemptyfieldsinsummary = (!empty($visforms->hideemptyfieldsinsummary)) ? true : false; $vfObjForJs->summaryemptycaliszero = (!empty($visforms->summaryemptycaliszero) && (!empty($visforms->hideemptyfieldsinsummary))) ? true : false; $fieldsForJsa = array(); $userinputsa = array(); $restrictData = array(); for ($i = 0; $i < $nbFields; $i++) { $field = $visforms->fields[$i]; if (isset($field->userInput)) { $userinputsa[] = json_encode(array( 'type' => $field->typefield, 'label' =>'field'. $field->id, // value can either be a string or an array (select, checkbox group), therefore use JSON_FORCE_OBJECT on json_encode 'value' => $field->userInput, 'isDisabled' => ((!empty($field->isDisabled)) ? true : false), 'isForbidden' => ((!empty($field->isForbidden)) ? true : false)), JSON_FORCE_OBJECT); } if (isset($field->showWhenForForm) && (is_array($field->showWhenForForm))) { $restrictData[] = 'field' . $field->id . ' : ' . '"' . implode(', ', $field->showWhenForForm) . '"'; } // enclose all keys in "" if converted to JSON-String with registry later $summaryLabel = (empty($field->customlabelforsummarypage)) ? $field->label : $field->customlabelforsummarypage; $fieldsForJsa[] = array('id' => (int) $field->id, 'type' => $field->typefield ,'label'=> $summaryLabel); } $userinputss = implode(',', $userinputsa); $userinputs = "[" . $userinputss . "]"; $restrictDataString = "{" . implode(", ", $restrictData) . "}"; $vfObjForJs->fields = $fieldsForJsa; $jsonform = json_encode($vfObjForJs, JSON_FORCE_OBJECT); if ($textareaRequired == true || $hasHTMLEditor == true) { // we need an editor and create a simple tinyMCE editor EditorHelper::initEditor(); } $js = ' jQuery(document).ready(function () { jQuery("#' .$parentFormId. '").validate({ submitHandler: function (form) { var returnVal = true; if (window["' .$parentFormId. 'SubmitAction"] && typeof window["' .$parentFormId. 'SubmitAction"] === "function") { returnVal = window["' .$parentFormId. 'SubmitAction"](this); } if (!returnVal) { return false; } // invisible Recaptcha execute() callback handler // only loaded, when the selected captcha option is "invisible recaptcha" if (window["VfInitIGReCaptcha"] && typeof window["VfInitIGReCaptcha"] === "function") { grecaptcha.execute(); return false; } form.submit(); jQuery(form).find(\'input[type="submit"]\').prop("disabled", true); jQuery(form).find(\'input[type="reset"]\').prop("disabled", true); jQuery(form).find(\'input[type="image"]\').prop("disabled", true); '; if (!empty($visforms->showmessageformprocessing)) { $js .= 'visForm.showProcessFormMsg("' .$parentFormId. '"); '; } $js .= '}, // errorElement: \'span\', ignoreTitle: true, wrapper: "p", // absolutly necessary when working with tinymce! ignore: ".ignore, input[type=\"button\"]", rules: { '; // insert rules that we cannot put into html attributes because they are no valid attributs or valid attribute values for ($i = 0; $i < $nbFields; $i++) { $field = $visforms->fields[$i]; if (isset($field->validateArray)) { if (isset($field->typefield) && ($field->typefield == "select" || $field->typefield == "selectsql" || $field->typefield == "multicheckbox") || $field->typefield == "multicheckboxsql" || $field->typefield == 'location') { $js .= ' "' . $field->name . '[]": { '; } else if ( $field->typefield == 'email' && array_key_exists('mailExists', $field->validateArray)) { $js .= ' "' . $field->name . '_code" : { '; } else { $js .= ' "' . $field->name . '" : { '; } foreach ($field->validateArray as $n => $v) { if ($n == 'geolocation') { // geolocation is a dummy value used to get a value in validateArray for location fields $js .= ' ispair: "field' . $field->id.'", '; } else if ($n == 'mailExists') { $js .= ' "remote": { url : "'. Uri::root(true) .'/index.php?option=com_visforms&task=visforms.checkVerificationCode", type: "post", data : {verificationAddr: function () {return document.getElementById("field' . $field->id.'").value;}, code : function () {return document.getElementById("field' . $field->id.'_code").value;}, fid: '.$visforms->id. ', "'.Session::getFormToken().'" : 1}, dataFilter: function (data) {if (data === "1") {return true;} else {return false}}}'; } else if (($n == "equalTo") || ($n == "remote")) { $js .= $n . ': "' . $v . '", '; } else { $js .= $n . ': ' . $v . ', '; } } $js .= '}, '; unset($n); unset($v); } } // add required for hcaptcha if (isset($visforms->captcha)) { if ($visforms->captcha == 3) { $js .= '"h-captcha-response" : { required : true}, '; } if ($visforms->captcha == 4 ) { $js .= '"g-recaptcha-response" : { required : true}, '; } } $js .= '}, messages: { '; // ToDo replace all possible occurrences of @ in error message, because Joomla email cloaking will break javascript // Add field type specific Visforms error messages (Language tags can be modified, using Joomla language manager). for ($i = 0; $i < $nbFields; $i++) { $field = $visforms->fields[$i]; // Field type specific Visforms error messages for date fields if (isset($field->typefield) && $field->typefield == "date" && !(isset($field->customErrorMsgArray))) { if (isset($field->dateFormatJs) || (isset($field->validateArray) && array_key_exists('minage', $field->validateArray))) { $js .= ' "' . $field->name . '" : { '; if (isset($field->dateFormatJs)) { switch ($field->dateFormatJs) { case "%d.%m.%Y": $js .= ' dateDMY: "' . addslashes(Text::sprintf('COM_VISFORMS_ENTER_VALID_DATE_FORMAT', 'dd.mm.YYYY')) . '", '; break; case "%m/%d/%Y": $js .= ' dateMDY: "' . addslashes(Text::sprintf('COM_VISFORMS_ENTER_VALID_DATE_FORMAT', 'mm/dd/YYYY')) . '", '; break; case "%Y-%m-%d": $js .= ' dateYMD: "' . addslashes(Text::sprintf('COM_VISFORMS_ENTER_VALID_DATE_FORMAT', 'YYYY-mm-dd')) . '", '; break; } } if (isset($field->validateArray) && array_key_exists('minage', $field->validateArray)) { $js .= ' minage: "' . addslashes(Text::sprintf('COM_VISFORMS_MINAGE_VALIDATION_FAILED_JS', $field->minage)) . '", '; } $js .= ' }, '; } } else if (isset($field->typefield) && $field->typefield == "tel" && !(isset($field->customErrorMsgArray)) && (isset($field->validateArray) && array_key_exists('phonevalidation', $field->validateArray))) { $js .= '"' . $field->name . '" : { phonevalidation: "' . addslashes(Text::sprintf('COM_VISFORMS_PHONENUMBER_FORMAT_VALIDATION_FAILED_JS', $field->phonevalidation, Text::_("COM_VISFORMS_PHONE_NUMBER_FORMAT_".$field->phonevalidation))) . '" }, '; } else if (isset($field->typefield) && $field->typefield == "file" && !(isset($field->customErrorMsgArray))) { $js .= '"' . $field->name . '" : { filesize: "' . addslashes(Text::sprintf('COM_VISFORMS_JS_ERROR_WARNFILETOOLARGE', ($field->maxfilesize))) . '" , '; $js .= ' fileextension: "' . addslashes(Text::sprintf('COM_VISFORMS_JS_ERROR_WARNFILETYPE', ($field->allowedextensions))) . '" }, '; } else if (isset($field->typefield) && $field->typefield == "email" && isset($field->validateArray) && array_key_exists('mailExists', $field->validateArray) && !(isset($field->customErrorMsgArray))) { $js .= '"' . $field->name . '_code" : { remote: "' . addslashes(Text::_('COM_VISFORMS_VALIDATION_CODE_INVALID')) . '", '; $js .= ' required : "'. addslashes(Text::_('COM_VISFORMS_ENTER_VALIDATION_CODE')) .'"} , '; } // User defined error message (from field configuration, @ already replaced) if (isset($field->customErrorMsgArray)) { // User defined error message for Selects and multicheckboxes if (isset($field->typefield) && ($field->typefield == "select" || $field->typefield == "selectsql" || $field->typefield == "multicheckbox" || $field->typefield == "multicheckboxsql")) { $js .= '"' . $field->name . '[]": { '; foreach ($field->customErrorMsgArray as $n => $v) { $js .= $n . ': "' . addslashes($v) . '", '; } $js .='}, '; } else { // User defined error message for 'normal' fields $js .= '"' . $field->name . '": { '; foreach ($field->customErrorMsgArray as $n => $v) { if ($n === "date" && (isset($field->dateFormatJs))) { switch ($field->dateFormatJs) { case "%d.%m.%Y": $js .= 'dateDMY: ' . addslashes($v) . '", '; break; case "%m/%d/%Y": $js .= 'dateMDY: ' . addslashes($v) . '", '; break; case "%Y-%m-%d": $js .= 'dateYMD: ' . addslashes($v) . '", '; break; } } else { $js .= $n . ': "' . addslashes($v) . '",'; } } $js .= '}, '; } } else { // Adapat Error message for multicheckbox minlength, maxlength if we use the default message texts if (isset($field->typefield) && (($field->typefield == "multicheckbox") || ($field->typefield == "multicheckboxsql"))) { $js .= '"' . $field->name . '[]": { '; $js .= 'minlength: jQuery.validator.format("' . addslashes(Text::_('COM_VISFORMS_ENTER_VAILD_MINLENGTH_MULTICHECKBOX')) . '"), '; $js .= 'maxlength: jQuery.validator.format("' . addslashes(Text::_('COM_VISFORMS_ENTER_VAILD_MAXLENGTH_MULTICHECKBOX')) . '") '; $js .= '}, '; } } } // Custom Captcha Error Message (ToDo escape potential @) if (isset($visforms->captchacustomerror) && $visforms->captchacustomerror != "") { $js .= '"' . $visforms->context . 'viscaptcha_response": { required : "' . addslashes($visforms->captchacustomerror) . '", }, "h-captcha-response": { required : "' . addslashes($visforms->captchacustomerror) . '", }, "g-recaptcha-response": { required : "' . addslashes($visforms->captchacustomerror) . '", }, '; } $js .= ' }, '; // in accordion view, display a summary message, that form contains errors if (!empty($visforms->mpdisplaytype) && !empty($visforms->accordioncounter)) { if ($visforms->mpdisplaytype == 1) { $js .= 'showErrors: function(errorMap, errorList) { let errorNoteDiv = jQuery("#' .$parentFormId. '").closest(".visforms-form").find(".error-note"); errorNoteDiv.html("' . addslashes(Text::_('COM_VISFORMS_VALIDATOR_ERROR_COUNT_MESSAGE1')) .'" + this.numberOfInvalids() + "'. addslashes(Text::_('COM_VISFORMS_VALIDATOR_ERROR_COUNT_MESSAGE2')) .'"); this.defaultShowErrors(); if (!this.numberOfInvalids()) { errorNoteDiv.addClass("vishidden"); } else { errorNoteDiv.removeClass("vishidden"); } }, invalidHandler: function(form, validator) { let errors = validator.numberOfInvalids(); if (errors) { // scroll to Error div // if the accordion tab with the first error is open, then the error is focused let errorNoteDiv = jQuery("#' .$parentFormId. '").closest(".visforms-form").find(".error-note"); let elOffset = errorNoteDiv.offset().top; let elHeight = errorNoteDiv.height(); let windowHeight = jQuery(window).height(); let offset; // focus Error div in the middle of the view port if (elHeight < windowHeight) { offset = elOffset - ((windowHeight / 2) - (elHeight / 2)); } else { offset = elOffset; } let speed = 700; jQuery("html, body").animate({scrollTop: offset}, speed); } }, '; } } $js .= 'errorPlacement: function (error, element) { let errorfieldid = element.attr("data-error-container-id"); if (!errorfieldid && element.attr("name") === "h-captcha-response") { errorfieldid = "fc-tbxh-captcha-response_field"; } if (!errorfieldid && element.attr("name") === "g-recaptcha-response") { errorfieldid = "fc-tbxg-recaptcha-response_field"; } jQuery("#' .$parentFormId. '" + " div." + errorfieldid).html(""); error.appendTo("#' .$parentFormId. '" + " div." + errorfieldid); error.addClass("errorcontainer"); // if an error occurs on a hidden selectSql field, show the field if (jQuery(element).hasClass("hideOnEmptyOptionList") || jQuery(element).hasClass("hideOnPreSelectedSolitaryOption")) { jQuery(element).closest("." + element[0].id).removeClass("vishidden"); } }, '; // necessary in multi page forms where pages are validated using validator function valid() // Click on next button does not automatically result in focus on first invalid field // so we force focus on the first invalid field after page validation if (empty($visforms->mpdisplaytype) && empty($visforms->accordioncounter)) { $js .= 'invalidHandler: function(form, validator) { let errors = validator.numberOfInvalids(); if (errors) { validator.errorList[0].element.focus(); } }'; } $js .= '}); jQuery(".captcharefresh'.$visforms->id.'").on( "click", function () { if (jQuery("#captchacode'.$visforms->id.'")) { jQuery("#captchacode'.$visforms->id.'").attr("src", "' . Uri::root(true) .'/index.php?option=com_visforms&task=visforms.captcha&sid=" + Math.random() + "&id='.$visforms->id.'"); } }); jQuery("#'.$parentFormId.'").initVisform({ visform: '. $jsonform.', restrictData: '.$restrictDataString.', userInputs: '.$userinputs.'}); }); '; $wa->addInlineScript($js); endif; endif;