I’ve been trying to get better at following the JQuery UI Theme styles – the fact of the matter is I’ve just never been great at writing fancy style sheets, so having a re-usable framework complete with fancy gradient backgrounds is awesome. However, I’ve always been frustrated by the lack of a good “container” skeleton widget in the standard toolkit. I decided to spend a little bit of time designing a panel widget that works on items with this structure:
<div><h4>{title}</h4>{content}</div>
Let me know what you think!
You'll need these styles defined somewhere (I use Styles.css):
.ui-panel div.ui-panel-header
{
padding: 4px 8px 2px 12px;
height: 22px;
}
.ui-panel a.ui-panel-header
{
float: right;
}
.ui-panel div.ui-panel-content
{
padding: 4px 4px 4px 4px;
}
$.widget('ui.panel', {options: { collapsable: true, collapsed: false, title: null,barHeight: 29
}, defaults: { headerCss: 'ui-widget-header ui-corner-top ui-panel-header' , contentsCss: 'ui-widget-content ui-corner-bottom ui-panel-content ui-helper-clearfix' , panelCss: 'ui-widget ui-panel' , showSpeed: 'slow' , titleSelector: 'h1,h2,h3,h4,h5' , titleTemplate: '<span />'}, _create: function () { var buffer;var self = this;
self.initialState = { }; // Parse attribute optionsif (self.element.attr('collapsable') == 'false')
self.options.collapsable = false;if (self.element.attr('collapsed') == 'true')
self.options.collapsable = true; // Create the header divself.header = $('<div class="' + self.defaults.headerCss + '" />');
// Look for an h element to rip out for the title. If it is a h1 or h2, increase the bar's heightself.initialState.header = self.element.children(self.defaults.titleSelector).first();
if (self.initialState.header.length == 1) {self.initialState.header.remove();
if (self.initialState.header[0].tagName == 'H1' || self.initialState.header[0].tagName == 'H2'
&& self.options.barHeight == 29)
self.options.barHeight = 49;
if (self.options.title == null)
self.options.title = self.initialState.header.text();
}
buffer = $(self.defaults.titleTemplate);
if (self.options.title != null)
buffer.text(self.options.title);
self.header.append(buffer);
// TODO: Create the collapsable div and wire it up if (self.options.collapsable) { buffer = $("<a class='ui-panel-header ui-icon ui-icon-circle-triangle-n' href='javascript:void(0)'></a>");buffer.bind('click', function() { self._trigger('toggle'); });
self.header.append(buffer);
}
// Create the content element and move original content into it.self.contents = $('<div class="' + self.defaults.contentsCss + '" />');
self.contents.text(self.element.text());
self.element.text('');self.element.children().appendTo(self.contents);
// Finally, add my panel class and throw everything into the document.self.element.addClass(self.defaults.panelCss);
self.element.append(self.header);
self.element.append(self.contents);
self.element.bind('paneltoggle', function(event) {
if (self.options.collapsed)self.expand();
elseself.collapse();
return true;
});
self.element.bind('panelcollapse', function(event) {
if (self.options.collapsed == false) {
self.contents.hide(self.defaults.showSpeed,
function() {self.header.children('a').removeClass('ui-icon-circle-triangle-n')
.addClass('ui-icon-circle-triangle-s');});
self.options.collapsed = true;}
return true;
});
self.element.bind('panelexpand', function(event) {
if (self.options.collapsed) {self.contents.show(self.defaults.showSpeed,
function() {self.header.children('a').removeClass('ui-icon-circle-triangle-s')
.addClass('ui-icon-circle-triangle-n');});
self.options.collapsed = false;}
return true;
});
}, expand: function () {this._trigger('expand');
}, collapse: function() {this._trigger('collapse');
}, destroy: function () {this.element.unbind('panelexpand panelcollapse');
// Return element to pre-widget state this.header.remove(); this.contents.detach();this.element.text(this.contents.text());
if (this.initialState.header != null)
this.element.append(this.initialState.header);
this.element.append(this.contents.children());
// Call base destructor $.Widget.prototype.destroy.apply(this, arguments); }});
$.extend($.ui.panel, { version: '@VERSION') });