SortList.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // wrapped by build app
  2. define("dojox/widget/SortList", ["dijit","dojo","dojox","dojo/require!dijit/layout/_LayoutWidget,dijit/_Templated"], function(dijit,dojo,dojox){
  3. dojo.provide("dojox.widget.SortList");
  4. dojo.experimental("dojox.widget.SortList"); // level: prototype, designed for dijit.chat.demo
  5. dojo.require("dijit.layout._LayoutWidget");
  6. dojo.require("dijit._Templated");
  7. dojo.declare("dojox.widget.SortList",
  8. [dijit.layout._LayoutWidget, dijit._Templated],
  9. {
  10. // summary: A sortable unordered-list with a fixed header for use in dijit.demos.chat
  11. // for demonstration purposes only for now. feel free to make API suggestions
  12. // or fixes.
  13. //
  14. // title: String
  15. // The title in the header
  16. title: "",
  17. // heading: String
  18. // In the event a parent container is expecting a title="" attribute, set it for the parent
  19. // via title, and the title of this widget via heading="" ... assuming you want different
  20. // titles for each. eg: TabContainer, AccordionContainer, etc.
  21. heading: "",
  22. // descending: Boolean
  23. // Toggle sort order based on this value.
  24. descending: true,
  25. // selected: Array
  26. // A list of the selected <li> nodes at any given time.
  27. selected: null,
  28. // sortable: Boolean
  29. // toggle to enable/disable sorting
  30. sortable: true,
  31. // FIXME: this is really simple store support
  32. store: "",
  33. key: "name",
  34. baseClass: "dojoxSortList",
  35. templateString: dojo.cache("dojox.widget", "SortList/SortList.html", "<div class=\"sortList\" id=\"${id}\">\n\t\t<div class=\"sortListTitle\" dojoAttachPoint=\"titleNode\">\n\t\t<div class=\"dijitInline sortListIcon\">&thinsp;</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>"),
  36. _addItem: function(item){
  37. dojo.create("li", {
  38. innerHTML: this.store.getValue(item, this.key).replace(/</g, "&lt;")
  39. }, this.containerNode);
  40. },
  41. postCreate: function(){
  42. if(this.store){
  43. this.store = dojo.getObject(this.store);
  44. var props = {
  45. onItem: dojo.hitch(this, "_addItem"),
  46. onComplete: dojo.hitch(this, "onSort")
  47. };
  48. this.store.fetch(props);
  49. }else{ this.onSort(); }
  50. this.inherited(arguments);
  51. },
  52. startup: function(){
  53. this.inherited(arguments);
  54. if(this.heading){
  55. this.setTitle(this.heading);
  56. this.title = this.heading;
  57. }
  58. // we cheat, and give the browser just enough time so we know our height
  59. setTimeout(dojo.hitch(this,"resize"), 5);
  60. if(this.sortable){ this.connect(this.titleNode,"onclick", "onSort"); }
  61. },
  62. resize: function(){
  63. // summary: do our additional calculations when resize() is called by or in a parent
  64. this.inherited(arguments);
  65. // FIXME:
  66. // the 10 comes from the difference between the contentBox and calculated height
  67. // because of badding and border extents. this shouldn't be done this way, a theme change will
  68. // break it: but we also don't want to run getComputedStyle or dojo.coords() every time resize()
  69. // is fired.
  70. var offset = ((this._contentBox.h) - (dojo.style(this.titleNode,"height")))-10;
  71. this.bodyWrapper.style.height = Math.abs(offset) + "px";
  72. },
  73. onSort: function(/* Event */e){
  74. // summary: sort the data, and style the nodes.
  75. var arr = dojo.query("li",this.domNode);
  76. if (this.sortable){
  77. this.descending = !this.descending;
  78. dojo.addClass(this.titleNode,((this.descending)?"sortListDesc":"sortListAsc"));
  79. dojo.removeClass(this.titleNode,((this.descending)?"sortListAsc":"sortListDesc"));
  80. arr.sort(this._sorter);
  81. if(this.descending){ arr.reverse(); }
  82. }
  83. var i=0;
  84. dojo.forEach(arr,function(item){
  85. dojo[(i++) % 2 === 0 ? "addClass" : "removeClass"](item,"sortListItemOdd");
  86. this.containerNode.appendChild(item);
  87. },this);
  88. },
  89. _set: function(/* Event */e){
  90. // summary: set hover state
  91. if(e.target !== this.bodyWrapper){
  92. dojo.addClass(e.target,"sortListItemHover");
  93. }
  94. },
  95. _unset: function(/* Event */e){
  96. // summary: remove hover state (FIXME: combine with _set?)
  97. dojo.removeClass(e.target,"sortListItemHover");
  98. },
  99. _handleClick: function(/* Event */e){
  100. // summary: click listener for data portion of widget. toggle selected state
  101. // of node, and update this.selected array accordingly
  102. dojo.toggleClass(e.target,"sortListItemSelected");
  103. e.target.focus();
  104. this._updateValues(e.target.innerHTML);
  105. },
  106. _updateValues: function(){
  107. this._selected = dojo.query("li.sortListItemSelected", this.containerNode);
  108. this.selected = [];
  109. dojo.forEach(this._selected, function(node){
  110. this.selected.push(node.innerHTML);
  111. }, this);
  112. this.onChanged(arguments);
  113. },
  114. _sorter: function(a,b){
  115. // summary: a basic sort function, use query sort, or keep this?
  116. var aStr = a.innerHTML;
  117. var bStr = b.innerHTML;
  118. if(aStr>bStr){ return 1; }
  119. if(aStr<bStr){ return -1; }
  120. return 0;
  121. },
  122. setTitle: function(/* String */title){
  123. // summary: Sets the widget title to a String
  124. this.focusNode.innerHTML = this.title = title;
  125. },
  126. onChanged: function(){
  127. // summary: stub function, passes the last changed item, and is fired after current state
  128. }
  129. });
  130. });