1

In my plug-in I need to wrapp all sidebar's children in a div to let them overflow but if those elements are loaded dynamically the function does not work and I don't know either how to make it work.

The code is:

<div class="sidebar">
</div>

var $sidebar = $( '.sidebar' );

$sidebar.load( 'external-page.ext' );

$sidebar.MyPlugin();

$.fn.MyPlugin = function() {
    this.wrapInner( '<div />' );
});

If those elements are not loaded dynamically there is no problem.

Firstly the code was:

$sidebar.wrapInner( '<div/>' );

and this just works fine if elemens are not loaded dynamically, so I tried this way:

var children = $sidebar.children();

$( document ).on( 'load', children, function() {
    $( this ).wrapAll( '<div />' );
});

but, of course it does not work. Can you please help me?

I thought that this rule would have worked this time too but it didn't. What did I mistake?

You can find the whole code here. And a demo here

MORE DETAILS

I want to handle this issue from the inside, not from the outside! I don't know if users will load content dinamically or not. that's the point. So there is a way to handle this issue inside the plugin and not outside?

Community
  • 1
  • 1
ctrlmaniac
  • 404
  • 4
  • 13
  • 28
  • not sure if this helps @dcdeiv but tried to set up a fiddle which should demonstrate the problem may a little different: http://jsfiddle.net/82ptezgL/ result should be after click to show `hello hello` with `background-color:red;` – caramba Sep 18 '14 at 06:41
  • @caramba probably I miss the point, is this what are you looking for: http://jsfiddle.net/IrvinDominin/82ptezgL/1/ ? – Irvin Dominin Sep 18 '14 at 07:12
  • @IrvinDominin thank you for you comment, it kinda is :) but need to add the wrapInner outside the load function. the element gets loaded from somewhere and I want to manipulate it from somewhere else.. – caramba Sep 18 '14 at 07:32
  • @caramba but in your fiddle the wrapInner is fired before the click so the element not exist in that moment. If you execute the wrapInner in a next moment (eg in another click) it'll work. Can you provide your specific contest? – Irvin Dominin Sep 18 '14 at 07:44
  • @IrvinDominin thanks for your time and effort. in words: I have a gallery loading and adding elements to the DOM. Now when that is done I would like to change some of those elements (add others). I have a `gallery.ready()` but that doenst works – caramba Sep 18 '14 at 07:53
  • can u please setup a working fiddle that explains the error more clearly? – Balaji Viswanath Sep 24 '14 at 16:40

3 Answers3

2

From the manual

http://api.jquery.com/load/

Callback Function

If a "complete" callback is provided, it is executed after post-processing and HTML insertion has been performed. The callback is fired once for each element in the jQuery collection, and this is set to each DOM element in turn.

Try the following code and see if this works:

$sidebar.load( 'external-page.ext', function() { $sidebar.MyPlugin(); } );

Thanks.

Shaheer
  • 2,105
  • 4
  • 25
  • 39
  • thanks for your answer, already trid `load` but didn't work. added a fiddle above where the question is. could you have a try there `$(window).load(function(){});` included – caramba Sep 18 '14 at 06:42
  • 1
    http://jsfiddle.net/1dq8puyk/ here it works fine, (it will wrap .sidebar div, if you want to to wrap the inner elements, then you should call .MyPlugin on the inner elements) – Shaheer Sep 18 '14 at 07:07
  • Well, since I cannot control what users do, I want to handle this issue from the inside, not from the outside! I don't know if users will load content dinamically or not. that's the point. – ctrlmaniac Sep 18 '14 at 15:41
  • you could still ask for a class or jquery selector from the users, to select the inner elements., in the config of your plugin – Shaheer Sep 21 '14 at 06:05
0

$.load() makes an ajax call to load the data ,

So there is a possibility that your this.wrapInner( '<div />' ) method has invoked before any data is loaded inside the div.sidebar. Make sure this.wrapInner( '<div />' ) is called after all data has been loaded successfully using the complete callback.

$.load() trigger callback for each div ,call your plugin from callback

$sidebar.load('http://fiddle.jshell.net/vikrant47/ncagab2y/1/show/', function () {
            $(this).MyPlugin();
        }    
    });

DEMO

OR

If you are using $.load() only to load inside multiple elements then you could probably use one of the more powerful jQuery ajax methods (i.e., get() or post() or ajax()).

$.get('http://fiddle.jshell.net/vikrant47/ncagab2y/1/show/', {}, function(data) {
        $sidebar.html(data).MyPlugin();
    });

DEMO using $.get() Method


UPDATE-

Answer to the comment-

You should not have to worry about weather user gonna call your plugin like this $sidebar.load(...).MyPlugin().User must be aware enough about how to handle asynchronous methods.

You can not make your plugin work until there is some data inside div.slider but ,you can add ajax loading functionality inside your plugin like -

$(document).ready(function () {
    $.fn.MyPlugin = function (options) {
        var $elem=this;
        var init = function () {
            options.load = $.extend({}, $.fn.MyPlugin.defaultOptions.load, options.load);
            load();
        }
       //adding load method to load data dynamically
        var load = function () {
            if (!options.load.url) {
                alert("url can not be empty");
            } else {
                $.ajax({
                    url: options.load.url,
                    type: options.load.type,                    
                    data: options.load.data,
                    success: function (response) {
                        options.load.success.call(this, response);
                        $elem.html(response).wrapInner('<div class="wrapper"/>');//wrap after data has been loaded successfully
                    },
                    error : function (jqXHR, textStatus, errorThrown) {
                        alert("error occured" + textStatus + " ," + errorThrown)
                    }
                })
            }
        }
        init();
    }
    $.fn.MyPlugin.defaultOptions = {
        load: {
            tye: "get",
            data: {},
            success: function () {}
        }
    };

Now use your plugin like-

    var $sidebar = $('.sidebar');
    $sidebar.MyPlugin({
        load: {
            url: 'http://fiddle.jshell.net/vikrant47/ncagab2y/1/show/'
        }
    });
});

DEMO with load

vikrant singh
  • 2,091
  • 1
  • 12
  • 16
  • I want to handle this issue from the inside, not from the outside! I don't know if users will load content dinamically or not. – ctrlmaniac Sep 18 '14 at 15:41
0

Try adding adding below piece to plugin . Added at lines 84 - 110 at gist .

            var target = $sidebar.get(0);

            // create an observer instance
            var observer = new MutationObserver(function (mutations) {
                mutations.forEach(function (mutation) {
                    // do stuff when
                    // `childList` modified
                    // i.e.g., 
                    $.each(mutation.addedNodes, function (k, v) {
                        $(v)
                        .wrapInner('<div data-' 
                        + dataName 
                        + '="sub-wrapper"></div>')
                    })

                });
            });

            // configuration of the observer:
            var _config = {
                childList: true
            };

            // pass in the target node, as well as the observer options
            observer.observe(target, _config);

jsfiddle http://jsfiddle.net/guest271314/s5wzptc8/

See MutationObserver

guest271314
  • 1
  • 15
  • 104
  • 177
  • This looks verry interesting, checking back when I got some more time. dear guest, thank you for your answer! – caramba Sep 22 '14 at 06:19