How do I use the "live" feature of bootstrap's popovers? - javascript

In the old days, bootstrap's popover had a "live" option which allowed us to make the $('.myclass').popover({live: true}) call even before the DOM elements existed. I looked at the docs for 2.2 and this seems to be gone. What's the new way to do it?

The live mode is not used any more.
The Bootstrap JS plugins now use delegated events via the jQuery .on method. You can supply an event delegation target selector pointing to an element which might or might not exist.
$('.some-container').popover({
selector: '.has-popover'
});
Working example generating DOM elements with popover attached: http://jsfiddle.net/asKF9/

Related

CKEDITOR destroy

I want to remove all divs, classes, attributes and pretty much anything CKEDITOR added to the DOM. For example calling jquery tabs("destroy"); will remove all added divs added by jQuery tabs. How can I do the same for CKEDITOR, cant seem to find the solution.
$("body").find("[edit]").each(function() {
$(this).ckeditor();
});
Thats how I'm calling ckeditor. I found this in the documentation, but am not sure how to use it. http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#destroy
If you can construct a selector for what you want to remove, you can use jQuery's remove function. For example, if all the CKEditor elements contain "ckeditor" in their class, you could use
$("[class*='ckeditor']").remove()
to remove them all from the DOM.
https://api.jquery.com/remove/
According to http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.html#.remove you should use the destroy() function not remove()
Removes an editor instance from the global CKEDITOR object.
This function is available for internal use only. External code
must use CKEDITOR.editor.prototype.destroy to avoid memory leaks.
So the code would be
$([class*='ckeditor']).destroy(true)
You need to keep things separated. You can't use jQuery to remove CKEditor instances, and you can't use CKEditor to remove jQuery dialogs or any other jQuery widget.
jQuery's .remove() is to remove elements from the DOM, that is correct, but that does not properly destroy any added events etc.
So you use CKEditor's .destroy() to remove any instances from your DOM and then you can remove any jQuery containers (tabs, dialogs or whatever) after with jQuery's destruction method. For a jQuery-UI dialog that would be: $("#myDiv").dialog("destroy").
// So to create you use
var editor = CKEditor.replace('id-of-your-input');
// and to destroy you use:
editor.destroy();
It's that simple.
I created a plunk here where i create and destroy a CKEditor in steps in a jQuery Dialog: http://plnkr.co/edit/z1YJa4?p=preview
The official docs are here:
http://sdk.ckeditor.com/samples/saveajax.html
Hope that helps.

bootstrap affix plugin memory leak

These lines in the bootstrap affix plugin seem to cause a memory leak because the window gets a reference to the affix instance that's never released.
As a workaround I'm using this code to release the references when removing the affixed element from the DOM:
$(window)
.off('scroll.bs.affix.data-api')
.off('click.bs.affix.data-api');
Seems kind of hacky- is there a better way of doing this? Didn't see anything in the affix plugin docs.
By default, bootstrap Affix listens for scroll and click events on $(window) using the .bs, .affix, and .data-api namespaces.
$.off('.affix'); will remove all listeners in the .affix namespace.
$(window).off('.affix'); will remove all listeners in the .affix namespace from the window element. If you only have one Affix, and are affixing it to the window, it has the exact same effect as $.off('.affix');
Adding in the other namespaces makes it more specific, but unless you are using the .affix namespace in your own code, the added specificity doesn't change anything. You don't want to remove the other namespaces independently of .affix if you are using any other bootstrap elements.
$('.affix').off('.affix'); will not work because the listeners are not on the Affixed element, but on the target that element is Affixed to, i.e. the window.
pstenstrm is correct that there is no way to detect that an element is removed from the DOM, or injected for that matter. So if the code later re-injects the element, and you want to behave as an Affix again, you'll need to use the bootstrap JS api to call Affix again.
I took #Carrie Kendall's recommendation and opened a bug report... well commented on a related bug report.
https://github.com/twbs/bootstrap/issues/13655
What we need in this case is a "destroy" method for the affix plugin and some documentation on the getbootstrap site so that people using the affix plugin in single page apps can avoid the memory leak pitfall when removing their affixed content.
There is no way to detect when an element is removed from the DOM. The affix plugin can't automatically remove the listeners. The way you do it is the right way.
Though by calling $(window).off() you remove every listener, even those you might want to keep. It would be safer to only call $.off() on the element you are removing.
$('.affix').off('.affix');
The .bs, .affix and .data-api after the event name are namespaces. By calling $.off('.affix') you remove every event declared in that namespace. Which is probably the only better of doing what you're doing.

