PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/static/public/js/libs/bobamo/list.js

http://github.com/jspears/bobamo
JavaScript | 172 lines | 159 code | 10 blank | 3 comment | 21 complexity | d62889a3a3a278462c5e6301f97bfa5c MD5 | raw file
Possible License(s): Apache-2.0
  1. // Filename: views/${schema.modelName}/list
  2. define([
  3. 'jquery',
  4. 'underscore',
  5. 'Backbone',
  6. 'replacer',
  7. 'libs/renderer/renderers',
  8. 'libs/table/jquery.bobamo-paginate',
  9. 'libs/table/jquery.sorter'
  10. ], function ($, _, Backbone, replacer, Renderer) {
  11. "use strict";
  12. function _null(v) {
  13. return v != null;
  14. };
  15. function _dir(v) {
  16. if (v.direction)
  17. return replacer('<span class="sortable elementActivate" data-field="{field}" data-label="{label}" data-direction="{direction}">{label}</span>',v);
  18. return null;
  19. };
  20. var ListItemView = Backbone.View.extend({
  21. tagName:"tr",
  22. initialize:function (options) {
  23. this.renderer = options && options.renderer || new Renderer();
  24. this.model.bind("change", this.render, this);
  25. this.model.bind("destroy", this.close, this);
  26. this.sort = [];
  27. return this;
  28. },
  29. format:function(field, idx, model, schema){
  30. return this.renderer.render(model.get(field), field, model, idx, schema && schema.renderer);
  31. },
  32. _fields:{},
  33. _format:function(field, idx){
  34. var schema = field in this._fields ? this._fields[field] : (this._fields[field] = this.schema(field, this.model));
  35. return this.format(field, idx, this.model, schema)
  36. },
  37. schema:function(field, model){
  38. if (!(model || field))
  39. return null;
  40. var fields = field.split('.');
  41. var schema = model.schema;
  42. if (!schema) return null;
  43. var val = schema[fields.shift()];
  44. while(fields.length){
  45. var key = fields.shift();
  46. if (val && val.subSchema)
  47. val = val.subSchema[key];
  48. else{
  49. console.log('no schema for ', fields, field, key);
  50. return null;
  51. }
  52. }
  53. return val;
  54. },
  55. render:function (eventName) {
  56. var tmpl = (this.template || this.options.template)({item:this.model, format:_.bind(this._format, this)});
  57. var $el = $(this.el);
  58. $el.html(tmpl);
  59. return this;
  60. }
  61. });
  62. var ListView = Backbone.View.extend({
  63. tagName:'div',
  64. classNames:['span7'],
  65. events:{
  66. 'paginate-change .pager_table':'doPage',
  67. 'sorter-change .sortable':'onSort'
  68. },
  69. renderer:new Renderer({}),
  70. initialize:function (options) {
  71. if (!this.template) {
  72. throw new Error('template must be defined');
  73. }
  74. if (!this.collection){
  75. throw new Error('collection must be defined');
  76. }
  77. this.collection.on('reset', this.renderList, this);
  78. this.collection.on('fetch', function(){
  79. console.log('fetch', arguments)
  80. this.renderList.apply(this, _.toArray(arguments)) }, this);
  81. return this;
  82. },
  83. itemView:ListItemView,
  84. renderItem:function (item) {
  85. var template = this.listItemTemplate;
  86. if (this.$ul) {
  87. var lel = new ListItemView({model:item, renderer:this.renderer, template:template}).render().el;
  88. this.$ul.append(lel);
  89. }
  90. return this;
  91. },
  92. renderList:function () {
  93. console.log('renderList',arguments)
  94. this.$ul = this.$el.find('tbody');
  95. this.$ul.children().remove();
  96. _.each(this.collection.models, this.renderItem, this);
  97. this.$paginate.paginate('update', {sort:this.sort_str ? ' sorting by: ' + this.sort_str : '', total:this.collection.total});
  98. $('.sortable', this.$table).sorter();
  99. this.trigger('fetched', arguments);
  100. return this;
  101. },
  102. doPage:function (evt) {
  103. this.update('Loading page <b>' + evt.page + '</b> of {items}');
  104. return this;
  105. },
  106. update:function (message, opt) {
  107. var $p = this.$paginate.paginate('wait', message);
  108. var self = this;
  109. var params = this.collection.params;
  110. var data = _.extend({
  111. limit:parseInt($p.attr('data-limit')),
  112. skip:Math.max(0, parseInt($p.attr('data-skip')))
  113. },opt);
  114. var sort = [];
  115. _.each(this.sorts, function (v, k) {
  116. if (!v.direction) return;
  117. sort.push([v.field, v.direction].join(':'));
  118. });
  119. var populate = [];
  120. _.each(this.renderer.config, function(v){
  121. console.log('renderer',v);
  122. if (v.property && ~v.property.indexOf('.')){
  123. //TODO - Mongoose throws an exception if you populate a non IdRef fix mers so that it doesn't
  124. // send it.
  125. var mangle = v.property.split('.');
  126. mangle.pop();
  127. populate.push(mangle.join('.'))
  128. }
  129. });
  130. if (populate.length)
  131. data.populate = populate.join(',');
  132. this.collection.params = data;
  133. data.sort = sort.join(',');
  134. this.collection.fetch({data:data, success:_.bind(this._fetch, this)});
  135. return this;
  136. },
  137. _fetch:function(){
  138. this.collection.trigger('list-data', arguments);
  139. },
  140. onSort:function (evt) {
  141. var obj = {field:evt.field, direction:evt.direction, label:evt.label};
  142. this.sorts = _.filter(this.sorts, function (v, k) {
  143. return v.field != obj.field;
  144. })
  145. this.sorts.unshift(obj);
  146. var str = _(this.sorts).map(_dir).filter(_null).join(', ')
  147. this.sort_str = str;
  148. this.update('Sorting {items} ' + ( str ? 'by ' + str : 'naturally' )+'.');
  149. return this;
  150. },
  151. render:function (obj) {
  152. this.$container = obj && obj.container ? $(obj.container) : $('#content');
  153. this.$table = $(this.template());
  154. this.$paginate = $('.pager_table', this.$table).paginate();
  155. this.$el.append(this.$table);
  156. this.update('Loading {items}');
  157. this.$container.html(this.$el);
  158. return this;
  159. }
  160. });
  161. return ListView;
  162. });