Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Rails 3数据确认属性的jQuery UI对话框,而不是alert()_Javascript_Jquery_Ruby On Rails_Unobtrusive Javascript - Fatal编程技术网

Javascript Rails 3数据确认属性的jQuery UI对话框,而不是alert()

Javascript Rails 3数据确认属性的jQuery UI对话框,而不是alert(),javascript,jquery,ruby-on-rails,unobtrusive-javascript,Javascript,Jquery,Ruby On Rails,Unobtrusive Javascript,在Rails 3中,将:confirm参数传递给link_to将填充链接的数据确认属性。这将在单击链接时引发JS警报() 我使用的是rails jQuery UJS适配器()。rails.js中的相关代码是: $('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () { var el = $(this); if (el.tr

在Rails 3中,将:confirm参数传递给link_to将填充链接的数据确认属性。这将在单击链接时引发JS警报()

我使用的是rails jQuery UJS适配器()。rails.js中的相关代码是:

$('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () {
    var el = $(this);
    if (el.triggerAndReturn('confirm')) {
        if (!confirm(el.attr('data-confirm'))) {
            return false;
        }
    }
});

我想知道如何修改它以生成jQuery对话框(例如),允许用户确认或取消


我对JavaScript的了解不足以优雅地实现这一点。我目前的方法是简单地重写$('body').delegate()函数,而不是实例化一个lightbox。但是,我认为有一种比这更有效的方法。

我不明白为什么在JavaScript confirm()函数仍然可以正常工作的情况下,您需要使用jQuery对话框。我会这样做:

$('a[data-confirm]').click(funciton() {
  confirm($(this).data("confirm"));
});
$.rails.allowAction = function(element) {
        var message = element.data('confirm'),
        answer = false, callback;
        if (!message) { return true; }

        if ($.rails.fire(element, 'confirm')) {
                myCustomConfirmBox(message, function() {
                        callback = $.rails.fire(element,
                                'confirm:complete', [answer]);
                        if(callback) {
                                var oldAllowAction = $.rails.allowAction;
                                $.rails.allowAction = function() { return true; };
                                element.trigger('click');
                                $.rails.allowAction = oldAllowAction;
                        }
                });
        }
        return false;
}

function myCustomConfirmBox(message, callback) {
        // implement your own confirm box here
        // call callback() if the user says yes
}
如果你想使用一个对话框,它有点不同。您可以一次性创建所需的每个对话框,也可以在应用程序范围内采用统一的方法,以便rails.js或application.js可以处理任何对话框实例。例如,您的页面上需要这样的内容:

<a class="dialogLauncher">The link that creates your dialog</a>
<div class="dialog" title="My confirmation title" style="display:none">
  <p>My confirmation message</p>
</div>
如果您想进一步自定义对话框,请签出

编辑

现在我想到了这一点,这将是一个定制表单生成器的好机会。当某个属性存在时,您可以覆盖其中一个Rails链接标记以输出类似于上面列出的html,即
:dialog=>true
。这肯定是一种很有讽刺意味的方式。您还可以在标记中添加其他选项,如对话框标题等

编辑


更好的是,不要像通常那样使用
:dialog=>true
,而是使用
:confirm=>“我的确认消息”
,但是在覆盖link\u to时,您将使用
:confirm
选项创建jQuery需要的对话框html,删除该选项,然后调用
super
,这就是我让它工作的方法。请提出任何更正/改进建议

# 在rails.js中

// Added new variable
var deleteConfirmed = false;

// Changed function to use jquery dialog instead of confirm   
$('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () {
        var el = $(this);
        /*
        if (el.triggerAndReturn('confirm')) {

            if (!confirm(el.attr('data-confirm'))) {
                return false;
            }

        }
        */

        if (el.triggerAndReturn('confirm')) {    

            if(deleteConfirmed) {
                deleteConfirmed = false;
                return true;
            }

            $( "#dialog-confirm" ).dialog("option", "buttons",
                    {
                        "Delete": function() {
                            $( this ).dialog( "close" );
                            deleteConfirmed = true;
                            el.trigger('click');   
                            return true;
                        },
                        Cancel: function() {
                            $( this ).dialog( "close" );
                            return false;
                        }
                    }
            );

            $( "#dialog-confirm" ).dialog("open");

            return false;

        }


    });
# # 在application.js中

//Ensure confirm Dialog is pre-created
jQuery(function () {


    $( "#dialog-confirm" ).dialog({
        autoOpen: false,
        resizable: false,
        height:140,
        modal: true     
    });

});
# # 在layout.html中 Alt您可以将此div放置在生成的html中的任何位置

        <div id='dialog-confirm' title='Confirm Delete'> 
          <p> 
            <span class='ui-icon-alert' style='float:left; margin:0 7px 20px 0;'> 
              This item will be permanently deleted. Are you sure?
            </span> 
          </p> 
        </div> 
#


此项目将被永久删除。你确定吗?


我刚刚为Rails jquery ujs添加了一个外部API,以实现这种定制。现在,您可以通过插入(并重新写入)函数
$.rails.allowAction
使rails.js使用自定义确认对话框

请参阅我的文章,以获取带有示例的完整解释

编辑:从开始,我将
确认
对话框功能移动到
$.rails
对象,以便现在可以更轻松地修改或替换它。例如

$.rails.confirm = function(message) { return myConfirmDialog(message); };

