define(['underscore',
'jquery',
'backbone',
"models/portals/PortalImage",
"views/portals/editor/PortEditorImageView"],
function(_, $, Backbone, PortalImage, ImageEdit){
/**
* @class PortEditorLogosView
* @classcategory Views/Portals/Editor
*/
var PortEditorLogosView = Backbone.View.extend(
/** @lends PortEditorLogosView.prototype */{
/**
* The type of View this is
* @type {string}
*/
type: "PortEditorLogos",
/**
* The HTML tag name to use for this view's element
* @type {string}
*/
tagName: "div",
/**
* The HTML classes to use for this view's element
* @type {string}
*/
className: "port-editor-logos",
/**
* The PortalModel that is being edited
* @type {Portal}
*/
model: undefined,
/**
* A reference to the PortalEditorView
* @type {PortalEditorView}
*/
editorView: undefined,
/**
* The events this view will listen to and the associated function to call.
* @type {Object}
*/
events: {
"keyup .edit-image.new .basic-text" : "handleNewInput",
"click .remove" : "handleRemove"
},
/**
* Creates a new PortEditorLogosView
* @param {Object} options - A literal object with options to pass to the view
* @property {Portal} options.model - The Portal whose logos are rendered in this view
* @property {PortalEditorView} options.editorView - Gets set as PortalEditorLogosView.editorView
*/
initialize: function(options){
try{
if( typeof options == "object" ){
this.model = options.model || undefined;
this.editorView = options.editorView;
}
} catch(e){
console.log("PortEditorLogosView failed to initialize. Error message: " + e);
}
},
/**
* Renders this view
*/
render: function(){
try{
var savedLogos = this.model.get("acknowledgmentsLogos"),
newLogo = new PortalImage({ nodeName: "acknowledgmentsLogo" });
// If there are no acknowledgmentsLogos yet, then set a new empty logo for
// the user to enter information into
if( !savedLogos || !savedLogos.length){
this.model.set( "acknowledgmentsLogos", [newLogo]);
// If there are already logos, add a new blank logo to the end of the list.
// Note that empty logos won't get serialized
} else {
savedLogos.push(newLogo);
this.model.set("acknowledgmentsLogos", savedLogos);
}
// Iterate over each logo in the PortalModel and render an ImageView
_.each(this.model.get("acknowledgmentsLogos"), function(portalImage){
this.renderAckLogoInput(portalImage);
}, this);
}
catch(e){
console.log("PortEditorLogosView failed to render, error message: " + e );
}
},
/**
* renderAckLogoInput - Adds a new ImageEdit view for a specified PortalImage model for an acknowledgments logo.
*
* @param {PortalImage} portalImage The PortalImage model to create an ImageEdit view for.
*/
renderAckLogoInput: function(portalImage){
try {
var view = this;
// Check if this is a new, empty acknowledgmentsLogo
var isNew = !portalImage.get("identifier") &&
!portalImage.get("associatedURL") &&
!portalImage.get("label");
var imageEdit = new ImageEdit({
parentModel: this.model,
editorView: this.editorView,
model: portalImage,
imageUploadInstructions: "Drag & drop a partner logo or click to upload",
imageWidth: 150,
imageHeight: 150,
minWidth: 100,
minHeight: 100,
maxHeight: 300,
maxWidth: 300,
nameLabel: "Organization name",
urlLabel: "Organization URL",
imageTagName: "img",
removeButton: true
});
$(this.el).append(imageEdit.el);
imageEdit.render();
// When user adds a file, this imageEdit is no longer new
imageEdit.listenToOnce(imageEdit.uploader, "addedfile", function(){
view.handleNewInput(this)
});
if(isNew){
$(imageEdit.el).addClass("new");
// Don't allow users to remove the new portalImage -
// it's the only place to add an acknowledgmentsLogo.
$(imageEdit.el).find(".remove.icon").hide();
}
} catch (e) {
console.log("Could not render an ImageEdit view for an acknowledgmentsLogo. Error message: " + e);
}
},
/**
* handleNewInput - Called when a user enters any input into a new ImageEdit
* view. It removes the "new" class, shows the "remove" button, and adds a new
* ImageEdit view with a blank PortalImage model.
*
* @param {object} eventOrView either the keyup event when user enters text
* into an imageEdit input, OR the imageEdit view which contains the
* imageUploader where a user just uploaded an image.
*/
handleNewInput: function(eventOrView){
try {
// Get the relevant imageEdit view element
var imageEditEl = eventOrView.target ?
// when the arguement is an event
$(eventOrView.target).closest(".edit-image.new") :
// when the argument is a view
eventOrView.$el;
// This function should only modify new image-edit views
if(!imageEditEl || !imageEditEl.hasClass("new")){
return
}
var currentLogos = this.model.get("acknowledgmentsLogos"),
newLogo = new PortalImage({ nodeName: "acknowledgmentsLogo" });
// Remove the 'new' class
imageEditEl.removeClass("new");
// Allow users to delete this logo
imageEditEl.find(".remove.icon").show();
// Add a new blank portalImage
currentLogos.push(newLogo);
this.model.set("acknowledgmentsLogos", currentLogos);
// Show the new EditImage view
this.renderAckLogoInput(newLogo);
this.editorView.showControls();
} catch (e) {
console.log("Failed to handle user input in an acknowledgments logo imageEdit view. Error message: " + e);
}
},
/**
* showValidation - Show validation errors for each logoView
*/
showValidation: function(){
var logoViews = $(this.el).find(".edit-image");
_.each(logoViews, function(logoView){
$(logoView).data("view").showValidation();
});
},
/**
* This function is called when a logo is removed. The logo removal itself is done
* by the PortEditorImageView. This function performs additional functionality that
* should happen after the removal.
*/
handleRemove: function(){
this.editorView.showControls();
}
});
return PortEditorLogosView;
});