Automatically call jQuery functions on new dom elements

Is it possible to call an jQuery function on newly matched items automatically?
For example I have the following code:
$(document).ready(function(){
$('[draggable]').draggable();
});
This adds the 'draggable' to each element which matches [draggable] however when further along the road new elements with the attribute 'draggable' are added those are not getting the 'draggable()' function getting called on them.
Is it possible to monitor the DOM or something and also call this method on each new dom item which matches the selector?
I know there is something like this for 'click' events and such (the jquery delegate method) but as far as I know I can't seem to use that for this case.
Check "Mutation Events" there is an event called DOMNodeInserted maybe it helps you
by the way, check: JQuery - use element with DOMNodeInserted
You can use the arrive.js library that I developed for the exact same purpose (it uses MutationObserver internally). Usage:
document.arrive('[draggable]', function(){
// 'this' refers to the newly created element
$(this).draggable();
});
there was ".live()" for jQuery, but i see it's deprecated?!
don't get the transformation from ".live()" to the new ".on()"-method currently, but take a look # yourself and maybe ask in their forum...
this should be the right way to do...
http://api.jquery.com/live/
.on() is what you need if you are running jQuery 1.7 or later. It will run on elements as they are added to the page, as well as those already in place when it's called. If you're using an earlier version, take a look at the .live() method, which has since been deprecated but has the same functionality with added elements.
Depending on which version of jQuery you're using, look into the .on() method. If I understand what you're looking for here, it should meet your needs.
The equivalent in previous versions of the framework was .live().

JavaScript/jQuery: Monitor change to element?

Is there any way (aside from creating a new event) that I can tell when a particular CSS class has been added to an element?
If you don't have access to the code that's adding the class, there's a jQuery plugin called livequery that will allow you to run code when elements are added to the DOM (or when you do things like add a class to an element).
http://brandonaaron.net/code/livequery/docs
$('div.myClass').livequery(function() {
alert('myClass was added');
});
$('#someDiv').addClass("myClass"); // The livequery code will run
This works specifically with jQuery methods.
You could extend jQuery's addClass() to fire an event when it adds a class. However, this means you'll have to add classes always with this method.
If you don't do that, you'll have to poll and look for differences in the class attribute. I don't recommend doing that. Besides performance, you'll need to handle classes being removed too.
There is a DOM Level 3 specification to detect changes to an elements attributes, it is supported in a couple of browsers... Also IE supports an onpropertychange (http://msdn.microsoft.com/en-us/library/ms536956(VS.85).aspx) event too.
It's probably not going to be enough though. Your best bet is use window.setInterval() and check if the value has changed.

dynamically added HTML elements won't be affected by plugins !

there are plugins such as flowplayer overlay that asks to put a "rel" attribute to the HTML element to make it trigger certain events ... the problem is , when I create dynamically elements that have that rel attribute ,, they won't trigger it ... what is the solution for this !?
You should use the live() method to trigger events for dynamically created elements.
Example:
$('selector').live('click', function(){
// your code .........................
});
Since jQuery 1.4.2 you can also use .delegate():
Description: Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.
The use of delegate can sometimes result in less and more understandable code than .live().
Edit the plugin so it uses live() to handle events.
Generally, there is the jQuery live() function to address exactly this kind of issue.
You would have to change the plugin to use live(), or run their initialization function every time new content is added.
The latter approach can be pretty resource-intensive on the client end and is not very clean, but if the number of elements in question is not too much, it can often be the easiest way.

Categories