jquery - 在 jQuery UI 对话框中显示复选框并提供取消按钮

标签 jquery jquery-ui jquery-selectors jquery-ui-dialog checkbox

我正在尝试解决可能是一个非常常见的问题,并准备了一个简化的测试用例来展示它和我的努力。

我正在尝试显示几个 jQuery UI 对话框,每个对话框都包含多个同名的复选框(下面的测试代码中的fruitscandy)

在每个对话框中,我有 4 个按钮:保存取消全选取消全选:

screenshot

前 3 个按钮已在我的代码中正常工作。

更新按钮实际上会call DataTable's fnDraw() function ,那部分也已经在工作了。 (我不想在服务器上保存复选框值,我想在客户端完成所有操作 - 我知道,这是可能的)。

我的问题是实现对话框的取消按钮:

1)我应该在对话框打开事件中保存当前设置的复选框列表吗?然后点击取消即可恢复它们?有一些优雅的 jQuery 方法吗?

2)我不知道如何仅处理当前打开的对话框的复选框。

下面是我当前的测试代码,它可以立即运行 - 感谢 Google CDN:

<html>
<head>
<style type="text/css" title="currentStyle">
        @import "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/redmond/jquery-ui.css";
</style>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript">

$(function() { 
        var buttons = {
                Cancel: cancel,
                Save: save,
                'Deselect All': deselect,
                'Select All': select
        };

        $('#fruits').dialog({ 
                autoOpen: false, 
                modal: true,
                buttons: buttons
        });

        $('#candy').dialog({ 
                autoOpen: false, 
                modal: true,
                buttons: buttons
        });
});

function update() {
        var boxes = new Array();
        $(':checkbox').each(function() {
                if ($(this).is(':checked')) {
                        boxes.push(
                                $(this).attr('name') + 
                                '=' +
                                $(this).val() 
                        );
                }
        });

        alert('boxes: ' + boxes.join('&'));
}

function select() {
        $(':checkbox').prop('checked', true);
}

function deselect() {
        $(':checkbox').prop('checked', false);
}

function save() {
        // XXX how to implement?
        $(this).dialog('close');
}

function cancel() {
        // XXX how to implement?
        $(this).dialog('close');
}

</script>
</head>
<body>

<p><input type="button" value="Select fruits" onclick="$('#fruits').dialog('open');"></p>
<div id="fruits" title="fruits">
<p><label><input type="checkbox" name="fruits" value="apple">apple</label></p>
<p><label><input type="checkbox" name="fruits" value="banana">banana</label></p>
<p><label><input type="checkbox" name="fruits" value="pear">pear</label></p>
</div>

<p><input type="button" value="Select candy" onclick="$('#candy').dialog('open');"></p>
<div id="candy" title="candy">
<p><label><input type="checkbox" name="candy" value="toffee">toffee</label></p>
<p><label><input type="checkbox" name="candy" value="fudge">fudge</label></p>
</div>

<p><input type="button" onclick="update();" value="Update"></p>

</body>
</html>
<小时/>

更新:感谢 mootinator,以下代码可以正常工作,但我仍然有 2 个小问题/问题:

1) 是否可以使用open事件代替自定义的openDialog()方法?

2) 我的取消全选和全选按钮修改页面上的所有复选框 - 而不是仅修改属于当前对话框的复选框。我想知道如何只选择后者? (以某种方式在 selectAll() 和 deselectAll() 中使用 $(this) )?

我已经尝试过

function selectAll() {
        $($(this) + ' :checkbox').prop('checked', true);
}

function deselectAll() {
        $($(this) + ' :checkbox').prop('checked', false);
}

但出现语法错误。

enter image description here

<html>
<head>
<style type="text/css" title="currentStyle">
        @import "/css/demo_table_jui.css";
        @import "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/redmond/jquery-ui.css";
</style>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript" src="/js/jquery.dataTables.min.js"></script>
<script type="text/javascript">

$(function() {
        var buttons = {
                Cancel: cancel,
                Save: save,
                'Deselect All': deselectAll,
                'Select All': selectAll
        };

        $('#openCandy').button();
        $('#openFruits').button();
        $('#update').button();

        $('#openCandy').click(function() {
                openDialog('#candy');
        });

        $('#openFruits').click(function() {
                openDialog('#fruits');
        });

        $('#fruits').dialog({
                autoOpen: false,
                modal:    true,
                buttons:  buttons
        });

        $('#candy').dialog({
                autoOpen: false,
                modal:    true,
                buttons:  buttons
        });
});

function update() {
        var boxes = new Array();
        $(':checkbox').each(function() {
                if ($(this).is(':checked')) {
                        boxes.push(
                                $(this).attr('name') +
                                '=' +
                                $(this).val()
                        );
                }
        });

        alert('boxes: ' + boxes.join('&'));
}

