2009-08-05 26 views
12

Trong ứng dụng web ASP.NET của tôi, tôi đang cố gắng tạo ra một cách phổ biến cảnh báo người dùng trước khi điều hướng khỏi biểu mẫu khi họ đã thực hiện thay đổi, bằng cách sử dụng jQuery. Công cụ khá chuẩn, nhưng sau nhiều lần tìm kiếm, tôi vẫn chưa tìm được một kỹ thuật hoạt động.ASP.NET, jQuery, dạng bẩn và window.onbeforeunload

Dưới đây là những gì tôi có vào thời điểm này:

addToPostBack = function(func) { 
     var old__doPostBack = __doPostBack; 
     if (typeof __doPostBack != 'function') { 
      __doPostBack = func; 
     } else { 
      __doPostBack = function() { 
       old__doPostBack(); 
       func(); 
      } 
     } 
    } 

    var isDirty = false; 

    $(document).ready(function() { 
     addToPostBack(function() { 
      alert("Postback detected.") 
      clearDirty(); 
     }); 
     $(':input').bind("change select keydown", setDirty); 
     window.onbeforeunload = function(e) { 
      var msg = "You have unsaved changes. " 
      if (isDirty == true) { 
       var e = e || window.event; 
       if (e) { e.returnValue = msg; } 
       return msg; 
      } 
     }; 
    }); 

    setDirty = function() {isDirty = true;} 

    clearDirty = function() {isDirty = false;} 

này hoạt động như xa như cảnh báo người sử dụng từ hướng đi. Vấn đề là tôi nhận được cảnh báo trên mỗi lần đăng lại cùng một trang. Có một số điều về hình thức của tôi mà có thể gây ra một postback:

  1. Có Lưu, Hủy bỏ và Xóa linkbuttons trên trang
  2. Có thể có linkbuttons khác trên trang đó thực hiện chức năng server-side khi ở trên cùng một trang
  3. Có thể có các điều khiển khác có tính năng tự động khởi động = true cũng có các chức năng phía máy chủ được đính kèm với chúng, nhưng không dẫn đến việc người dùng rời khỏi trang.

Không có điều nào trong số này nên kích động cảnh báo vì người dùng không rời khỏi trang. Mã của tôi cố gắng để cướp addToPostBack (more details on that in this question) để xóa bit isDirty trước khi đăng lại, nhưng vấn đề là trong IE onbeforeunload cháy trước __doPostBack, rõ ràng vì IE kích hoạt onbeforeunload ngay lập tức khi liên kết được nhấp (as described here).

Tất nhiên, tôi có thể kết nối từng điều khiển để xóa bit wasDirty, nhưng tôi muốn một giải pháp hoạt động ở cấp biểu mẫu và không yêu cầu tôi chạm vào từng điều khiển có thể kích hoạt postback.

Có ai có cách tiếp cận hoạt động trong ASP.NET và không liên quan đến việc kết nối mọi điều khiển có thể gây ra đăng lại không?

+0

Bạn chỉ có thể gian lận và kiểm tra mã nguồn SO để xem họ làm gì. – Powerlord

+1

SO sử dụng beforeunload, nhưng MVC == no postbacks == không có vấn đề cụ thể của Herb. –

Trả lời

2

Bạn luôn có thể tạo lớp trang không được thừa kế có phương thức OnLoad/OnUnload tùy chỉnh bổ sung thêm javascript thực thi ngay lập tức.

Sau đó, bạn không phải xử lý nó ở cấp độ kiểm soát cụ thể mà là mức biểu mẫu/trang.

+0

Không rõ ràng về những gì bạn đang đề xuất. Phương pháp/phương pháp này sẽ làm gì? –

2

Thú vị, nhưng ... tại sao bạn không làm mọi thứ với jQuery?

var defaultSubmitControl = false; 
var dirty = false; 
$(document).ready(function() { 
    $('form').submit(function() { dirty = false }); 
    $(window).unload(function() { 
     if (dirty && confirm('Save?')) { 
      __doPastBack(defaultSubmitControl || $('form :submit[id]').get(0).id, ''); 
     } 
    }); 
}); 
··· 
dirty = true; 
··· 

Bây giờ, nếu mà vẫn gây ra vấn đề tương tự (unload kích hoạt trước khi submit), bạn có thể thử một khác nhau sự kiện cây, vì vậy thay vì gọi __doPostBack trực tiếp bạn làm ...

setTimeout(function() { 
    __doPastBack(defaultSubmitControl || $('form :submit[id]').get(0).id, ''); 
}, 1); // I think using 0 (zero) works too 

