I am trying to get modals to consistently work with Meteor. They have this problem of disappearing when data context values change. I've already solved a portion of this problem, as documented by this question, but now it's back, and it's happening when values in the surrounding template change, rather than values in the template.
Here's the actual modal:
<div class="modal fade" id="paymentModal" tabindex="-1" role="dialog" aria-labelledby="paymentModalLabel" 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="paymentModalLabel">Make a Payment</h4>
</div>
<div class="modal-body">
{{> paymentModalBody}}
</div>
<div class="modal-footer">
{{> paymentModalFeedback}}
</div>
</div>
</div>
</div>
The modal works fine when the values changing are inside of it (or in other words, when paymentModalBody
or paymentModalFeedback
have changing values, since those template re-renders don't cause the main modal elements to be re-rendered), but....
this is happening inside my userView
template, which displays information about a user (duh). The modal handles payment interaction with the user, and calls a Meteor.method
called...
makeBraintreePayment: function(saleObj) {
var now = new Date();
Gateway.transaction.sale(saleObj, Meteor.bindEnvironment(
function (err, result) {
if (result.success) {
if (result.transaction.customer.id && saleObj.options.storeInVaultOnSuccess) {
Meteor.users.update(Meteor.userId(), {$set: { braintree_id: result.transaction.customer.id }});
}
var paymentId = Payments.insert({ ... });
Meteor.users.update(Meteor.userId(), {$push: { 'payment_ids': paymentId }});
return result.transaction.id;
} else {
throw new Meteor.Error(401, result.message);
}
},
function(err) {
console.log('bind failure: ' + err.message);
}
));
}
now again, all of this works just fine, but, after the payment is made and the modal has displayed the success message, after a second or two the modal disappears and leaves only the background, locking out the user and making it necessary to refresh the page. Broken.
It's pretty clear to me that this is happening because of those Meteor.users.update
calls, since they're changing the data context of the userView
template, which is causing the modal template to be re-rendered. So, I tried to use preserve
:
Template.userView.preserve(['#paymentModal', '.modal-dialog', '.modal-content', '.modal-header', '.modal-body', 'modal-footer', '.modal-title', '.close']);
and this:
Template.userView.preserve(['#paymentModal']);
Neither worked. This should be maintaining the html for all of the static modal elements, while allowing everything around it to be re-rendered, but it doesn't.
What's going on? How to I solve this?
Thanks in advance!
P.S.
I have been trying to solve this problem by using a more stable modal library, bootboxjs
, but I've had a different problem with that. If you can offer some insight on either that would be awesome!