正如其他人所提到的,您不能使用jQuery对话框,因为
$.rails.confirm
需要阻止,直到它返回用户的答案

但是,您可以在
应用程序.js
文件中覆盖
$.rails.allowAction
,如下所示:

$('a[data-confirm]').click(funciton() {
  confirm($(this).data("confirm"));
});
$.rails.allowAction = function(element) {
        var message = element.data('confirm'),
        answer = false, callback;
        if (!message) { return true; }

        if ($.rails.fire(element, 'confirm')) {
                myCustomConfirmBox(message, function() {
                        callback = $.rails.fire(element,
                                'confirm:complete', [answer]);
                        if(callback) {
                                var oldAllowAction = $.rails.allowAction;
                                $.rails.allowAction = function() { return true; };
                                element.trigger('click');
                                $.rails.allowAction = oldAllowAction;
                        }
                });
        }
        return false;
}

function myCustomConfirmBox(message, callback) {
        // implement your own confirm box here
        // call callback() if the user says yes
}

它的工作原理是立即返回
false
,从而有效地取消单击事件。然而,然后,您的自定义函数可以调用回调函数来实际跟踪链接/提交表单。

我喜欢@Marc Schütz关于重写
$.rails.allowAction的回答。allowAction是我在网上找到的大部分内容,但我不太喜欢重写
allowAction
中的功能,因为它在整个过程中都在使用jquery ujs代码库(如果有副作用呢?或者如果该方法的源在将来的更新中更改呢?)

到目前为止,最好的方法是使
$.rails.confirm
返回一个承诺。。。但是:(

所以…我推出了我自己的方法,我认为这是值得一提的,因为它比上面概述的方法更轻。它不会劫持
allowAction
。这里是:

# Nuke the default confirmation dialog. Always return true 
# since we don't want it blocking our custom modal.
$.rails.confirm = (message) -> true

# Hook into any data-confirm elements and pop a custom modal
$(document).on 'confirm', '[data-confirm]', ->
  if !$(this).data('confirmed')
    myCustomModal 'Are you sure?', $(this).data('confirm'), =>
      $(this).data('confirmed', true)
      $(this).trigger('click.rails')
    false
  else
    true

# myCustomModal is a function that takes (title, message, confirmCallback)
它是如何工作的?如果您查看,您会注意到如果
确认事件
返回错误值,
allowAction
方法将停止。因此流是:

  • 用户单击带有
    数据确认
    属性的链接或按钮。链接或按钮上没有
    数据确认
    ,因此我们进入第一个if块,触发自定义模式并返回false,从而停止ujs单击处理程序中的继续操作
  • 用户在自定义模式中确认,并触发回调。我们通过
    数据('confirmed',true)
    在元素上存储状态,并重新触发先前触发的相同事件(
    单击.rails
  • 这一次,
    confirm事件
    将落入
    else
    块(因为
    data('confirled')
    为真)并返回真,导致
    allowAction
    块计算为真
  • 我确信我甚至错过了其他可能使这更简单的方法,但我认为这是一种非常灵活的方法,可以在不破坏核心
    jquery ujs
    功能的情况下获得自定义确认模式


    (另外,因为我们正在使用
    .on()
    这将在加载时或将来绑定到页面上的任何
    数据确认
    元素,这与
    .delegate()
    的工作方式类似,以防您感到奇怪。)

    这就是我解决此问题的方法。 我尝试了很多不同的方法,但只有这一种有效

    在rails.js中

    function myCustomConfirmBox(element, callback) {
    
        const modalConfirmDestroy = document.getElementById('modal-confirm');
    
        // wire up cancel
        $("#modal-confirm #cancel-delete").click(function (e) {
            e.preventDefault();
            modalConfirmDestroy.classList.remove('modal--open');
        });
    
        // wire up OK button.
        $("#modal-confirm #confirm-delete").click(function (e) {
            e.preventDefault();
            modalConfirmDestroy.classList.remove('modal--open');
            callback(element, true);
        });
    
        // show the dialog.
        modalConfirmDestroy.classList.add('modal--open');
    }
    
    在这里,我使用了@Mark G.的代码,但做了一些修改。因为代码中剪掉的$(this.trigger('click.rails')对我不起作用

    $.rails.confirm = function(message) {return true};
    
    $(document).on('confirm', '[data-confirm]', (event)=> {
        if (!$(this).data('confirmed'))
        {
            myCustomConfirmBox($(this), (element, choice)=> {
                element.data('confirmed', choice);
                let clickedElement = document.getElementById(event.target.id);
                clickedElement.click();
            });
            return false;
        }
        else
        {
            return true;
        }
    });
    
    然后在html.erb文件中,我有以下链接代码:

    <%= link_to "documents/#{document.id}", method: "delete", data: {confirm: "sure?"}, id: "document_#{document.id}" %>
    
    
    
    此代码适用于modal:

    <div id="modal-confirm" class="modal modal-confirm">
      <h2 class="modal__ttl">Title</h2>
      <div class="modal__inner">
        <p>Description</p>
        <div class="modal__btns">
          <button type="button" name="cancel" id="cancel-delete" class="btn btn-primary">Cancel</button>
          <button type="button" name="confirm" id="confirm-delete" class="btn delete_button btn-secondary">Delete</button>
        </div>
      </div>
    </div>
    
    
    标题
    描述

    取消 删除

    我希望,它能帮助某些人。

    确认的全部目的是向用户询问一个带有“是”的问题/n