define(['underscore', 'jquery', 'backbone',
'views/metadata/BaseEML211View',
'views/metadata/EMLGeoCoverageView',
'views/metadata/EMLPartyView',
'views/metadata/EMLMethodsView',
'views/metadata/EMLTempCoverageView',
'models/metadata/eml211/EML211',
'models/metadata/eml211/EMLGeoCoverage',
'models/metadata/eml211/EMLKeywordSet',
'models/metadata/eml211/EMLParty',
'models/metadata/eml211/EMLProject',
'models/metadata/eml211/EMLText',
'models/metadata/eml211/EMLTaxonCoverage',
'models/metadata/eml211/EMLTemporalCoverage',
'models/metadata/eml211/EMLMethods',
'text!templates/metadata/eml.html',
'text!templates/metadata/EMLPartyCopyMenu.html',
'text!templates/metadata/metadataOverview.html',
'text!templates/metadata/dates.html',
'text!templates/metadata/locationsSection.html',
'text!templates/metadata/taxonomicCoverage.html',
'text!templates/metadata/taxonomicClassificationTable.html',
'text!templates/metadata/taxonomicClassificationRow.html',
'themes/ess-dive/views/metadata/EMLFundingOrganizationsSubView',
'themes/ess-dive/views/metadata/EMLProjectSubView',
'themes/ess-dive/views/metadata/EMLDOEContractsSubView',
'themes/ess-dive/views/metadata/EMLVocabularySubView',
'themes/ess-dive/views/metadata/EMLReferencePaperSubView'],
function (_, $, Backbone, BaseEML211View, EMLGeoCoverageView, EMLPartyView, EMLMethodsView, EMLTempCoverageView,
EML, EMLGeoCoverage, EMLKeywordSet, EMLParty, EMLProject, EMLText, EMLTaxonCoverage,
EMLTemporalCoverage, EMLMethods, Template, EMLPartyCopyMenuTemplate, OverviewTemplate,
DatesTemplate, LocationsTemplate,
TaxonomicCoverageTemplate, TaxonomicClassificationTable, TaxonomicClassificationRow, EMLFundingOrganizationsSubView,
EMLProjectSubView, EMLDOEContractsSubView, EMLVocabularySubView, EMLReferencePaperSubView) {
var PARTY_TYPE_MAP = {
"contact" : "contact",
"creator" : "creator",
"contributor" : "associatedParty"
};
var PARTY_LABELS_MAP = {
"contact" : "Contact",
"creator" : "Creators",
"contributor" : "Contributors"
}
var PARTY_HELP_MAP = {
"contact" : "Person who should be listed as the contact for the data package " +
"for the purposes of the DOI or for users seeking further information for the " +
"data. <br/><em>Only one contact is allowed per data package. If none are entered, " +
"you will be set as the contact for this document.</em>",
"creator" : "The main researchers involved in producing the data. " +
"These include authors, owners, originators and principal investigators " +
"who should be listed in the citation. <br/><em>One or more creators is required. " +
"If none are entered, you will be set as the creator of this document. List creators " +
"in the order they need to appear in the citation. More entries will appear as you enter information.</em>",
"contributor" : "Additional contributors involved in producing the data. These " +
"could include people who assisted in creating the data package but wouldn't be " +
"considered authors for publication. <br/><em>Enter as many contributors as needed.</em>"
};
var ORGANIZATIONS = [];
var EMLView = BaseEML211View.extend({
renderFunding: function(){
// Override funding section
},
get_organization_list: function() {
if (ORGANIZATIONS.length==0) {
// Synchronous call
ORGANIZATIONS = JSON.parse($.ajax({type: "GET", url: MetacatUI.root + "/js/themes/ess-dive/data/organizations.json", async: false}).responseText);
}
return ORGANIZATIONS;
},
/***
* Updates the placeholders for all data sections
*
*/
updateInputPlaceHolders: function(){
// Grab all data-sections
var sectionElements = $(document).find("section[data-section]");
if (typeof sectionElements != "undefined") {
// Iterate over all data sections
_.each(sectionElements, function(sectionEl){
var sectionName = $(sectionEl).attr("data-section");
// Get all text areas and input fields
var inputElements = $(sectionEl).find("textarea,input");
// Get the helper text from teh app model configuration
var helperText = MetacatUI.appModel.get("formHelpText") &&
MetacatUI.appModel.get("formHelpText").datasetEdit[sectionName];
if (typeof inputElements != "undefined") {
_.each(inputElements, function (element) {
// the input name is either in data-category
// or data-attribute
var name = $(element).attr("data-category");
if (typeof name == "undefined") {
name = $(element).attr("data-attribute");
}
if (typeof name != "undefined" && typeof helperText != "undefined" )
// update the place holder
$(element).attr("placeholder", helperText[name]);
});
}
});
}
},
/**
* Extend to update all placeholder helper text
*/
renderAllSections: function(){
BaseEML211View.prototype.renderAllSections.apply(this)
// Add the helper text
this.updateInputPlaceHolders();
},
/**
* Extend the initialization function to add the Funding Organization Sub View
* @param options
* @returns {*}
*/
renderOverview: function(){
BaseEML211View.prototype.renderOverview.apply(this);
var overviewEl = this.$container.find(".overview");
// Remove the funding container. ESS-DIVE will manage
// funding contract numbers with alternative identifers
var funding = overviewEl.find(".funding-container");
$( funding ).parent().remove();
// Remove the keyword container. ESS-DIVE will manage
// keywords as variables and categories
var keyword = overviewEl.find(".keyword-container");
$( keyword ).parent().remove();
// Replace empty keyword container with the subview
$(overviewEl.find(".keyword-categorical-container")).replaceWith(
new EMLVocabularySubView({parentModel:this.model,
type:"categorical"}).render().el);
// Replace empty keyword variable container with the subview
$(overviewEl.find(".keyword-variable-container")).replaceWith(
new EMLVocabularySubView({parentModel:this.model,
type:"variable"}).render().el);
// Add the ESS-DIVE subviews the the overview section
$(overviewEl).append(new EMLProjectSubView({parentModel:this.model}).render().el);
$(overviewEl).append(new EMLFundingOrganizationsSubView({parentModel:this.model}).render().el);
$(overviewEl).append(new EMLDOEContractsSubView({parentModel:this.model}).render().el);
$(overviewEl).append(new EMLReferencePaperSubView({parentModel:this.model}).render().el);
},
/***
* Render an EML Party on the edit form
*
* @param {EMLView} view - EMLView isntance
* @param type - the type of party could be an assosiatedParty role of a party type
* @param parties - the parties to render edit sections for
*/
renderParty: function (view, type, parties){
view.$(".section.people").append("<i>All information entered in this section will be made public once the data " +
"package is published.</i>",
"<h4>" + PARTY_LABELS_MAP[type] + "<i class='required-icon hidden' data-category='"+type+"'></i></h4>",
'<p class="subtle">'+ PARTY_HELP_MAP[type]+'</p>',
'<div class="party-section" data-attribute="'+type+'"></div>');
_.each(parties, view.renderPerson, view);
// Publishers and contact need at least one .
if(type != "contact" || parties.length == 0)
view.renderPerson(null, type);
},
/**
* Overrides the handlePersonTyping function
*
* This function reacts to the user typing a new person in the person section (an EMLPartyView)
*/
handlePersonTyping: function(e){
var container = $(e.target).parents(".eml-party"),
emlParty = container.length? container.data("model") : null,
partyType = container.length && emlParty? emlParty.get("role") || emlParty.get("type") : null;
if(this.$("[data-attribute='" + partyType + "'] .eml-party.new").length > 1) return;
//Render a new person if more than one are allowed
if( partyType != "contact" )
this.renderPerson(null, partyType);
},
/**
* Entirely override base class to control the number of persons rendered on copy
* @param emlParty
* @param partyType
*/
renderPerson: function(emlParty, partyType){
//If no model is given, create a new model
if(!emlParty){
var emlParty = new EMLParty({
parentModel: this.model
});
//Mark this model as new
var isNew = true;
//Find the party type or role based on the type given
if(_.contains(emlParty.get("roleOptions"), partyType))
emlParty.set("role", partyType);
else if(_.contains(emlParty.get("typeOptions"), partyType))
emlParty.set("type", partyType);
}
else{
var isNew = false;
//Get the party type, if it was not sent as a parameter
if(!partyType || typeof partyType != "string")
var partyType = emlParty.get("role") || emlParty.get("type");
}
//Find the container section for this party type
var container = this.$(".section.people").find('[data-attribute="' + partyType + '"]');
//See if this view already exists
if( !isNew && container.length && emlParty ){
var partyView;
_.each(container.find(".eml-party"), function(singlePartyEl){
//If this EMLPartyView element is for the current model, then get the View
if( $(singlePartyEl).data("model") == emlParty )
partyView = $(singlePartyEl).data("view");
});
//If a partyView was found, just rerender it and exit
if(partyView){
partyView.render();
return;
}
}
//If there still is no partyView found, create a new one
var partyView = new EMLPartyView({
model: emlParty,
edit: this.edit,
isNew: isNew,
});
//If this person type is not on the page yet, add it
if(!container.length){
this.addNewPersonType(emlParty.get("type") || emlParty.get("role"));
container = this.$(".section.people").find('[data-attribute="' + partyType + '"]');
}
// Find can return more than one new row
var newParties = container.find(".new");
if(!isNew && newParties.length)
container.find(".new")[0].before(partyView.render().el);
else {
container.append(partyView.render().el);
}
// Add autocomplete to the organization input fields
var view = this;
var organization_input_fields = view.$el.find('input[name="Organization"]');
$.map(organization_input_fields, function(input_field) {
$(input_field).autocomplete({
source: view.get_organization_list()
});
});
//Initialize the tooltips
this.$("input.tooltip-this").tooltip({
placement: "top",
title: function () {
return $(this).attr("placeholder")
},
delay: 1000
});
//if( partyType != "contact" )
// container.append("<a class='edit-add-people-link' >Add +</a>");
},
/**
* Overrides the renderPeople view of the form
*/
renderPeople: function () {
this.$(".section.people").empty().append("<h2>People</h2>");
// Instance variable expected by other functions
this.partyTypeMap = PARTY_LABELS_MAP;
//Iterate through party map and get associated parties
for (var key in this.partyTypeMap) {
if (this.partyTypeMap.hasOwnProperty(key))
{
var parties = null;
// If this is an associatedParty we need to get the role
if ("associatedParty" == PARTY_TYPE_MAP[key]) {
parties = _.filter(this.model.get("associatedParty"), function(party){ return party.get("role") == key })
}
else
{
parties = this.model.get(key);
}
// Always the party form section
this.renderParty(this, key, parties);
}
}
//Listen to the EML model for new EMLParty models that are added behind the scenes
// (mainly from EMLParty.createFromUser()
var view = this;
this.listenTo(this.model, "change:creator change:contributor", function (emlModel, changedModels) {
if (changedModels && changedModels.length)
this.renderPerson(changedModels[0], changedModels[0].get("type"));
});
},
/*
* Override Switch section
*/
switchSection: function(e){
if(!e) return;
e.preventDefault();
var clickedEl = $(e.target),
section = clickedEl.attr("data-section") ||
clickedEl.children("[data-section]").attr("data-section") ||
clickedEl.parents("[data-section]").attr("data-section");
if(this.visibleSection == "all")
this.scrollToSection(section);
else{
this.$(".section." + this.activeSection).hide()
this.$(".section." + section).show();
this.highlightTOC(section);
this.activeSection = section;
this.visibleSection = section;
$(document).scrollTop(this.$(".section." + section).offset().top - $("#Navbar").height());
//$("body").scrollTop(this.$(".section." + section).offset().top - $("#Navbar").height());
}
},
/*
* Override remove person, add validation trigger
*/
removePerson: function(e){
BaseEML211View.prototype.removePerson.apply(this,[e]);
//trigger validation check for first part entry
this.$(".section.people").find('[data-attribute="creator"]').find(".eml-party").first().data("view").showValidation();
}
});
return EMLView;
});