Truyền dữ liệu vào Hộp thoại giao diện người dùng jQuery


83

Tôi đang phát triển một ASP.Net MVCtrang web và trên đó, tôi liệt kê một số đặt chỗ từ một truy vấn cơ sở dữ liệu trong một bảng với ActionLinklệnh hủy đặt chỗ trên một hàng cụ thể với một số BookingIdnhư sau:

Đặt chỗ của tôi

<table cellspacing="3">
    <thead>
        <tr style="font-weight: bold;">
            <td>Date</td>
            <td>Time</td>
            <td>Seats</td>      
            <td></td>              
            <td></td>
        </tr>
    </thead>            
    <tr>
        <td style="width: 120px;">2008-12-27</td>
        <td style="width: 120px;">13:00 - 14:00</td>
        <td style="width: 100px;">2</td>
        <td style="width: 60px;"><a href="/Booking.aspx/Cancel/15">cancel</a></td>
        <td style="width: 80px;"><a href="/Booking.aspx/Change/15">change</a></td>
    </tr>            
    <tr>
        <td style="width: 120px;">2008-12-27</td>
        <td style="width: 120px;">15:00 - 16:00</td>
        <td style="width: 100px;">3</td>
        <td style="width: 60px;"><a href="/Booking.aspx/Cancel/10">cancel</a></td>
        <td style="width: 80px;"><a href="/Booking.aspx/Change/10">change</a></td>
    </tr>  
</table>

Điều tuyệt vời là nếu tôi có thể sử dụng jQuery Dialogđể bật lên một thông báo hỏi liệu người dùng có chắc chắn muốn hủy đặt phòng hay không. Tôi đã cố gắng làm cho điều này hoạt động nhưng tôi vẫn gặp khó khăn về cách tạo một hàm jQuery chấp nhận các tham số để tôi có thể thay thế

<a href="https://stackoverflow.com/Booking.aspx/Cancel/10">cancel</a>

với

<a href="#" onclick="ShowDialog(10)">cancel</a>.

Sau đó, ShowDialoghàm sẽ mở hộp thoại và cũng truyền tham số 10 vào hộp thoại để nếu người dùng nhấp vào có thì nó sẽ đăng href:/Booking.aspx/Change/10

Tôi đã tạo Hộp thoại jQuery trong một tập lệnh như sau:

$(function() {
    $("#dialog").dialog({
        autoOpen: false,
        buttons: {
            "Yes": function() {
                alert("a Post to :/Booking.aspx/Cancel/10 would be so nice here instead of the alert");},
            "No": function() {$(this).dialog("close");}
        },
        modal: true,
        overlay: {
            opacity: 0.5,
            background: "black"
        }
    });
});   

và chính hộp thoại:

   <div id="dialog" title="Cancel booking">Are you sure you want to cancel your booking?</div>

Vì vậy, cuối cùng cho câu hỏi của tôi: Làm thế nào tôi có thể thực hiện điều này? hoặc là có một cách tốt hơn để làm điều đó?

Câu trả lời:


45

Bạn có thể làm như thế này:

  • đánh dấu <a>bằng một lớp học, nói "hủy bỏ"
  • thiết lập hộp thoại bằng cách tác động lên tất cả các phần tử với class = "hủy":

    $('a.cancel').click(function() { 
      var a = this; 
      $('#myDialog').dialog({
        buttons: {
          "Yes": function() {
             window.location = a.href; 
          }
        }
      }); 
      return false;
    });
    

(cộng với các tùy chọn khác của bạn)

Các điểm chính ở đây là:

  • làm cho nó càng không phô trương càng tốt
  • nếu tất cả những gì bạn cần là URL, bạn đã có nó trong href.

Tuy nhiên, tôi khuyên bạn nên đặt nó thành POST thay vì GET, vì hành động hủy có tác dụng phụ và do đó không tuân thủ ngữ nghĩa của GET ...


Thanx cho một câu trả lời tốt. Tôi sẽ thử nó, một câu hỏi. bạn đề cập rằng tốt hơn nên đặt nó thành POST thay vì GET ngụ ý rằng một href thông thường như href = "/ Booking.aspx / Cancel / 10" sẽ là GET đúng không? và nếu vậy thì nó sẽ như thế nào để biến nó thành một bài đăng?
Frederik

