将数据传递到jQuery UI对话框


83

我正在开发一个ASP.Net MVC网站,在该网站上,我在一个表中列出了来自数据库查询的一些预订,并带有ActionLink来取消特定行上的预订,BookingId例如:

我的预订

<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>

最好的是,如果我可以使用jQuery Dialog弹出一条消息,询问用户是否确定要取消预订。我一直在尝试使其工作,但我一直坚持如何创建一个接受参数的jQuery函数,以便我可以替换

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

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

ShowDialog然后,该函数将打开对话框,并将参数10传递给对话框,以便如果用户单击“是”,它将发布href:/Booking.aspx/Change/10

我已经在如下脚本中创建了jQuery对话框:

$(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"
        }
    });
});   

对话框本身:

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

最后,我的问题是:我该如何完成?还是有更好的方法呢?

Answers:


45

您可以这样做:

  • <a>用一个班级标记“取消”
  • 通过对所有具有class =“ cancel”的元素进行操作来设置对话框:

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

(加上其他选项)

这里的关键点是:

  • 使它尽可能不引人注目
  • 如果您只需要URL,那么您已经在href中添加了它。

但是,我建议您将其设置为POST而不是GET,因为cancel操作具有副作用,因此不符合GET语义...


感谢您的好答案。我将尝试一下,尽管有一个问题。您提到最好将它设为POST而不是GET,这意味着像href =“ / Booking.aspx / Cancel / 10”这样的常规href就是GET ist吧?如果可以的话,发布该帖子会是什么样子呢?
弗雷德里克

为了使其成为帖子,您可以使用jQuery $ .post()ajax函数,而不是更改window.location。参见docs.jquery.com/Ajax/jQuery.post#examples
Franck)

1
我不会使用$ .post(),这种方法不会降级。只需编写没有任何ajax的标准<form>,使其无需确认即可工作,然后在<form>的顶部添加确认
Mauricio Scheffer

这也被称为hijax方法(domscripting.com/blog/display/41
毛雅伯

你不具备使用后,但如果你使用获取一个数据库变更操作,你打开自己的“跨站请求伪造”攻击......看到:en.wikipedia.org/wiki/Cross- site_request_forgery
strickli

273

jQuery提供了一种为您存储数据的方法,无需使用虚拟属性或查找问题的解决方法。

绑定点击事件:

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

和您的对话框:

$("#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
这是一个绝妙的解决方案。我不知道您可以使用.data在对话框上设置数据。我一直在设置年龄的全局变量,然后从对话框中访问它们,然后销毁它们!
凯文·布拉德肖

非常感谢您使用.data()魔术。请注意以下更新:“从jQuery 1.7开始,.on()方法是将事件处理程序附加到文档的首选方法” api.jquery.com/bind
daniloquio 2012年

2
.data参数无疑是解决方法。谢谢!
安德里亚斯(Andreas)

1
+1我搜索了jQuery ui文档,直到我意识到这是jQuery核心本身的方法,才找到它。非常好的收获
Tivie

@ boris-guery嗨,我尝试了一下,但是没有成功。它只是不会阻止默认操作,因此会转到链接而不是打开对话框。任何帮助将不胜感激:我做一个jsfiddle:jsfiddle.net/sebababi/9zKcZ
Sebastian

2

就您使用jQuery所做的事情而言,我的理解是您可以像平常一样链接函数,而内部函数可以访问外部函数。所以您的ShowDialog(x)函数包含这些其他函数,您可以在其中重新使用x变量,它将用作外部函数对参数的引用。

我同意mausch的观点,您应该真正考虑对这些操作使用POST,这将<form>在每个元素周围添加一个标签,但是使自动化脚本或工具触发Cancel事件的可能性大大降低。更改操作可以保持原样,因为它(大概只是打开一个编辑表单)。


1

我现在尝试了您的建议,发现它确实可行,

  1. 对话框div总是以明文形式写出
  2. 在$ .post版本中,它实际上是按照调用控制器并实际上取消预订的方式工作的,但是对话框保持打开状态,并且页面不会刷新。使用获取版本window.location = h.ref的效果很好。

下面是我的“新”脚本:

$('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;
});

});

有什么线索吗?

哦,我的操作链接现在看起来像这样:

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

请参阅我对有关使用$ .post()和hijax方法的回答的评论
Mauricio Scheffer

1

查看代码,您需要做的就是添加功能以关闭窗口并更新页面。在“是”功能中,您应该输入:

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

删除表格行的代码并不是很有趣,因此我将让您处理细节问题,但基本上,您需要在发布对话框后告诉对话框该怎么做。这可能是一个聪明的对话,但需要某种指导。


感谢您的回答。我将尝试一下,还找到一种删除行的方法...
Frederik

我在考虑这个问题,如果您在'<TR>'标签中添加一个id,那么您也许可以使jQuery轻松地删除该行。
thaBadDawg

1

经过数小时的try / catch之后,我终于有了这个工作示例,它在AJAX POST上使用新行的工作很快地追加到了TABLE(这是我真正的问题):

Tha魔术附带了以下链接:

<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>

这是使用AJAX POST和Jquery Dialog的最终工作:

  <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

这项工作对我来说:

<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')); } }
        });
    }

在对话框警报显示100中单击“ Sposta”时


0

好的,div标签的第一个问题很简单:我刚添加了一个标签style="display:none;",然后在显示对话框之前在对话框脚本中添加了它:

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

但是对于后期版本,我仍然不走运。


请参阅我对有关使用$ .post()和hijax方法的回答的评论
Mauricio Scheffer

0

只是提供一些想法可能会对您有所帮助,如果您想完全控制对话框,则可以尝试避免使用默认按钮选项,而可以在#dialog div中自己添加按钮。您还可以将数据放入链接的某些虚拟属性中,例如Click。需要时调用attr(“ data”)。


0

我采用了受Boris Guery启发的解决方案,如下所示:链接:

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

将动作绑定到它:

$('.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;
        }
    });

然后访问id字段(在这种情况下,值为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

我希望这有帮助

$("#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
嘿@ffernandez,最好尝试对您的操作进行一些描述-而不是在OP上扔代码。
thomasfedb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.