5294eee73d4f2a805657ca650552e65c22f857c6 tdreszer Fri May 2 13:46:57 2014 -0700 Vis changes are now queued for update because quick vis changes followed by refresh wer creating a race condition. Redmine 13164. diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index b7e61dd..2ba14d1 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -441,42 +441,44 @@ if ($(obj).hasClass('noLink')) // TITLE_BUT_NO_LINK return false; if (obj.href.match('#') || obj.target.length > 0) { //alert("Matched # ["+obj.href+"] or has target:"+obj.target); return true; } var thisForm=$(obj).parents('form'); if(thisForm == undefined || $(thisForm).length == 0) thisForm=$("FORM"); if($(thisForm).length > 1 ) thisForm=$(thisForm)[0]; if(thisForm != undefined && $(thisForm).length == 1) { //alert("posting form:"+$(thisForm).attr('name')); - return postTheForm($(thisForm).attr('name'),obj.href); + var href = obj.href + vis.cartUpdatesGet(); + return postTheForm($(thisForm).attr('name'),href); } return true; } } /////////////////////////////////////////////// //// visibility (mixed with group toggle) ///// /////////////////////////////////////////////// var vis = { enumOrder: new Array("hide", "dense", "full", "pack", "squish"), // map cgi enum visibility codes to strings + cartUpdateQueue: {}, update: function (track, visibility) { // Updates visibility state in hgTracks.trackDb and any visible elements on the page. // returns true if we modify at least one select in the group list var rec = hgTracks.trackDb[track]; var selectUpdated = false; $("select[name=" + escapeJQuerySelectorChars(track) + "]").each(function(t) { $(this).attr('class', visibility == 'hide' ? 'hiddenText' : 'normalText'); $(this).val(visibility); selectUpdated = true; }); if(rec) { rec.localVisibility = visibility; } return selectUpdated; @@ -513,48 +515,87 @@ return setTableRowVisibility(button, prefix, "hgtgroup", "group",false,arguments[2]); else return setTableRowVisibility(button, prefix, "hgtgroup", "group",false); }, expandAllGroups: function (newState) { // Set visibility of all track groups to newState (true means expanded). // This code also modifies the corresponding hidden fields and the gif's of the +/- img tag. imageV2.markAsDirtyPage(); $(".toggleButton[id$='_button']").each( function (i) { // works for old img type AND new BUTTONS_BY_CSS vis.toggleForGroup(this,this.id.substring(0,this.id.length - 7),newState); // clip '_button' suffix }); return false; }, + cartUpdatesGet: function () + { // returns any outstanding cart updates as a string, and clears the queue + var updates = ""; + for (var track in vis.cartUpdateQueue) { + updates += "&" + track + "=" + vis.cartUpdateQueue[track]; + } + + vis.cartUpdateQueue = {}; + return updates; + }, + + // NOTE: could update in background, however, failing to hit "refresh" is a user choice + // cartUpdatesViaAjax: function () + // { // Called via timer: updates the cart via setVars. + // if (Object.keys(vis.cartUpdateQueue).length === 0) + // return; + // + // var tracks = []; + // var newVis = []; + // for (var track in vis.cartUpdateQueue) { + // tracks.push(track) + // newVis.push(vis.cartUpdateQueue[track]); + // } + // if (tracks.length === 0) + // return; + // vis.cartUpdateQueue = {}; + // setCartVars(tracks,newVis,async=false); // sync to avoid another race condition mess + // }, + + cartUpdateAddToQueue: function (track,newVis) + { // creates a string of updates to save for ajax batch or a submit + vis.cartUpdateQueue[track] = newVis; + + // NOTE: could update in background, however, failing to hit "refresh" is a user choice + // first in queue, schedule background update + // if (Object.keys(vis.cartUpdateQueue).length === 1) + // setTimeout("vis.cartUpdatesViaAjax();",10000); + }, + initForAjax: function() { // To better support the back-button, it is good to eliminate extraneous form puts // Towards that end, we support visBoxes making ajax calls to update cart. var sels = $('select.normalText,select.hiddenText'); $(sels).change(function() { var track = $(this).attr('name'); if ($(this).val() == 'hide') { var rec = hgTracks.trackDb[track]; if(rec) rec.visibility = 0; // else Would be nice to hide subtracks as well but that may be overkill $(document.getElementById('tr_' + track)).remove(); imageV2.highlightRegion(); $(this).attr('class', 'hiddenText'); } else $(this).attr('class', 'normalText'); - setCartVar(track,$(this).val()); + vis.cartUpdateAddToQueue(track,$(this).val()); return false; }); // Now we can rid the submt of the burden of all those vis boxes var form = $('form#TrackForm'); $(form).submit(function () { $('select.normalText,select.hiddenText').attr('disabled',true); }); $(form).attr('method','get'); }, restoreFromBackButton: function() // Re-enabling vis dropdowns is necessarty because intiForAjax() disables them on submit. { $('select.normalText,select.hiddenText').attr('disabled',false); } @@ -3204,31 +3245,32 @@ if(keepCurrentTrackVisible) { var item = rightClick.currentMapItem || imageV2.lastTrack; if(item) { var top = $(document.getElementById("tr_" + item.id)).position().top; if(top >= $(window).scrollTop() || top < $(window).scrollTop() + $(window).height()) { // don't bother if the item is not currently visible. currentId = item.id; currentIdYOffset = top - $(window).scrollTop(); } } } $.ajax({ type: "GET", url: "../cgi-bin/hgTracks", - data: params + "&hgt.trackImgOnly=1&hgt.ideogramToo=1&hgsid=" + getHgsid(), + data: params + "&hgt.trackImgOnly=1&hgt.ideogramToo=1&hgsid=" + + getHgsid() + vis.cartUpdatesGet(), dataType: "html", trueSuccess: imageV2.updateImgAndMap, success: catchErrorOrDispatch, error: errorHandler, cmd: 'wholeImage', loadingId: showLoadingImage("imgTbl"), disabledEle: disabledEle, currentId: currentId, currentIdYOffset: currentIdYOffset, cache: false }); }, highlightRegion: function() // highlight vertical region in imgTbl based on hgTracks.highlight (#709).