Để biến nó thành một bài đăng, thay vì thay đổi window.location, bạn có thể sử dụng hàm ajax của jQuery $ .post (). Xem docs.jquery.com/Ajax/jQuery.post#examples
Franck

1
Tôi sẽ không sử dụng $ .post (), cách tiếp cận đó không giảm tốt. Chỉ cần viết một <form> tiêu chuẩn mà không có bất kỳ ajax nào, làm cho nó hoạt động mà không cần xác nhận, và sau đó thêm xác nhận "trên đầu" của <form> của bạn
Mauricio Scheffer

Đây còn được gọi là cách tiếp cận hijax ( domscripting.com/blog/display/41 )
Mauricio Scheffer

Bạn không cần phải sử dụng bài đăng, nhưng nếu bạn sử dụng get cho một hoạt động thay đổi cơ sở dữ liệu, bạn sẽ tự mở mình trước một cuộc tấn công "giả mạo yêu cầu trên nhiều trang web" ... xem: en.wikipedia.org/wiki/Cross- site_request_forgery
strickli

273

jQuery cung cấp một phương pháp lưu trữ dữ liệu cho bạn, không cần sử dụng thuộc tính giả hoặc tìm cách giải quyết vấn đề của bạn.

Ràng buộc sự kiện nhấp chuột:

$('a[href*=/Booking.aspx/Change]').bind('click', function(e) {
    e.preventDefault();
    $("#dialog-confirm")
        .data('link', this)  // The important part .data() method
        .dialog('open');
});

Và hộp thoại của bạn:

$("#dialog-confirm").dialog({
    autoOpen: false,
    resizable: false,
    height:200,
    modal: true,
    buttons: {
        Cancel: function() {
            $(this).dialog('close');
        },
        'Delete': function() {
            $(this).dialog('close');
            var path = $(this).data('link').href; // Get the stored result
            $(location).attr('href', path);
        }
    }
});

15
Đây là một giải pháp tuyệt vời. Tôi không biết rằng bạn có thể đặt dữ liệu trên hộp thoại bằng cách sử dụng .data. Tôi đã thiết lập các biến toàn cục cho các độ tuổi, truy cập chúng từ hộp thoại của mình và sau đó hủy chúng!
Kevin Bradshaw

Cảm ơn bạn rất nhiều vì điều kỳ diệu .data () này. Lưu ý đến bản cập nhật sau: "Kể từ jQuery 1.7, phương thức .on () là phương thức ưu tiên để đính kèm các trình xử lý sự kiện vào tài liệu" api.jquery.com/bind
daniloquio 13/02/12

2
Tham số .data chắc chắn là con đường để đi. Cảm ơn!
Andreas

1
+1 Tôi đã tìm kiếm tài liệu jquery ui và không thể tìm thấy điều này cho đến khi tôi nhận ra rằng đây là một phương thức từ chính jQuery core. Bắt rất hay
Tivie

@ boris-guery Xin chào, tôi đã thử nhưng không làm được. Nó chỉ không ngăn hành động mặc định, vì vậy nó đi đến liên kết thay vì mở hộp thoại. Mọi sự giúp đỡ sẽ được đánh giá cao: Tôi thực hiện một jsfiddle: jsfiddle.net/sebababi/9zKcZ
Sebastian

2

Về những gì bạn đang làm với jQuery, tôi hiểu là bạn có thể chuỗi các hàm như bạn có và các hàm bên trong có quyền truy cập vào các biến từ các hàm bên ngoài. Cũng vậy, hàm ShowDialog (x) của bạn chứa các hàm khác này, bạn có thể sử dụng lại biến x bên trong chúng và nó sẽ được lấy làm tham chiếu đến tham số từ hàm bên ngoài.