function selectAll() {
        $(':checkbox').prop('checked', true);
}

function deselectAll() {
        $(':checkbox').prop('checked', false);
}

function openDialog(sel) {
    $(sel).dialog('open');
    $(sel + ' :checkbox').each(function() {
        $(this).data('XXX', $(this).is(':checked'));
    });
}

function cancel() {
        $(this).find(':checkbox').each(function() {
            $(this).prop('checked', $(this).data('XXX'));
        });
        $(this).dialog('close');
}

function save() {
        $(this).dialog('close');
}

</script>
</head>
<body>

<p><input id="openFruits" type="button" value="Select fruits"></p>
<div id="fruits" title="fruits">
<p><label><input type="checkbox" name="fruits" value="apple">apple</label></p>
<p><label><input type="checkbox" name="fruits" value="banana">banana</label></p>
<p><label><input type="checkbox" name="fruits" value="pear">pear</label></p>
</div>

<p><input id="openCandy" type="button" value="Select candy"></p>
<div id="candy" title="candy">
<p><label><input type="checkbox" name="candy" value="toffee">toffee</label></p>
<p><label><input type="checkbox" name="candy" value="fudge">fudge</label></p>
</div>

<p><input id="update" type="button" onclick="update();" value="Update"></p>

</body>
</html>
<小时/>

更新2:实际上我有第三个也是更大的问题:对话框右上角的关闭X按钮无法正常工作(它保存而不是取消)。

我尝试向两个对话框添加 close: cancel,,但在 Chrome 中出现运行时错误:

Uncaught RangeError: Maximum call stack size exceeded
f.event.remove
f.event.remove
f.fn.extend.unbind
a.extend.destroy
a.extend.destroy
a.widget.close
a.widget.bridge.a.fn.(anonymous function)
e.extend.each
e.fn.e.each
a.widget.bridge.a.fn.(anonymous function)
cancel
a.Widget._trigger
a.widget.close
a.widget.bridge.a.fn.(anonymous function)
.....etc....
<小时/>

UPDATE3:可能是因为我在循环中调用$(this).dialog('close')

不过,我没有找到解决此问题的简单方法:如果我创建一个单独的函数

function restore() {
        $(this).find(':checkbox').each(function() {
            $(this).prop('checked', $(this).data('XXX'));
        });
}

function cancel() {
        restore();
        $(this).dialog('close');
}

并将其作为关闭:恢复传递到对话框,然后保存按钮中断

最佳答案

我对您的代码做了一些修改。也许最简单的事情(不一定是最好的)是将状态保存在全局变量中。 (更强大的解决方案可能只涉及将状态与对话框状态/选项一起保存)。

更新:清理了解决方案,将复选框本身的初始状态存储在 DOM 中,而不是存储在全局变量中。

http://jsfiddle.net/rhdNH/8/

我添加了自定义打开功能,方便保存状态,并完成了取消功能。每当您使用 removeProp 关闭时,您可能还想清理“原始”属性,但这并不是绝对必要的。

以下是您需要对第 1 点 (open:openDialog) 进行的更改,以便不必直接调用 openDialog。

$('#fruits').dialog({ 
    autoOpen: false, 
    modal: true,
    buttons: buttons,
    open: openDialog
});

$('#candy').dialog({ 
    autoOpen: false, 
    modal: true,
    buttons: buttons,
    open: openDialog
});

这就是您的选择/取消选择应该是什么样子,只对打开的对话框起作用:

function select() {
    $(':checkbox', this).prop('checked', true);
}

function deselect() {
    $(':checkbox', this).prop('checked', false);
}

这里是 openDialog 编辑为使用 this 而不是 jQuery 选择器:

function openDialog() {
    $(':checkbox', this).each(function() {
        $(this).prop('original', $(this).is(':checked'));
    });
}

function cancel() {
        $(this).find('input[type="checkbox"]').each(function() {
            $(this).prop('checked', $(this).prop('original'));
        });
        $(this).dialog('close');
}

关于jquery - 在 jQuery UI 对话框中显示复选框并提供取消按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7648004/

相关文章:

jQuery 类选择器和 $(this)

javascript - Javascript 中的过滤逻辑 - 查找数组中的值范围

javascript - 如何基本上像 jQuery masonry 那样重新安排 DIV?

jQuery UI 可从 Accordion 中拖出

jQuery UI 选项卡给出 'Mismatching fragment identifier' 错误消息

jQuery - contains/filter 和 insertBefore 重新排列列表 (div > ul > li) 问题

jquery - 为什么以下创建 DOM 元素的方法不能在 IE7 和 IE8 中使用 jQuery?

javascript - 一个接一个改变多个div的颜色

javascript - 条件语句不响应结果

jquery - SlickGrid 自定义 CSS 问题