Jquery widget shares data when creating multiple instances

I created a jquery widget and it worked until I needed another instance. This is when I noticed that two instances are using the same data. The plugin should keep track of which rows are checked in the table, so I don’t need to calculate them every time I need to use them. If I go around the widget on two tables, click one row on one table - both tables will have the same data. This happens with both tables. I created a couple of jquery widgets, so I'm not sure how this happens, but I went through the code and see how it happens.

Looks like I'm misusing the factory widget. Thanks for any help in advance!

Here is the widget code.

$.widget('ui.selectAndFilter', { _init: function () { }, _create: function () { var self = this; self.options.$mainTable = $(self.element).addClass(this.options.cssWidgetClass); self.options.$mainTable.find('tbody tr').bind('click', function (e) { self._onClick(e, $(this), false); //Need to determine what todo with last param - redrawTables }); }, options: { cssWidgetClass: 'select-and-filter', cssSelectedClass: 'selected', $mainTable: {}, childTables: [], canMultiSelect: false, clickFinishedCallbacks: [], minCount: 1 }, destroy: function () { $(this.element).removeClass(this.options.cssWidgetClass); }, _checkedIds: [], checkRow: function ($tr) { if ($.isDigit($tr)) $tr = $(this.options.$mainTable.find('tbody tr:eq(' + $tr + ')')); if ($tr.length) { var id = $tr.addClass(this.options.cssSelectedClass).find(':checkbox').attr('checked', true).val(); this._addId(id); } return this; }, _uncheckRow: function ($tr) { if ($tr.length) { var id = $tr.removeClass(this.options.cssSelectedClass).find(':checkbox').attr('checked', false).val(); return this._removeId(id); } }, uncheckAllRows: function () { var self = this; this.options.$mainTable.find('tr.' + this.options.cssSelectedClass).each(function () { self._uncheckRow($(this)); }); return self; }, _removeId: function (id) { this._checkedIds.splice(this._checkedIds.indexOf(id), 1); return this._checkedIds; }, _addId: function (id) { if (this._checkedIds.indexOf(id) == -1) this._checkedIds.push(id); return this._checkedIds; }, _onClick: function (event, $tr, redrawTables) { if ($tr.hasClass(this.options.cssSelectedClass) && this._checkedIds.length > this.options.minCount) { this._uncheckRow($tr); } else { if (!this.options.canMultiSelect) { this.uncheckAllRows(); } this.checkRow($tr); } this.redrawTables(); this._trigger('click'); }, redrawTables: function () { $.each(this.options.childTables, function () { this.fnDraw(); }); }, checkedIds: function () { return this._checkedIds; } }); 

And then the code to create them.

 tables['schedule'].selectAndFilter({canMultiSelect:selectMulti, childTables: redrawTables}); tables['start'].selectAndFilter({canMultiSelect: selectMulti}) tables['batch'].selectAndFilter({minCount:0}); 
+4
source share
1 answer

The problem was that the _checkedIds array was global for the widget, and not in a separate context.

Added this line to the _create method:

 this._checkedIds = []; 

And removed this line from the widget:

 _checkedIds: [], 
+6
source

All Articles