New file |
0,0 → 1,153 |
if(!dojo._hasResource["dojox.widget.SortList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dojox.widget.SortList"] = true; |
dojo.provide("dojox.widget.SortList"); |
dojo.experimental("dojox.widget.SortList"); // level: prototype, designed for dijit.chat.demo |
|
dojo.require("dijit.layout._LayoutWidget"); |
dojo.require("dijit._Templated"); |
|
dojo.declare("dojox.widget.SortList", |
[dijit.layout._LayoutWidget, dijit._Templated], |
{ |
// summary: a sortable <ul> with a fixed header for use in dijit.demos.chat |
// for demonstration purposes only for now. feel free to make API suggestions |
// or fixes. |
// |
// title: String |
// the title in the header |
title: "", |
|
// heading: String |
// in the event a parent container is expecting a title="" attribute, set it for the parent |
// via title, and the title of this widget via heading="" ... assuming you want different |
// titles for each. eg: TabContainer, AccordionContainer, etc. |
heading: "", |
|
// descending: Boolean |
// toggle sort order based on this value. |
descending: true, |
|
// selected: Array |
// a list of the selected <li> nodes at any given time. |
selected: null, |
|
|
// sortable: Boolean |
// toggle to enable/disable sorting |
sortable: true, |
|
// FIXME: this is really simple store support |
store: "", |
key: "name", |
|
templateString:"<div class=\"sortList\" id=\"${id}\">\n\t\t<div class=\"sortListTitle\" dojoAttachPoint=\"titleNode\">\n\t\t<div class=\"sortListIcon\"></div>\n\t\t<span dojoAttachPoint=\"focusNode\">${title}</span>\n\t\t</div>\n\t\t<div class=\"sortListBodyWrapper\" dojoAttachEvent=\"onmouseover: _set, onmouseout: _unset, onclick:_handleClick\" dojoAttachPoint=\"bodyWrapper\">\n\t\t<ul dojoAttachPoint=\"containerNode\" class=\"sortListBody\"></ul>\n\t</div>\n</div>\n", |
|
_addItem: function(item){ |
var node = document.createElement("li"); |
var text = this.store.getValue(item,this.key); |
node.innerHTML = text; |
this.containerNode.appendChild(node); |
}, |
|
postCreate: function(){ |
if (this.store){ |
// FIXME: is this right? |
this.store = eval(this.store); |
var props = { |
onItem: dojo.hitch(this,"_addItem"), |
onComplete: dojo.hitch(this,"onSort") |
}; |
this.store.fetch(props); |
}else{ this.onSort(); } |
this.inherited("postCreate",arguments); |
}, |
|
startup: function(){ |
this.inherited("startup",arguments); |
if(this.heading){ |
this.setTitle(this.heading); this.title=this.heading; |
} |
// we cheat, and give the browser just enough time so we know our height |
setTimeout(dojo.hitch(this,"resize"),5); |
if (this.sortable){ this.connect(this.titleNode,"onclick", "onSort"); } |
}, |
|
resize: function(){ |
// summary: do our additional calculations when resize() is called by or in a parent |
this.inherited("resize",arguments); |
// FIXME: |
// the 10 comes from the difference between the contentBox and calculated height |
// because of badding and border extents. this shouldn't be done this way, a theme change will |
// break it: but we also don't want to run getComputedStyle or dojo.coords() every time resize() |
// is fired. |
var offset = ((this._contentBox.h) - (dojo.style(this.titleNode,"height")))-10; |
this.bodyWrapper.style.height = Math.abs(offset) + "px"; |
}, |
|
onSort: function(/* Event */e){ |
// summary: sort the data, and style the nodes. |
|
var arr = dojo.query("li",this.domNode); |
if (this.sortable){ |
this.descending = !this.descending; |
dojo.addClass(this.titleNode,((this.descending)?"sortListDesc":"sortListAsc")); |
dojo.removeClass(this.titleNode,((this.descending)?"sortListAsc":"sortListDesc")); |
arr.sort(this._sorter); |
if(this.descending){ arr.reverse(); } |
} |
var i=0; |
dojo.forEach(arr,function(item){ |
dojo[(((i++)%2)===0)?"addClass":"removeClass"](item,"sortListItemOdd"); |
this.containerNode.appendChild(item); |
},this); |
}, |
|
_set: function(/* Event */e){ |
// summary: set hover state |
if (e.target != this.bodyWrapper){ |
dojo.addClass(e.target,"sortListItemHover"); |
} |
}, |
|
_unset: function(/* Event */e){ |
// summary: remove hover state (FIXME: combine with _set?) |
dojo.removeClass(e.target,"sortListItemHover"); |
}, |
|
_handleClick: function(/* Event */e){ |
// summary: click listener for data portion of widget. toggle selected state |
// of node, and update this.selected array accordingly |
dojo.toggleClass(e.target,"sortListItemSelected"); |
e.target.focus(); |
this._updateValues(e.target.innerHTML); |
}, |
|
_updateValues: function(){ |
this._selected = dojo.query("li.sortListItemSelected",this.containerNode); |
this.selected = []; |
dojo.forEach(this._selected,function(node){ |
this.selected.push(node.innerHTML); |
},this); |
this.onChanged(arguments); |
}, |
|
_sorter: function(a,b){ |
// summary: a basic sort function, use query sort, or keep this? |
var aStr = a.innerHTML; |
var bStr = b.innerHTML; |
if(aStr>bStr){ return 1; } |
if(aStr<bStr){ return -1; } |
return 0; |
}, |
|
setTitle: function(/* String */title){ |
// summary: Sets the widget title to a String |
this.focusNode.innerHTML = title; |
}, |
|
onChanged: function(){ |
// summary: stub function, passes the last changed item, and is fired after current state |
} |
}); |
|
} |