Source: themes/ess-dive/views/metadata/EMLVocabularySubView.js

define(['underscore', 'jquery', 'backbone', 'models/metadata/eml211/EMLKeywordSet',
        'text!themes/ess-dive/templates/metadata/keywords.html'],
    function (_, $, Backbone, EMLKeywordSet, Template) {


        /***
         * SubView for managing Variable Vocabularies
         *
         * @type {void|*}
         */
        var EMLVocabularySubView = Backbone.View.extend({

                tagName: "div",

                events: {
                    "click  .remove": "handleRemove"
                },

                id: null,

                template: _.template(Template),
            
                /**
                 * Initialize the Sub View
                 *
                 * Expects:
                 *
                 *  - options.type
                 *  - options.parentModel
                 *
                 * @param options
                 */
                initialize: function (options) {
                    // Assign the member variables to this instance
                    this.parentModel = options.parentModel;
                    this.type=options.type;

                    this.cssClass =  "keyword-"+this.type+"-container";
                    this.inputId = "new-keyword-"+this.type+"-value";

                    this.dataCategory = "keyword"+ this.capitalize(this.type) +"Sets";
                    
                    this.events["change input#"+this.inputId]="handleAdd";
                    this.events["autocompletechange input#"+this.inputId]="handleAdd";

                    // Get the current keywords
                    this.keywords = this.getKeywords();
                    this.keywordsJSON = this.getJSON();

                },
                /**
                 * Capitalize the string
                 *
                 * @param text
                 * @returns {string}
                 */
                capitalize: function(text){
                    return text.charAt(0).toUpperCase() + text.slice(1);

                },

                /**
                 * Load the vocabularies  from JSON file
                 */
                getJSON: function () {

                    // syncrhonous call
                    return JSON.parse($.ajax({
                        type: "GET",
                        url: MetacatUI.root + "/js/themes/ess-dive/data/vocabularies_keywords_"+this.type+".json",
                        async: false
                    }).responseText);

                },

                /**
                 * Get the list of variables
                 * @returns {Array}
                 */
                getKeywords: function () {
                    var variableJSON = this.getJSON();

                    return _.values(_.mapObject(variableJSON, function (val, key) {
                            return key + ": "+val;
                    }));
                },

                /**
                 * Return the variables
                 */
                getSelectedKeywords: function () {
                    var keywordVariables = [];
                    _.each(this.parentModel.get("keywordSets"), function (keywordSetModel) {
                        if( keywordSetModel.get("thesaurus").startsWith(this.type.toUpperCase()+":"))
                            _.each(keywordSetModel.get("keywords"), function (keyword) {
                                keywordVariables.push(keyword+":"+keywordSetModel.get("thesaurus"))
                            }, keywordSetModel.get("thesaurus"));
                    }, this);
                    return keywordVariables;
                },

                /**
                 * Render the template with the data
                 *
                 * @returns {EMLVocabularySubView}
                 */
                render: function () {
                    // Render the template with the selected funding organizations
                    this.$el.html(this.template(
                        {
                            "keywords": this.getSelectedKeywords(),
                            "keywordsJSON": this.keywordsJSON,
                            "inputId":this.inputId,
                            "dataCategory": this.dataCategory,
                            "cssClass": this.cssClass,
                            "noneType":  this.type.toUpperCase()+":NONE"
                        }
                    ));


                    // Add the keywords for the autocomplete list
                    var input = this.$el.find("#"+this.inputId)[0];
                    $(input).autocomplete({
                        source: this.keywords,
                        delay: 1000,
                        limit: 200,
                    });

                    // This is a Subview
                    this.delegateEvents();

                    return this;
                },

                /**
                 * Remove a keyword
                 * @param e
                 */
                handleRemove: function (e) {

                    // Get the keyword and the thesaurus
                    var thesaurus = $(e.target).data('keyword-thesaurus');
                    var variable = $(e.target).data('keyword-variable');

                    // get the target from the EML Model
                    var keywordSet = _.find(this.parentModel.get("keywordSets"),
                            function(keywordSet){
                                return keywordSet.get("thesaurus").endsWith(thesaurus);
                            });

                    // Remove the specified variable
                    keywordSet.set("keywords",_.without(keywordSet.get("keywords"), variable));

                    // If there are no variables left then remove it from the model
                    if (keywordSet.get("keywords").length == 0) {
                        this.parentModel.set("keywordSets", _.without(this.parentModel.get("keywordSets"),keywordSet))
                    }

                    this.render();

                    // Trigger a change on the entire package
                    MetacatUI.rootDataPackage.packageModel.set("changed", true);

                },


                /**
                 * Event on select change. Update the model with the selected value
                 *
                 * @param e
                 */
                handleAdd: function (e) {

                    // Get the Keywords
                    var keywordSets = this.parentModel.get("keywordSets");

                    // Find the Thesaurus
                    var result = $(e.target).val().split(": ");
                    var selected_keyword = result[0];

                    // Get the Thesaurus
                    var thesaurus = this.type.toUpperCase()+":NONE";
                    if ( result.length ==  2) thesaurus = result[1];

                    // Was this keyword  selected?
                    var exists = _.find(keywordSets, function (keywordSet) {
                        return keywordSet.get("thesaurus") == thesaurus &&
                            _.contains(keywordSet.get("keywords"),selected_keyword);
                    });

                    if (!exists || exists.length == 0) {

                        // Add the keyword to the model
                        var result = _.find(keywordSets, function (keywordSet) {
                            return keywordSet.get("thesaurus") == thesaurus;
                        });
                        if (result) {
                            // Add to the existing keyword set
                            result.get("keywords").push(selected_keyword);
                        }
                        else{
                            // New Thesaurus, Create a new keyword set
                            var keywordSet =  new EMLKeywordSet({
                                parentModel: this.parentModel,
                                keywords: [selected_keyword],
                                thesaurus: thesaurus
                            });

                            // Does the parent already have a key word set?
                            if(this.parentModel.get("keywordSets")){
                                this.parentModel.get("keywordSets").push(keywordSet)
                            }
                            else{
                                this.parentModel.set("keywordSets",[keywordSet])
                            }

                        }
                        // Trigger a change on the entire package
                        MetacatUI.rootDataPackage.packageModel.set("changed", true);


                    }
                    this.render();

                }
            }
        );


        return EMLVocabularySubView;
    }
);