Я пытаюсь решить, вероятно, очень распространенную проблему и подготовил упрощенный тестовый пример, демонстрирующий это и мои усилия.
Я пытаюсь отобразить несколько диалоговых окон jQuery UI, каждый из которых содержит несколько флажков с одинаковыми именами ( fruits и candy в моем тестовом коде ниже)
В каждом диалоге у меня есть 4 кнопки: Сохранить , Отмена , Выбрать все и Отменить выбор всех :
Первые 3 кнопки уже работают в моем коде.
Кнопка Update на самом деле вызовет функцию 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>
ОБНОВЛЕНИЕ: Благодаря mootinator работает следующий код, но у меня все еще есть 2 незначительных проблемы / вопроса:
1) Можно ли использовать open событие вместо пользовательского метода openDialog ()?
2) Кнопки «Отменить выбор всех» и «Выбрать все» изменяют все флажки на странице, а не только те, которые принадлежат текущему диалоговому окну. Интересно, как выбрать только последние? (каким-то образом используйте $ (this) в selectAll () и deselectAll ())?
Я пробовал
function selectAll() {
$($(this) + ' :checkbox').prop('checked', true);
}
function deselectAll() {
$($(this) + ' :checkbox').prop('checked', false);
}
но получите синтаксическую ошибку.
<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: На самом деле у меня есть 3-я и более серьезная проблема: закрывающая 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');
}
и передать его как close: восстановить в диалогах, затем кнопка Save обрывает