Ale*_*ber 8 checkbox jquery jquery-ui jquery-selectors jquery-ui-dialog
我试图解决可能是一个非常常见的问题,并准备了一个简化的测试用例来展示它和我的努力.
我正在尝试显示几个jQuery UI对话框,每个对话框包含几个相同名称的复选框(下面我的测试代码中的水果和糖果)
在每个对话框中,我有4个按钮:保存,取消,全选和取消全选:

前三个按钮已经在我的代码中工作.
该更新按钮将实际上调用DataTable的fnDraw()函数,这部分已经工作了.(而且我不想在中间保存服务器上的复选框值,我想在客户端做所有事情 - 我知道,这是可能的).
我的问题是为对话框实现取消按钮:
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>
Run Code Online (Sandbox Code Playgroud)
更新:感谢mootinator以下代码正在运行,但我仍有2个小问题/问题:
1)是否可以使用open事件而不是自定义openDialog()方法?
2)我取消选择全部和全选按钮修改页面上的所有复选框 - 而不是仅修改属于当前对话框的复选框.我想知道如何只选择后者?(以某种方式在selectAll()和deselectAll()中使用$(this)?
我试过了
function selectAll() {
$($(this) + ' :checkbox').prop('checked', true);
}
function deselectAll() {
$($(this) + ' :checkbox').prop('checked', false);
}
Run Code Online (Sandbox Code Playgroud)
但得到语法错误.

<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>
Run Code Online (Sandbox Code Playgroud)
UPDATE2:实际上我有一个第三个更大的问题:对话框右上角的关闭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....
Run Code Online (Sandbox Code Playgroud)
UPDATE3:可能是因为我在一个循环中调用$(this).dialog('close')?
我没有看到一个简单的方法来解决它:如果我创建一个单独的功能
function restore() {
$(this).find(':checkbox').each(function() {
$(this).prop('checked', $(this).data('XXX'));
});
}
function cancel() {
restore();
$(this).dialog('close');
}
Run Code Online (Sandbox Code Playgroud)
并将其传递给关闭:恢复到对话框,然后保存按钮中断
我对您的代码做了一些修改。可能最简单的事情(不一定是最好的事情)是将状态保存在全局变量中。(更强大的解决方案可能只涉及将状态与对话框状态/选项一起保存)。
更新:清理了解决方案,将复选框本身的初始状态存储在 DOM 中,而不是存储在全局变量中。
我添加了自定义打开函数,方便保存状态,并完成了取消功能。每当您关闭使用时,您可能还想清理“原始”属性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
});
Run Code Online (Sandbox Code Playgroud)
这就是您的选择/取消选择应该是什么样子,只作用于打开的对话框:
function select() {
$(':checkbox', this).prop('checked', true);
}
function deselect() {
$(':checkbox', this).prop('checked', false);
}
Run Code Online (Sandbox Code Playgroud)
这里被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');
}
Run Code Online (Sandbox Code Playgroud)