Skip to content

Instantly share code, notes, and snippets.

@devdays
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devdays/b98d8bca844c1fd241aa to your computer and use it in GitHub Desktop.
Save devdays/b98d8bca844c1fd241aa to your computer and use it in GitHub Desktop.
Sample jQuery UI Widget
<!DOCTYPE html>
<html>
<head>
<!--
From http://ajpiano.com/widgetfactory/
Copyright 2014 Bruce D Kyle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Original presentation is copyrighted by Google 2010.
-->
<title>Filterable Widget</title>
<link href="Content/themes/base/core.css" rel="stylesheet" />
<link href="Content/themes/base/theme.css" rel="stylesheet" />
</head>
<body>
<button type="button" id="activation">Toggle Filterable</button>
<ul id="cheeses">
<li data-price="17.99">Gruyere</li>
<li data-price="16.99">Comte</li>
<li data-price="4.99">Provolone</li>
<li data-price="8.99">Cheddar</li>
<li data-price="18.99">Parmigiano Reggiano</li>
<li data-price=".99">Government</li>
</ul>
<div id="register">
One pound of each would cost $<span id="total"></span>
</div>
<script src="Scripts/jquery-2.1.3.js"></script>
<script src="Scripts/jquery-ui-1.11.3.js"></script>
<script src="Scripts/filterable/jquery-filterable-0.0.3.js"></script>
<script>
$(function() {
var total = $("#total"),
cheeses = $("#cheeses"),
register = $("#register"),
price = $("<span>"),
activation = $("#activation").button({icons:{primary:"ui-icon-search"}});
activation.click(function() {
if (cheeses.is(":aj-filterable")) {
return cheeses.filterable("destroy");
}
cheeses.filterable({
className: "cheese",
create: function() { register.addClass("ui-widget-header cheese").show(); },
filtered: function(e, ui) {
var t = 0;
ui.visible.each(function() { t = t + parseFloat($(this).data("price")); });
console.log( t );
total.text(t.toFixed(2));
},
setOption: function(e, ui) {
ui.option == "className" && register.toggleClass([ui.original, ui.current].join(" "));
},
hover: function(e, ui) {
if (e.originalEvent.type == "mouseenter") {
price.text(" - " + ui.hovered.data("price") + " per lb").appendTo(ui.hovered);
} else {
price.detach();
}
}
});
setTimeout(function() { cheeses.filterable("option", "className", "cheesePlease"); },3000);
});
});
</script>
</body>
</html>
/*
From http://ajpiano.com/widgetfactory/
Copyright 2014 Bruce D Kyle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License..
*/
(function ($) {
// The jQuery.aj namespace will automatically be created if it doesn't exist
$.widget("aj.filterable", {
// These options will be used as defaults
options: {
className: ""
},
_create: function () {
// this.element -- a jQuery object of the element the widget was invoked on.
// this.options -- the merged options hash
console.log("_create" + this.options.className);
// Cache references to collections the widget needs to access regularly
this.filterElems = this.element.children()
.addClass("ui-widget-content " + this.options.className);
this.filterInput = $("<input type='text'>")
.insertBefore(this.element)
.wrap("<div class='ui-widget-header " + this.options.className + "'>");
// bind events on elements:
this._on(this.filterElems, {
mouseenter: "_hover",
mouseleave: "_hover"
});
// toggles ui-state-focus for you:
this._focusable(this.filterInput);
// _hoverable works for ui-state-hover, but we will do something slighty different in our hover
this._on(this.filterInput, {
"keyup": "filter"
});
this.timeout = false;
},
filter: function (event) {
// Debounce the keyup event with a timeout, using the specified delay
clearTimeout(this.timeout);
console.log("_create" + this.options.className);
// like setTimeout, only better!
this.timeout = this._delay(function () {
var re = new RegExp(this.filterInput.val(), "i"),
visible = this.filterElems.filter(function () {
var $t = $(this), matches = re.test($t.text());
// Leverage the CSS Framework to handle visual state changes
$t.toggleClass("ui-helper-hidden", !matches);
return matches;
});
// Trigger a callback so the user can respond to filtering being complete
// Supply an object of useful parameters with the second argument to _trigger
this._trigger("filtered", event, {
visible: visible
});
}, this.options.delay);
},
_hover: function (event) {
$(event.target).toggleClass("ui-state-active", event.type === "mouseenter");
this._trigger("hover", event, {
hovered: $(event.target)
});
},
_setOption: function (key, value) {
var oldValue = this.options[key];
console.log("_setOption: " + key + ": " + value);
// Check for a particular option being set
if (key === "className") {
// Gather all the elements we applied the className to
this.filterInput.parent().add(this.filterElems)
// Switch the new className in for the old
.toggleClass(oldValue + " " + value);
console.log("toggle class : " + oldValue + " " + value);
}
// Call the base _setOption method
this._super(key, value);
// The widget factory doesn't fire an callback for options changes by default
// In order to allow the user to respond, fire our own callback
this._trigger("setOption", null, {
option: key,
original: oldValue,
current: value
});
},
_destroy: function () {
// Use the destroy method to reverse everything your plugin has applied
this.filterInput.parent().remove();
// Remove any classes, including CSS framework classes, that you applied
this.filterElems.removeClass("ui-widget-content ui-helper-hidden ui-state-active " + this.options.className);
return this._super();
}
});
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment