PageRenderTime 23ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/static/js/lib/rib.js

https://github.com/pozadi/mf2
JavaScript | 321 lines | 204 code | 77 blank | 40 comment | 10 complexity | 7325422db2b22d286479cd87f1ff11e9 MD5 | raw file
  1. /**
  2. * Rib.js - Backbone.js extension (utils for https://github.com/pozadi/mf2)
  3. * Author: https://github.com/pozadi
  4. * License: MIT
  5. */
  6. /*global $ _ Backbone Rib _t __ core Tag Payment Vault Filter*/
  7. window.Rib = (function(){
  8. "use strict";
  9. var
  10. Rib = {
  11. Views: {}
  12. };
  13. /**
  14. * Utils
  15. */
  16. Rib.U = _.extend({
  17. el2ModelProxy: function(callback){
  18. return function(event){
  19. var el = $(event.target);
  20. while(true){
  21. if (el.filter(document.body).length === 1) {
  22. return;
  23. }
  24. if (el.attr('id') && _(el.attr('id')).startsWith('cid_')) {
  25. var cid = el.attr('id').split('_')[1],
  26. model = this.collection.getByCid(cid);
  27. if (model) {
  28. callback.call(this, model, el);
  29. }
  30. return;
  31. }
  32. el = el.parent();
  33. }
  34. };
  35. },
  36. model2ElProxy: function(callback){
  37. return function(model){
  38. var el = this.$('#cid_' + model.cid); // will called in View context, so we can use this.$
  39. if(el.length > 0){
  40. var params = [el[0]].concat([].slice.call(arguments));
  41. callback.apply(this, params);
  42. }
  43. };
  44. },
  45. alert: function(message) {
  46. var view = new window.Rib.Views.MessageBox({message: message});
  47. this.modalDialog(view);
  48. return view;
  49. },
  50. confirm: function(message, onOk, onCancel) {
  51. var view = new window.Rib.Views.MessageBox({message: message, cancel: true});
  52. view.def.then(onOk, onCancel);
  53. this.modalDialog(view);
  54. return view;
  55. },
  56. modalDialog: function(view) {
  57. this.trigger('need_dialog', view);
  58. },
  59. bindAll: function(obj, triggerable, events) {
  60. _(events).chain().values().uniq().each(function(method){
  61. obj[method] = _(obj[method]).bind(obj);
  62. });
  63. _(events).each(function(method, event){
  64. triggerable.bind(event, obj[method]);
  65. });
  66. }
  67. }, Backbone.Events);
  68. /**
  69. * Model
  70. */
  71. Rib.Model = Backbone.Model.extend({
  72. });
  73. /**
  74. * Collection
  75. */
  76. Rib.Collection = Backbone.Collection.extend({
  77. newEntity: function() {
  78. this.add({});
  79. }
  80. });
  81. /**
  82. * View
  83. */
  84. Rib.View = Backbone.View.extend({
  85. tmpl: function(){return '';}
  86. });
  87. /**
  88. * Default model view
  89. */
  90. Rib.Views.DefaultModel = Rib.View.extend({
  91. tagName: "div",
  92. initialize: function () {
  93. _.bindAll(this, 'remove');
  94. this.model.bind('destroy', this.remove);
  95. },
  96. render: function() {
  97. var data = this.forTmpl();
  98. $(this.el).html(this.tmpl(data));
  99. return this;
  100. },
  101. forTmpl: function() {
  102. var data = this.model.toJSON();
  103. data.cid = this.model.cid;
  104. return data;
  105. }
  106. });
  107. /**
  108. * Default view for collection
  109. */
  110. Rib.Views.DefaultCollection = Rib.View.extend({
  111. list_selector: null,
  112. initialize: function () {
  113. _.bindAll(this, 'addOne', 'addAll', 'removeOne');
  114. this.collection.bind('add', this.addOne);
  115. this.collection.bind('remove', this.removeOne);
  116. this.collection.bind('reset', this.addAll);
  117. this.addAll();
  118. },
  119. removeOne: Rib.U.model2ElProxy(function(el, model) {
  120. $(el).remove();
  121. }),
  122. addOne: function(model) {
  123. var el = this.list_selector ? this.$(this.list_selector) : $(this.el),
  124. data = this.forTmpl(model);
  125. el.append(this.tmpl(data));
  126. },
  127. addAll: function() {
  128. this.collection.each(this.addOne);
  129. },
  130. forTmpl: function(model) {
  131. var data = model.toJSON();
  132. data.cid = model.cid;
  133. return data;
  134. }
  135. });
  136. /**
  137. * View for editable collection
  138. */
  139. var edit = function(model){
  140. var formView = new this.FormView({model: model});
  141. Rib.U.modalDialog(formView);
  142. return formView;
  143. };
  144. Rib.Views.EditableCollection = Rib.Views.DefaultCollection.extend({
  145. FormView: Rib.Views.DefaultModel,
  146. editOnNew: true,
  147. initialize: function (args) {
  148. Rib.Views.DefaultCollection.prototype.initialize.call(this);
  149. this.events = _.extend({
  150. 'click .edit': 'onClickEdit',
  151. 'click .delete': 'onClickDelete'
  152. }, this.events);
  153. this.delegateEvents();
  154. },
  155. edit: edit,
  156. onClickEdit: Rib.U.el2ModelProxy(edit),
  157. addOne: function(model) {
  158. Rib.Views.DefaultCollection.prototype.addOne.call(this, model);
  159. if(this.editOnNew && model.isNew()){
  160. // console.log('add fire', model);
  161. var formView = this.edit(model);
  162. formView.bind('close', function(){
  163. core._router.back();
  164. });
  165. }
  166. },
  167. beforeDelete: function(){ return true; },
  168. onClickDelete: Rib.U.el2ModelProxy(function(model){
  169. if (!this.beforeDelete(model)) {
  170. return;
  171. }
  172. Rib.U.confirm(_t('messages.shure-want-delete', {/*name: model.toStr()*/}), function(){
  173. model.destroy();
  174. });
  175. })
  176. });
  177. /**
  178. * Form view skeleton
  179. */
  180. Rib.Views.Form = Rib.Views.DefaultModel.extend({
  181. tagName: "form",
  182. initialize: function () {
  183. Rib.Views.DefaultModel.prototype.initialize.call(this);
  184. this.bind('close', this.remove);
  185. this.events = _.extend({
  186. 'submit' : 'onSubmit',
  187. 'click .cancel': 'cancel'
  188. }, this.events);
  189. this.delegateEvents();
  190. },
  191. validate: function() {
  192. return true;
  193. },
  194. save: function() {
  195. /* this.model.set({
  196. * 'name': this.$('.name').val()
  197. * });
  198. *
  199. * this.model.save();
  200. */
  201. },
  202. onSubmit: function() {
  203. if (this.validate()) {
  204. this.save();
  205. this.trigger('close');
  206. }
  207. return false; // prevent submit
  208. },
  209. cancel: function() {
  210. if(this.model.isNew()) {
  211. this.model.destroy();
  212. }
  213. this.trigger('close');
  214. }
  215. });
  216. /**
  217. * MessageBox view
  218. */
  219. Rib.Views.MessageBox = Backbone.View.extend({
  220. className: 'message-box',
  221. tmpl: _t('message-box'),
  222. def: null,
  223. events: {
  224. 'click .ok' : 'onClickOk',
  225. 'click .cancel': 'cancel'
  226. },
  227. initialize: function () {
  228. this.def = $.Deferred();
  229. },
  230. cancel: function() {
  231. this.def.reject();
  232. this.trigger('close');
  233. },
  234. onClickOk: function() {
  235. this.def.resolve();
  236. this.trigger('close');
  237. },
  238. render: function() {
  239. $(this.el).html(this.tmpl(this.options));
  240. return this;
  241. }
  242. });
  243. return Rib;
  244. })();