edbd78ba2667d41249ee0c521d49304c038ffeb1 galt Fri Feb 19 17:27:19 2021 -0800 Added counts to hgTrackUi facets. refs #25321 diff --git src/hg/js/ddcl.js src/hg/js/ddcl.js index a83e480..bc7ce9a 100644 --- src/hg/js/ddcl.js +++ src/hg/js/ddcl.js @@ -18,35 +18,41 @@ // selectOptions: original multiSelect.options (get updated, sent to cart, etc.) // control: The whole gaggle of elements that get created when one multiSelect becomes a ddcl // controlLabel: Just the text inside the closed control // controlSelector: the closed box waiting to be clicked // dropWrapper: The div that contains all the checkboxes and is only seen when the DDCL is open // allCheckboxes: one to one correspondence with selectOptions // Don't complain about line break before '||' etc: /* jshint -W014 */ var ddcl = { //mySelf: null, // There is no need for a "mySelf" unless this object is being instantiated. textOfObjWrappedInStyle: function (obj) { // returns the obj text and if there is obj style, the text gets span wrapped with it + var text = ''; var style = $(obj).attr('style'); if (style && style.length > 0) text = "<span style='"+style+"'>"; text += $(obj).text(); + + if (obj.facetCount > 0) { + text += ' ('+obj.facetCount+')'; + } + if (style && style.length > 0) text += "</span>"; return text; }, textOfCurrentSelections: function (options) { // Generates a multi-line string of currently selected options var chosen = $(options).filter(':selected'); // Works with FF and Chrome but not IE! if (chosen.length === 0 && theClient.isIe()) chosen = $(options).find(':selected'); // Works with IE but not FF and Chrome! var chosenCount = $(chosen).length; var msg = ''; if (chosenCount === 0) { msg = 'Please select...'; @@ -80,59 +86,113 @@ onOpen: function (event) { // Called by a DDCL onClick event (when the drop list is opened) var controlSelector = this; // Set the label var control = $(controlSelector).parent(); ddcl.labelSet(control,"Select multiple...",'#000088','Selecting...'); // Find the active 'items' and original 'options' var id = $(control).attr('id').substring('ddcl-'.length); var dropWrapper = $('#ddcl-' + id + '-ddw');//.first(); var multiSelect = $(document.getElementById(id)); var allCheckboxes = $(dropWrapper).find("input.active"); var selectOptions = multiSelect[0].options; + // Special juice to handle "exclude" options based upon competing filterBoxes try { if (( $(multiSelect).hasClass('filterComp') && filterCompositeExcludeOptions(multiSelect)) || ( $(multiSelect).hasClass('filterTable') && filterTable.excludeOptions(multiSelect))) { // "exclude" items based upon the exclude tag of the true options allCheckboxes.each(function(index) { var item = $(this).parent(); + // GREY OUT if ($(selectOptions[index]).hasClass('excluded')) { $(item).addClass("ui-state-excluded"); - } else //if ($(item).hasClass("ui-state-excluded")) + } else { $(item).removeClass("ui-state-excluded"); + } }); } } catch (err) {} // OK if filterCompositeExcludeOptions is not defined. // Show only first as selected if it is selected if (allCheckboxes[0].checked === true) { allCheckboxes.each(function(index) { if (index > 0) + { $(this).attr('checked',false); + } }); } + + + var hideCount = 0; + var itemHeight = 0; + + // update the facetCounts + allCheckboxes.each(function(index) { + var item = $(this).parent(); + + if (index === 0) { + itemHeight = item[0].clientHeight; + } + + var facetSpan=$(item).find('span'); + var facetCount = selectOptions[index].facetCount; + if (index === 0 || facetCount === 0 || facetCount === undefined) { // Al + $(facetSpan).html(''); + } else { + $(facetSpan).html(' ('+facetCount+')'); + } + // facetSpan and item and this did not work to get it to hide: + if (index === 0 || (facetCount !== 0) || $(this).attr('checked')) { + $(item).show(); + } else { + $(item).hide(); + ++hideCount; + } + }); + + + // make dynamic height based on current window size + var maxDropHeight = $(window).height() - 80; + if (maxDropHeight < 49) + maxDropHeight = 49; + + // each element 22 high plus one Close panel at bottom + var dropHeight = ($(multiSelect).children().length - hideCount + 1) * itemHeight; + + if (dropHeight > maxDropHeight) + dropHeight = maxDropHeight; + $(dropWrapper).css({ + height: dropHeight + "px", + }); + dropWrapper.find(".ui-dropdownchecklist-dropcontainer").css({ + height: dropHeight + "px" + }); + + + }, - onComplete: function (multiSelect) { + onCompleteDraw: function (multiSelect) { // Called by ui.dropdownchecklist.js when selections have been made // Also called at init to fill the selector with current choices // Warning: In IE this gets called when still selecting! var id = $(multiSelect).attr('id'); // If no options are selected, may have to force all var chosen = $(multiSelect).find('option:selected'); if (chosen.length === 0) { if ($(multiSelect).hasClass('noneIsAll')) { //$(multiSelect).first('option').first().attr('selected',true); multiSelect.options[0].selected = true; // How to check the first item? var dropWrapper = $('#ddcl-' + id + '-ddw'); @@ -144,32 +204,59 @@ if (index > 0) $(this).attr('selected',false); }); } var msg = ddcl.textOfCurrentSelections(multiSelect.options); var control = $('#ddcl-' + id); var newColor = ''; if ($(multiSelect).find('option:selected').length === 0) newColor = '#AA0000'; // red //else if (msg.search(/color:/i) === -1) // newColor = 'black'; ddcl.labelSet(control,msg,newColor,'Click to select...'); + }, + + onComplete: function (multiSelect) { + + + // Called by ui.dropdownchecklist.js when selections have been made + // Also called at init to fill the selector with current choices + ddcl.onCompleteDraw(multiSelect); + // Notice special handling for a custom event $(multiSelect).trigger('done',multiSelect); + + }, + + + reinitFacetCounts: function () { + // ReInitialize the DDCLs (drop-down checkbox-list) + + var possibleSelections = {}; // use as hash + + $('select.filterComp').each( function(i) { + var multiSelect = this; + // skip if setup not run yet. + var id = $(multiSelect).attr('id'); + if (id && (id.length > 0) && normed($('#ddcl-' + id))) { + filterCompositeExcludeOptionsQuick(multiSelect, possibleSelections); + ddcl.onCompleteDraw(multiSelect); + } + }); }, reinit: function (filterBys,force) { // ReInitialize the DDCLs (drop-down checkbox-list) // This is done when the track search with tabs gets switched to advanced tab // because the DDCLs were setup on hidden filterBys and dimensiuons are wrong. // if not force, then only reinit when the dimensions are suspect // NOTE: If force is true, this doesn't do anything!! if (filterBys.length < 1) return; $(filterBys).each( function(i) { // Do this by 'each' to set noneIsAll individually var multiSelect = this; if (!force) { // condition on bad dimensions @@ -192,30 +279,31 @@ } }); }, setup: function (obj) { // Initialize the multiselect as a DDCL (drop-down checkbox-list) //mySelf = this; // There is no need for a "mySelf" unless this object is being instantiated // Defaults var myFirstIsAll = true; var myNoneIsAll = false; var myIcon = $(obj).hasClass('filterBy') ? {} : null; var myEmptyText = 'Select...'; var myClose = 'close '; var myDropHeight = filterByMaxHeight(obj); + // parse optional args for (var vIx=1;vIx<arguments.length;vIx++) { switch(arguments[vIx]) { case 'noneIsAll': myNoneIsAll = true; break; case 'firstNotAll': myFirstIsAll = false; break; case 'arrows': myIcon = {}; break; case 'noClose': myClose = null; break; case 'label': vIx++; if (vIx<arguments.length) myEmptyText = arguments[vIx]; break; @@ -233,62 +321,82 @@ if (name && name.length > 0) id = 'dd-' + name; else { id = 'ix' + $('select').index(obj); } $(obj).attr('id',id); } else { if (normed($('#ddcl-' + id))) // Don't set up twice! return; } // These values can only be taken from the select before it becomes a DDCL var maxWidth = $(obj).width(); if (maxWidth === 0) // currently hidden so wait for a reinit(); return; + var minWidth = $(obj).css('min-width'); if (minWidth && minWidth.length > 0) { // Is a string, so convert and compare minWidth = parseInt(minWidth); if (maxWidth < minWidth) maxWidth = minWidth; } maxWidth = (Math.ceil(maxWidth / 10) * 10) + 10; // Makes for more even boxes var style = $(obj).attr('style'); // The magic starts here: $(obj).dropdownchecklist({ firstItemChecksAll: true, noneIsAll: myNoneIsAll, maxDropHeight: myDropHeight, icon: myIcon, emptyText: myEmptyText, explicitClose: myClose, textFormatFunction: function () { return 'selecting...'; } , onComplete: ddcl.onComplete }); if (myNoneIsAll) $(obj).addClass('noneIsAll'); // Declare this as none selected same as all selected - ddcl.onComplete(obj); // shows selected items in multiple lines + + // shows selected items in multiple lines + try { + if (!obj.options[0].selected) { // All selected + if (( $(obj).hasClass('filterComp') + && filterCompositeExcludeOptions(obj)) + || ( $(obj).hasClass('filterTable') + && filterTable.excludeOptions(obj))) { + // do nothing + } + } + } + catch (err) {} // OK if filterCompositeExcludeOptions is not defined. + ddcl.onCompleteDraw(obj); + $(obj).trigger('done',obj); + // Set up the selector (control seen always and replacing select) var control = $('#ddcl-' + id); if (!control) { warn('ddcl.setup('+id+') failed to create drop-down checkbox-list'); return; } var controlSelector = $(control).find(".ui-dropdownchecklist-selector"); + $(controlSelector).click(ddcl.onOpen); + + maxWidth += 60; // extra space for the facet count " (9999)" + $(controlSelector).css({width:maxWidth+'px'}); var controlText = $(control).find(".ui-dropdownchecklist-text"); $(controlText).css({width:maxWidth+'px'}); // Set up the drop list (control seen only on fucus and with items to choose) var dropWrapper = $('#ddcl-' + id + '-ddw'); if (!dropWrapper) { warn('ddcl.setup('+id+') failed to create drop-down checkbox-list'); return; } // Individual items need styling var itemHeight = 22; // Exclude the close button var dropItems = $(dropWrapper).find(".ui-dropdownchecklist-item"); $(dropItems).hover(function () {$(this).css({backgroundColor:'#CCFFCC'});}, @@ -298,31 +406,33 @@ var itemCount = dropItems.length; if (myClose && myClose.length > 0) { // target the close button var dropClose = $(dropWrapper).find(".ui-dropdownchecklist-close"); $(dropClose).css({height:(itemHeight - 1)+'px',textAlign:'center'}); itemCount++; } // The whole droplist needs styling var dropContainerDiv = dropWrapper.find(".ui-dropdownchecklist-dropcontainer"); var maxHeight = (itemHeight*itemCount) + 1; // extra prevents unwanted vertical scrollbar var divHeight = dropContainerDiv.outerHeight(); if (divHeight > maxHeight) { $(dropContainerDiv).css({height:maxHeight+'px'}); $(dropWrapper).css({height:maxHeight+'px'}); } - maxWidth += 30; // extra avoids horizontal scrollBar when vertical one is included + + + maxWidth -= 10; // tweak width for dropdown $(dropContainerDiv).css({width:(maxWidth)+'px'}); $(dropWrapper).css({width:maxWidth+'px'}); // Finally we can get style from the original select and apply it to the whole control if (style && style.length > 0) { var styles = style.split(';'); for (var ix = 0;ix < styles.length;ix++) { var aStyleDef = styles[ix].split(':'); aStyleDef[0] = aStyleDef[0].replace(' ',''); // no spaces if (aStyleDef[0] !== 'display') // Need to see if other styles should be restricted. $(control).css(aStyleDef[0],aStyleDef[1]); if (aStyleDef[0].substring(0,4) === 'font') // Fonts should be applied too $(dropItems).css(aStyleDef[0],aStyleDef[1]); } }