16f7813a9ec3a414a96077377694fa2ef83a8a1f
braney
  Fri Oct 27 15:59:33 2017 -0700
add auto-save to hgCollection

diff --git src/hg/js/hgCollection.js src/hg/js/hgCollection.js
index 99b005e..3b3ef45 100644
--- src/hg/js/hgCollection.js
+++ src/hg/js/hgCollection.js
@@ -1,26 +1,28 @@
 // hgCollection.js - Interactive features for GTEX Body Map version of GTEx Gene track UI page
 
 // Copyright (C) 2017 The Regents of the University of California
 
 var hgCollection = (function() {
     var names = []; // a list of names that have been used
     var selectedNode = "collectionList"; // keep track of id of selected row
     var selectedTree = "collectionList"; // keep track of id of selected row
     var $tracks;  // the #tracks object
     var trees = [];
     var isDirty = false;
+    var goTracks = false;
+    var doAjaxAsync = true;
 
     function currentTrackItems(node) {
         // populate the menu for the currentCollection tree
         var items = {
             addItem: { // The "add" menu item
                 label: "Add",
                 action: function () {
                     var nodeIds = $("#tracks").jstree( "get_selected");
                     isDirty = true;
                     var nodes = [];
                     var node;
                     for(ii=0; ii < nodeIds.length;ii++) {
                         node = $("#tracks").jstree('get_node', nodeIds[ii]);
                         if (node.children.length === 0)
                             nodes.push(node);
@@ -220,31 +222,31 @@
         var mytext = JSON.stringify(v);
         return mytext;
     }
 
     function saveCollections(trees) {
        // called when the "Save" button is pressed
        var json = "[";
        $('#collectionList li').each(function() {
             json += addCollection(trees, this ) + ',';
         });
         json = json.slice(0, -1);
         json += ']';
         var requestData = 'jsonp=' + json;
         $.ajax({
             data:  requestData ,
-            async: true,
+            async: doAjaxAsync,
             dataType: "JSON",
             type: "PUT",
             url: "hgCollection?cmd=saveCollection",
             trueSuccess: updatePage,
             success: catchErrorOrDispatch,
             error: errorHandler,
         });
     }
 
     function rebuildLabel() {
         // rebuild the label for tree item
         var newText = selectedNode.li_attr.shortlabel + "   (" + selectedNode.li_attr.longlabel + ")";
         $(selectedTree).jstree('rename_node', selectedNode, newText);
     }
 
@@ -326,54 +328,55 @@
 
     function minusHit (event, data) {
         // called with the minus icon is hit
         var treeObject = $(event.currentTarget).parent().parent();
         var id = treeObject.attr('id');
         var node = treeObject.jstree("get_node", id);
         if (node.children.length === 0) {
             isDirty = true;
             $(selectedTree).jstree( "delete_node", node);
         }
     }
 
     function init() {
         $body = $("body");
 
+        // block user input when ajax is running
         $(document).on({
             ajaxStart: function() { $body.addClass("loading");    },
             ajaxStop: function() { $body.removeClass("loading"); }    
         });
+
         $('.gbButtonGoContainer').click(submitForm);
        
         window.addEventListener("beforeunload", function (e) {
-            if (!isDirty)
-                return undefined;
-
-            var confirmationMessage = 'Do you want to leave this page without saving?';
+            if (isDirty) {
+                doAjaxAsync = false;
+                saveCollections(trees);
+            }
 
-            (e || window.event).returnValue = confirmationMessage; //Gecko + IE
-            return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
+            return undefined;
         });
 
         // called at initialization time
         $("#viewFunc").change(viewFuncChange);
         $("#customName").change(nameChange);
         $("#customDescription").change(descriptionChange);
         $("#customVis").change(visChange);
         //$("#customColorInput").change(colorChange);
         $("#saveCollections").click ( function() {saveCollections(trees);} );
-        $("#discardChanges").click ( function () { window.location.reload(); });
+        $("#discardChanges").click ( function () { isDirty = false; window.location.reload(); });
 
         $("#newCollection").click ( newCollection );
         $( "#newCalcTrackDialog" ).dialog({ modal: true, 
             width: "50%", 
             autoOpen: false,
             });
         $("#newCalcTrackButton").click ( dialogCalcTrack );
         $("#newCalcTrack").click ( newCalcTrack );
         $('#collectionList').selectable({selected : selectCollection});
         
         $( "#collectionList" ).contextmenu(collectionListRightClick);
 
         $(document).bind("mousedown", function (e) {
                 // If the clicked element is not the menu
                 if ($(e.target).parents(".collectionList-menu").length === 0) {
@@ -445,44 +448,47 @@
             }
         });
         treeDiv.on("select_node.jstree", function (evt, data)  {
             $(evt.target).jstree("toggle_node", data.node);
         });
         treeDiv.on('click', '.jstree-themeicon ', plusHit);
 
         var firstElement = $("#collectionList li").first();
         selectElements($("#collectionList"), firstElement) ;
     }
 
    function submitForm() {
     // Submit the form (from GO button -- as in hgGateway.js)
     // Show a spinner -- sometimes it takes a while for hgTracks to start displaying.
         $('.gbIconGo').removeClass('fa-play').addClass('fa-spinner fa-spin');
+        goTracks = true;
         saveCollections(trees);
     }
 
     function updatePage(responseJson) {
         // called after AJAX call
         isDirty = false;
         if (!responseJson) {
             return;
         }
 
+        if (goTracks) {
             // we go straight to hgTracks after save
             $form = $('form');
             $form.submit();
         }
+    }
 
     function getUniqueName(root) {
         // make sure name is unique in track hub
         if (!names[root]) {
             names[root] = true;
             return root;
         } else {
             var counter = 1;
 
             for(;;counter++) {
                 var name  = root + counter;
                 if (!names[name]) {
                     names[name] = true;
                     return name;
                 }