【问题标题】:Passing data to a jQuery UI Dialog将数据传递给 jQuery UI 对话框
【发布时间】:2010-09-28 12:18:32
【问题描述】:

我正在开发一个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 函数,以便我可以替换

&lt;a href="/Booking.aspx/Cancel/10"&gt;cancel&lt;/a&gt;

&lt;a href="#" onclick="ShowDialog(10)"&gt;cancel&lt;/a&gt;

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>

最后我的问题是:我怎样才能做到这一点?还是有更好的方法?

【问题讨论】:

    标签: javascript jquery asp.net-mvc jquery-ui jquery-ui-dialog


    【解决方案1】:

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

    【讨论】:

    • 这是一个绝妙的解决方案。我不知道您可以使用 .data 在对话框上设置数据我已经设置了多年的全局变量,从我的对话框中访问它们然后销毁它们!
    • 非常感谢这个 .data() 魔术。请注意以下更新:“从 jQuery 1.7 开始,.on() 方法是将事件处理程序附加到文档的首选方法”api.jquery.com/bind
    • .data 参数绝对是要走的路。谢谢!
    • +1 我搜索了 jquery ui 文档,但直到我意识到这是 jQuery 核心本身的一种方法才找到它。很好的收获
    • @boris-guery 嗨,我试过了,但没能成功。它只是不会阻止默认操作,因此它会转到链接而不是打开对话框。任何帮助将不胜感激:我做了一个 jsfiddle:jsfiddle.net/sebababi/9zKcZ
    【解决方案2】:

    你可以这样做:

    • 用课程标记&lt;a&gt;,说“取消”
    • 通过使用 class="cancel" 作用于所有元素来设置对话框:

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

    (加上你的其他选择)

    这里的重点是:

    • 尽量不显眼
    • 如果您只需要 URL,那么您已经在 href 中拥有它。

    但是,我建议您将其设为 POST 而不是 GET,因为取消操作会产生副作用,因此 doesn't comply with GET semantics...

    【讨论】:

    • 感谢您的回答。我会尝试一下,不过有一个问题。您提到最好将其设为 POST 而不是 GET,这意味着像 href="/Booking.aspx/Cancel/10" 这样的常规 href 将是 GET 对吗?如果是这样,那它会成为一个帖子吗?
    • 为了使它成为一个帖子,而不是改变 window.location,你可以使用 jQuery $.post() ajax 函数。见docs.jquery.com/Ajax/jQuery.post#examples
    • 我不会使用 $.post(),这种方法不会很好地降级。只需编写一个不带任何 ajax 的标准
      ,使其无需确认即可工作,然后 然后 在您的
      的“顶部”添加确认
    • 这也称为 hijax 方法 (domscripting.com/blog/display/41)
    • 您没有必须使用 post,但如果您使用 get 进行数据库更改操作,您将面临“跨站点请求伪造”攻击...见:en.wikipedia.org/wiki/Cross-site_request_forgery
    【解决方案3】:

    就您使用 jQuery 所做的事情而言,我的理解是您可以像您拥有的那样链接函数,并且内部函数可以访问外部变量的变量。您的 ShowDialog(x) 函数是否包含这些其他函数,您可以在其中重复使用 x 变量,并将其作为对外部函数参数的引用。

    我同意 mausch 的观点,您真的应该考虑使用 POST 来执行这些操作,这将在每个元素周围添加一个 &lt;form&gt; 标签,但会降低自动脚本或工具触发 Cancel 事件的可能性。 Change 操作可以保持原样,因为它(可能只是打开了一个编辑表单)。

    【讨论】:

      【解决方案4】:

      我现在已经尝试了你的建议,发现它有点工作,

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

      });

      有什么线索吗?

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

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

      【讨论】:

      • 查看我的 cmets 关于使用 $.post() 和 hijax 方法的回答
      【解决方案5】:

      查看您的代码,您需要添加关闭窗口和更新页面的功能。在你的“是”函数中你应该写:

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

      删除表格行的代码写起来并不有趣,所以我会让你处理细节,但基本上,你需要在发布后告诉对话框要做什么。这可能是一个聪明的对话,但它需要某种方向。

      【讨论】:

      • 感谢您的回答。我会尝试一下,并找到一种方法来删除该行...
      • 我在想,如果你在 '' 标签中添加一个 id,那么你也许可以让 jQuery 轻松删除该行。
      【解决方案6】:

      经过几个小时的 try/catch 之后,我终于有了这个工作示例,它在 AJAX POST 上工作,新行附加到表中(这是我真正的问题):

      魔法自带链接:

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

      【讨论】:

        【解决方案7】:

        这对我有用:

        &lt;a href="#" onclick="sposta(100)"&gt;SPOSTA&lt;/a&gt;

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

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

        【讨论】:

          【解决方案8】:

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

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

          但是对于发布版本,我仍然不走运。

          【讨论】:

          • 查看我的 cmets 关于使用 $.post() 和 hijax 方法的回答
          【解决方案9】:

          给你一些想法可能会对你有所帮助,如果你想完全控制对话框,你可以尽量避免使用默认按钮选项,并在你的#dialog div中自己添加按钮。您还可以将数据放入链接的一些虚拟属性中,例如 Click。需要时调用 attr("data")。

          【讨论】:

            【解决方案10】:

            我采用的受 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){
            
                            }
                        })
                    }
                }
            });
            

            【讨论】:

              【解决方案11】:

              希望对你有帮助

              $("#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>
              

              【讨论】:

              • 嘿@ffernandez,最好尝试包括一些您正在做的事情的描述 - 而不是只是向 OP 扔代码。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-05-07
              • 1970-01-01
              • 2012-06-26
              相关资源
              最近更新 更多