Reputation: 1083
We got a simple jQuery script on Drupal site that injects a div class with content:
(function($) {
Drupal.behaviors.myHelpText = {
attach: function (context, settings) {
//code starts
//change placeholder text
$('.form-item-quantity').append('<span class="help-block">For orders over 10 call for volume pricing</span>');
$('.help-block').css("flex-basis", "100%");
//code ends
}
};
})(jQuery);
The page has Drupal Commerce and various product attribute fields that gets processed by Ajax every time selecting an attribute. And when doing that our script injects same duplicate line each time on Ajax load/update.
How to avoid that? We just want jQuery code work once on page load.
Upvotes: 0
Views: 250
Reputation: 10165
You have to understand that drupal.behaviors fire on page load and when ajax returns results. It is designed this way because you may want your code to run again on the ajax results, for example, if you are updating part of the page via ajax and it needs event listeners applied, or a class added.
The context
variable is the key here.
on first page load, the context will be the whole window, but when ajax returns the result, the context will just be what is returned by the ajax.
Knowing this, you should be using context
in your jquery selectors.
eg.
(function($) {
Drupal.behaviors.myHelpText = {
attach: function (context, settings) {
//code starts
//change placeholder text
$('.form-item-quantity', context).append('<span class="help-block">For orders over 10 call for volume pricing</span>');
$('.help-block', context).css("flex-basis", "100%");
//code ends
}
};
})(jQuery);
For added protection against something processing multiple times, you can use jquery once(), but this is usually not needed if using the context variable in the selector. jQuery once() separate library that must be loaded.
Upvotes: 1
Reputation: 76
Why don't use jQuery once? My thought — it's a classic approach. A bunch of examples lives in docs on drupal.org
$('.form-item-quantity').once('help-appended').append('<span class="help-block">For orders over 10 call for volume pricing</span>');
And I'm not sure you need to apply styles via js. A css file is a better place for it. And jquery once should be available in your environment. That's it.
Upvotes: 0
Reputation: 1666
Only add the element if it doesn't exist, otherwise do nothing.
(function($) {
Drupal.behaviors.myHelpText = {
attach: function (context, settings) {
if (!document.getElementById('help')) {
$('.form-item-quantity').append(
'<span id="help" class="help-block">For orders over 10 call for volume ricing</span>'
);
$('.help-block').css("flex-basis", "100%");
}
}
};
})(jQuery);
Upvotes: 1