X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=js%2Fcrm.backbone.js;h=eb45249c1717e9fd3ac194efdfc7d0a811baabb0;hb=c3b9508c6f950351186517c3a321a0aed4ee7ff8;hp=6d02cc246f95be4ab59c1099c51ed4620db6b802;hpb=e4687acc3e9d699d49ad04703d57f69e50f5f43c;p=civicrm-core.git diff --git a/js/crm.backbone.js b/js/crm.backbone.js index 6d02cc246f..eb45249c17 100644 --- a/js/crm.backbone.js +++ b/js/crm.backbone.js @@ -1,5 +1,4 @@ -(function($) { - var CRM = (window.CRM) ? (window.CRM) : (window.CRM = {}); +(function($, _) { if (!CRM.Backbone) CRM.Backbone = {}; /** @@ -32,14 +31,14 @@ }; switch (method) { case 'read': - CRM.api(model.crmEntityName, 'get', model.toCrmCriteria(), apiOptions); + CRM.api(model.crmEntityName, model.toCrmAction('get'), model.toCrmCriteria(), apiOptions); break; // replace all entities matching "x.crmCriteria" with new entities in "x.models" case 'crm-replace': var params = this.toCrmCriteria(); params.version = 3; params.values = this.toJSON(); - CRM.api(model.crmEntityName, 'replace', params, apiOptions); + CRM.api(model.crmEntityName, model.toCrmAction('replace'), params, apiOptions); break; default: apiOptions.error({is_error: 1, error_message: "CRM.Backbone.sync(" + method + ") not implemented for collections"}); @@ -70,10 +69,13 @@ switch (method) { case 'create': // pass-through case 'update': + var params = model.toJSON(); + params.options || (params.options = {}); + params.options.reload = 1; if (!model._isDuplicate) { - CRM.api(model.crmEntityName, 'create', model.toJSON(), apiOptions); + CRM.api(model.crmEntityName, model.toCrmAction('create'), params, apiOptions); } else { - CRM.api(model.crmEntityName, 'duplicate', model.toJSON(), apiOptions); + CRM.api(model.crmEntityName, model.toCrmAction('duplicate'), params, apiOptions); } break; case 'read': @@ -84,7 +86,7 @@ apiOptions.error({is_error: 1, error_message: 'Missing ID for ' + model.crmEntityName}); return; } - CRM.api(model.crmEntityName, apiAction, params, apiOptions); + CRM.api(model.crmEntityName, model.toCrmAction(apiAction), params, apiOptions); break; default: apiOptions.error({is_error: 1, error_message: "CRM.Backbone.sync(" + method + ") not implemented for models"}); @@ -113,8 +115,17 @@ // Defaults - if specified in ModelClass, preserve _.defaults(ModelClass.prototype, { crmEntityName: crmEntityName, + crmActions: {}, // map: string backboneActionName => string serverSideActionName + crmReturn: null, // array: list of fields to return + toCrmAction: function(action) { + return this.crmActions[action] ? this.crmActions[action] : action; + }, toCrmCriteria: function() { - return (this.get('id')) ? {id: this.get('id')} : {}; + var result = (this.get('id')) ? {id: this.get('id')} : {}; + if (this.crmReturn != null) { + result.return = this.crmReturn; + } + return result; }, duplicate: function() { var newModel = new ModelClass(this.toJSON()); @@ -274,7 +285,7 @@ * }); * CRM.Backbone.extendCollection(ContactCollection); * - * // Use class + * // Use class (with passive criteria) * var c = new ContactCollection([], { * crmCriteria: {contact_type: 'Organization'} * }); @@ -282,8 +293,21 @@ * c.get(123).set('property', 'value'); * c.get(456).setDeleted(true); * c.save(); + * + * // Use class (with active criteria) + * var criteriaModel = new SomeModel({ + * contact_type: 'Organization' + * }); + * var c = new ContactCollection([], { + * crmCriteriaModel: criteriaModel + * }); + * c.fetch(); + * c.get(123).set('property', 'value'); + * c.get(456).setDeleted(true); + * c.save(); * @endcode * + * * @param Class CollectionClass * @see tests/qunit/crm-backbone */ @@ -292,10 +316,40 @@ // Defaults - if specified in CollectionClass, preserve _.defaults(CollectionClass.prototype, { crmEntityName: CollectionClass.prototype.model.prototype.crmEntityName, + crmActions: {}, // map: string backboneActionName => string serverSideActionName + toCrmAction: function(action) { + return this.crmActions[action] ? this.crmActions[action] : action; + }, toCrmCriteria: function() { - return (this.crmCriteria) ? _.extend({}, this.crmCriteria) : {}; + var result = (this.crmCriteria) ? _.extend({}, this.crmCriteria) : {}; + if (this.crmReturn != null) { + result.return = this.crmReturn; + } else if (this.model && this.model.prototype.crmReturn != null) { + result.return = this.model.prototype.crmReturn; + } + return result; + }, + + /** + * Get an object which represents this collection's criteria + * as a live model. Any changes to the model will be applied + * to the collection, and the collection will be refreshed. + * + * @param criteriaModelClass + */ + setCriteriaModel: function(criteriaModel) { + var collection = this; + this.crmCriteria = criteriaModel.toJSON(); + this.listenTo(criteriaModel, 'change', function() { + collection.crmCriteria = criteriaModel.toJSON(); + collection.debouncedFetch(); + }); }, + debouncedFetch: _.debounce(function() { + this.fetch({reset: true}); + }, 100), + /** * Reconcile the server's collection with the client's collection. * New/modified items from the client will be saved/updated on the @@ -324,9 +378,14 @@ sync: CRM.Backbone.sync, initialize: function(models, options) { options || (options = {}); - if (options.crmCriteria) { + if (options.crmCriteriaModel) { + this.setCriteriaModel(options.crmCriteriaModel); + } else if (options.crmCriteria) { this.crmCriteria = options.crmCriteria; } + if (options.crmActions) { + this.crmActions = _.extend(this.crmActions, options.crmActions); + } if (origInit) { return origInit.apply(this, arguments); } @@ -505,8 +564,8 @@ var wrapError = function (model, options) { var error = options.error; options.error = function(resp) { - if (error) error(model, resp, options); + if (error) error(model, resp, optio) model.trigger('error', model, resp, options); }; }; -})(cj); +})(CRM.$, CRM._);