Tôi đồng ý với mausch, bạn thực sự nên xem xét việc sử dụng POST cho những hành động này, thao tác này sẽ thêm <form>thẻ xung quanh mỗi phần tử, nhưng làm cho khả năng một tập lệnh hoặc công cụ tự động kích hoạt sự kiện Hủy ít hơn nhiều. Hành động Thay đổi có thể giữ nguyên vì nó (có lẽ chỉ mở một biểu mẫu chỉnh sửa).


1

Bây giờ tôi đã thử các đề xuất của bạn và thấy rằng nó tương đối hiệu quả,

  1. Hộp thoại div luôn được viết bằng văn bản rõ ràng
  2. Với phiên bản $ .post, nó thực sự hoạt động trong điều kiện bộ điều khiển được gọi và thực sự hủy đặt chỗ, nhưng hộp thoại vẫn mở và trang không làm mới. Với phiên bản get window.location = h.ref hoạt động tuyệt vời.

Xem kịch bản "mới" của tôi bên dưới:

$('a.cancel').click(function() {
        var a = this;               
        $("#dialog").dialog({
            autoOpen: false,
            buttons: {
                "Ja": function() {
                    $.post(a.href);                     
                },
                "Nej": function() { $(this).dialog("close"); }
            },
            modal: true,
            overlay: {
                opacity: 0.5,

            background: "black"
        }
    });
    $("#dialog").dialog('open');
    return false;
});

});

Bất kì manh mối nào?

oh và liên kết Hành động của tôi bây giờ trông giống như sau:

<%= Html.ActionLink("Cancel", "Cancel", new { id = v.BookingId }, new  { @class = "cancel" })%>

Xem ý kiến của tôi về câu trả lời của tôi về việc sử dụng $ .post () và cách tiếp cận Hijax
Mauricio Scheffer

1

Xem mã của bạn, điều bạn cần làm là thêm chức năng đóng cửa sổ và cập nhật trang. Trong hàm "Có", bạn nên viết:

        buttons: {
            "Ja": function() {
                $.post(a.href);
                $(a). // code to remove the table row
                $("#dialog").dialog("close");
            },
            "Nej": function() { $(this).dialog("close"); }
        },

Mã xóa hàng trong bảng không thú vị khi viết vì vậy tôi sẽ để bạn xử lý các chi tiết phức tạp, nhưng về cơ bản, bạn cần cho hộp thoại biết phải làm gì sau khi đăng nó. Nó có thể là một hộp thoại thông minh nhưng nó cần một số định hướng.


Thanx cho câu trả lời của bạn. Tôi sẽ cố gắng nó ra và cũng có thể tìm thấy một cách để loại bỏ các hàng ...
Frederik

Tôi đang nghĩ về điều đó, nếu bạn thêm id vào thẻ '<TR>' thì bạn có thể yêu cầu jQuery xóa hàng đó một cách dễ dàng.
thaBadDawg 29/12/08

1

Sau HÀNG GIỜ LẦN thử / bắt, cuối cùng tôi đã có ví dụ làm việc này, ví dụ này hoạt động trên AJAX POST với các hàng mới gắn vào BẢNG một cách nhanh chóng (đó là vấn đề thực sự của tôi):

Tha ma thuật đi kèm với liên kết này:

<a href="#" onclick="removecompany(this);return false;" id="remove_13">remove</a>
<a href="#" onclick="removecompany(this);return false;" id="remove_14">remove</a>
<a href="#" onclick="removecompany(this);return false;" id="remove_15">remove</a>

Đây là lần cuối cùng làm việc với AJAX POST và Hộp thoại Jquery:

  <script type= "text/javascript">/*<![CDATA[*/
    var $k = jQuery.noConflict();  //this is for NO-CONFLICT with scriptaculous
     function removecompany(link){
        companyid = link.id.replace('remove_', '');
    $k("#removedialog").dialog({
                bgiframe: true,
                resizable: false,
                height:140,
                autoOpen:false,
                modal: true,
                overlay: {
                    backgroundColor: '#000',
                    opacity: 0.5
                },
                buttons: {
                    'Are you sure ?': function() {
                        $k(this).dialog('close');
                        alert(companyid);
                        $k.ajax({
                              type: "post",
                              url: "../ra/removecompany.php",
                              dataType: "json",
                              data: {
                                    'companyid' : companyid
                                    },
                              success: function(data) {
                                    //alert(data);
                                    if(data.success)
                                    {
                                        //alert('success'); 
                                        $k('#companynew'+companyid).remove();
                                    }
                          }
                        }); // End ajax method
                    },
                    Cancel: function() {
                        $k(this).dialog('close');
                    }
                }
            });
            $k("#removedialog").dialog('open'); 
            //return false;
     }
    /*]]>*/</script>
    <div id="removedialog" title="Remove a Company?">
        <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>
        This company will be permanently deleted and cannot be recovered. Are you sure?</p>
    </div>

