Просмотр исходного кода

Ticket #4442 - Forms: Check for unsubmitted data before leaving the page.

AntonLV 3 лет назад
Родитель
Сommit
93b8aa4c81

+ 1 - 1
inc/classes/BxDolForm.php

@@ -1017,7 +1017,7 @@ class BxDolForm extends BxDol implements iBxDolReplaceable
 
     function getName ()
     {
-        return $this->aFormAttrs['name'];
+        return isset($this->aFormAttrs['name']) ? $this->aFormAttrs['name'] : '';
     }
 
     function setId ($sId)

+ 75 - 16
inc/js/classes/BxDolForm.js

@@ -12,22 +12,92 @@ function BxDolForm(oOptions)
         return;
 
     this._sObjName = oOptions.sObjName === undefined ? 'oForm' : oOptions.sObjName; // javascript object name, to run current object instance from onTimer
+    this._sName = oOptions.sName; // form name
     this._sObject = oOptions.sObject; // form object
     this._sDisplay = oOptions.sDisplay; // form display
 
     this._sActionsUri = 'form.php';
     this._sActionsUrl = oOptions.sRootUrl + this._sActionsUri; // actions url address
+    this._sTxtLeavePageConfirmation = oOptions.sTxtLeavePageConfirmation === undefined ? _t('_sys_leave_page_confirmation') : oOptions.sTxtLeavePageConfirmation;
+
+    this._bChanged = false;
 
     this._sAnimationEffect = 'fade';
     this._iAnimationSpeed = 'slow';
     this._aHtmlIds = oOptions.aHtmlIds;
-    
-    var $this = this;
-	$(document).ready(function () {
-		$this.checkError();
-	});
+
+    this.init();
 }
 
