Jonathan Clark
Jonathan Clark

Reputation: 20538

Defining multiple instances of a jquery ui widget on a single page

I am developing a website where I use a custom build jQuery widget to load data into multiple divs.

This is the code for the widget:

(function ($, window, document, undefined) {

    $.widget ("my.contentloader", {

        options: {

            loading_message: true

        },

        _create: function () {

            var that = this;

            $.ajax ({

                type: "POST", 

                url: that.options.url, 

                data: {data: that.options.formdata, limit: that.options.limit, offset: that.options.offset},

                beforeSend: function (html) {

                    if (that.options.loading_message) {

                        $(that.options.target_area).html ("<div id='loading'>Loading</div>");

                    }

                },

                success: function (html) {

                    if (that.options.loading_message) {

                        $('#loading').remove ();

                    }

                    $(that.options.target_area).html (html);

                },

                error: function (html) {

                    $(that.options.error_area).html (html);

                }

            });

        },

        _setOption: function (key, value) {

            this.options[key] = value;

            $.Widget.prototype._setOption.apply (this, arguments);

    }

    });

})(jQuery, window, document);

I load data using the widget like this:

$('#targetdiv').contentloader ({

 url: '<?php echo $action_url; ?>',

 target_area: '#popup_box',

 formdata: {'username' : username_email, 'password' : password}

});

I am having problems loading multiple instances on the same page. Is there a way to not instantiate the widget on a specific div like this?

$('#targetdiv').contentloader

Upvotes: 0

Views: 1913

Answers (1)

Ringo
Ringo

Reputation: 5473

I think you need to assign each instance to a variable. That way, you can control each instance, or write a function that iterates over an array of instances.

var contentLoaders = [];
$('.target-div').each(function(i, data) {
    contentLoaders[i] = $.widget("my.contentloader", { ... });
});

So then you should be able to operate on each loader independently, like:

for (var i in contentLoaders) {
    var contentLoader = contentLoaders[i];
    contentLoader.option( ... );
}

Also, you're using the DOM ID $('#loading') for multiple instances of the widget. This is wrong. You need to either use separate loaders for each widget, or else check to see if the ID exists and only insert the new node if it doesn't exist. And same for removing it.

** I've added this example block, hope it helps: **

//
// This is a way to do it if you want to explicitly define each contentloader.
// Below that, I'll write out a way to define the contentloaders in a loop.
//


var contentLoader1 = $('#targetdiv1').contentloader ({
 url: '<?php echo $action_url; ?>',
 target_area: '#popup_box',
 formdata: {'username' : username_email, 'password' : password}
});
contentLoader1.option('url', 'http://google.com');

var contentLoader2 = $('#targetdiv2').contentloader ({
 url: '<?php echo $action_url; ?>',
 target_area: '#popup_box',
 formdata: {'username' : username_email, 'password' : password}
});
contentLoader2.option('url', 'http:/apple.com');

// Push each widget instance into an array of widget objects
var contentLoaders = [];
contentLoaders.push(contentLoader1);
contentLoaders.push(contentLoader2);
for (var i in contentLoaders) {
    console.log(i, contentLoaders[i].option('url'));
}
// Should print:
// 0 http://google.com
// 1 http://apple.com



//
//
// How to set a bunch of widgets at once from an array of content loader data
//
//

var contentLoaderData = [
    {
        divid: '#targetDiv1',
        url: 'google.com',
        formdata: {
            username: 'joeshmo',
            password: 'joeshmo1'
        }
    },
    {
        divid: '#targetDiv2',
        url: 'apple.com',
        formdata: {
            username: 'plainjane',
            password: 'plainjane1'
        }
    }
];

// Array of widget instances
var contentLoaders = [];
$.each(contentLoaderData, function(index, value) {
    var contentLoader = $(this.divid).contentloader({
        url: this.url,
        target_area: '#popup_box',
        formdata: {'username' : this.formdata.username, 'password' : this.formdata.password}
    });
    // Push each contentLoader instance into the contentLoaders array
    contentLoaders.push(contentLoader);
});
for (var i in contentLoaders) {
    console.log(i, contentLoaders[i].option('url'));
}
// Should print:
// 0 http://google.com
// 1 http://apple.com

Upvotes: 1

Related Questions