Mottie / tablesorter

Github fork of Christian Bach's tablesorter plugin + awesomeness ~
https://mottie.github.io/tablesorter/docs/
2.61k stars 754 forks source link

Default widgetOptions get overwritten after first use #1640

Open lesilent opened 5 years ago

lesilent commented 5 years ago

When extending the default widgetOptions, they get overwritten after they've been applied to a table. I believe this issue might be the same as the one in #1356 (which I think is still an issue even with the newest version). Below is my example.

https://jsbin.com/boxujocagu/1/edit?html,output

I noticed the problem when upgrading from an older version.

lesilent commented 5 years ago

Mottie, I think I have a fix for this. The source of this problem is in the applyWidgetOptions function line 2000:

$.extend( true, ts.defaults.widgetOptions, widget.options );

This, in effect, overwrites any default widgetOptions that the might be assigned directly (eg. jQuery.tablesorter.defaults.widgetOptions.filter_cssFilter = 'form-control'; ).

The solution would be to make a copy of the existing defaults.widgetOptions, and then re-apply them after the widget.options has been applied, like so:

var tmp = jQuery.extend(true, {}, ts.defaults.widgetOptions);

$.extend( true, ts.defaults.widgetOptions, widget.options, tmp );
Mottie commented 5 years ago

Actually, widget.options comes directly from the widget on initialization, not the user settings for the widget, those go into the config. So that shouldn't be an issue since the options being added shouldn't already exist in the defaults.

lesilent commented 5 years ago

I'm referring to when a default widgetOption is set directly:

  1. Set a global/custom default widgetOption like so:

jQuery.tablesorter.defaults.widgetOptions.filter_cssFilter = 'form-control';

  1. When tablesorter is first called, the config extends the defaults:

c = $.extend( true, {}, ts.defaults, settings, ts.instanceMethods );

The custom filter_CssFilter widget option is in both the config and the defaults, ie:

c.widgetOptions.filter_cssFilter = 'form-control'; jQuery.tablesorter.defaults.widgetOptions.filter_cssFilter = 'form-control';

  1. applyWidgetOptions function is called:

c.widgetOptions = $.extend( true, wo, c.widgetOptions );

Initially, the custom widget option is still in both the config and the defaults, ie:

c.widgetOptions.filter_cssFilter = 'form-control'; jQuery.tablesorter.defaults.widgetOptions.filter_cssFilter = 'form-control';

  1. However, later in the same function, the widget.options are added to defaults for the option validator:

$.extend( true, ts.defaults.widgetOptions, widget.options );

The custom widget option is still in the config, but now the default.widgetOtions has been overwritten by the widget.options, ie:

c.widgetOptions.filter_cssFilter = 'form-control'; jQuery.tablesorter.defaults.widgetOptions.filter_cssFilter = '';

  1. First table works as expected since its config has the global/custom default widget option that was set up in step 1, but subsequent tables don't because they were overwritten by the widget.options in step 4.

TLDR: Currently, you can set default options directly (eg. jQuery.tablesorter.defaults.theme = 'bootstrap') but you cannot set default widgetOptions (eg. jQuery.tablesorter.defaults.widgetOptions.filter_cssFilter = 'form-control';) that "stick" since they get overwritten after first use by the applyWidgetOptions function.