+BxDolForm.prototype.init = function()
+{
+    var $this = this;
+
+    var bName = this._sName != undefined && this._sName.length > 0;
+    var bObject = this._sObject != undefined && this._sObject.length > 0;
+    if(!bName && !bObject)
+        return;
+
+    var sForm = '';
+    var oForm = null;
+    if(bName) {
+        sForm = this._sName;
+        oForm = $('#' + sForm);
+    }
+    if(!oForm.length && bObject) {
+        sForm = this._sObject;
+        oForm = $('#' + sForm);
+    }
+    if(!oForm.length)
+        return;
+
+    if(oForm.find('.bx-form-warn:visible').length > 0) {
+        oForm.find(':text').each(function() {
+            if($(this).val() > 0)
+                $this._bChanged = true;
+        });
+    }
+
+    document.getElementById(sForm).addEventListener('input', () => {
+        $this._bChanged = true;
+    });
+
+    document.getElementById(sForm).addEventListener('submit', (event) => {
+        $this._bChanged = false;
+    });
+
+    window.addEventListener('beforeunload', (event) => {
+        if(!$this._bChanged) 
+            return;
+
+        event.preventDefault();
+        event.returnValue = '';
+    });
+    
+    $('a').bind('click', function() {
+        if(!$this._bChanged)
+            return;
+
+        var oLink = $(this);
+        var sHref = oLink.attr('href');
+        var sOnclick = oLink.attr('onclick');
+        if(!sHref || (sOnclick != undefined && sOnclick.trim().length > 0))
+            return;
+
+        sHref = sHref.trim();
+        if(!sHref || sHref == 'javascript:void(0)')
+            return;
+
+        event.preventDefault();
+
+        bx_confirm($this._sTxtLeavePageConfirmation, function() {
+            $this._bChanged = false;
+
+            oLink.get(0).click();
+        });
+    });
+};
+
 BxDolForm.prototype.showHelp = function(oLink, sInputName)
 {
     var oData = this._getDefaultParams();
@@ -88,15 +158,4 @@ BxDolForm.setCheckBoxValue = function (obj) {
     oHidden.val(val);
 }
 
-BxDolForm.prototype.checkError = function () {
-
-    var $aErr = $('form[name="' + this._sObject + '"]').find('.bx-form-warn:visible');
-    
-    if ($aErr.length > 0){
-        $([document.documentElement, document.body]).animate({
-            scrollTop: $aErr.first().closest('.bx-form-element-wrapper').offset().top - 50
-        }, 200);
-    }
-}
-
 /** @} */

+ 7 - 0
inc/js/jquery.webForms.js

@@ -29,6 +29,13 @@
     }
     
     $.fn.processWebForms = function() {
+        // move to the first error
+        var aErrors = $('.bx-form-warn:visible', this);
+        if(aErrors.length > 0)
+            $([document.documentElement, document.body]).animate({
+                scrollTop: aErrors.first().closest('.bx-form-element-wrapper').offset().top - 50
+            }, 200);
+
         // switchers
         $('.bx-switcher-cont', this).each(function() {
             var eSwitcher = $(this);

+ 1 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -3919,4 +3919,5 @@ If it is not enabled then please consider implement this optimization, since it
     <string name="_sys_page_title_redirect"><![CDATA[Redirect Confirmation]]></string>
     <string name="_sys_page_block_title_redirect"><![CDATA[Confirm redirect]]></string>
     <string name="_sys_redirect_confirmation"><![CDATA[<div class="bx-def-font-h2 bx-def-margin-sec-bottom">You're going to a link outside {1}</div><div class="bx-def-font-small">Link: {0}</div><div class="bx-def-margin-sec-top">Are you sure you want to follow this link?</div>]]></string>
+    <string name="_sys_leave_page_confirmation"><![CDATA[<div class="bx-def-font-h2">Leave the page?</div><div class="bx-def-margin-sec-top">If you do it, your changes will not be saved.</div>]]></string>
 </resources>

+ 1 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -3840,4 +3840,5 @@
   <string name="_sys_page_title_redirect"><![CDATA[Подтверждение перехода на другой сайт]]></string>
   <string name="_sys_page_block_title_redirect"><![CDATA[Подтвердите переход на другой сайт]]></string>
   <string name="_sys_redirect_confirmation"><![CDATA[<div class="bx-def-font-h2 bx-def-margin-sec-bottom">Вы переходите по ссылке за пределы сайта "{1}"</div><div class="bx-def-font-small">Ссылка: {0}</div><div class="bx-def-margin-sec-top">Вы действительно хотите перейти по этой ссылке?</div>]]></string>
+  <string name="_sys_leave_page_confirmation"><![CDATA[<div class="bx-def-font-h2">Покинуть страницу?</div><div class="bx-def-margin-sec-top">Если Вы это сделаете, ваши изменения не будут сохранены.</div>]]></string>
 </resources>

+ 3 - 1
template/scripts/BxBaseFormView.php

@@ -388,10 +388,12 @@ class BxBaseFormView extends BxDolForm
 
         $sCode = "if(window['" . $sJsObjName . "'] == undefined) window['" . $sJsObjName . "'] = new " . $sJsObjClass . "(" . json_encode(array(
             'sObjName' => $sJsObjName,
+            'sName' => $this->getName(),
             'sObject' => isset($this->aParams['object']) ? $this->aParams['object'] : '',
             'sDisplay' => isset($this->aParams['display']) ? $this->aParams['display'] : '',
             'sRootUrl' => BX_DOL_URL_ROOT,
             'aHtmlIds' => $this->_aHtmlIds,
+            'sTxtLeavePageConfirmation' => _t('_sys_leave_page_confirmation')
         )) . ");";
 
         return $bWrap ? $this->oTemplate->_wrapInTagJsCode($sCode) : $sCode;
@@ -462,7 +464,7 @@ BLAH;
         }
 
         if(!$this->_bDynamicMode)
-            $sForm = $this->getJsScript(true) . $sForm;
+            $sForm = $sForm . $this->getJsScript(true);
 
         return $sForm;
     }