1

Công việc này đối với tôi:

<a href="#" onclick="sposta(100)">SPOSTA</a>

function sposta(id) {
        $("#sposta").data("id",id).dialog({
            autoOpen: true,
            modal: true,
            buttons: { "Sposta": function () { alert($(this).data('id')); } }
        });
    }

Khi bạn nhấp vào "Sposta" trong màn hình cảnh báo hộp thoại 100


0

Ok, vấn đề đầu tiên với thẻ div rất dễ dàng: Tôi chỉ thêm một style="display:none;"vào nó và sau đó trước khi hiển thị hộp thoại, tôi đã thêm điều này vào tập lệnh hộp thoại của mình:

$("#dialog").css("display", "inherit");

Nhưng đối với phiên bản đăng bài, tôi vẫn không may mắn.


Xem ý kiến của tôi về câu trả lời của tôi về việc sử dụng $ .post () và cách tiếp cận Hijax
Mauricio Scheffer

0

Chỉ cần cung cấp cho bạn một số ý tưởng có thể giúp ích cho bạn, nếu bạn muốn hộp thoại kiểm soát hoàn toàn, bạn có thể cố gắng tránh sử dụng các tùy chọn nút mặc định và tự thêm các nút vào div #dialog của mình. Bạn cũng có thể đặt dữ liệu vào một số thuộc tính giả của liên kết, như Nhấp chuột. gọi attr ("dữ liệu") khi bạn cần.


0

Một giải pháp lấy cảm hứng từ Boris Guery mà tôi đã thuê trông như thế này: Liên kết:

<a href="#" class = "remove {id:15} " id = "mylink1" >This is my clickable link</a>

ràng buộc một hành động với nó:

$('.remove').live({
        click:function(){
            var data = $('#'+this.id).metadata();
            var id = data.id;
            var name = data.name;
            $('#dialog-delete')
                .data('id', id)
                .dialog('open');    
            return false;
        }
    });

Và sau đó để truy cập trường id (trong trường hợp này là giá trị 15:

$('#dialog-delete').dialog({
    autoOpen: false,
    position:'top',
    width: 345,
    resizable: false,
    draggable: false,
    modal: true,
    buttons: {            
        Cancel: function() {

            $(this).dialog('close');
        },
        'Confirm delete': function() {
            var id = $(this).data('id');
            $.ajax({
                url:"http://example.com/system_admin/admin/delete/"+id,
                type:'POST',
                dataType: "json",
                data:{is_ajax:1},
                success:function(msg){

                }
            })
        }
    }
});

0

Tôi hi vọng cái này giúp được

$("#dialog-yesno").dialog({
    autoOpen: false,
    resizable: false,
    closeOnEscape: false,
    height:180,
    width:350,
    modal: true,
    show: "blind",
    open: function() {
        $(document).unbind('keydown.dialog-overlay');
        },
    buttons: {
        "Delete": function() {
            $(this).dialog("close");
            var dir = $(this).data('link').href;
            var arr=dir.split("-");
            delete(arr[1]);
        },
    "Cancel": function() {
        $(this).dialog("close");
        }
    }
});



<a href="product-002371" onclick="$( '#dialog-yesno' ).data('link', this).dialog( 'open' ); return false;">Delete</a>

1
Này @ffernandez, có lẽ tốt nhất bạn nên thử đưa vào một số mô tả về những gì bạn đang làm - thay vì sau đó chỉ cần ném mã vào OP.
thomasfedb
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.