diff --git a/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.widget.js b/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.widget.js index 052fdeb1eb..6758c05aad 100644 --- a/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.widget.js +++ b/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.widget.js @@ -325,12 +325,8 @@ if (!PrimeFaces.widget) { //remove script tag this.removeScriptElement(this.id); - if (this.widgetVar) { - var $this = this; - this.jq.on("remove", function() { - PrimeFaces.detachedWidgets.push($this.widgetVar); - }); - } + // clean up the widget if its DOM element is removed from the DOM + this.bindDomRemovalEvent(this.jq); }, /** @@ -585,6 +581,23 @@ if (!PrimeFaces.widget) { } return this.cfg.formId; + }, + + /** + * Registers a DOM element such that its removal from the DOM results in the widget becoming "detached," + * subsequently leading to its removal upon completion of the AJAX call. + * + * @param {JQuery | HTMLElement} watchElement The HTML element that if removed from the DOM will detach this widget. + * @since 14.0.0 + */ + bindDomRemovalEvent: function(watchElement) { + if (this.widgetVar) { + var $this = this; + var jq = $(watchElement); + jq.off("remove.widget").on("remove.widget", function() { + PrimeFaces.detachedWidgets.push($this.widgetVar); + }); + } } }); diff --git a/primefaces/src/main/resources/META-INF/resources/primefaces/menu/menu.base.js b/primefaces/src/main/resources/META-INF/resources/primefaces/menu/menu.base.js index ac510bc6d4..1964fcf7ff 100644 --- a/primefaces/src/main/resources/META-INF/resources/primefaces/menu/menu.base.js +++ b/primefaces/src/main/resources/META-INF/resources/primefaces/menu/menu.base.js @@ -78,6 +78,9 @@ PrimeFaces.widget.Menu = PrimeFaces.widget.BaseWidget.extend({ var $this = this; this.trigger = PrimeFaces.expressions.SearchExpressionFacade.resolveComponentsAsSelector(this.jq, this.cfg.trigger); + + // if the trigger is removed from the DOM we should destroy this menu widget + this.bindDomRemovalEvent(this.trigger); //mark trigger and descendants of trigger as a trigger for a primefaces overlay this.trigger.data('primefaces-overlay-target', true).find('*').data('primefaces-overlay-target', true); diff --git a/primefaces/src/main/resources/META-INF/resources/primefaces/sticky/sticky.js b/primefaces/src/main/resources/META-INF/resources/primefaces/sticky/sticky.js index e64fdb629c..9d691046d8 100644 --- a/primefaces/src/main/resources/META-INF/resources/primefaces/sticky/sticky.js +++ b/primefaces/src/main/resources/META-INF/resources/primefaces/sticky/sticky.js @@ -40,6 +40,8 @@ PrimeFaces.widget.Sticky = PrimeFaces.widget.BaseWidget.extend({ height: this.target.height() }; + // if the target is removed from the DOM we should destroy this widget + this.bindDomRemovalEvent(this.target); this.bindEvents(); },