define([
"jquery",
"underscore",
"backbone",
"models/portals/PortalSectionModel",
"views/MarkdownView",
"text!templates/portals/portalSection.html",
], function ($, _, Backbone, PortalSectionModel, MarkdownView, Template) {
/**
* @class PortalSectionView
* @classdesc The PortalSectionView is a generic view to render
* portal sections, with a default rendering of a
* MarkdownView
* @classcategory Views/Portals
* @module views/PortalSectionView
* @name PortalSectionView
* @extends Backbone.View
* @constructor
*/
var PortalSectionView = Backbone.View.extend(
/** @lends PortalSectionView.prototype */ {
/**
* The type of View this is
* @type {string}
* @readonly
*/
type: "PortalSection",
/**
* The display name for this Section
* @type {string}
*/
sectionName: "",
/**
* The unique label for this Section. It most likely matches the label on the model, but
* may include a number after if more than one section has the same name.
* @type {string}
*/
uniqueSectionLabel: "",
/**
* The HTML tag name for this view's element
* @type {string}
*/
tagName: "div",
/**
* The HTML classes to use for this view's element
* @type {string}
*/
className: "tab-pane portal-section-view",
/**
* Specifies if this section is active or not
* @type {boolean}
*/
active: false,
/**
* The PortalSectionModel that is being edited
* @type {PortalSection}
*/
model: undefined,
/**
* @type {UnderscoreTemplate}
*/
template: _.template(Template),
/**
* @param {Object} options - A literal object with options to pass to the view
* @property {PortalSection} options.model - The PortalSection rendered in this view
* @property {string} options.sectionName - The name of the portal section
*/
initialize: function (options) {
// Get all the options and apply them to this view
if (typeof options == "object") {
var optionKeys = Object.keys(options);
_.each(
optionKeys,
function (key, i) {
this[key] = options[key];
},
this,
);
}
},
/**
Renders the view
*/
render: function () {
//Add the active class to the element
if (this.active) {
this.$el.addClass("active");
}
//Add an id to this element so links work
this.$el.attr("id", this.getName({ linkFriendly: true }));
this.$el.html(
this.template({
imageURL: this.model.get("image")
? this.model.get("image").get("imageURL")
: "",
title: this.model.get("title"),
introduction: this.model.get("introduction"),
}),
);
this.$el.data("view", this);
//If there is Markdown, render it
if (this.model.get("content").get("markdown")) {
//Create a MarkdownView
this.markdownView = new MarkdownView({
markdown: this.model.get("content").get("markdown"),
citations: this.model.get("literatureCited"),
showTOC: true,
});
// Listen to the markdown view and when it is rendered, format the rendered markdown
this.listenTo(
this.markdownView,
"mdRendered",
this.postMarkdownRender,
);
// Render the view
this.markdownView.render();
// Add the markdown view element to this view
this.$(".portal-section-content").html(this.markdownView.el);
}
},
/**
* This funciton is called after this view has fully rendered and is
* visible on the webpage
*/
postRender: function () {
_.each(this.subviews, function (subview) {
if (subview.postRender) {
subview.postRender();
}
});
document.body.style.removeProperty("height");
this.markdownView?.tocView?.setAffix();
},
/**
* When the portal section markdown is rendered in a MarkdownView, format the
* resulting HTML as needed for this view
*/
postMarkdownRender: function () {
// If the window location has a hash, scroll to it
if (window.location.hash && this.$(window.location.hash).length) {
var view = this;
// Wait 0.5 seconds to allow images time to load before we scroll down the page
setTimeout(function () {
// Scroll to the element specified in the hash
MetacatUI.appView.scrollTo(view.$(window.location.hash));
}, 500);
}
},
/**
* Gets the name of this section and returns it
* @param {Object} [options] - Optional options for the name that is returned
* @property {Boolean} options.linkFriendly - If true, the name will be stripped of special characters
* @return {string} The name for this section
*/
getName: function (options) {
var name = "";
//If a section name is set on the view, use that
if (this.sectionName) {
name = this.sectionName;
}
//If the model is a PortalSectionModel, use the label from the model
else if (PortalSectionModel.prototype.isPrototypeOf(this.model)) {
name = this.model.get("label");
} else {
name = "Untitled";
}
if (typeof options == "object") {
if (options.linkFriendly) {
name = name.replace(/[^a-zA-Z0-9 ]/g, "").replace(/ /g, "-");
}
}
return name;
},
},
);
return PortalSectionView;
});