114 lines
5.3 KiB
JavaScript
114 lines
5.3 KiB
JavaScript
/**
|
|
* A generic card view class.
|
|
*
|
|
* Subclasses can override any of the following:
|
|
* - configuration (string or function): Sets the display style of the card as square or list. Can take values of
|
|
* "square_card" or "list_card". Defaults to "square_card".
|
|
* - action (function): Action to take when the action button is clicked. Defaults to a no-op.
|
|
* - cardClass (string or function): Class name for this card's DOM element. Defaults to the empty string.
|
|
* - pennant (string or function): Text of the card's pennant. No pennant is displayed if this value is falsy.
|
|
* - title (string or function): Title of the card. Defaults to the empty string.
|
|
* - description (string or function): Description of the card. Defaults to the empty string.
|
|
* - details (array or function): Array of child views to be rendered as details of this card. The class "meta-detail"
|
|
* is automatically added to each rendered child view to ensure appropriate styling. Defaults to an empty list.
|
|
* - actionClass (string or function): Class name for the action DOM element. Defaults to the empty string.
|
|
* - actionUrl (string or function): URL to navigate to when the action button is clicked. Defaults to the empty string.
|
|
* - actionContent: Content of the action button. This may include HTML. Default to the empty string.
|
|
*/
|
|
;(function (define) {
|
|
'use strict';
|
|
define(['jquery',
|
|
'underscore',
|
|
'backbone',
|
|
'text!templates/components/card/card.underscore'],
|
|
function ($, _, Backbone, cardTemplate) {
|
|
var CardView = Backbone.View.extend({
|
|
tagName: 'li',
|
|
|
|
events: {
|
|
'click .action' : 'action'
|
|
},
|
|
|
|
/**
|
|
* constructor is needed in addition to initialize because of Backbone's initialization order.
|
|
* initialize seems to run last in the initialization process, after className. However, className
|
|
* depends on this.configuration being set to pick the appropriate class. Therefore, configuration
|
|
* is set in the constructor, but the rest of the initialization happens in initialize.
|
|
*/
|
|
constructor: function (options) {
|
|
if (!this.configuration) {
|
|
this.configuration = (options && options.configuration) ? options.configuration : 'square_card';
|
|
}
|
|
Backbone.View.prototype.constructor.apply(this, arguments);
|
|
},
|
|
|
|
initialize: function () {
|
|
this.render();
|
|
},
|
|
|
|
template: _.template(cardTemplate),
|
|
|
|
switchOnConfiguration: function (square_result, list_result) {
|
|
return this.callIfFunction(this.configuration) === 'square_card' ?
|
|
square_result : list_result;
|
|
},
|
|
|
|
callIfFunction: function (value) {
|
|
if ($.isFunction(value)) {
|
|
return value.call(this);
|
|
} else {
|
|
return value;
|
|
}
|
|
},
|
|
|
|
className: function () {
|
|
var result = 'card ' +
|
|
this.switchOnConfiguration('square-card', 'list-card') + ' ' +
|
|
this.callIfFunction(this.cardClass);
|
|
if (this.callIfFunction(this.pennant)) {
|
|
result += ' has-pennant';
|
|
}
|
|
return result;
|
|
},
|
|
|
|
render: function () {
|
|
var maxLength = 72,
|
|
description = this.callIfFunction(this.description);
|
|
if (description.length > maxLength) {
|
|
description = description.substring(0, maxLength).trim() + '...'
|
|
}
|
|
this.$el.html(this.template({
|
|
pennant: this.callIfFunction(this.pennant),
|
|
title: this.callIfFunction(this.title),
|
|
description: description,
|
|
action_class: this.callIfFunction(this.actionClass),
|
|
action_url: this.callIfFunction(this.actionUrl),
|
|
action_content: this.callIfFunction(this.actionContent),
|
|
configuration: this.callIfFunction(this.configuration),
|
|
srInfo: this.srInfo
|
|
}));
|
|
var detailsEl = this.$el.find('.card-meta');
|
|
_.each(this.callIfFunction(this.details), function (detail) {
|
|
// Call setElement to rebind event handlers
|
|
detail.setElement(detail.el).render();
|
|
detail.$el.addClass('meta-detail');
|
|
detailsEl.append(detail.el);
|
|
});
|
|
return this;
|
|
},
|
|
|
|
action: function () { },
|
|
cardClass: '',
|
|
pennant: '',
|
|
title: '',
|
|
description: '',
|
|
details: [],
|
|
actionClass: '',
|
|
actionUrl: '',
|
|
actionContent: ''
|
|
});
|
|
|
|
return CardView;
|
|
});
|
|
}).call(this, define || RequireJS.define);
|