ivaynberg/select2 — pull request #2519 by prantlf (2014-07-08 09:11:48+00:00)
Title: Add support for jQuery UI

This change offers to resolve the #990. It enables adding/removing of extra classes in additional to the select2-* ones, which allows supporting the jQuery UI themes. The same support can serve other GUI frameworks too. There is a sample of native, jQuery UI and Bootstrap stylings in the [theming-sample branch](https://github.com/prantlf/select2/tree/theming-sample). I am willing modify it according to your feedback and if accepted, update the API documentation too.

This change includes:

**Prepare for styling by jQuery UI themes**

Separate the native look&feel styling to select2-native.css; leave the structural styling in select2-base.css. Theme-specific properties include color, background, border, box-shadow, filter, font. These are decided by the jQuery UI theme.

Introduce an array of additional CSS classes to be added after the original select2-* ones. The select2-* classes make the public interface and they are always present. jQuery UI theming is based on different class names and also different class structure; their classes are added and removed with the select2-* ones. Every framework/theme can attach its classes to the select2-* according to its class concepts. I started with approx. 40, of which approx. 20 are used by the native, jQuery UI and Bootstrap stylings.

// List all recognized classes with empty strings - base to be merged with the theme
$.fn.select2.defaults.classes_base = {
"container": "", // appended after select2-container
...
};

// Define native look&feel class appendices
$.fn.select2.defaults.classes_native = {
"container": "select2-container-native",
...
};

// Define jQuery UI look&feel class appendices
$.fn.select2.defaults["classes_jquery-ui"] = {
"container": "ui-widget ui-widget-content ui-corner-all",
...
};

// Make the default theme overridale on the page
$.fn.select2.defaults.theme_default = "native";

prepareOpts: function (opts) {
...
opts.theme || (opts.theme = opts.theme_default);
opts.classes = opts["classes_" + opts.theme];
opts.classes = $.extend({}, opts.classes_base, opts.classes);
}

**Native styling**

Built-in, no interface changes for the Select2 integrators.

**Bootstrap styling**

The same two CSS files as with the original Select2 - select2.css and select2-bootstrap.css. Additional including of select2-bootstrap.js needed, a breaking change.

**jQuery UI styling**

Additional including of select2-jquery-ui.css and select2-jquery-ui.js needed. Except for the classes from jQuery UI, the additional stylesheet tweaks the Select2 layout to look better with the jQuery UI. Dropping it would require modifying the Select2 native styling, which I didn't find worth; evey other GUI framework might need it...

**Other Notes:**

An array of strings with classes to append is a more lightweight implementation, which prevents theme implementors from breaking the CSS class interface of the Select2. Other code and events can depend that the original classes will be still present.

Making Select2 just add ui-* classes from jQuery UI would break pages, which use Bootstrap for the main GUI controls and jQuery UI for some specific scenarios (widget factory, draggable, selectable or autocomplete widgets). That's why the explicit class adding only if the theme is turned on. Including select2-jquery-ui.js doesn't turn the jQuery theme on from the same reason.

On the other hand, Bootstrap is not as encapsulated as jQuery UI and is rather difficult to integrate with other GUI frameworks. When it is used, than fully, and that's why including select2-bootstrap.js makes it default as well.

The native theme could be implemented without the "-native" class suffixes in the classes_native array. It could be enabled just by including the select2-native.css. It would be more lightweight, but it'd disallow using the native and other themes together, which would be probably a rare scenario.

The Bootstrap theme could be implemented without the "-bootstrap" class suffixes in the classes_native array, which would need no select2-bootstrap.js. It could be enabled just by including the select2-bootstrap.css. It would be more lightweight, but it'd disallow using the Boostrap and other themes together, which is probably not realistic because of the Bootstrap nature.

I divided the classes in the native and Bootstrap themes including the class appendixes for the sake of consistence as a sample for theming for other GUI frameworks.