Bootstrap 弹出窗口 - 将事件动态附加到弹出窗口的按钮
Bootstrap Popup - Attach event to button for popover dynamically
我打算使用 Bootstrap Popover 模块作为删除事件的确认,这样当 <button>
被点击时,它不会简单地触发一个函数,而是打开一个弹出窗口,让我们用户确认 或取消 操作。
上下文需要注意的是环境是self-built,one-page~mvc webapp,里面的元素是动态添加的(所以不知道多少预先定义元素,我也不能对每个元素的操作进行硬编码)
在目前的情况下(没有弹出窗口)我做了类似的事情来触发直接(non-conformation)动作:
$view.on('click', '.deleteButton', function () {
var id = $(this).attr('data-id');
api.delete('someUrl' + id, successFunction);
}):
按钮的标记与此类似:
<button class="deleteButton" data-id="2">Delete me!</button>
但是,现在我想添加一个确认步骤(例如"Are you sure you want to delete this magnificent button? (Y/N)"),并想到使用bootstrap popover。
经过一番头脑风暴,我想到了如下策略。这不是最佳解决方案(最佳解决方案是扩展 popover 模块,以便我能够将 confirmationFunction 和 cancelFunction 传递给 popover)。
首先,我必须启动弹出窗口。
$view.find('.deleteButton').popover({
title: 'Are you sure?', //Example title
html: true, //Essential for the html to work as expected
selector: '.deleteButton', //Allow ajaxing in of new elements
container: '.viewName', //So that the popovers reside w/in the current view and thus can be bound to $view (a jQuery object for the view)
content: [...], //Two <button>s with a specified class, e.g. .viewName__deleteButton--popover
});
其次,我会将事件绑定到弹出框内的按钮
$view.on('click', '.viewName__deleteButton--popover', function () {
var id = ??; // Here comes the troubling part - how do I get the ID of the clicked button? How can I target the original button? If I can do that, I think it would solve everything.
api.delete('someUrl' + id, successFunction);
});
出现的问题是如何定位最初点击的按钮?
我能想出的唯一解决方案,一点也不整洁,就是做这样的事情:
var popoverId = $(this).parents('.popover').attr('id'); //returns popoverXXXXXX
var parentElement = $view.find('[aria-describedBy="' + popoverId + '"]');
它有效,但它是一个非常肮脏的解决方案,根本感觉不到 'nice'。
有什么方法可以更简洁地完成这项工作吗?最好我能够定义一个通用函数,例如 $element.confirmationPopover({popoverSettings...}, confirmationFunction, declineFunction);
,它可以在多种情况下使用。
(PS: 我想不出这个问题的简洁标题,一如既往地感谢您的建议!)
我通过创建 jQuery 的扩展来解决它,这样:
$.fn.confirmationPopover = function (passedInOptions) {
var $view = this;
var defaultOptions = {
confirmationLabel: 'Yes',
container: '.' + this.attr('class'),
declineLabel: 'No',
html: true,
placement: 'left', //top | left | right | bottom
rowClasses: false
};
if (!passedInOptions.declineClass) {
passedInOptions.declineClass = passedInOptions.selector + '__popover__decline';
}
var obj = {}; //Merged options
$.extend(true, obj, defaultOptions, passedInOptions);
var popoverContent = '<div class="row ' + (obj.rowClasses ? obj.rowClasses : 'tac') + '">' +
'<button class="button button--small ' + obj.confirmationClass + '">' + obj.confirmationLabel + '</button>' +
'<button class="button button--small button--outline ' + obj.declineClass + '">' + obj.declineLabel + '</button>' +
'</div>';
if (!obj.content) {
obj.content = popoverContent;
}
/* Initiate Popover */
$view.popover(obj);
/**
* Bind confirmation Button
*/
$view.on('click', '.' + obj.confirmationClass, function () {
var popoverId = $(this).parents('.popover').attr('id');
var $this = $view.find('[aria-describedBy="' + popoverId + '"]');
obj.confirmationFunction($this);
});
/**
* Bind decline button
*/
$view.on('click', '.' + obj.declineClass, function () {
var popoverId = $(this).parents('.popover').attr('id');
var $this = $view.find('[aria-describedBy="' + popoverId + '"]');
if (typeof obj.declineFunction === 'function') {
obj.declineFunction($this);
} else {
$this.popover('hide');
}
});
return this;
};
你也可以用popoverX! .它是 bootstrap 弹出框的模态版本。
我打算使用 Bootstrap Popover 模块作为删除事件的确认,这样当 <button>
被点击时,它不会简单地触发一个函数,而是打开一个弹出窗口,让我们用户确认 或取消 操作。
上下文需要注意的是环境是self-built,one-page~mvc webapp,里面的元素是动态添加的(所以不知道多少预先定义元素,我也不能对每个元素的操作进行硬编码)
在目前的情况下(没有弹出窗口)我做了类似的事情来触发直接(non-conformation)动作:
$view.on('click', '.deleteButton', function () {
var id = $(this).attr('data-id');
api.delete('someUrl' + id, successFunction);
}):
按钮的标记与此类似:
<button class="deleteButton" data-id="2">Delete me!</button>
但是,现在我想添加一个确认步骤(例如"Are you sure you want to delete this magnificent button? (Y/N)"),并想到使用bootstrap popover。
经过一番头脑风暴,我想到了如下策略。这不是最佳解决方案(最佳解决方案是扩展 popover 模块,以便我能够将 confirmationFunction 和 cancelFunction 传递给 popover)。
首先,我必须启动弹出窗口。
$view.find('.deleteButton').popover({
title: 'Are you sure?', //Example title
html: true, //Essential for the html to work as expected
selector: '.deleteButton', //Allow ajaxing in of new elements
container: '.viewName', //So that the popovers reside w/in the current view and thus can be bound to $view (a jQuery object for the view)
content: [...], //Two <button>s with a specified class, e.g. .viewName__deleteButton--popover
});
其次,我会将事件绑定到弹出框内的按钮
$view.on('click', '.viewName__deleteButton--popover', function () {
var id = ??; // Here comes the troubling part - how do I get the ID of the clicked button? How can I target the original button? If I can do that, I think it would solve everything.
api.delete('someUrl' + id, successFunction);
});
出现的问题是如何定位最初点击的按钮?
我能想出的唯一解决方案,一点也不整洁,就是做这样的事情:
var popoverId = $(this).parents('.popover').attr('id'); //returns popoverXXXXXX
var parentElement = $view.find('[aria-describedBy="' + popoverId + '"]');
它有效,但它是一个非常肮脏的解决方案,根本感觉不到 'nice'。
有什么方法可以更简洁地完成这项工作吗?最好我能够定义一个通用函数,例如 $element.confirmationPopover({popoverSettings...}, confirmationFunction, declineFunction);
,它可以在多种情况下使用。
(PS: 我想不出这个问题的简洁标题,一如既往地感谢您的建议!)
我通过创建 jQuery 的扩展来解决它,这样:
$.fn.confirmationPopover = function (passedInOptions) {
var $view = this;
var defaultOptions = {
confirmationLabel: 'Yes',
container: '.' + this.attr('class'),
declineLabel: 'No',
html: true,
placement: 'left', //top | left | right | bottom
rowClasses: false
};
if (!passedInOptions.declineClass) {
passedInOptions.declineClass = passedInOptions.selector + '__popover__decline';
}
var obj = {}; //Merged options
$.extend(true, obj, defaultOptions, passedInOptions);
var popoverContent = '<div class="row ' + (obj.rowClasses ? obj.rowClasses : 'tac') + '">' +
'<button class="button button--small ' + obj.confirmationClass + '">' + obj.confirmationLabel + '</button>' +
'<button class="button button--small button--outline ' + obj.declineClass + '">' + obj.declineLabel + '</button>' +
'</div>';
if (!obj.content) {
obj.content = popoverContent;
}
/* Initiate Popover */
$view.popover(obj);
/**
* Bind confirmation Button
*/
$view.on('click', '.' + obj.confirmationClass, function () {
var popoverId = $(this).parents('.popover').attr('id');
var $this = $view.find('[aria-describedBy="' + popoverId + '"]');
obj.confirmationFunction($this);
});
/**
* Bind decline button
*/
$view.on('click', '.' + obj.declineClass, function () {
var popoverId = $(this).parents('.popover').attr('id');
var $this = $view.find('[aria-describedBy="' + popoverId + '"]');
if (typeof obj.declineFunction === 'function') {
obj.declineFunction($this);
} else {
$this.popover('hide');
}
});
return this;
};
你也可以用popoverX! .它是 bootstrap 弹出框的模态版本。