Tôi đã không thử điều này và nó từ đầu của tôi, nhưng tôi nghĩ rằng nó có thể là một cách để giải quyết nó.

0

tôi đang tìm kiếm sau này quá nhưng những gì tôi đã tìm cho đến nay là, một giải pháp sử dụng tất cả các điều khiển html html thay vì điều khiển web asp.net, bạn có nghĩ về điều đó không?

<script type="text/javascript"> 
    $(document).ready(function() { 
     $("form").dirty_form(); 
     $("#btnCancel").dirty_stopper(); 
    });    
    </script> 
1

Làm việc này bằng cách theo dõi cơ bản vị trí chuột.Hãy nhớ rằng bạn vẫn có thể nhận được các giá trị dương cho giá trị Y của bạn (do đó, < 50 dòng mã của tôi), nhưng miễn là các nút gửi của bạn có độ dài lớn hơn 100 pixel thì bạn sẽ ổn.

Đây là Javascript tôi đã thêm để theo dõi những thay đổi chuột và nắm bắt được sự kiện onbeforeunload:

<script language="JavaScript1.2"> 
    <!-- 

    // Detect if the browser is IE or not. 
    // If it is not IE, we assume that the browser is NS. 
    var IE = document.all?true:false 

    // If NS -- that is, !IE -- then set up for mouse capture 
    if (!IE) document.captureEvents(Event.MOUSEMOVE) 

    // Set-up to use getMouseXY function onMouseMove 
    document.onmousemove = getMouseXY; 

    // Temporary variables to hold mouse x-y pos.s 
    var tempX = 0 
    var tempY = 0 

    // Main function to retrieve mouse x-y pos.s 

    function getMouseXY(e) { 
     if (IE) { // grab the x-y pos.s if browser is IE 
     tempX = event.clientX + document.body.scrollLeft 
     tempY = event.clientY + document.body.scrollTop 
     } else { // grab the x-y pos.s if browser is NS 
     tempX = e.pageX 
     tempY = e.pageY 
     } 
     // catch possible negative values in NS4 
     if (tempX < 0){tempX = 0} 
     if (tempY < 0){tempY = 0} 
     // show the position values in the form named Show 
     // in the text fields named MouseX and MouseY 
     document.Show.MouseX.value = tempX 
     document.Show.MouseY.value = tempY 
     return true 
    } 

    //--> 
    </script> 


    <script type="text/javascript"> 

     window.onbeforeunload = HandleOnClose; 

     function HandleOnClose(e) { 

      var posY = 0; 
      var elem = document.getElementsByName('MouseY'); 
      if (elem[0]) { 
       posY = elem[0].value; 
      } 

      if (posY < 50) { // Your form "submit" buttons will hopefully be more than 100 pixels down due to movement 
       return "You have not selected an option, are you sure you want to close?"; 
      } 
     } 

    </script> 

Sau đó, chỉ cần thêm các hình thức sau đây vào trang của bạn:

<form name="Show"> 
     <input type="hidden" name="MouseX" value="0" size="4"> 
     <input type="hidden" name="MouseY" value="0" style="display:block" size="0"> 
    </form> 

Và đó là nó! Nó có thể sử dụng một chút dọn dẹp (loại bỏ MouseX, vv), nhưng điều này làm việc trong ứng dụng ASP.net 3.5 hiện tại của tôi và nghĩ rằng tôi sẽ đăng bài để giúp đỡ bất cứ ai. Hoạt động trong IE 7 và Firefox 3.6, chưa thử Chrome.

8

Tôi đã xem qua bài đăng này trong khi Googling cho một giải pháp để làm điều tương tự trong MVC. Giải pháp này, thích nghi từ thảo dược ở trên, dường như hoạt động tốt. Vì không có MVC cụ thể về điều này, nó sẽ hoạt động tốt cho PHP, ASP cổ điển hoặc bất kỳ loại ứng dụng nào khác sử dụng HTML và JQuery.

var isDirty = false; 

$(document).ready(function() { 
    $(':input').bind("change select keydown", setDirty); 
    $('form').submit(clearDirty); 

    window.onbeforeunload = function (e) { 
     var msg = "You have unsaved changes. " 
     if (isDirty == true) { 
      var e = e || window.event; 
      if (e) { e.returnValue = msg; } 
      return msg; 
     } 
    }; 
}); 

setDirty = function() { isDirty = true; } 
clearDirty = function() { isDirty = false; } 
Các vấn đề liên quan