I am trying to fully bind twitter bootstrap modal with knockout. By fully bind I mean that I want every close interaction with modal dialog to work with knockout. I have seen some of the questions, which partially bind them (for example this one does not allow esc).
I am using almost identical binding (which I actually found elsewhere)
ko.bindingHandlers.modal = {
init: function (element, valueAccessor) {
$(element).modal({
show: false
});
},
update: function (element, valueAccessor) {
var value = valueAccessor();
if (ko.utils.unwrapObservable(value)) {
$(element).modal('show');
} else {
$(element).modal('hide');
}
}
}
But the problem is that not everything work in my Fiddle. As you see if you close Modal with Close button, you can fire this modal again. But if you close it with Esc key, or with clicking on background, or on the X button, you can not open Modal again.
I know that the problem is due to the fact that when I close modal with other means (it is not changing observable and therefore when I fire it for the second time - nothing changes). But I can not figure out how to do this properly.
Here is my hack :-), where everything works. I am giving new value each time. But is there a better way?
bootstrap modal provided events, you just need to hook up event 'hidden.bs.modal'.
BTW, do proper disposal too. http://jsfiddle.net/C8w8v/377/
ko.bindingHandlers.modal = {
init: function (element, valueAccessor) {
$(element).modal({
show: false
});
var value = valueAccessor();
if (ko.isObservable(value)) {
// Update 28/02/2018
// Thank @HeyJude for fixing a bug on
// double "hide.bs.modal" event firing.
// Use "hidden.bs.modal" event to avoid
// bootstrap running internal modal.hide() twice.
$(element).on('hidden.bs.modal', function() {
value(false);
});
}
// Update 13/07/2016
// based on @Richard's finding,
// don't need to destroy modal explicitly in latest bootstrap.
// modal('destroy') doesn't exist in latest bootstrap.
// ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
// $(element).modal("destroy");
// });
},
update: function (element, valueAccessor) {
var value = valueAccessor();
if (ko.utils.unwrapObservable(value)) {
$(element).modal('show');
} else {
$(element).modal('hide');
}
}
}
slightly neater BS binding code - and classes are added when needed.:
ko.bindingHandlers.BSModal= {
init: function (element, valueAccessor) {
var value = valueAccessor();
$(element).addClass('modal').addClass('fade').modal({ keyboard: false, show: ko.unwrap(value) });;
},
update: function (element, valueAccessor) {
var value = valueAccessor();
ko.unwrap(value) ? $(element).modal('show') : $(element).modal('hide');
}
};
Then just data-bind="BSModal: true/false Observable"
value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With