Bootstrap 模态和 Datatables.net
Bootstrap Modal and Datatables.net
我在数据表事件处理程序中显示一个 bootstrap 模态对话框,其定义如下:
dt_table.on('click', 'tr', function(e) {
//console.log('row clicked');
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
}
else {
//check to see if user has any pending changes
var saveButton = document.getElementById('saveBtn');
if (saveButton && !saveButton.disabled) {
//for now if save button is enabled ask user if they're sure they don't want to save pending changes first
var options = {
'backdrop' : 'static', //prevents clicking outside the model to dismiss dialog
}
$('#pendingChanges').modal(options);
var save_pending_changes = $('#save_pending_changes').val();
console.log(save_pending_changes);
if (save_pending_changes) {
// console.log(e);
//e.preventDefault();
return;
}
}
console.log('about to execute default behavior');
//first unselect any other selected row
dt_table.$('tr.selected').removeClass('selected');
//then select row of interest
$(this).addClass('selected');
var rowIndices = dt_table.row('.selected')[0];
selectedRowIndex = rowIndices[0];
//set hidden param
$('#selectedRowIndex').val(selectedRowIndex);
var row = dt_table.rows(rowIndices);
if (row.data().length == 0) {
//e.preventDefault();
return;
}
var id = row.data()[0]['id'];
var url = '/report/' + id + '/';
//window.location = url;
$('#notes_display').load(url + ' #notes_display');
}
});
我 运行 遇到的问题是整个事件处理程序在模态消失之前执行。它的行为就好像模态在它自己的线程中是 运行 一样。我该如何解决这个问题?
我的模态定义为
<div class="modal fade" id="pendingChanges" tabindex="-1" role="dialog" aria-labelledby="pendingChangesLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="pendingChangesLabel">You have unsaved changes</h3>
</div>
<div class="modal-body">
<p>
<strong>Are you sure you want to leave?</strong>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="saveChanges(true)">No</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="saveChanges(false)">Yes</button>
</div>
</div>
</div>
</div>
逻辑示例会有所帮助 :) 但我想我明白了问题所在。我会建议您在 promises 中拆分工作流程:
//determine if modal should displayed
function determine(tr) {
return new Promise(function(resolve) {
//dont know the logic here
resolve(true / false)
})
}
//show modal and return caption of the clicked button
function showModal() {
return new Promise(function(resolve) {
$('#pendingChanges button').one('click', function(e) {
resolve(e.currentTarget.innerText)
})
$('#pendingChanges').modal({
backdrop: 'static',
keyboard: false
})
})
}
dt_table.on('click', 'tr', function(e) {
determine(this).then(function(result) {
if (result) {
showModal().then(function(button) {
console.log(button) //Yes or No
})
}
})
})
未测试,但应该没问题。
determine()
是否应根据 <tr>
显示模态
- 调用
showModal()
仅在单击按钮时才解析
- 你得到
Yes
或 No
感谢 davidkonrad 我解决了我的问题。这是工作代码。
<input type="hidden" name="save_pending_changes" id="save_pending_changes" value="false"/>
<!-- Modal -->
<div class="modal fade" id="pendingChanges" tabindex="-1" role="dialog" aria-labelledby="pendingChangesLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="pendingChangesLabel">You have unsaved changes</h3>
</div>
<div class="modal-body">
<p>
<strong>Are you sure you want to leave?</strong>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="saveChanges(true)">No</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="saveChanges(false)">Yes</button>
</div>
</div>
</div>
</div>
function saveChanges(save) {
$('#save_pending_changes').val(save);
}
dt_table.on('click', 'tr', function(e) {
var oldRow = getCurrentRow();
determine(this).then(function(result) {
var enabled = result['enabled'];
var tr = result['tr'];
if (enabled) {
showModal().then(function(save) {
if (save == 'true') {
setSelection(oldRow);
return;
}
else {
select(tr);
}
})
}
else {
select(tr);
}
})
})
//determine if modal should displayed
function determine(tr) {
return new Promise(function(resolve) {
//check to see if user has any pending changes
var saveButton = document.getElementById('saveBtn');
var enabled = false;
if (saveButton) {
enabled = !saveButton.disabled;
}
var result = {};
result['enabled'] = enabled;
result['tr'] = tr;
resolve(result);
})
}
//show modal and return caption of the clicked button
function showModal() {
return new Promise(function(resolve) {
$('#pendingChanges button').one('click', function(e) {
var save_pending_changes = $('#save_pending_changes').val();
resolve(save_pending_changes);
})
$('#pendingChanges').modal({
backdrop: 'static',
keyboard: false
})
})
}
function getCurrentRow() {
return (dt_table.$('tr.selected'));
}
function setSelection(row) {
//first unselect any other selected row
dt_table.$('tr.selected').removeClass('selected');
//then select row
row.addClass('selected');
}
function select(tr) {
//first unselect any other selected row
dt_table.$('tr.selected').removeClass('selected');
//then select row of interest
$(tr).addClass('selected');
var rowIndices = dt_table.row('.selected')[0];
selectedRowIndex = rowIndices[0];
//set hidden param
$('#selectedRowIndex').val(selectedRowIndex);
var row = dt_table.rows(rowIndices);
if (row.data().length == 0) {
//e.preventDefault();
return;
}
var id = row.data()[0]['id'];
var url = '/report/' + id + '/';
//window.location = url;
$('#notes_display').load(url + ' #notes_display');
}
我在数据表事件处理程序中显示一个 bootstrap 模态对话框,其定义如下:
dt_table.on('click', 'tr', function(e) {
//console.log('row clicked');
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
}
else {
//check to see if user has any pending changes
var saveButton = document.getElementById('saveBtn');
if (saveButton && !saveButton.disabled) {
//for now if save button is enabled ask user if they're sure they don't want to save pending changes first
var options = {
'backdrop' : 'static', //prevents clicking outside the model to dismiss dialog
}
$('#pendingChanges').modal(options);
var save_pending_changes = $('#save_pending_changes').val();
console.log(save_pending_changes);
if (save_pending_changes) {
// console.log(e);
//e.preventDefault();
return;
}
}
console.log('about to execute default behavior');
//first unselect any other selected row
dt_table.$('tr.selected').removeClass('selected');
//then select row of interest
$(this).addClass('selected');
var rowIndices = dt_table.row('.selected')[0];
selectedRowIndex = rowIndices[0];
//set hidden param
$('#selectedRowIndex').val(selectedRowIndex);
var row = dt_table.rows(rowIndices);
if (row.data().length == 0) {
//e.preventDefault();
return;
}
var id = row.data()[0]['id'];
var url = '/report/' + id + '/';
//window.location = url;
$('#notes_display').load(url + ' #notes_display');
}
});
我 运行 遇到的问题是整个事件处理程序在模态消失之前执行。它的行为就好像模态在它自己的线程中是 运行 一样。我该如何解决这个问题?
我的模态定义为
<div class="modal fade" id="pendingChanges" tabindex="-1" role="dialog" aria-labelledby="pendingChangesLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="pendingChangesLabel">You have unsaved changes</h3>
</div>
<div class="modal-body">
<p>
<strong>Are you sure you want to leave?</strong>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="saveChanges(true)">No</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="saveChanges(false)">Yes</button>
</div>
</div>
</div>
</div>
逻辑示例会有所帮助 :) 但我想我明白了问题所在。我会建议您在 promises 中拆分工作流程:
//determine if modal should displayed
function determine(tr) {
return new Promise(function(resolve) {
//dont know the logic here
resolve(true / false)
})
}
//show modal and return caption of the clicked button
function showModal() {
return new Promise(function(resolve) {
$('#pendingChanges button').one('click', function(e) {
resolve(e.currentTarget.innerText)
})
$('#pendingChanges').modal({
backdrop: 'static',
keyboard: false
})
})
}
dt_table.on('click', 'tr', function(e) {
determine(this).then(function(result) {
if (result) {
showModal().then(function(button) {
console.log(button) //Yes or No
})
}
})
})
未测试,但应该没问题。
determine()
是否应根据<tr>
显示模态
- 调用
showModal()
仅在单击按钮时才解析 - 你得到
Yes
或No
感谢 davidkonrad 我解决了我的问题。这是工作代码。
<input type="hidden" name="save_pending_changes" id="save_pending_changes" value="false"/>
<!-- Modal -->
<div class="modal fade" id="pendingChanges" tabindex="-1" role="dialog" aria-labelledby="pendingChangesLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="pendingChangesLabel">You have unsaved changes</h3>
</div>
<div class="modal-body">
<p>
<strong>Are you sure you want to leave?</strong>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" onclick="saveChanges(true)">No</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="saveChanges(false)">Yes</button>
</div>
</div>
</div>
</div>
function saveChanges(save) {
$('#save_pending_changes').val(save);
}
dt_table.on('click', 'tr', function(e) {
var oldRow = getCurrentRow();
determine(this).then(function(result) {
var enabled = result['enabled'];
var tr = result['tr'];
if (enabled) {
showModal().then(function(save) {
if (save == 'true') {
setSelection(oldRow);
return;
}
else {
select(tr);
}
})
}
else {
select(tr);
}
})
})
//determine if modal should displayed
function determine(tr) {
return new Promise(function(resolve) {
//check to see if user has any pending changes
var saveButton = document.getElementById('saveBtn');
var enabled = false;
if (saveButton) {
enabled = !saveButton.disabled;
}
var result = {};
result['enabled'] = enabled;
result['tr'] = tr;
resolve(result);
})
}
//show modal and return caption of the clicked button
function showModal() {
return new Promise(function(resolve) {
$('#pendingChanges button').one('click', function(e) {
var save_pending_changes = $('#save_pending_changes').val();
resolve(save_pending_changes);
})
$('#pendingChanges').modal({
backdrop: 'static',
keyboard: false
})
})
}
function getCurrentRow() {
return (dt_table.$('tr.selected'));
}
function setSelection(row) {
//first unselect any other selected row
dt_table.$('tr.selected').removeClass('selected');
//then select row
row.addClass('selected');
}
function select(tr) {
//first unselect any other selected row
dt_table.$('tr.selected').removeClass('selected');
//then select row of interest
$(tr).addClass('selected');
var rowIndices = dt_table.row('.selected')[0];
selectedRowIndex = rowIndices[0];
//set hidden param
$('#selectedRowIndex').val(selectedRowIndex);
var row = dt_table.rows(rowIndices);
if (row.data().length == 0) {
//e.preventDefault();
return;
}
var id = row.data()[0]['id'];
var url = '/report/' + id + '/';
//window.location = url;
$('#notes_display').load(url + ' #notes_display');
}