Files
edx-platform/lms/static/js/components/card/views/card.js
azanbinzahid cd06c74d2c PROD-2181
2020-12-16 17:44:00 +05:00

119 lines
5.5 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',
'edx-ui-toolkit/js/utils/html-utils'
],
function($, _, Backbone, cardTemplate, HtmlUtils) {
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: HtmlUtils.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() + '...';
}
HtmlUtils.setHtml(
this.$el,
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);