Skip to content

Instantly share code, notes, and snippets.

@nickciolpan
Last active December 31, 2022 00:46
Show Gist options
  • Save nickciolpan/ddffbd0e480b10c9541f0fb21361ab44 to your computer and use it in GitHub Desktop.
Save nickciolpan/ddffbd0e480b10c9541f0fb21361ab44 to your computer and use it in GitHub Desktop.
DRY JQuery
// 1. Namespace js functionality classes with 'js-',
// never ever attach events to regular class or id. Separation of concers
// 'round-box' can't have some bonus unexpected hover effect. That should be 'js-flips-on-hover'.
// 2. Jquery selectors are expensive browser operations. All should be cached ( saved to variable )
// I'm keeping .class and $selector separated for edge cases in which dom-content is dynamic and can't be cached.
var multiSelectClass = '.js-multiselect'),
$multiSelect = $(multiSelectClass),
defaults = {
buttonClass: 'btn btn-default',
buttonWidth: '100%',
nonSelectedText: '---------',
nSelectedText: ' selecionados',
allSelectedText: 'Todos',
includeSelectAllOption: false,
numberDisplayed: 1,
enableFiltering: false,
enableCaseInsensitiveFiltering: false
};
// 3.To keep it DRY, plugins should be intialized just once in your application.
// The source of truth should be the the element that initializes it.
// Have a default fallback
if ($multiSelect.length > 0) {
$multiSelect.each(function () {
var $this = $(this),
dataset = $this.data(),
options = {
buttonClass: $this.data('button-class') || defaults.buttonClass,
buttonWidth: $this.data('button-width') || defaults.buttonWidth,
nonSelectedText: $this.data('non-selected-text') || defaults.nonSelectedText,
nSelectedText: $this.data('n-selected-text') || defaults.nSelectedText,
allSelectedText: $this.data('all-selected-text') || defaults.allSelectedText,
includeSelectAllOption: $this.data('include-select-all-option') || defaults.includeSelectAllOption,
numberDisplayed: $this.data('number-displayed') || defaults.numberDisplayed,
enableFiltering: $this.data('enable-filtering') || defaults.enableFiltering,
enableCaseInsensitiveFiltering: $this.data('enable-case-insensitive-filtering') || defaults.enableCaseInsensitiveFiltering,
};
// Since the number of plugin options can vary greatly,
// any other non vital options that have no default specify
// will be identitified in the dataset and injected as option at runtime.
Object.keys(dataset).map(function (property) {
if (!defaults.hasOwnProperty(property)) {
$.extend(options, {property: $this.data(property)});
}
})
// We finally init the plugin for
// every element on page with it's specify options
$this.multiselect(options);
});
}
// 4. Case scenarios.
// a. Initializes with default settings
<select class="js-multiselect">
<option />
</select>
// b. With options (Unspecified options will fallback to default)
<select class="js-multiselect" data-option-1="true" data-option-2="Text to display...">
<option />
</select>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment