Reputation: 3805
I have a link which allows a user to set their payment method as their default payment method if it is not already the default payment method. If they click it, I also have a short script that watches for a dom change for the clicked link, and if the href or link text becomes the href or text for the "default" payment method, it will check all of the other links on the page and make sure they are set to say "Make Default" and point to the correct URL's, etc (since one of them would say it is the default payment method).
Anyhow, my issue here is that if I update a link via jQuery, the anchor tag will be correct as far as the HTML goes, but clicking it will not allow the data-toggle to occur anymore.
Here is the initial link setup. The first time you click it, the data-toggle works, so the toggled info changes and it becomes the default. Then, another link like this is clicked, and this one would revert back into this state via my jQuery. At that point, it no longer toggles. I've tried to find a way to trigger the toggle without following through with the event, but if I stop the event, I would stop the toggle. And if I temporarily change the href, then I'm just altering it via jQuery and doing what I'm already doing.
<a class="default-billing default-billing-bank fws-ajax"
id="<?php echo $method->bank_id; ?>"
href="/account/billing_bank_default/<?php echo $method->bank_id; ?>"
data-toggle-href="javascript:void(0)"
data-toggle-html="Default">Make Default</a>
Here is the jQuery I'm using to reset the default link when another link was clicked and made default.
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('.default-billing').on('click', function() {
var _this = jQuery(this);
jQuery('.default-billing').one('DOMSubtreeModified', function() {
//alert('Changed: ' + $("<div />").append(jQuery(this).clone()).html());
if (jQuery(this).text() == 'Default' || jQuery(this).prop('href') == 'javascript:void(0)') {
//alert('Default');
_this.removeClass('default-billing');
setTimeout(updateDefaultBillingLinks(), 300);
_this.addClass('default-billing');
}
});
});
});
function updateDefaultBillingLinks() {
jQuery('.default-billing').each(function() {
if (jQuery(this).text() == 'Default') {
/* I am not using this part, but tried it to see if I could just toggle it manually. I couldn't.
jQuery(this).toggle();
*/
jQuery(this).text('Make Default');
jQuery(this).data('toggle-href', 'javascript:void(0)');
jQuery(this).data('toggle-html', 'Default');
if (jQuery(this).hasClass('.default-billing-card')) {
jQuery(this).prop('href', '/account/billing_card_default/' + jQuery(this).prop('id'));
}
if (jQuery(this).hasClass('.default-billing-bank')) {
jQuery(this).prop('href', '/account/billing_bank_default/' + jQuery(this).prop('id'));
}
}
});
}
</script>
UPDATE/RESOLVED
Apparently, I did have to use the .data('toggle-[attribute]')
, but my other issue was that when I was checking the .hasClass()
, I was putting a .
in front of the class name. I had to remove that.
Final jQuery:
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('.default-billing').on('click', function() {
var _this = jQuery(this);
jQuery('.default-billing').one('DOMSubtreeModified', function() {
if (jQuery(this).text() == 'Default' || jQuery(this).prop('href') == 'javascript:void(0)') {
_this.removeClass('default-billing');
jQuery('.default-billing').each(function() {
if (jQuery(this).text() == 'Default') {
jQuery(this).text('Make Default');
jQuery(this).data('toggle-href', 'javascript:void(0)');
jQuery(this).data('toggle-html', 'Default');
if (jQuery(this).hasClass('default-billing-card')) {
jQuery(this).prop('href', '/account/billing_card_default/' + jQuery(this).prop('id'));
}
if (jQuery(this).hasClass('default-billing-bank')) {
jQuery(this).prop('href', '/account/billing_bank_default/' + jQuery(this).prop('id'));
}
}
});
_this.addClass('default-billing');
}
});
});
});
</script>
Upvotes: 1
Views: 849
Reputation: 11983
You can remove the need to monitor the DOM to see if the update was successful by calling the update yourself in javascript. Example:
$('.default-billing').on('click', function(e) {
var _this = jQuery(this);
e.preventDefault();
if (_this.hasClass('is-default'))
return;
if (_this.closest('table').find('.updating').length > 0)
return;
_this.addClass('updating');
//$.ajax(this.href)
// fake Ajax call for test
__fakeAjax(this.href)
.then(function(resp) { setDefaultUI(_this); })
.always( function(){ _this.removeClass('updating') });
});
function setDefaultUI($el){
$el
.text('Default')
.addClass('is-default')
.closest('table')
.find('.is-default')
.not($el)
.text('Make Default')
.removeClass('is-default')
}
function __fakeAjax(href) {
console.log(`faking call to ${href}`);
var d = $.Deferred();
setTimeout(d.resolve, 1000);
return d.promise();
};
.is-default { font-weight:bold; }
.updating::after { content: '...'; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<caption>Banks
<tr>
<td>Bank 1
<td><a class="default-billing default-billing-bank fws-ajax is-default" href="/account/billing_bank_default/1">Default</a>
<tr>
<td>Bank 2
<td><a class="default-billing default-billing-bank fws-ajax" href="/account/billing_bank_default/2">Make Default</a>
<tr>
<td>Bank 3
<td><a class="default-billing default-billing-bank fws-ajax" href="/account/billing_bank_default/3">Make Default</a>
<tr>
<td>Bank 4
<td><a class="default-billing default-billing-bank fws-ajax" href="/account/billing_bank_default/4">Make Default</a>
</table>
<table>
<caption>Cards
<tr>
<td>Card 1
<td><a class="default-billing default-billing-card fws-ajax is-default" href="/account/billing_card_default/1">Default</a>
<tr>
<td>Card 2
<td><a class="default-billing default-billing-card fws-ajax" href="/account/billing_card_default/2">Make Default</a>
</table>
Upvotes: 0
Reputation: 1509
dont use $selector.data
method use $selector.attr
bootstrap being a css library depends on html attributes
not html5 dataset values
so instead of
jQuery(this).data('toggle-href', 'javascript:void(0)');
jQuery(this).data('toggle-html', 'Default');
use this
jQuery(this).attr('data-toggle-href', 'javascript:void(0)');
jQuery(this).attr('data-toggle-html', 'Default');
Upvotes: 1