我有一个HTML表的行绑定到数据库行。我希望每行都有一个“删除行”链接,但我想事先与用户确认。
有没有办法使用Twitter引导模式对话框来做到这一点?
我有一个HTML表的行绑定到数据库行。我希望每行都有一个“删除行”链接,但我想事先与用户确认。
有没有办法使用Twitter引导模式对话框来做到这一点?
当前回答
你可以尝试更多可重用的我的解决方案与回调函数。在这个函数中,您可以使用POST请求或一些逻辑。 使用的库:JQuery 3>和Bootstrap 3>。
https://jsfiddle.net/axnikitenko/gazbyv8v/
测试的Html代码:
...
<body>
<a href='#' id="remove-btn-a-id" class="btn btn-default">Test Remove Action</a>
</body>
...
Javascript:
$(function () {
function remove() {
alert('Remove Action Start!');
}
// Example of initializing component data
this.cmpModalRemove = new ModalConfirmationComponent('remove-data', remove,
'remove-btn-a-id', {
txtModalHeader: 'Header Text For Remove', txtModalBody: 'Body For Text Remove',
txtBtnConfirm: 'Confirm', txtBtnCancel: 'Cancel'
});
this.cmpModalRemove.initialize();
});
//----------------------------------------------------------------------------------------------------------------------
// COMPONENT SCRIPT
//----------------------------------------------------------------------------------------------------------------------
/**
* Script processing data for confirmation dialog.
* Used libraries: JQuery 3> and Bootstrap 3>.
*
* @param name unique component name at page scope
* @param callback function which processing confirm click
* @param actionBtnId button for open modal dialog
* @param text localization data, structure:
* > txtModalHeader - text at header of modal dialog
* > txtModalBody - text at body of modal dialog
* > txtBtnConfirm - text at button for confirm action
* > txtBtnCancel - text at button for cancel action
*
* @constructor
* @author Aleksey Nikitenko
*/
function ModalConfirmationComponent(name, callback, actionBtnId, text) {
this.name = name;
this.callback = callback;
// Text data
this.txtModalHeader = text.txtModalHeader;
this.txtModalBody = text.txtModalBody;
this.txtBtnConfirm = text.txtBtnConfirm;
this.txtBtnCancel = text.txtBtnCancel;
// Elements
this.elmActionBtn = $('#' + actionBtnId);
this.elmModalDiv = undefined;
this.elmConfirmBtn = undefined;
}
/**
* Initialize needed data for current component object.
* Generate html code and assign actions for needed UI
* elements.
*/
ModalConfirmationComponent.prototype.initialize = function () {
// Generate modal html and assign with action button
$('body').append(this.getHtmlModal());
this.elmActionBtn.attr('data-toggle', 'modal');
this.elmActionBtn.attr('data-target', '#'+this.getModalDivId());
// Initialize needed elements
this.elmModalDiv = $('#'+this.getModalDivId());
this.elmConfirmBtn = $('#'+this.getConfirmBtnId());
// Assign click function for confirm button
var object = this;
this.elmConfirmBtn.click(function() {
object.elmModalDiv.modal('toggle'); // hide modal
object.callback(); // run callback function
});
};
//----------------------------------------------------------------------------------------------------------------------
// HTML GENERATORS
//----------------------------------------------------------------------------------------------------------------------
/**
* Methods needed for get html code of modal div.
*
* @returns {string} html code
*/
ModalConfirmationComponent.prototype.getHtmlModal = function () {
var result = '<div class="modal fade" id="' + this.getModalDivId() + '"';
result +=' tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">';
result += '<div class="modal-dialog"><div class="modal-content"><div class="modal-header">';
result += this.txtModalHeader + '</div><div class="modal-body">' + this.txtModalBody + '</div>';
result += '<div class="modal-footer">';
result += '<button type="button" class="btn btn-default" data-dismiss="modal">';
result += this.txtBtnCancel + '</button>';
result += '<button id="'+this.getConfirmBtnId()+'" type="button" class="btn btn-danger">';
result += this.txtBtnConfirm + '</button>';
return result+'</div></div></div></div>';
};
//----------------------------------------------------------------------------------------------------------------------
// UTILITY
//----------------------------------------------------------------------------------------------------------------------
/**
* Get id element with name prefix for this component.
*
* @returns {string} element id
*/
ModalConfirmationComponent.prototype.getModalDivId = function () {
return this.name + '-modal-id';
};
/**
* Get id element with name prefix for this component.
*
* @returns {string} element id
*/
ModalConfirmationComponent.prototype.getConfirmBtnId = function () {
return this.name + '-confirm-btn-id';
};
其他回答
得到的配方
对于这个任务,您可以使用已经可用的插件和引导扩展。或者你也可以用3行代码弹出确认窗口。来看看。
假设我们有这样的链接(注意data-href而不是href)或按钮,我们想要对它们进行删除确认:
<a href="#" data-href="delete.php?id=23" data-toggle="modal" data-target="#confirm-delete">Delete record #23</a>
<button class="btn btn-default" data-href="/delete.php?id=54" data-toggle="modal" data-target="#confirm-delete">
Delete record #54
</button>
这里#confirm-delete指向HTML中的一个模态弹出div。它应该有一个“OK”按钮,配置如下:
<div class="modal fade" id="confirm-delete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
...
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<a class="btn btn-danger btn-ok">Delete</a>
</div>
</div>
</div>
</div>
现在你只需要这个小javascript使删除操作可确认:
$('#confirm-delete').on('show.bs.modal', function(e) {
$(this).find('.btn-ok').attr('href', $(e.relatedTarget).data('href'));
});
因此,在show.bs.modal event delete button上,href被设置为带有相应记录id的URL。
演示:http://plnkr.co/edit/NePR0BQf3VmKtuMmhVR7?p=preview
帖子食谱
我意识到在某些情况下可能需要执行POST或DELETE请求,而不是GET请求。它仍然很简单,没有太多的代码。看看下面使用这种方法的演示:
// Bind click to OK button within popup
$('#confirm-delete').on('click', '.btn-ok', function(e) {
var $modalDiv = $(e.delegateTarget);
var id = $(this).data('recordId');
$modalDiv.addClass('loading');
$.post('/api/record/' + id).then(function() {
$modalDiv.modal('hide').removeClass('loading');
});
});
// Bind to modal opening to set necessary data properties to be used to make request
$('#confirm-delete').on('show.bs.modal', function(e) {
var data = $(e.relatedTarget).data();
$('.title', this).text(data.recordTitle);
$('.btn-ok', this).data('recordId', data.recordId);
});
// Bind click to OK button within popup $('#confirm-delete').on('click', '.btn-ok', function(e) { var $modalDiv = $(e.delegateTarget); var id = $(this).data('recordId'); $modalDiv.addClass('loading'); setTimeout(function() { $modalDiv.modal('hide').removeClass('loading'); }, 1000); // In reality would be something like this // $modalDiv.addClass('loading'); // $.post('/api/record/' + id).then(function() { // $modalDiv.modal('hide').removeClass('loading'); // }); }); // Bind to modal opening to set necessary data properties to be used to make request $('#confirm-delete').on('show.bs.modal', function(e) { var data = $(e.relatedTarget).data(); $('.title', this).text(data.recordTitle); $('.btn-ok', this).data('recordId', data.recordId); }); .modal.loading .modal-content:before { content: 'Loading...'; text-align: center; line-height: 155px; font-size: 20px; background: rgba(0, 0, 0, .8); position: absolute; top: 55px; bottom: 0; left: 0; right: 0; color: #EEE; z-index: 1000; } <script data-require="jquery@*" data-semver="2.0.3" src="//code.jquery.com/jquery-2.0.3.min.js"></script> <script data-require="bootstrap@*" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> <link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" /> <div class="modal fade" id="confirm-delete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel">Confirm Delete</h4> </div> <div class="modal-body"> <p>You are about to delete <b><i class="title"></i></b> record, this procedure is irreversible.</p> <p>Do you want to proceed?</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-danger btn-ok">Delete</button> </div> </div> </div> </div> <a href="#" data-record-id="23" data-record-title="The first one" data-toggle="modal" data-target="#confirm-delete"> Delete "The first one", #23 </a> <br /> <button class="btn btn-default" data-record-id="54" data-record-title="Something cool" data-toggle="modal" data-target="#confirm-delete"> Delete "Something cool", #54 </button>
演示:http://plnkr.co/edit/V4GUuSueuuxiGr4L9LmG?p=preview
引导2.3
这是我为Bootstrap 2.3模态回答这个问题时所做的代码的原始版本。
$('#modal').on('show', function() {
var id = $(this).data('id'),
removeBtn = $(this).find('.danger');
removeBtn.attr('href', removeBtn.attr('href').replace(/(&|\?)ref=\d*/, '$1ref=' + id));
});
演示:http://jsfiddle.net/MjmVr/1595/
这是我的确认框“jquery组件”引导 在你的代码中使用这个:
function ConfirmBox({title,message,result}){
let confirm = $(`
<div class="modal fade" tabindex="-1" id="confirmBox" role="dialog" aria-labelledby="modalLabelSmall" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header" style="text-align:center">
<button type="button" class="close" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="modalLabelSmall">${title}</h4>
</div>
<div class="modal-body">
${message}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default confirmButton">sure</button>
</div>
</div>
</div>
</div>
`);
//append confirm box to the DOM
$("body").append(confirm);
confirm.modal();
//handlers
confirm.find("button.confirmButton").one("click",function(){
result(true);
confirm.modal("hide");
});
confirm.find("button.close").one("click",function(){
result(false);
confirm.modal("hide");
})
//remove modal after hiding it
confirm.one('hidden.bs.modal', function () {
confirm.remove();
});
}
POST配方导航到目标页面和可重用的刀片文件
Dfsq的回答非常好。我对它做了一些修改,以适应我的需求:我实际上需要一个模式,在点击之后,用户也会被导航到相应的页面。异步执行查询并不总是需要的。
使用Blade我创建了文件资源/views/includes/confirmation_modal.blade.php:
<div class="modal fade" id="confirmation-modal" tabindex="-1" role="dialog" aria-labelledby="confirmation-modal-label" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4>{{ $headerText }}</h4>
</div>
<div class="modal-body">
{{ $bodyText }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<form action="" method="POST" style="display:inline">
{{ method_field($verb) }}
{{ csrf_field() }}
<input type="submit" class="btn btn-danger btn-ok" value="{{ $confirmButtonText }}" />
</form>
</div>
</div>
</div>
</div>
<script>
$('#confirmation-modal').on('show.bs.modal', function(e) {
href = $(e.relatedTarget).data('href');
// change href of button to corresponding target
$(this).find('form').attr('action', href);
});
</script>
现在,使用它很简单:
<a data-href="{{ route('data.destroy', ['id' => $data->id]) }}" data-toggle="modal" data-target="#confirmation-modal" class="btn btn-sm btn-danger">Remove</a>
这里没有太多变化,模态可以像这样包含:
@include('includes.confirmation_modal', ['headerText' => 'Delete Data?', 'bodyText' => 'Do you really want to delete these data? This operation is irreversible.',
'confirmButtonText' => 'Remove Data', 'verb' => 'DELETE'])
只要把动词放在那里,它就会用到它。这样,也可以利用CSRF。
帮了我,也许也能帮到别人。
我发现这个很有用,很容易使用,而且看起来很漂亮:http://maxailloud.github.io/confirm-bootstrap/。
要使用它,在你的页面中包含.js文件,然后运行:
$('your-link-selector').confirmModal();
你可以应用各种各样的选项,让它在确认删除时看起来更好,我使用:
$('your-link-selector').confirmModal({
confirmTitle: 'Please confirm',
confirmMessage: 'Are you sure you want to delete this?',
confirmStyle: 'danger',
confirmOk: '<i class="icon-trash icon-white"></i> Delete',
confirmCallback: function (target) {
//perform the deletion here, or leave this option
//out to just follow link..
}
});
下面的解决方案比bootbox.js更好,因为
它可以做bootbox.js能做的所有事情; 使用语法更简单 它允许你优雅地控制你的信息的颜色使用“错误”,“警告”或“信息” Bootbox有986行长,我的只有110行长
digimango.messagebox.js:
const dialogTemplate = '\ <div class ="modal" id="digimango_messageBox" role="dialog">\ <div class ="modal-dialog">\ <div class ="modal-content">\ <div class ="modal-body">\ <p class ="text-success" id="digimango_messageBoxMessage">Some text in the modal.</p>\ <p><textarea id="digimango_messageBoxTextArea" cols="70" rows="5"></textarea></p>\ </div>\ <div class ="modal-footer">\ <button type="button" class ="btn btn-primary" id="digimango_messageBoxOkButton">OK</button>\ <button type="button" class ="btn btn-default" data-dismiss="modal" id="digimango_messageBoxCancelButton">Cancel</button>\ </div>\ </div>\ </div>\ </div>'; // See the comment inside function digimango_onOkClick(event) { var digimango_numOfDialogsOpened = 0; function messageBox(msg, significance, options, actionConfirmedCallback) { if ($('#digimango_MessageBoxContainer').length == 0) { var iDiv = document.createElement('div'); iDiv.id = 'digimango_MessageBoxContainer'; document.getElementsByTagName('body')[0].appendChild(iDiv); $("#digimango_MessageBoxContainer").html(dialogTemplate); } var okButtonName, cancelButtonName, showTextBox, textBoxDefaultText; if (options == null) { okButtonName = 'OK'; cancelButtonName = null; showTextBox = null; textBoxDefaultText = null; } else { okButtonName = options.okButtonName; cancelButtonName = options.cancelButtonName; showTextBox = options.showTextBox; textBoxDefaultText = options.textBoxDefaultText; } if (showTextBox == true) { if (textBoxDefaultText == null) $('#digimango_messageBoxTextArea').val(''); else $('#digimango_messageBoxTextArea').val(textBoxDefaultText); $('#digimango_messageBoxTextArea').show(); } else $('#digimango_messageBoxTextArea').hide(); if (okButtonName != null) $('#digimango_messageBoxOkButton').html(okButtonName); else $('#digimango_messageBoxOkButton').html('OK'); if (cancelButtonName == null) $('#digimango_messageBoxCancelButton').hide(); else { $('#digimango_messageBoxCancelButton').show(); $('#digimango_messageBoxCancelButton').html(cancelButtonName); } $('#digimango_messageBoxOkButton').unbind('click'); $('#digimango_messageBoxOkButton').on('click', { callback: actionConfirmedCallback }, digimango_onOkClick); $('#digimango_messageBoxCancelButton').unbind('click'); $('#digimango_messageBoxCancelButton').on('click', digimango_onCancelClick); var content = $("#digimango_messageBoxMessage"); if (significance == 'error') content.attr('class', 'text-danger'); else if (significance == 'warning') content.attr('class', 'text-warning'); else content.attr('class', 'text-success'); content.html(msg); if (digimango_numOfDialogsOpened == 0) $("#digimango_messageBox").modal(); digimango_numOfDialogsOpened++; } function digimango_onOkClick(event) { // JavaScript's nature is unblocking. So the function call in the following line will not block, // thus the last line of this function, which is to hide the dialog, is executed before user // clicks the "OK" button on the second dialog shown in the callback. Therefore we need to count // how many dialogs is currently showing. If we know there is still a dialog being shown, we do // not execute the last line in this function. if (typeof (event.data.callback) != 'undefined') event.data.callback($('#digimango_messageBoxTextArea').val()); digimango_numOfDialogsOpened--; if (digimango_numOfDialogsOpened == 0) $('#digimango_messageBox').modal('hide'); } function digimango_onCancelClick() { digimango_numOfDialogsOpened--; if (digimango_numOfDialogsOpened == 0) $('#digimango_messageBox').modal('hide'); }
使用digimango.messagebox.js:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>A useful generic message box</title> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <link rel="stylesheet" type="text/css" href="~/Content/bootstrap.min.css" media="screen" /> <script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript"></script> <script src="~/Scripts/bootstrap.js" type="text/javascript"></script> <script src="~/Scripts/bootbox.js" type="text/javascript"></script> <script src="~/Scripts/digimango.messagebox.js" type="text/javascript"></script> <script type="text/javascript"> function testAlert() { messageBox('Something went wrong!', 'error'); } function testAlertWithCallback() { messageBox('Something went wrong!', 'error', null, function () { messageBox('OK clicked.'); }); } function testConfirm() { messageBox('Do you want to proceed?', 'warning', { okButtonName: 'Yes', cancelButtonName: 'No' }, function () { messageBox('Are you sure you want to proceed?', 'warning', { okButtonName: 'Yes', cancelButtonName: 'No' }); }); } function testPrompt() { messageBox('How do you feel now?', 'normal', { showTextBox: true }, function (userInput) { messageBox('User entered "' + userInput + '".'); }); } function testPromptWithDefault() { messageBox('How do you feel now?', 'normal', { showTextBox: true, textBoxDefaultText: 'I am good!' }, function (userInput) { messageBox('User entered "' + userInput + '".'); }); } </script> </head> <body> <a href="#" onclick="testAlert();">Test alert</a> <br/> <a href="#" onclick="testAlertWithCallback();">Test alert with callback</a> <br /> <a href="#" onclick="testConfirm();">Test confirm</a> <br/> <a href="#" onclick="testPrompt();">Test prompt</a><br /> <a href="#" onclick="testPromptWithDefault();">Test prompt with default text</a> <br /> </body> </html>