From 6e78df4be9abb7e1ce959e9b83b9d38bd77fcade Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 2 Mar 2021 22:49:52 +0000 Subject: Adoping code from the following link to make resizeable columns for search result table - https://datatables.net/forums/discussion/63231/resizing-columns-using-jquery-ui --- wqflask/wqflask/templates/search_result_page.html | 519 +++++++++++++--------- 1 file changed, 303 insertions(+), 216 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index e7a7bc51..a33d1b1a 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -7,6 +7,7 @@ + {% endblock %} {% block content %} @@ -171,225 +172,311 @@ return params; }; - //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters - trait_table = $('#trait_table').DataTable( { - 'drawCallback': function( settings ) { - $('#trait_table tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } - change_buttons() - }); - }, - 'createdRow': function ( row, data, index ) { - $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); - $('td', row).eq(1).attr("align", "right"); - $('td', row).eq(1).attr('data-export', index+1); - $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); - {% if dataset.type == 'ProbeSet' %} - $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - if ($('td', row).eq(3).text().length > 20) { - $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20)); - $('td', row).eq(3).text($('td', row).eq(3).text() + '...') - } - $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); - $('td', row).slice(5,10).attr("align", "right"); - $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); - $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); - $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); - $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); - $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); - {% elif dataset.type == 'Publish' %} - $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('align', 'right'); - $('td', row).slice(6,10).attr("align", "right"); - $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); - $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); - $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); - $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); - $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text()); - {% elif dataset.type == 'Geno' %} - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - {% endif %} + var tableId = "trait_table"; + + columnDefs = [ + { + 'data': null, + 'width': "25px", + 'orderDataType': "dom-checkbox", + 'orderable': false, + 'render': function(data, type, row, meta) { + return '' + } + }, + { + 'title': "Index", + 'type': "natural", + 'width': "30px", + 'data': "index" + }, + { + 'title': "Record", + 'type': "natural-minus-na", + 'data': null, + 'width': "60px", + 'render': function(data, type, row, meta) { + return '' + data.display_name + '' + } + }{% if dataset.type == 'ProbeSet' %}, + { + 'title': "Symbol", + 'type': "natural", + 'width': "120px", + 'data': "symbol" + }, + { + 'title': "Description", + 'type': "natural", + 'data': null, + 'render': function(data, type, row, meta) { + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return escape(data.description) + } + } + }, + { + 'title': "
Location
", + 'type': "natural-minus-na", + 'width': "125px", + 'data': "location" + }, + { + 'title': "
Mean
", + 'type': "natural-minus-na", + 'width': "30px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak  
LOD  
", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak Location
", + 'type': "natural-minus-na", + 'width': "125px", + 'data': "lrs_location" + }, + { + 'title': "
Effect  
Size  
", + 'type': "natural-minus-na", + 'data': "additive", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }{% elif dataset.type == 'Publish' %}, + { + 'title': "Description", + 'type': "natural", + 'width': "500px", + 'data': null, + 'render': function(data, type, row, meta) { + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return data.description + } + } + }, + { + 'title': "
Mean
", + 'type': "natural-minus-na", + 'width': "30px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Authors", + 'type': "natural", + 'width': "300px", + 'data': null, + 'render': function(data, type, row, meta) { + author_list = data.authors.split(",") + if (author_list.length >= 6) { + author_string = author_list.slice(0, 6).join(",") + ", et al." + } else{ + author_string = data.authors + } + return author_string + } + }, + { + 'title': "
Year
", + 'type': "natural-minus-na", + 'data': null, + 'width': "25px", + 'render': function(data, type, row, meta) { + if (data.pubmed_id != "N/A"){ + return '' + data.pubmed_text + '' + } else { + return data.pubmed_text + } }, - 'data': trait_list, - 'columns': [ - { - 'data': null, - 'width': "25px", - 'orderDataType': "dom-checkbox", - 'orderable': false, - 'render': function(data, type, row, meta) { - return '' - } - }, - { - 'title': "Index", - 'type': "natural", - 'width': "30px", - 'data': "index" - }, - { - 'title': "Record", - 'type': "natural-minus-na", - 'data': null, - 'width': "60px", - 'render': function(data, type, row, meta) { - return '' + data.display_name + '' - } - }{% if dataset.type == 'ProbeSet' %}, - { - 'title': "Symbol", - 'type': "natural", - 'width': "120px", - 'data': "symbol" - }, - { - 'title': "Description", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.description)) - } catch(err){ - return escape(data.description) - } - } - }, - { - 'title': "
Location
", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "location" - }, - { - 'title': "
Mean
", - 'type': "natural-minus-na", - 'width': "30px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak  
LOD  
", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak Location
", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "lrs_location" - }, - { - 'title': "
Effect  
Size  
", - 'type': "natural-minus-na", - 'data': "additive", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }{% elif dataset.type == 'Publish' %}, - { - 'title': "Description", - 'type': "natural", - 'width': "500px", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.description)) - } catch(err){ - return data.description - } + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak  
LOD  
", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak Location
", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "lrs_location" + }, + { + 'title': "
Effect  
Size  
", + 'type': "natural-minus-na", + 'width': "60px", + 'data': "additive", + 'orderSequence': [ "desc", "asc"] + }{% elif dataset.type == 'Geno' %}, + { + 'title': "
Location
", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "location" + }{% endif %} + ]; + + loadDataTable(); + + function loadDataTable(){ + //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters + trait_table = $('#' + tableId).DataTable( { + 'drawCallback': function( settings ) { + $('#' + tableId + ' tr').off().on("click", function(event) { + if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { + var obj =$(this).find('input'); + obj.prop('checked', !obj.is(':checked')); + } + if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ + $(this).removeClass("selected") + } else if (event.target.tagName.toLowerCase() !== 'a') { + $(this).addClass("selected") + } + change_buttons() + }); + }, + 'createdRow': function ( row, data, index ) { + $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); + $('td', row).eq(1).attr("align", "right"); + $('td', row).eq(1).attr('data-export', index+1); + $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); + {% if dataset.type == 'ProbeSet' %} + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + if ($('td', row).eq(3).text().length > 20) { + $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20)); + $('td', row).eq(3).text($('td', row).eq(3).text() + '...') } - }, - { - 'title': "
Mean
", - 'type': "natural-minus-na", - 'width': "30px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Authors", - 'type': "natural", - 'width': "300px", - 'data': null, - 'render': function(data, type, row, meta) { - author_list = data.authors.split(",") - if (author_list.length >= 6) { - author_string = author_list.slice(0, 6).join(",") + ", et al." - } else{ - author_string = data.authors - } - return author_string + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + $('td', row).slice(5,10).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); + {% elif dataset.type == 'Publish' %} + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('align', 'right'); + $('td', row).slice(6,10).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text()); + {% elif dataset.type == 'Geno' %} + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + {% endif %} + }, + "data": trait_list, + "columns": columnDefs, + "order": [[1, "asc" ]], + "sDom": "iti", + "destroy": true, + "autoWidth": false, + "deferRender": true, + "bSortClasses": false, + {% if trait_list|length > 20 %} + "scrollY": "100vh", + "scroller": true, + "scrollCollapse": true, + {% else %} + "iDisplayLength": -1, + {% endif %} + "initComplete": function (settings) { + //Add JQueryUI resizable functionality to each th in the ScrollHead table + $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ + handles: "e", + alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother + stop: function () { + saveColumnSettings(); + loadDataTable(); } - }, - { - 'title': "
Year
", - 'type': "natural-minus-na", - 'data': null, - 'width': "25px", - 'render': function(data, type, row, meta) { - if (data.pubmed_id != "N/A"){ - return '' + data.pubmed_text + '' - } else { - return data.pubmed_text - } - }, - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak  
LOD  
", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak Location
", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "lrs_location" - }, - { - 'title': "
Effect  
Size  
", - 'type': "natural-minus-na", - 'width': "60px", - 'data': "additive", - 'orderSequence': [ "desc", "asc"] - }{% elif dataset.type == 'Geno' %}, - { - 'title': "
Location
", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "location" - }{% endif %} - ], - "order": [[1, "asc" ]], - 'sDom': "iti", - "autoWidth": true, - "bSortClasses": false, - {% if trait_list|length > 20 %} - "scrollY": "100vh", - "scroller": true, - "scrollCollapse": true - {% else %} - "iDisplayLength": -1 - {% endif %} - } ); + }); + }, + } ); + } + + function setUserColumnsDefWidths() { + + var userColumnDef; + + // Get the settings for this table from localStorage + var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; + + if (userColumnDefs.length === 0 ) return; + + columnDefs.forEach( function(columnDef) { + + // Check if there is a width specified for this column + userColumnDef = userColumnDefs.find( function(column) { + return column.targets === columnDef.targets; + }); + + // If there is, set the width of this columnDef in px + if ( userColumnDef ) { + + columnDef.width = userColumnDef.width + 'px'; + + } + + }); + + } + + + function saveColumnSettings() { + + var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; + + var width, header, existingSetting; + + trait_table.columns().every( function ( targets ) { + + // Check if there is a setting for this column in localStorage + existingSetting = userColumnDefs.findIndex( function(column) { return column.targets === targets;}); + + // Get the width of this column + header = this.header(); + width = $(header).width(); + + if ( existingSetting !== -1 ) { + + // Update the width + userColumnDefs[existingSetting].width = width; + + } else { + + // Add the width for this column + userColumnDefs.push({ + targets: targets, + width: width, + }); + + } + + }); + + // Save (or update) the settings in localStorage + localStorage.setItem(tableId, JSON.stringify(userColumnDefs)); + + } - trait_table.draw(); //ZS: This makes the table adjust its height properly on initial load + //trait_table.draw(); //ZS: This makes the table adjust its height properly on initial load $('.toggle-vis').on( 'click', function (e) { e.preventDefault(); @@ -409,7 +496,7 @@ $('#redraw').click(function() { - var table = $('#trait_table').DataTable(); + var table = $('#' + tableId).DataTable(); table.colReorder.reset() }); -- cgit v1.2.3 From 3c4043e445d0708490b2a14805b8e3eaa75c23fd Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 11 Mar 2021 22:35:11 +0000 Subject: Added some CSS to make cell content cut off with ellipses if a column is narrower than the content's width --- wqflask/wqflask/static/new/css/trait_list.css | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/wqflask/wqflask/static/new/css/trait_list.css b/wqflask/wqflask/static/new/css/trait_list.css index c7249721..6d49f009 100644 --- a/wqflask/wqflask/static/new/css/trait_list.css +++ b/wqflask/wqflask/static/new/css/trait_list.css @@ -52,3 +52,21 @@ div.dts div.dataTables_paginate,div.dts div.dataTables_length{ display:none } +/* This is the important CSS */ +table.dataTable { + table-layout: fixed; + width: 100%; + white-space: nowrap; + overflow: hidden; +} + +table.dataTable th { + white-space: nowrap; + overflow: hidden; +} + +table.dataTable td { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} \ No newline at end of file -- cgit v1.2.3 From c03dded58477b48ce54a8a03da90aae45a256758 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 11 Mar 2021 22:43:35 +0000 Subject: Made a variety of changes to make column resizeability work - the main issue was related to there being both an sWidth and width parameter --- wqflask/wqflask/templates/search_result_page.html | 317 +++++++++++----------- 1 file changed, 166 insertions(+), 151 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index a33d1b1a..210cef30 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -125,8 +125,8 @@ {% endif %} {% endif %} -
- +
+
@@ -175,161 +175,174 @@ var tableId = "trait_table"; columnDefs = [ - { - 'data': null, - 'width': "25px", - 'orderDataType': "dom-checkbox", - 'orderable': false, - 'render': function(data, type, row, meta) { - return '' - } - }, - { - 'title': "Index", - 'type': "natural", - 'width': "30px", - 'data': "index" - }, - { - 'title': "Record", - 'type': "natural-minus-na", - 'data': null, - 'width': "60px", - 'render': function(data, type, row, meta) { - return '' + data.display_name + '' + { + 'data': null, + 'width': "25px", + 'orderDataType': "dom-checkbox", + 'orderable': false, + 'targets': 0, + 'render': function(data, type, row, meta) { + return '' + } + }, + { + 'title': "Index", + 'type': "natural", + 'width': "30px", + 'targets': 1, + 'data': "index" + }, + { + 'title': "Record", + 'type': "natural-minus-na", + 'data': null, + 'width': "60px", + 'targets': 2, + 'render': function(data, type, row, meta) { + return '' + data.display_name + '' + } + }{% if dataset.type == 'ProbeSet' %}, + { + 'title': "Symbol", + 'type': "natural", + 'width': "120px", + 'targets': 3, + 'data': "symbol" + }, + { + 'title': "Description", + 'type': "natural", + 'data': null, + 'targets': 4, + 'render': function(data, type, row, meta) { + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return escape(data.description) } - }{% if dataset.type == 'ProbeSet' %}, - { - 'title': "Symbol", - 'type': "natural", - 'width': "120px", - 'data': "symbol" - }, - { - 'title': "Description", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - try { + } + }, + { + 'title': "
Location
", + 'type': "natural-minus-na", + 'width': "125px", + 'targets': 5, + 'data': "location" + }, + { + 'title': "
Mean
", + 'type': "natural-minus-na", + 'width': "30px", + 'data': "mean", + 'targets': 6, + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak  
LOD  
", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'targets': 7, + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak Location
", + 'type': "natural-minus-na", + 'width': "125px", + 'targets': 8, + 'data': "lrs_location" + }, + { + 'title': "
Effect  
Size  
", + 'type': "natural-minus-na", + 'data': "additive", + 'width': "60px", + 'targets': 9, + 'orderSequence': [ "desc", "asc"] + }{% elif dataset.type == 'Publish' %}, + { + 'title': "Description", + 'type': "natural", + 'width': "500px", + 'data': null, + 'render': function(data, type, row, meta) { + try { return decodeURIComponent(escape(data.description)) - } catch(err){ - return escape(data.description) - } + } catch(err){ + return data.description } - }, - { - 'title': "
Location
", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "location" - }, - { - 'title': "
Mean
", - 'type': "natural-minus-na", - 'width': "30px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak  
LOD  
", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak Location
", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "lrs_location" - }, - { - 'title': "
Effect  
Size  
", - 'type': "natural-minus-na", - 'data': "additive", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }{% elif dataset.type == 'Publish' %}, - { - 'title': "Description", - 'type': "natural", - 'width': "500px", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.description)) - } catch(err){ - return data.description - } + } + }, + { + 'title': "
Mean
", + 'type': "natural-minus-na", + 'width': "30px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Authors", + 'type': "natural", + 'width': "300px", + 'data': null, + 'render': function(data, type, row, meta) { + author_list = data.authors.split(",") + if (author_list.length >= 6) { + author_string = author_list.slice(0, 6).join(",") + ", et al." + } else{ + author_string = data.authors } - }, - { - 'title': "
Mean
", - 'type': "natural-minus-na", - 'width': "30px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Authors", - 'type': "natural", - 'width': "300px", - 'data': null, - 'render': function(data, type, row, meta) { - author_list = data.authors.split(",") - if (author_list.length >= 6) { - author_string = author_list.slice(0, 6).join(",") + ", et al." - } else{ - author_string = data.authors - } - return author_string + return author_string + } + }, + { + 'title': "
Year
", + 'type': "natural-minus-na", + 'data': null, + 'width': "25px", + 'render': function(data, type, row, meta) { + if (data.pubmed_id != "N/A"){ + return '' + data.pubmed_text + '' + } else { + return data.pubmed_text } }, - { - 'title': "
Year
", - 'type': "natural-minus-na", - 'data': null, - 'width': "25px", - 'render': function(data, type, row, meta) { - if (data.pubmed_id != "N/A"){ - return '' + data.pubmed_text + '' - } else { - return data.pubmed_text - } - }, - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak  
LOD  
", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak Location
", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "lrs_location" - }, - { - 'title': "
Effect  
Size  
", - 'type': "natural-minus-na", - 'width': "60px", - 'data': "additive", - 'orderSequence': [ "desc", "asc"] - }{% elif dataset.type == 'Geno' %}, - { - 'title': "
Location
", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "location" - }{% endif %} + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak  
LOD  
", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak Location
", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "lrs_location" + }, + { + 'title': "
Effect  
Size  
", + 'type': "natural-minus-na", + 'width': "60px", + 'data': "additive", + 'orderSequence': [ "desc", "asc"] + }{% elif dataset.type == 'Geno' %}, + { + 'title': "
Location
", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "location" + }{% endif %} ]; loadDataTable(); function loadDataTable(){ + + setUserColumnsDefWidths(); + //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters trait_table = $('#' + tableId).DataTable( { 'drawCallback': function( settings ) { @@ -391,7 +404,8 @@ "deferRender": true, "bSortClasses": false, {% if trait_list|length > 20 %} - "scrollY": "100vh", + "scrollY": "500px", + "scrollX": true, "scroller": true, "scrollCollapse": true, {% else %} @@ -411,6 +425,10 @@ } ); } + window.addEventListener('resize', function(){ + trait_table.columns.adjust(); + }); + function setUserColumnsDefWidths() { var userColumnDef; @@ -430,12 +448,12 @@ // If there is, set the width of this columnDef in px if ( userColumnDef ) { + columnDef.sWidth = userColumnDef.width + 'px'; columnDef.width = userColumnDef.width + 'px'; } }); - } @@ -473,11 +491,8 @@ // Save (or update) the settings in localStorage localStorage.setItem(tableId, JSON.stringify(userColumnDefs)); - } - //trait_table.draw(); //ZS: This makes the table adjust its height properly on initial load - $('.toggle-vis').on( 'click', function (e) { e.preventDefault(); -- cgit v1.2.3 From 8d727b8de708e48b298f42c673f8e902ac3df6a4 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 11 Mar 2021 22:57:49 +0000 Subject: Added a parameter to prevent columnDefs from being overwritten on initial table generation + changed the default table width to 100% --- wqflask/wqflask/templates/search_result_page.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 210cef30..973e9c23 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -125,8 +125,8 @@ {% endif %} {% endif %} -
-

Loading...
+
+
@@ -337,11 +337,13 @@ }{% endif %} ]; - loadDataTable(); + loadDataTable(true); - function loadDataTable(){ + function loadDataTable(first_run=false){ - setUserColumnsDefWidths(); + if (!first_run){ + setUserColumnsDefWidths(); + } //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters trait_table = $('#' + tableId).DataTable( { -- cgit v1.2.3 From 814258b95436c5aabd76d932fde8386fea187e84 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 11 Mar 2021 23:08:43 +0000 Subject: Set scrollX in all cases so the adjustablee columns also work for shorter results that don't use Scroller (<20 results) --- wqflask/wqflask/templates/search_result_page.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 973e9c23..b2820496 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -405,9 +405,9 @@ "autoWidth": false, "deferRender": true, "bSortClasses": false, + "scrollX": true, {% if trait_list|length > 20 %} "scrollY": "500px", - "scrollX": true, "scroller": true, "scrollCollapse": true, {% else %} -- cgit v1.2.3 From f421a7b319696bb57b9ea4c0a3ec94a32fa4aa65 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 24 Mar 2021 19:31:04 +0000 Subject: Use autoWidth on initial table load, though I'll change this to only apply when certain fields (like Description) are below a certain width Added some code tracking the change in width when a column's width is adjusted, so that the table_container width can be changed accordingly --- wqflask/wqflask/templates/search_result_page.html | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index b2820496..22a22e68 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -126,7 +126,7 @@ {% endif %}
-

Loading...
+
@@ -174,6 +174,8 @@ var tableId = "trait_table"; + var width_change = 0; //ZS: For storing the change in width so overall table width can be adjusted by that amount + columnDefs = [ { 'data': null, @@ -196,7 +198,6 @@ 'title': "Record", 'type': "natural-minus-na", 'data': null, - 'width': "60px", 'targets': 2, 'render': function(data, type, row, meta) { return '' + data.display_name + '' @@ -232,7 +233,7 @@ { 'title': "
Mean
", 'type': "natural-minus-na", - 'width': "30px", + 'width': "40px", 'data': "mean", 'targets': 6, 'orderSequence': [ "desc", "asc"] @@ -346,7 +347,7 @@ } //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters - trait_table = $('#' + tableId).DataTable( { + table_settings = { 'drawCallback': function( settings ) { $('#' + tableId + ' tr').off().on("click", function(event) { if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { @@ -402,7 +403,7 @@ "order": [[1, "asc" ]], "sDom": "iti", "destroy": true, - "autoWidth": false, + "autoWidth": true, "deferRender": true, "bSortClasses": false, "scrollX": true, @@ -418,13 +419,22 @@ $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ handles: "e", alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother + resize: function( event, ui ) { + width_change = ui.size.width - ui.originalSize.width; + }, stop: function () { saveColumnSettings(); loadDataTable(); } }); }, - } ); + } + + if (!first_run){ + table_settings['autoWidth'] = false; + $('#table_container').css("width", String($('#trait_table').width() + width_change) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly + } + trait_table = $('#' + tableId).DataTable(table_settings); } window.addEventListener('resize', function(){ @@ -488,7 +498,6 @@ }); } - }); // Save (or update) the settings in localStorage -- cgit v1.2.3 From ed911b95571948c8c34ff5f3286f322cc9cfbbcf Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 24 Mar 2021 22:12:14 +0000 Subject: Store a dictionary of maximum widths for each field + create a variable indicating if there are any wide columns (too wide to use DataTables' 'autoWidth' setting) --- wqflask/wqflask/search_results.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index f23c0582..c4d8d4ce 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -98,7 +98,6 @@ class SearchResultPage(object): species = webqtlDatabaseFunction.retrieve_species(self.dataset.group.name) # result_set represents the results for each search term; a search of # "shh grin2b" would have two sets of results, one for each term - logger.debug("self.results is:", pf(self.results)) for index, result in enumerate(self.results): if not result: @@ -164,6 +163,19 @@ class SearchResultPage(object): trait_dict[key] = trait_dict[key].decode('utf-8') trait_list.append(trait_dict) + self.max_widths = {} + for i, trait in enumerate(trait_list): + for key in trait.keys(): + self.max_widths[key] = max(len(str(trait[key])), self.max_widths[key]) if key in self.max_widths else len(str(trait[key])) + + self.wide_columns_exist = False + if this_trait.dataset.type == "Publish": + if (self.max_widths['display_name'] > 25 or self.max_widths['description'] > 100 or self.max_widths['authors']> 80): + self.wide_columns_exist = True + if this_trait.dataset.type == "ProbeSet": + if (self.max_widths['display_name'] > 25 or self.max_widths['symbol'] > 25 or self.max_widths['description'] > 100): + self.wide_columns_exist = True + self.trait_list = trait_list if self.dataset.type == "ProbeSet": -- cgit v1.2.3 From 52dcfe71be8cd86bfc19fa310fa3d65920d6f2af Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 24 Mar 2021 22:12:57 +0000 Subject: Added some default widths for situations where some wide columns exist and autoWidth can't be used on initial load + changed the logic for how to recalculate table width when a column is manually resized --- wqflask/wqflask/templates/search_result_page.html | 55 +++++++++++++++++------ 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 22a22e68..8ecddc53 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -125,7 +125,7 @@ {% endif %} {% endif %} -
+

Loading...
@@ -190,23 +190,29 @@ { 'title': "Index", 'type': "natural", - 'width': "30px", + 'width': "35px", 'targets': 1, 'data': "index" - }, + } + {% if dataset.type == 'ProbeSet' %}, { 'title': "Record", 'type': "natural-minus-na", 'data': null, + {% if wide_columns_exist == true %} + 'width': "{{ max_widths.display_name * 5 }}px", + {% endif %} 'targets': 2, 'render': function(data, type, row, meta) { return '' + data.display_name + '' } - }{% if dataset.type == 'ProbeSet' %}, + }, { 'title': "Symbol", 'type': "natural", - 'width': "120px", + {% if wide_columns_exist == true %} + 'width': "200px", + {% endif %} 'targets': 3, 'data': "symbol" }, @@ -214,6 +220,9 @@ 'title': "Description", 'type': "natural", 'data': null, + {% if wide_columns_exist == true %} + 'width': "600px", + {% endif %} 'targets': 4, 'render': function(data, type, row, meta) { try { @@ -261,10 +270,21 @@ 'targets': 9, 'orderSequence': [ "desc", "asc"] }{% elif dataset.type == 'Publish' %}, + { + 'title': "Record", + 'type': "natural-minus-na", + 'data': null, + {% if wide_columns_exist == true %} + 'width': "100px", + {% endif %} + 'targets': 2, + 'render': function(data, type, row, meta) { + return '' + data.display_name + '' + } + }, { 'title': "Description", 'type': "natural", - 'width': "500px", 'data': null, 'render': function(data, type, row, meta) { try { @@ -277,14 +297,16 @@ { 'title': "
Mean
", 'type': "natural-minus-na", - 'width': "30px", + 'width': "60px", 'data': "mean", 'orderSequence': [ "desc", "asc"] }, { 'title': "Authors", 'type': "natural", - 'width': "300px", + {% if wide_columns_exist == true %} + 'width': "400px", + {% endif %} 'data': null, 'render': function(data, type, row, meta) { author_list = data.authors.split(",") @@ -300,7 +322,7 @@ 'title': "
Year
", 'type': "natural-minus-na", 'data': null, - 'width': "25px", + 'width': "50px", 'render': function(data, type, row, meta) { if (data.pubmed_id != "N/A"){ return '' + data.pubmed_text + '' @@ -403,7 +425,11 @@ "order": [[1, "asc" ]], "sDom": "iti", "destroy": true, + {% if wide_columns_exist != true %} "autoWidth": true, + {% else %} + "autoWidth": false, + {% endif %} "deferRender": true, "bSortClasses": false, "scrollX": true, @@ -432,9 +458,15 @@ if (!first_run){ table_settings['autoWidth'] = false; - $('#table_container').css("width", String($('#trait_table').width() + width_change) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly + $('#table_container').css("width", String($('#trait_table').width() + width_change {% if trait_list|length > 20 %}+ 17{% endif %}) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly } trait_table = $('#' + tableId).DataTable(table_settings); + + {% if trait_list|length > 20 %} + if (first_run){ + $('#table_container').css("width", String($('#trait_table').width() + 17) + "px"); + } + {% endif %} } window.addEventListener('resize', function(){ @@ -442,7 +474,6 @@ }); function setUserColumnsDefWidths() { - var userColumnDef; // Get the settings for this table from localStorage @@ -468,9 +499,7 @@ }); } - function saveColumnSettings() { - var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; var width, header, existingSetting; -- cgit v1.2.3 From 498a7760fa70788827a28b90ea6f2fd0d94931a5 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Jun 2021 19:28:47 +0000 Subject: Resolving conflict in search_result_page.html --- wqflask/wqflask/templates/search_result_page.html | 519 +++++++++++++--------- 1 file changed, 303 insertions(+), 216 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 7ec335d5..13f3c7c1 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -7,6 +7,7 @@ + {% endblock %} {% block content %} @@ -171,225 +172,311 @@ return params; }; - //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters - trait_table = $('#trait_table').DataTable( { - 'drawCallback': function( settings ) { - $('#trait_table tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } - change_buttons() - }); - }, - 'createdRow': function ( row, data, index ) { - $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 13px;"); - $('td', row).eq(1).attr("align", "right"); - $('td', row).eq(1).attr('data-export', index+1); - $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); - {% if dataset.type == 'ProbeSet' %} - $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - if ($('td', row).eq(3).text().length > 20) { - $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20)); - $('td', row).eq(3).text($('td', row).eq(3).text() + '...') - } - $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); - $('td', row).slice(5,10).attr("align", "right"); - $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); - $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); - $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); - $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); - $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); - {% elif dataset.type == 'Publish' %} - $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('align', 'right'); - $('td', row).slice(6,10).attr("align", "right"); - $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); - $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); - $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); - $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); - $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text()); - {% elif dataset.type == 'Geno' %} - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - {% endif %} + var tableId = "trait_table"; + + columnDefs = [ + { + 'data': null, + 'width': "25px", + 'orderDataType': "dom-checkbox", + 'orderable': false, + 'render': function(data, type, row, meta) { + return '' + } + }, + { + 'title': "Index", + 'type': "natural", + 'width': "30px", + 'data': "index" + }, + { + 'title': "Record", + 'type': "natural-minus-na", + 'data': null, + 'width': "60px", + 'render': function(data, type, row, meta) { + return '' + data.display_name + '' + } + }{% if dataset.type == 'ProbeSet' %}, + { + 'title': "Symbol", + 'type': "natural", + 'width': "120px", + 'data': "symbol" + }, + { + 'title': "Description", + 'type': "natural", + 'data': null, + 'render': function(data, type, row, meta) { + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return escape(data.description) + } + } + }, + { + 'title': "
Location
", + 'type': "natural-minus-na", + 'width': "125px", + 'data': "location" + }, + { + 'title': "
Mean
", + 'type': "natural-minus-na", + 'width': "30px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak  
LOD  
", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak Location
", + 'type': "natural-minus-na", + 'width': "125px", + 'data': "lrs_location" + }, + { + 'title': "
Effect  
Size  
", + 'type': "natural-minus-na", + 'data': "additive", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }{% elif dataset.type == 'Publish' %}, + { + 'title': "Description", + 'type': "natural", + 'width': "500px", + 'data': null, + 'render': function(data, type, row, meta) { + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return data.description + } + } + }, + { + 'title': "
Mean
", + 'type': "natural-minus-na", + 'width': "30px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Authors", + 'type': "natural", + 'width': "300px", + 'data': null, + 'render': function(data, type, row, meta) { + author_list = data.authors.split(",") + if (author_list.length >= 6) { + author_string = author_list.slice(0, 6).join(",") + ", et al." + } else{ + author_string = data.authors + } + return author_string + } + }, + { + 'title': "
Year
", + 'type': "natural-minus-na", + 'data': null, + 'width': "25px", + 'render': function(data, type, row, meta) { + if (data.pubmed_id != "N/A"){ + return '' + data.pubmed_text + '' + } else { + return data.pubmed_text + } }, - 'data': trait_list, - 'columns': [ - { - 'data': null, - 'width': "10px", - 'orderDataType': "dom-checkbox", - 'orderable': false, - 'render': function(data, type, row, meta) { - return '' - } - }, - { - 'title': "Index", - 'type': "natural", - 'width': "30px", - 'data': "index" - }, - { - 'title': "Record", - 'type': "natural-minus-na", - 'data': null, - 'width': "60px", - 'render': function(data, type, row, meta) { - return '' + data.display_name + '' - } - }{% if dataset.type == 'ProbeSet' %}, - { - 'title': "Symbol", - 'type': "natural", - 'width': "120px", - 'data': "symbol" - }, - { - 'title': "Description", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.description)) - } catch(err){ - return escape(data.description) - } - } - }, - { - 'title': "
Location
", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "location" - }, - { - 'title': "
Mean
", - 'type': "natural-minus-na", - 'width': "30px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak  
LOD  
", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak Location
", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "lrs_location" - }, - { - 'title': "
Effect  
Size  
", - 'type': "natural-minus-na", - 'data': "additive", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }{% elif dataset.type == 'Publish' %}, - { - 'title': "Description", - 'type': "natural", - 'width': "500px", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.description)) - } catch(err){ - return data.description - } + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak  
LOD  
", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak Location
", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "lrs_location" + }, + { + 'title': "
Effect  
Size  
", + 'type': "natural-minus-na", + 'width': "60px", + 'data': "additive", + 'orderSequence': [ "desc", "asc"] + }{% elif dataset.type == 'Geno' %}, + { + 'title': "
Location
", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "location" + }{% endif %} + ]; + + loadDataTable(); + + function loadDataTable(){ + //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters + trait_table = $('#' + tableId).DataTable( { + 'drawCallback': function( settings ) { + $('#' + tableId + ' tr').off().on("click", function(event) { + if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { + var obj =$(this).find('input'); + obj.prop('checked', !obj.is(':checked')); + } + if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ + $(this).removeClass("selected") + } else if (event.target.tagName.toLowerCase() !== 'a') { + $(this).addClass("selected") + } + change_buttons() + }); + }, + 'createdRow': function ( row, data, index ) { + $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); + $('td', row).eq(1).attr("align", "right"); + $('td', row).eq(1).attr('data-export', index+1); + $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); + {% if dataset.type == 'ProbeSet' %} + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + if ($('td', row).eq(3).text().length > 20) { + $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20)); + $('td', row).eq(3).text($('td', row).eq(3).text() + '...') } - }, - { - 'title': "
Mean
", - 'type': "natural-minus-na", - 'width': "30px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Authors", - 'type': "natural", - 'width': "300px", - 'data': null, - 'render': function(data, type, row, meta) { - author_list = data.authors.split(",") - if (author_list.length >= 6) { - author_string = author_list.slice(0, 6).join(",") + ", et al." - } else{ - author_string = data.authors - } - return author_string + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + $('td', row).slice(5,10).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); + {% elif dataset.type == 'Publish' %} + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('align', 'right'); + $('td', row).slice(6,10).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text()); + {% elif dataset.type == 'Geno' %} + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + {% endif %} + }, + "data": trait_list, + "columns": columnDefs, + "order": [[1, "asc" ]], + "sDom": "iti", + "destroy": true, + "autoWidth": false, + "deferRender": true, + "bSortClasses": false, + {% if trait_list|length > 20 %} + "scrollY": "100vh", + "scroller": true, + "scrollCollapse": true, + {% else %} + "iDisplayLength": -1, + {% endif %} + "initComplete": function (settings) { + //Add JQueryUI resizable functionality to each th in the ScrollHead table + $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ + handles: "e", + alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother + stop: function () { + saveColumnSettings(); + loadDataTable(); } - }, - { - 'title': "
Year
", - 'type': "natural-minus-na", - 'data': null, - 'width': "25px", - 'render': function(data, type, row, meta) { - if (data.pubmed_id != "N/A"){ - return '' + data.pubmed_text + '' - } else { - return data.pubmed_text - } - }, - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak  
LOD  
", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak Location
", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "lrs_location" - }, - { - 'title': "
Effect  
Size  
", - 'type': "natural-minus-na", - 'width': "60px", - 'data': "additive", - 'orderSequence': [ "desc", "asc"] - }{% elif dataset.type == 'Geno' %}, - { - 'title': "
Location
", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "location" - }{% endif %} - ], - "order": [[1, "asc" ]], - 'sDom': "iti", - "autoWidth": true, - "bSortClasses": false, - {% if trait_list|length > 20 %} - "scrollY": "100vh", - "scroller": true, - "scrollCollapse": true - {% else %} - "iDisplayLength": -1 - {% endif %} - } ); + }); + }, + } ); + } + + function setUserColumnsDefWidths() { + + var userColumnDef; + + // Get the settings for this table from localStorage + var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; + + if (userColumnDefs.length === 0 ) return; + + columnDefs.forEach( function(columnDef) { + + // Check if there is a width specified for this column + userColumnDef = userColumnDefs.find( function(column) { + return column.targets === columnDef.targets; + }); + + // If there is, set the width of this columnDef in px + if ( userColumnDef ) { + + columnDef.width = userColumnDef.width + 'px'; + + } + + }); + + } + + + function saveColumnSettings() { + + var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; + + var width, header, existingSetting; + + trait_table.columns().every( function ( targets ) { + + // Check if there is a setting for this column in localStorage + existingSetting = userColumnDefs.findIndex( function(column) { return column.targets === targets;}); + + // Get the width of this column + header = this.header(); + width = $(header).width(); + + if ( existingSetting !== -1 ) { + + // Update the width + userColumnDefs[existingSetting].width = width; + + } else { + + // Add the width for this column + userColumnDefs.push({ + targets: targets, + width: width, + }); + + } + + }); + + // Save (or update) the settings in localStorage + localStorage.setItem(tableId, JSON.stringify(userColumnDefs)); + + } - trait_table.draw(); //ZS: This makes the table adjust its height properly on initial load + //trait_table.draw(); //ZS: This makes the table adjust its height properly on initial load $('.toggle-vis').on( 'click', function (e) { e.preventDefault(); @@ -409,7 +496,7 @@ $('#redraw').click(function() { - var table = $('#trait_table').DataTable(); + var table = $('#' + tableId).DataTable(); table.colReorder.reset() }); -- cgit v1.2.3 From c81255153ac44462ee378908af12646a2697933c Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 11 Mar 2021 22:35:11 +0000 Subject: Added some CSS to make cell content cut off with ellipses if a column is narrower than the content's width --- wqflask/wqflask/static/new/css/trait_list.css | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/wqflask/wqflask/static/new/css/trait_list.css b/wqflask/wqflask/static/new/css/trait_list.css index c7249721..6d49f009 100644 --- a/wqflask/wqflask/static/new/css/trait_list.css +++ b/wqflask/wqflask/static/new/css/trait_list.css @@ -52,3 +52,21 @@ div.dts div.dataTables_paginate,div.dts div.dataTables_length{ display:none } +/* This is the important CSS */ +table.dataTable { + table-layout: fixed; + width: 100%; + white-space: nowrap; + overflow: hidden; +} + +table.dataTable th { + white-space: nowrap; + overflow: hidden; +} + +table.dataTable td { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} \ No newline at end of file -- cgit v1.2.3 From a3d4cdd47ec843612c4e33a5c45db9e152bb81c6 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 11 Mar 2021 22:43:35 +0000 Subject: Made a variety of changes to make column resizeability work - the main issue was related to there being both an sWidth and width parameter --- wqflask/wqflask/templates/search_result_page.html | 317 +++++++++++----------- 1 file changed, 166 insertions(+), 151 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 13f3c7c1..2cf1856b 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -125,8 +125,8 @@ {% endif %} {% endif %} -
-

Loading...
+
+
@@ -175,161 +175,174 @@ var tableId = "trait_table"; columnDefs = [ - { - 'data': null, - 'width': "25px", - 'orderDataType': "dom-checkbox", - 'orderable': false, - 'render': function(data, type, row, meta) { - return '' - } - }, - { - 'title': "Index", - 'type': "natural", - 'width': "30px", - 'data': "index" - }, - { - 'title': "Record", - 'type': "natural-minus-na", - 'data': null, - 'width': "60px", - 'render': function(data, type, row, meta) { - return '' + data.display_name + '' + { + 'data': null, + 'width': "25px", + 'orderDataType': "dom-checkbox", + 'orderable': false, + 'targets': 0, + 'render': function(data, type, row, meta) { + return '' + } + }, + { + 'title': "Index", + 'type': "natural", + 'width': "30px", + 'targets': 1, + 'data': "index" + }, + { + 'title': "Record", + 'type': "natural-minus-na", + 'data': null, + 'width': "60px", + 'targets': 2, + 'render': function(data, type, row, meta) { + return '' + data.display_name + '' + } + }{% if dataset.type == 'ProbeSet' %}, + { + 'title': "Symbol", + 'type': "natural", + 'width': "120px", + 'targets': 3, + 'data': "symbol" + }, + { + 'title': "Description", + 'type': "natural", + 'data': null, + 'targets': 4, + 'render': function(data, type, row, meta) { + try { + return decodeURIComponent(escape(data.description)) + } catch(err){ + return escape(data.description) } - }{% if dataset.type == 'ProbeSet' %}, - { - 'title': "Symbol", - 'type': "natural", - 'width': "120px", - 'data': "symbol" - }, - { - 'title': "Description", - 'type': "natural", - 'data': null, - 'render': function(data, type, row, meta) { - try { + } + }, + { + 'title': "
Location
", + 'type': "natural-minus-na", + 'width': "125px", + 'targets': 5, + 'data': "location" + }, + { + 'title': "
Mean
", + 'type': "natural-minus-na", + 'width': "30px", + 'data': "mean", + 'targets': 6, + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak  
LOD  
", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'targets': 7, + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak Location
", + 'type': "natural-minus-na", + 'width': "125px", + 'targets': 8, + 'data': "lrs_location" + }, + { + 'title': "
Effect  
Size  
", + 'type': "natural-minus-na", + 'data': "additive", + 'width': "60px", + 'targets': 9, + 'orderSequence': [ "desc", "asc"] + }{% elif dataset.type == 'Publish' %}, + { + 'title': "Description", + 'type': "natural", + 'width': "500px", + 'data': null, + 'render': function(data, type, row, meta) { + try { return decodeURIComponent(escape(data.description)) - } catch(err){ - return escape(data.description) - } + } catch(err){ + return data.description } - }, - { - 'title': "
Location
", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "location" - }, - { - 'title': "
Mean
", - 'type': "natural-minus-na", - 'width': "30px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak  
LOD  
", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak Location
", - 'type': "natural-minus-na", - 'width': "125px", - 'data': "lrs_location" - }, - { - 'title': "
Effect  
Size  
", - 'type': "natural-minus-na", - 'data': "additive", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }{% elif dataset.type == 'Publish' %}, - { - 'title': "Description", - 'type': "natural", - 'width': "500px", - 'data': null, - 'render': function(data, type, row, meta) { - try { - return decodeURIComponent(escape(data.description)) - } catch(err){ - return data.description - } + } + }, + { + 'title': "
Mean
", + 'type': "natural-minus-na", + 'width': "30px", + 'data': "mean", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "Authors", + 'type': "natural", + 'width': "300px", + 'data': null, + 'render': function(data, type, row, meta) { + author_list = data.authors.split(",") + if (author_list.length >= 6) { + author_string = author_list.slice(0, 6).join(",") + ", et al." + } else{ + author_string = data.authors } - }, - { - 'title': "
Mean
", - 'type': "natural-minus-na", - 'width': "30px", - 'data': "mean", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "Authors", - 'type': "natural", - 'width': "300px", - 'data': null, - 'render': function(data, type, row, meta) { - author_list = data.authors.split(",") - if (author_list.length >= 6) { - author_string = author_list.slice(0, 6).join(",") + ", et al." - } else{ - author_string = data.authors - } - return author_string + return author_string + } + }, + { + 'title': "
Year
", + 'type': "natural-minus-na", + 'data': null, + 'width': "25px", + 'render': function(data, type, row, meta) { + if (data.pubmed_id != "N/A"){ + return '' + data.pubmed_text + '' + } else { + return data.pubmed_text } }, - { - 'title': "
Year
", - 'type': "natural-minus-na", - 'data': null, - 'width': "25px", - 'render': function(data, type, row, meta) { - if (data.pubmed_id != "N/A"){ - return '' + data.pubmed_text + '' - } else { - return data.pubmed_text - } - }, - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak  
LOD  
", - 'type': "natural-minus-na", - 'data': "lod_score", - 'width': "60px", - 'orderSequence': [ "desc", "asc"] - }, - { - 'title': "
Peak Location
", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "lrs_location" - }, - { - 'title': "
Effect  
Size  
", - 'type': "natural-minus-na", - 'width': "60px", - 'data': "additive", - 'orderSequence': [ "desc", "asc"] - }{% elif dataset.type == 'Geno' %}, - { - 'title': "
Location
", - 'type': "natural-minus-na", - 'width': "120px", - 'data': "location" - }{% endif %} + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak  
LOD  
", + 'type': "natural-minus-na", + 'data': "lod_score", + 'width': "60px", + 'orderSequence': [ "desc", "asc"] + }, + { + 'title': "
Peak Location
", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "lrs_location" + }, + { + 'title': "
Effect  
Size  
", + 'type': "natural-minus-na", + 'width': "60px", + 'data': "additive", + 'orderSequence': [ "desc", "asc"] + }{% elif dataset.type == 'Geno' %}, + { + 'title': "
Location
", + 'type': "natural-minus-na", + 'width': "120px", + 'data': "location" + }{% endif %} ]; loadDataTable(); function loadDataTable(){ + + setUserColumnsDefWidths(); + //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters trait_table = $('#' + tableId).DataTable( { 'drawCallback': function( settings ) { @@ -391,7 +404,8 @@ "deferRender": true, "bSortClasses": false, {% if trait_list|length > 20 %} - "scrollY": "100vh", + "scrollY": "500px", + "scrollX": true, "scroller": true, "scrollCollapse": true, {% else %} @@ -411,6 +425,10 @@ } ); } + window.addEventListener('resize', function(){ + trait_table.columns.adjust(); + }); + function setUserColumnsDefWidths() { var userColumnDef; @@ -430,12 +448,12 @@ // If there is, set the width of this columnDef in px if ( userColumnDef ) { + columnDef.sWidth = userColumnDef.width + 'px'; columnDef.width = userColumnDef.width + 'px'; } }); - } @@ -473,11 +491,8 @@ // Save (or update) the settings in localStorage localStorage.setItem(tableId, JSON.stringify(userColumnDefs)); - } - //trait_table.draw(); //ZS: This makes the table adjust its height properly on initial load - $('.toggle-vis').on( 'click', function (e) { e.preventDefault(); -- cgit v1.2.3 From 8d0513d9c667f076bca1c54037bab740b04c1bbd Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 11 Mar 2021 22:57:49 +0000 Subject: Added a parameter to prevent columnDefs from being overwritten on initial table generation + changed the default table width to 100% --- wqflask/wqflask/templates/search_result_page.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 2cf1856b..6321c687 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -125,8 +125,8 @@ {% endif %} {% endif %} -
-

Loading...
+
+
@@ -337,11 +337,13 @@ }{% endif %} ]; - loadDataTable(); + loadDataTable(true); - function loadDataTable(){ + function loadDataTable(first_run=false){ - setUserColumnsDefWidths(); + if (!first_run){ + setUserColumnsDefWidths(); + } //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters trait_table = $('#' + tableId).DataTable( { -- cgit v1.2.3 From aa3625be807a661e44c7f0c62a539eec27ccca46 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 11 Mar 2021 23:08:43 +0000 Subject: Set scrollX in all cases so the adjustablee columns also work for shorter results that don't use Scroller (<20 results) --- wqflask/wqflask/templates/search_result_page.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 6321c687..06322a86 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -405,9 +405,9 @@ "autoWidth": false, "deferRender": true, "bSortClasses": false, + "scrollX": true, {% if trait_list|length > 20 %} "scrollY": "500px", - "scrollX": true, "scroller": true, "scrollCollapse": true, {% else %} -- cgit v1.2.3 From 682a7eeecc9f80836d11780feeabc3afab57b3e7 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 24 Mar 2021 19:31:04 +0000 Subject: Use autoWidth on initial table load, though I'll change this to only apply when certain fields (like Description) are below a certain width Added some code tracking the change in width when a column's width is adjusted, so that the table_container width can be changed accordingly --- wqflask/wqflask/templates/search_result_page.html | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 06322a86..601fd63a 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -126,7 +126,7 @@ {% endif %}
-

Loading...
+
@@ -174,6 +174,8 @@ var tableId = "trait_table"; + var width_change = 0; //ZS: For storing the change in width so overall table width can be adjusted by that amount + columnDefs = [ { 'data': null, @@ -196,7 +198,6 @@ 'title': "Record", 'type': "natural-minus-na", 'data': null, - 'width': "60px", 'targets': 2, 'render': function(data, type, row, meta) { return '' + data.display_name + '' @@ -232,7 +233,7 @@ { 'title': "
Mean
", 'type': "natural-minus-na", - 'width': "30px", + 'width': "40px", 'data': "mean", 'targets': 6, 'orderSequence': [ "desc", "asc"] @@ -346,7 +347,7 @@ } //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters - trait_table = $('#' + tableId).DataTable( { + table_settings = { 'drawCallback': function( settings ) { $('#' + tableId + ' tr').off().on("click", function(event) { if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { @@ -402,7 +403,7 @@ "order": [[1, "asc" ]], "sDom": "iti", "destroy": true, - "autoWidth": false, + "autoWidth": true, "deferRender": true, "bSortClasses": false, "scrollX": true, @@ -418,13 +419,22 @@ $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ handles: "e", alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother + resize: function( event, ui ) { + width_change = ui.size.width - ui.originalSize.width; + }, stop: function () { saveColumnSettings(); loadDataTable(); } }); }, - } ); + } + + if (!first_run){ + table_settings['autoWidth'] = false; + $('#table_container').css("width", String($('#trait_table').width() + width_change) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly + } + trait_table = $('#' + tableId).DataTable(table_settings); } window.addEventListener('resize', function(){ @@ -488,7 +498,6 @@ }); } - }); // Save (or update) the settings in localStorage -- cgit v1.2.3 From 56e3de19c28372ff618ef3aba483c4f717fafd91 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 24 Mar 2021 22:12:14 +0000 Subject: Store a dictionary of maximum widths for each field + create a variable indicating if there are any wide columns (too wide to use DataTables' 'autoWidth' setting) --- wqflask/wqflask/search_results.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 3cbda3dd..3095708d 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -101,7 +101,6 @@ class SearchResultPage: self.dataset.group.name) # result_set represents the results for each search term; a search of # "shh grin2b" would have two sets of results, one for each term - logger.debug("self.results is:", pf(self.results)) for index, result in enumerate(self.results): if not result: @@ -169,6 +168,19 @@ class SearchResultPage: trait_dict[key] = trait_dict[key].decode('utf-8') trait_list.append(trait_dict) + self.max_widths = {} + for i, trait in enumerate(trait_list): + for key in trait.keys(): + self.max_widths[key] = max(len(str(trait[key])), self.max_widths[key]) if key in self.max_widths else len(str(trait[key])) + + self.wide_columns_exist = False + if this_trait.dataset.type == "Publish": + if (self.max_widths['display_name'] > 25 or self.max_widths['description'] > 100 or self.max_widths['authors']> 80): + self.wide_columns_exist = True + if this_trait.dataset.type == "ProbeSet": + if (self.max_widths['display_name'] > 25 or self.max_widths['symbol'] > 25 or self.max_widths['description'] > 100): + self.wide_columns_exist = True + self.trait_list = trait_list if self.dataset.type == "ProbeSet": -- cgit v1.2.3 From c73f55287b986844d4c894e80a3cb76c1f05d8f8 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 24 Mar 2021 22:12:57 +0000 Subject: Added some default widths for situations where some wide columns exist and autoWidth can't be used on initial load + changed the logic for how to recalculate table width when a column is manually resized --- wqflask/wqflask/templates/search_result_page.html | 55 +++++++++++++++++------ 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 601fd63a..1826c694 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -125,7 +125,7 @@ {% endif %} {% endif %} -
+

Loading...
@@ -190,23 +190,29 @@ { 'title': "Index", 'type': "natural", - 'width': "30px", + 'width': "35px", 'targets': 1, 'data': "index" - }, + } + {% if dataset.type == 'ProbeSet' %}, { 'title': "Record", 'type': "natural-minus-na", 'data': null, + {% if wide_columns_exist == true %} + 'width': "{{ max_widths.display_name * 5 }}px", + {% endif %} 'targets': 2, 'render': function(data, type, row, meta) { return '' + data.display_name + '' } - }{% if dataset.type == 'ProbeSet' %}, + }, { 'title': "Symbol", 'type': "natural", - 'width': "120px", + {% if wide_columns_exist == true %} + 'width': "200px", + {% endif %} 'targets': 3, 'data': "symbol" }, @@ -214,6 +220,9 @@ 'title': "Description", 'type': "natural", 'data': null, + {% if wide_columns_exist == true %} + 'width': "600px", + {% endif %} 'targets': 4, 'render': function(data, type, row, meta) { try { @@ -261,10 +270,21 @@ 'targets': 9, 'orderSequence': [ "desc", "asc"] }{% elif dataset.type == 'Publish' %}, + { + 'title': "Record", + 'type': "natural-minus-na", + 'data': null, + {% if wide_columns_exist == true %} + 'width': "100px", + {% endif %} + 'targets': 2, + 'render': function(data, type, row, meta) { + return '' + data.display_name + '' + } + }, { 'title': "Description", 'type': "natural", - 'width': "500px", 'data': null, 'render': function(data, type, row, meta) { try { @@ -277,14 +297,16 @@ { 'title': "
Mean
", 'type': "natural-minus-na", - 'width': "30px", + 'width': "60px", 'data': "mean", 'orderSequence': [ "desc", "asc"] }, { 'title': "Authors", 'type': "natural", - 'width': "300px", + {% if wide_columns_exist == true %} + 'width': "400px", + {% endif %} 'data': null, 'render': function(data, type, row, meta) { author_list = data.authors.split(",") @@ -300,7 +322,7 @@ 'title': "
Year
", 'type': "natural-minus-na", 'data': null, - 'width': "25px", + 'width': "50px", 'render': function(data, type, row, meta) { if (data.pubmed_id != "N/A"){ return '' + data.pubmed_text + '' @@ -403,7 +425,11 @@ "order": [[1, "asc" ]], "sDom": "iti", "destroy": true, + {% if wide_columns_exist != true %} "autoWidth": true, + {% else %} + "autoWidth": false, + {% endif %} "deferRender": true, "bSortClasses": false, "scrollX": true, @@ -432,9 +458,15 @@ if (!first_run){ table_settings['autoWidth'] = false; - $('#table_container').css("width", String($('#trait_table').width() + width_change) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly + $('#table_container').css("width", String($('#trait_table').width() + width_change {% if trait_list|length > 20 %}+ 17{% endif %}) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly } trait_table = $('#' + tableId).DataTable(table_settings); + + {% if trait_list|length > 20 %} + if (first_run){ + $('#table_container').css("width", String($('#trait_table').width() + 17) + "px"); + } + {% endif %} } window.addEventListener('resize', function(){ @@ -442,7 +474,6 @@ }); function setUserColumnsDefWidths() { - var userColumnDef; // Get the settings for this table from localStorage @@ -468,9 +499,7 @@ }); } - function saveColumnSettings() { - var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; var width, header, existingSetting; -- cgit v1.2.3 From 62667ad7bd1a9a9fb555a87c873d7a54ab7f03f9 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 26 Mar 2021 19:39:15 +0000 Subject: Added checks in template for whether to explicitly set column width when wide column contents exist --- wqflask/wqflask/templates/search_result_page.html | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 1826c694..c165ad3c 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -179,7 +179,9 @@ columnDefs = [ { 'data': null, + {% if wide_columns_exist == true %} 'width': "25px", + {% endif %} 'orderDataType': "dom-checkbox", 'orderable': false, 'targets': 0, @@ -190,7 +192,9 @@ { 'title': "Index", 'type': "natural", + {% if wide_columns_exist == true %} 'width': "35px", + {% endif %} 'targets': 1, 'data': "index" } @@ -235,14 +239,18 @@ { 'title': "
Location
", 'type': "natural-minus-na", + {% if wide_columns_exist == true %} 'width': "125px", + {% endif %} 'targets': 5, 'data': "location" }, { 'title': "
Mean
", 'type': "natural-minus-na", + {% if wide_columns_exist == true %} 'width': "40px", + {% endif %} 'data': "mean", 'targets': 6, 'orderSequence': [ "desc", "asc"] @@ -251,14 +259,17 @@ 'title': "
Peak  
LOD  
", 'type': "natural-minus-na", 'data': "lod_score", - 'width': "60px", + {% if wide_columns_exist == true %} + 'width': "60px", {% endif %} 'targets': 7, 'orderSequence': [ "desc", "asc"] }, { 'title': "
Peak Location
", 'type': "natural-minus-na", + {% if wide_columns_exist == true %} 'width': "125px", + {% endif %} 'targets': 8, 'data': "lrs_location" }, @@ -266,7 +277,9 @@ 'title': "
Effect  
Size  
", 'type': "natural-minus-na", 'data': "additive", + {% if wide_columns_exist == true %} 'width': "60px", + {% endif %} 'targets': 9, 'orderSequence': [ "desc", "asc"] }{% elif dataset.type == 'Publish' %}, -- cgit v1.2.3 From d1beaa5ac7a3eea343d8447d771f7661173fabac Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 19 Apr 2021 21:15:14 +0000 Subject: Fixed resizeable columns to work with show/hide columns option + keep rows checked after resizing --- wqflask/wqflask/templates/search_result_page.html | 79 ++++++++++++++++++++--- 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index c165ad3c..eac3ec61 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -224,9 +224,6 @@ 'title': "Description", 'type': "natural", 'data': null, - {% if wide_columns_exist == true %} - 'width': "600px", - {% endif %} 'targets': 4, 'render': function(data, type, row, meta) { try { @@ -260,7 +257,8 @@ 'type': "natural-minus-na", 'data': "lod_score", {% if wide_columns_exist == true %} - 'width': "60px", {% endif %} + 'width': "60px", + {% endif %} 'targets': 7, 'orderSequence': [ "desc", "asc"] }, @@ -299,6 +297,7 @@ 'title': "Description", 'type': "natural", 'data': null, + 'targets': 3, 'render': function(data, type, row, meta) { try { return decodeURIComponent(escape(data.description)) @@ -310,8 +309,11 @@ { 'title': "
Mean
", 'type': "natural-minus-na", + {% if wide_columns_exist == true %} 'width': "60px", + {% endif %} 'data': "mean", + 'targets': 4, 'orderSequence': [ "desc", "asc"] }, { @@ -321,6 +323,7 @@ 'width': "400px", {% endif %} 'data': null, + 'targets': 5, 'render': function(data, type, row, meta) { author_list = data.authors.split(",") if (author_list.length >= 6) { @@ -335,7 +338,10 @@ 'title': "
Year
", 'type': "natural-minus-na", 'data': null, + {% if wide_columns_exist == true %} 'width': "50px", + {% endif %} + 'targets': 6, 'render': function(data, type, row, meta) { if (data.pubmed_id != "N/A"){ return '' + data.pubmed_text + '' @@ -349,30 +355,70 @@ 'title': "
Peak  
LOD  
", 'type': "natural-minus-na", 'data': "lod_score", + 'targets': 7, + {% if wide_columns_exist == true %} 'width': "60px", + {% endif %} 'orderSequence': [ "desc", "asc"] }, { 'title': "
Peak Location
", 'type': "natural-minus-na", + {% if wide_columns_exist == true %} 'width': "120px", + {% endif %} + 'targets': 8, 'data': "lrs_location" }, { 'title': "
Effect  
Size  
", 'type': "natural-minus-na", + {% if wide_columns_exist == true %} 'width': "60px", + {% endif %} 'data': "additive", + 'targets': 9, 'orderSequence': [ "desc", "asc"] }{% elif dataset.type == 'Geno' %}, { 'title': "
Location
", 'type': "natural-minus-na", + {% if wide_columns_exist == true %} 'width': "120px", + {% endif %} + 'targets': 2, 'data': "location" }{% endif %} ]; + recheck_rows = function(checked_rows){ + //ZS: This is meant to recheck checkboxes after columns are resized + check_cells = trait_table.column(0).nodes().to$(); + for (let i = 0; i < check_cells.length; i++) { + if (checked_rows.includes(i)){ + check_cells[i].childNodes[0].checked = true; + } + } + + check_rows = trait_table.rows().nodes(); + for (let i =0; i < check_rows.length; i++) { + if (checked_rows.includes(i)){ + check_rows[i].classList.add("selected") + } + } + } + + get_checked_rows = function(trait_table){ + let checked_rows = [] + $("#trait_table input").each(function(index){ + if ($(this).prop("checked") == true){ + checked_rows.push(index); + } + }); + + return checked_rows + } + loadDataTable(true); function loadDataTable(first_run=false){ @@ -473,13 +519,22 @@ table_settings['autoWidth'] = false; $('#table_container').css("width", String($('#trait_table').width() + width_change {% if trait_list|length > 20 %}+ 17{% endif %}) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly } + + let checked_rows = get_checked_rows(); trait_table = $('#' + tableId).DataTable(table_settings); + if (checked_rows.length > 0){ + recheck_rows(checked_rows); + } - {% if trait_list|length > 20 %} if (first_run){ + {% if trait_list|length > 20 %} $('#table_container').css("width", String($('#trait_table').width() + 17) + "px"); + {% else %} + {% if wide_columns_exist != true %} + $('#table_container').css("width", String($('#trait_table').width()) + "px"); + {% endif %} + {% endif %} } - {% endif %} } window.addEventListener('resize', function(){ @@ -507,8 +562,16 @@ columnDef.sWidth = userColumnDef.width + 'px'; columnDef.width = userColumnDef.width + 'px'; + $('.toggle-vis').each(function(){ + if ($(this).attr('data-column') == columnDef.targets){ + if ($(this).hasClass("active")){ + columnDef.bVisible = false + } else { + columnDef.bVisible = true + } + } + }) } - }); } @@ -527,10 +590,8 @@ width = $(header).width(); if ( existingSetting !== -1 ) { - // Update the width userColumnDefs[existingSetting].width = width; - } else { // Add the width for this column -- cgit v1.2.3 From dc70723199c1cf84d4debee01a86646650afbba9 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 22 Apr 2021 18:19:52 +0000 Subject: Temporarily replacing jquery-ui with the version that works with resizing DataTables columns --- wqflask/wqflask/templates/base.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 12dddf89..1a0335b6 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -255,7 +255,8 @@ }) - + + -- cgit v1.2.3 From 2d9220c3d88f5f818ae81e3cafdc69288c9cfbd8 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 4 May 2021 19:24:15 +0000 Subject: Changed recheck_rows to include the DataTable as input in preparation for moving it into a separate JS file that can be imported by all table templates --- wqflask/wqflask/templates/search_result_page.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index eac3ec61..279a1886 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -391,9 +391,9 @@ }{% endif %} ]; - recheck_rows = function(checked_rows){ + recheck_rows = function(the_table, checked_rows){ //ZS: This is meant to recheck checkboxes after columns are resized - check_cells = trait_table.column(0).nodes().to$(); + check_cells = the_table.column(0).nodes().to$(); for (let i = 0; i < check_cells.length; i++) { if (checked_rows.includes(i)){ check_cells[i].childNodes[0].checked = true; @@ -523,7 +523,7 @@ let checked_rows = get_checked_rows(); trait_table = $('#' + tableId).DataTable(table_settings); if (checked_rows.length > 0){ - recheck_rows(checked_rows); + recheck_rows(trait_table, checked_rows); } if (first_run){ -- cgit v1.2.3 From 304128b1231df425709fbe3b128bd0c5eda4139b Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 4 May 2021 19:29:01 +0000 Subject: Include table ID as input for get_checked_rows --- wqflask/wqflask/templates/search_result_page.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 279a1886..adc8c264 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -408,9 +408,9 @@ } } - get_checked_rows = function(trait_table){ + get_checked_rows = function(table_id){ let checked_rows = [] - $("#trait_table input").each(function(index){ + $("#" + table_id + " input").each(function(index){ if ($(this).prop("checked") == true){ checked_rows.push(index); } @@ -520,7 +520,7 @@ $('#table_container').css("width", String($('#trait_table').width() + width_change {% if trait_list|length > 20 %}+ 17{% endif %}) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly } - let checked_rows = get_checked_rows(); + let checked_rows = get_checked_rows(tableId); trait_table = $('#' + tableId).DataTable(table_settings); if (checked_rows.length > 0){ recheck_rows(trait_table, checked_rows); -- cgit v1.2.3 From 16338316a7529265aaa94d541698c8ed8cc97aba Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 4 May 2021 19:35:31 +0000 Subject: Include table/table_id as parameters in setUseerColumnsDefWidths and saveColumnSettings --- wqflask/wqflask/templates/search_result_page.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index adc8c264..a351256b 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -424,7 +424,7 @@ function loadDataTable(first_run=false){ if (!first_run){ - setUserColumnsDefWidths(); + setUserColumnsDefWidths(tableId); } //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters @@ -508,7 +508,7 @@ width_change = ui.size.width - ui.originalSize.width; }, stop: function () { - saveColumnSettings(); + saveColumnSettings(tableId, trait_table); loadDataTable(); } }); @@ -541,11 +541,11 @@ trait_table.columns.adjust(); }); - function setUserColumnsDefWidths() { + function setUserColumnsDefWidths(table_id) { var userColumnDef; // Get the settings for this table from localStorage - var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; + var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; if (userColumnDefs.length === 0 ) return; @@ -575,8 +575,8 @@ }); } - function saveColumnSettings() { - var userColumnDefs = JSON.parse(localStorage.getItem(tableId)) || []; + function saveColumnSettings(table_id, trait_table) { + var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; var width, header, existingSetting; -- cgit v1.2.3 From fe224fb35f926373ff75c9a19217a4602ca3ea99 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 4 May 2021 19:40:09 +0000 Subject: Moved several table functions out of search_results.html and into new file table_functions.js --- .../static/new/javascript/table_functions.js | 93 +++++++++++++++++++++ wqflask/wqflask/templates/search_result_page.html | 96 +--------------------- 2 files changed, 94 insertions(+), 95 deletions(-) create mode 100644 wqflask/wqflask/static/new/javascript/table_functions.js diff --git a/wqflask/wqflask/static/new/javascript/table_functions.js b/wqflask/wqflask/static/new/javascript/table_functions.js new file mode 100644 index 00000000..e24b3e03 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/table_functions.js @@ -0,0 +1,93 @@ +recheck_rows = function(the_table, checked_rows){ + //ZS: This is meant to recheck checkboxes after columns are resized + check_cells = the_table.column(0).nodes().to$(); + for (let i = 0; i < check_cells.length; i++) { + if (checked_rows.includes(i)){ + check_cells[i].childNodes[0].checked = true; + } + } + + check_rows = trait_table.rows().nodes(); + for (let i =0; i < check_rows.length; i++) { + if (checked_rows.includes(i)){ + check_rows[i].classList.add("selected") + } + } + } + +get_checked_rows = function(table_id){ + let checked_rows = [] + $("#" + table_id + " input").each(function(index){ + if ($(this).prop("checked") == true){ + checked_rows.push(index); + } + }); + + return checked_rows +} + +function setUserColumnsDefWidths(table_id) { + var userColumnDef; + + // Get the settings for this table from localStorage + var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; + + if (userColumnDefs.length === 0 ) return; + + columnDefs.forEach( function(columnDef) { + + // Check if there is a width specified for this column + userColumnDef = userColumnDefs.find( function(column) { + return column.targets === columnDef.targets; + }); + + // If there is, set the width of this columnDef in px + if ( userColumnDef ) { + + columnDef.sWidth = userColumnDef.width + 'px'; + columnDef.width = userColumnDef.width + 'px'; + + $('.toggle-vis').each(function(){ + if ($(this).attr('data-column') == columnDef.targets){ + if ($(this).hasClass("active")){ + columnDef.bVisible = false + } else { + columnDef.bVisible = true + } + } + }) + } + }); +} + +function saveColumnSettings(table_id, trait_table) { +var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; + +var width, header, existingSetting; + +trait_table.columns().every( function ( targets ) { + + // Check if there is a setting for this column in localStorage + existingSetting = userColumnDefs.findIndex( function(column) { return column.targets === targets;}); + + // Get the width of this column + header = this.header(); + width = $(header).width(); + + if ( existingSetting !== -1 ) { + // Update the width + userColumnDefs[existingSetting].width = width; + } else { + + // Add the width for this column + userColumnDefs.push({ + targets: targets, + width: width, + }); + + } +}); + +// Save (or update) the settings in localStorage +localStorage.setItem(table_id, JSON.stringify(userColumnDefs)); +} \ No newline at end of file diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index a351256b..436eb639 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -154,6 +154,7 @@ + - + - @@ -402,90 +401,89 @@ //ZS: Need to make sort by symbol, also need to make sure blank symbol fields at the bottom and symbols starting with numbers below letters table_settings = { - 'drawCallback': function( settings ) { - $('#' + tableId + ' tr').off().on("click", function(event) { - if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { - var obj =$(this).find('input'); - obj.prop('checked', !obj.is(':checked')); - } - if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ - $(this).removeClass("selected") - } else if (event.target.tagName.toLowerCase() !== 'a') { - $(this).addClass("selected") - } - change_buttons() - }); - }, - 'createdRow': function ( row, data, index ) { - $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); - $('td', row).eq(1).attr("align", "right"); - $('td', row).eq(1).attr('data-export', index+1); - $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); - {% if dataset.type == 'ProbeSet' %} - $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - if ($('td', row).eq(3).text().length > 20) { - $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20)); - $('td', row).eq(3).text($('td', row).eq(3).text() + '...') - } - $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); - $('td', row).slice(5,10).attr("align", "right"); - $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); - $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); - $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); - $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); - $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); - {% elif dataset.type == 'Publish' %} - $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); - $('td', row).eq(4).attr('align', 'right'); - $('td', row).slice(6,10).attr("align", "right"); - $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); - $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); - $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); - $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); - $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text()); - {% elif dataset.type == 'Geno' %} - $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); - {% endif %} - }, - "data": trait_list, - "columns": columnDefs, - "order": [[1, "asc" ]], - "sDom": "iti", - "destroy": true, - {% if wide_columns_exist != true %} - "autoWidth": true, - {% else %} - "autoWidth": false, - {% endif %} - "deferRender": true, - "bSortClasses": false, - "scrollX": true, - {% if trait_list|length > 20 %} - "scrollY": "500px", - "scroller": true, - "scrollCollapse": true, - {% else %} - "iDisplayLength": -1, - {% endif %} - "initComplete": function (settings) { - //Add JQueryUI resizable functionality to each th in the ScrollHead table - $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ - handles: "e", - alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother - resize: function( event, ui ) { - width_change = ui.size.width - ui.originalSize.width; - }, - stop: function () { - saveColumnSettings(tableId, trait_table); - loadDataTable(); - } - }); - }, + 'drawCallback': function( settings ) { + $('#' + tableId + ' tr').off().on("click", function(event) { + if (event.target.type !== 'checkbox' && event.target.tagName.toLowerCase() !== 'a') { + var obj =$(this).find('input'); + obj.prop('checked', !obj.is(':checked')); + } + if ($(this).hasClass("selected") && event.target.tagName.toLowerCase() !== 'a'){ + $(this).removeClass("selected") + } else if (event.target.tagName.toLowerCase() !== 'a') { + $(this).addClass("selected") + } + change_buttons() + }); + }, + 'createdRow': function ( row, data, index ) { + $('td', row).eq(0).attr("style", "text-align: center; padding: 0px 10px 2px 10px;"); + $('td', row).eq(1).attr("align", "right"); + $('td', row).eq(1).attr('data-export', index+1); + $('td', row).eq(2).attr('data-export', $('td', row).eq(2).text()); + {% if dataset.type == 'ProbeSet' %} + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + if ($('td', row).eq(3).text().length > 20) { + $('td', row).eq(3).text($('td', row).eq(3).text().substring(0, 20)); + $('td', row).eq(3).text($('td', row).eq(3).text() + '...') + } + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + $('td', row).slice(5,10).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(9).text()); + {% elif dataset.type == 'Publish' %} + $('td', row).eq(3).attr('title', $('td', row).eq(3).text()); + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + $('td', row).eq(4).attr('title', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('data-export', $('td', row).eq(4).text()); + $('td', row).eq(4).attr('align', 'right'); + $('td', row).slice(6,10).attr("align", "right"); + $('td', row).eq(5).attr('data-export', $('td', row).eq(5).text()); + $('td', row).eq(6).attr('data-export', $('td', row).eq(6).text()); + $('td', row).eq(7).attr('data-export', $('td', row).eq(7).text()); + $('td', row).eq(8).attr('data-export', $('td', row).eq(8).text()); + $('td', row).eq(9).attr('data-export', $('td', row).eq(8).text()); + {% elif dataset.type == 'Geno' %} + $('td', row).eq(3).attr('data-export', $('td', row).eq(3).text()); + {% endif %} + }, + "data": trait_list, + "columns": columnDefs, + "order": [[1, "asc" ]], + "sDom": "iti", + "destroy": true, + {% if wide_columns_exist != true %} + "autoWidth": true, + {% else %} + "autoWidth": false, + {% endif %} + "deferRender": true, + "bSortClasses": false, + {% if trait_list|length > 20 %} + "scrollY": "500px", + "scroller": true, + "scrollCollapse": true, + {% else %} + "iDisplayLength": -1, + {% endif %} + "initComplete": function (settings) { + //Add JQueryUI resizable functionality to each th in the ScrollHead table + $('#' + tableId + '_wrapper .dataTables_scrollHead thead th').resizable({ + handles: "e", + alsoResize: '#' + tableId + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother + resize: function( event, ui ) { + width_change = ui.size.width - ui.originalSize.width; + }, + stop: function () { + saveColumnSettings(tableId, trait_table); + loadDataTable(); + } + }); + } } if (!first_run){ -- cgit v1.2.3 From ef49a5bf5b1b2b010c71f77394c5b178c00b8942 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 21 Jun 2021 20:29:26 +0000 Subject: Fixed indentation in table_functions.js --- .../static/new/javascript/table_functions.js | 181 ++++++++++----------- 1 file changed, 88 insertions(+), 93 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/table_functions.js b/wqflask/wqflask/static/new/javascript/table_functions.js index e24b3e03..745563c2 100644 --- a/wqflask/wqflask/static/new/javascript/table_functions.js +++ b/wqflask/wqflask/static/new/javascript/table_functions.js @@ -1,93 +1,88 @@ -recheck_rows = function(the_table, checked_rows){ - //ZS: This is meant to recheck checkboxes after columns are resized - check_cells = the_table.column(0).nodes().to$(); - for (let i = 0; i < check_cells.length; i++) { - if (checked_rows.includes(i)){ - check_cells[i].childNodes[0].checked = true; - } - } - - check_rows = trait_table.rows().nodes(); - for (let i =0; i < check_rows.length; i++) { - if (checked_rows.includes(i)){ - check_rows[i].classList.add("selected") - } - } - } - -get_checked_rows = function(table_id){ - let checked_rows = [] - $("#" + table_id + " input").each(function(index){ - if ($(this).prop("checked") == true){ - checked_rows.push(index); - } - }); - - return checked_rows -} - -function setUserColumnsDefWidths(table_id) { - var userColumnDef; - - // Get the settings for this table from localStorage - var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; - - if (userColumnDefs.length === 0 ) return; - - columnDefs.forEach( function(columnDef) { - - // Check if there is a width specified for this column - userColumnDef = userColumnDefs.find( function(column) { - return column.targets === columnDef.targets; - }); - - // If there is, set the width of this columnDef in px - if ( userColumnDef ) { - - columnDef.sWidth = userColumnDef.width + 'px'; - columnDef.width = userColumnDef.width + 'px'; - - $('.toggle-vis').each(function(){ - if ($(this).attr('data-column') == columnDef.targets){ - if ($(this).hasClass("active")){ - columnDef.bVisible = false - } else { - columnDef.bVisible = true - } - } - }) - } - }); -} - -function saveColumnSettings(table_id, trait_table) { -var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; - -var width, header, existingSetting; - -trait_table.columns().every( function ( targets ) { - - // Check if there is a setting for this column in localStorage - existingSetting = userColumnDefs.findIndex( function(column) { return column.targets === targets;}); - - // Get the width of this column - header = this.header(); - width = $(header).width(); - - if ( existingSetting !== -1 ) { - // Update the width - userColumnDefs[existingSetting].width = width; - } else { - - // Add the width for this column - userColumnDefs.push({ - targets: targets, - width: width, - }); - - } -}); - -// Save (or update) the settings in localStorage -localStorage.setItem(table_id, JSON.stringify(userColumnDefs)); -} \ No newline at end of file +recheck_rows = function(the_table, checked_rows){ + //ZS: This is meant to recheck checkboxes after columns are resized + check_cells = the_table.column(0).nodes().to$(); + for (let i = 0; i < check_cells.length; i++) { + if (checked_rows.includes(i)){ + check_cells[i].childNodes[0].checked = true; + } + } + + check_rows = trait_table.rows().nodes(); + for (let i =0; i < check_rows.length; i++) { + if (checked_rows.includes(i)){ + check_rows[i].classList.add("selected") + } + } +} + +get_checked_rows = function(table_id){ + let checked_rows = [] + $("#" + table_id + " input").each(function(index){ + if ($(this).prop("checked") == true){ + checked_rows.push(index); + } + }); + + return checked_rows +} + +function setUserColumnsDefWidths(table_id) { + var userColumnDef; + + // Get the settings for this table from localStorage + var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; + + if (userColumnDefs.length === 0 ) return; + + columnDefs.forEach( function(columnDef) { + // Check if there is a width specified for this column + userColumnDef = userColumnDefs.find( function(column) { + return column.targets === columnDef.targets; + }); + + // If there is, set the width of this columnDef in px + if ( userColumnDef ) { + + columnDef.sWidth = userColumnDef.width + 'px'; + columnDef.width = userColumnDef.width + 'px'; + + $('.toggle-vis').each(function(){ + if ($(this).attr('data-column') == columnDef.targets){ + if ($(this).hasClass("active")){ + columnDef.bVisible = false + } else { + columnDef.bVisible = true + } + } + }) + } + }); +} + +function saveColumnSettings(table_id, trait_table) { + var userColumnDefs = JSON.parse(localStorage.getItem(table_id)) || []; + var width, header, existingSetting; + + trait_table.columns().every( function ( targets ) { + // Check if there is a setting for this column in localStorage + existingSetting = userColumnDefs.findIndex( function(column) { return column.targets === targets;}); + + // Get the width of this column + header = this.header(); + width = $(header).width(); + + if ( existingSetting !== -1 ) { + // Update the width + userColumnDefs[existingSetting].width = width; + } else { + // Add the width for this column + userColumnDefs.push({ + targets: targets, + width: width, + }); + } + }); + + // Save (or update) the settings in localStorage + localStorage.setItem(table_id, JSON.stringify(userColumnDefs)); +} -- cgit v1.2.3 From 6f621612f1f74694b9895c7252c1d72e7b2f7314 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 21 Jun 2021 20:33:11 +0000 Subject: Implemented resizeable columns for gene global search + fixed the way change_buttons is called and row highlighting works in the DataTables callback --- wqflask/wqflask/templates/gsearch_gene.html | 347 +++++++++++++++------------- 1 file changed, 183 insertions(+), 164 deletions(-) diff --git a/wqflask/wqflask/templates/gsearch_gene.html b/wqflask/wqflask/templates/gsearch_gene.html index 5549ac8a..3b8f9ff7 100644 --- a/wqflask/wqflask/templates/gsearch_gene.html +++ b/wqflask/wqflask/templates/gsearch_gene.html @@ -2,6 +2,7 @@ {% block title %}Search Results{% endblock %} {% block css %} + {% endblock %} {% block content %} @@ -31,7 +32,7 @@

-
+

Loading...
@@ -54,6 +55,7 @@ + - {% endblock %} -- cgit v1.2.3 From 48154b81c705f6eb2af16b0394e1e2e5bcca83b6 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 21 Jun 2021 20:35:07 +0000 Subject: Added table_functions.js to gsearch_pheno.html --- wqflask/wqflask/templates/gsearch_pheno.html | 1 + 1 file changed, 1 insertion(+) diff --git a/wqflask/wqflask/templates/gsearch_pheno.html b/wqflask/wqflask/templates/gsearch_pheno.html index 89316cbc..a5e30c8b 100644 --- a/wqflask/wqflask/templates/gsearch_pheno.html +++ b/wqflask/wqflask/templates/gsearch_pheno.html @@ -54,6 +54,7 @@ + - {% endblock %} -- cgit v1.2.3 From d99776e16fc991f75803836f6e3292cea9f6d621 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 24 Jun 2021 21:11:59 +0000 Subject: Gave initial widths for dataset and description columns in gene global search --- wqflask/wqflask/templates/gsearch_gene.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/templates/gsearch_gene.html b/wqflask/wqflask/templates/gsearch_gene.html index 3b8f9ff7..0a3ec027 100644 --- a/wqflask/wqflask/templates/gsearch_gene.html +++ b/wqflask/wqflask/templates/gsearch_gene.html @@ -132,6 +132,7 @@ 'title': "Dataset", 'type': "natural", 'targets': 6, + 'width': "320px", 'data': "dataset_fullname" }, { @@ -145,6 +146,7 @@ 'title': "Description", 'type': "natural", 'data': null, + 'width': "120px", 'targets': 8, 'render': function(data, type, row, meta) { try { @@ -260,7 +262,6 @@ "order": [[1, "asc" ]], 'sDom': "iti", "destroy": true, - "autoWidth": true, "deferRender": true, "bSortClasses": false, {% if trait_count > 20 %} @@ -301,9 +302,8 @@ {% if trait_list|length > 20 %} $('#table_container').css("width", String($('#trait_table').width() + 17) + "px"); {% endif %} + trait_table.draw(); } - - trait_table.draw(); } $('#redraw').click(function() { -- cgit v1.2.3 From a2919c924f647887f6383d1e2efebc914ade0da3 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 30 Jun 2021 20:24:52 +0000 Subject: Removed CSS that truncates cell content and adds an ellipses when the cell is too small to contain content; it now just makes the content wrap --- wqflask/wqflask/static/new/css/trait_list.css | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/wqflask/wqflask/static/new/css/trait_list.css b/wqflask/wqflask/static/new/css/trait_list.css index 6d49f009..ce3075d4 100644 --- a/wqflask/wqflask/static/new/css/trait_list.css +++ b/wqflask/wqflask/static/new/css/trait_list.css @@ -51,22 +51,3 @@ div.dts div.dataTables_scrollBody table { div.dts div.dataTables_paginate,div.dts div.dataTables_length{ display:none } - -/* This is the important CSS */ -table.dataTable { - table-layout: fixed; - width: 100%; - white-space: nowrap; - overflow: hidden; -} - -table.dataTable th { - white-space: nowrap; - overflow: hidden; -} - -table.dataTable td { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} \ No newline at end of file -- cgit v1.2.3 From c3302c1f44af146ab296110c11e68ab25ddae4df Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 1 Jul 2021 17:50:31 +0000 Subject: Changed initialize_show_trait_tables.js to include resizeable columns and deal with both primary/other tables in a single function --- .../new/javascript/initialize_show_trait_tables.js | 214 +++++++++++++-------- 1 file changed, 136 insertions(+), 78 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js index 6ca92fb6..d8a1b006 100644 --- a/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js +++ b/wqflask/wqflask/static/new/javascript/initialize_show_trait_tables.js @@ -15,6 +15,7 @@ build_columns = function() { 'data': null, 'orderDataType': "dom-checkbox", 'searchable' : false, + 'targets': 0, 'render': function(data, type, row, meta) { return '' } @@ -23,12 +24,14 @@ build_columns = function() { 'title': "ID", 'type': "natural", 'searchable' : false, + 'targets': 1, 'data': "this_id" }, { 'title': "Sample", 'type': "natural", 'data': null, + 'targets': 2, 'render': function(data, type, row, meta) { return '' + data.name + '' } @@ -38,6 +41,7 @@ build_columns = function() { 'orderDataType': "dom-input", 'type': "cust-txt", 'data': null, + 'targets': 3, 'render': function(data, type, row, meta) { if (data.value == null) { return '' @@ -48,12 +52,15 @@ build_columns = function() { } ]; + attr_start = 4 if (js_data.se_exists) { + attr_start += 2 column_list.push( { 'bSortable': false, 'type': "natural", 'data': null, + 'targets': 4, 'searchable' : false, 'render': function(data, type, row, meta) { return '±' @@ -64,6 +71,7 @@ build_columns = function() { 'orderDataType': "dom-input", 'type': "cust-txt", 'data': null, + 'targets': 5, 'render': function(data, type, row, meta) { if (data.variance == null) { return '' @@ -73,24 +81,47 @@ build_columns = function() { } } ); - } - if (js_data.has_num_cases === true) { - column_list.push( - { - 'title': "
N
", - 'orderDataType': "dom-input", - 'type': "cust-txt", - 'data': null, - 'render': function(data, type, row, meta) { - if (data.num_cases == null || data.num_cases == undefined) { - return '' - } else { - return '' + if (js_data.has_num_cases === true) { + attr_start += 1 + column_list.push( + { + 'title': "
N
", + 'orderDataType': "dom-input", + 'type': "cust-txt", + 'data': null, + 'targets': 6, + 'render': function(data, type, row, meta) { + if (data.num_cases == null || data.num_cases == undefined) { + return '' + } else { + return '' + } } } - } - ); + ); + } + } + else { + if (js_data.has_num_cases === true) { + attr_start += 1 + column_list.push( + { + 'title': "
N
", + 'orderDataType': "dom-input", + 'type': "cust-txt", + 'data': null, + 'targets': 4, + 'render': function(data, type, row, meta) { + if (data.num_cases == null || data.num_cases == undefined) { + return '' + } else { + return '' + } + } + } + ); + } } attr_keys = Object.keys(js_data.attributes).sort((a, b) => (js_data.attributes[a].name.toLowerCase() > js_data.attributes[b].name.toLowerCase()) ? 1 : -1) @@ -100,6 +131,7 @@ build_columns = function() { 'title': "
" + js_data.attributes[attr_keys[i]].name + "
", 'type': "natural", 'data': null, + 'targets': attr_start + i, 'render': function(data, type, row, meta) { attr_name = Object.keys(data.extra_attributes).sort()[meta.col - data.first_attr_col] @@ -119,14 +151,35 @@ build_columns = function() { return column_list } -var primary_table = $('#samples_primary').DataTable( { +columnDefs = build_columns() + +loadDataTable(first_run=true, table_id="samples_primary", table_data=js_data['sample_lists'][0]) +if (js_data.sample_lists.length > 1){ + loadDataTable(first_run=true, table_id="samples_other", table_data=js_data['sample_lists'][1]) +} + +function loadDataTable(first_run=false, table_id, table_data){ + + console.log("COL DEFS:", columnDefs) + + if (!first_run){ + setUserColumnsDefWidths(table_id); + } + + if (table_id == "samples_primary"){ + table_type = "Primary" + } else { + table_type = "Other" + } + + table_settings = { 'initComplete': function(settings, json) { $('.edit_sample_value').change(function() { edit_data_change(); }); }, 'createdRow': function ( row, data, index ) { - $(row).attr('id', "Primary_" + data.this_id) + $(row).attr('id', table_type + "_" + data.this_id) $(row).addClass("value_se"); if (data.outlier) { $(row).addClass("outlier"); @@ -154,75 +207,80 @@ var primary_table = $('#samples_primary').DataTable( { $('td', row).eq(attribute_start_pos + i + 1).attr("style", "text-align: " + js_data.attributes[attr_keys[i]].alignment + "; padding-top: 2px; padding-bottom: 0px;") } }, - 'data': js_data['sample_lists'][0], - 'columns': build_columns(), - 'order': [[1, "asc"]], - 'sDom': "Ztr", - 'autoWidth': true, - 'orderClasses': true, + 'data': table_data, + 'columns': columnDefs, + "order": [[1, "asc" ]], + "sDom": "iti", + "destroy": true, + "autoWidth": first_run, + "deferRender": true, + "bSortClasses": false, "scrollY": "100vh", - 'scroller': true, - 'scrollCollapse': true -} ); + "scrollCollapse": true, + "scroller": true, + "iDisplayLength": -1, + "initComplete": function (settings) { + //Add JQueryUI resizable functionality to each th in the ScrollHead table + $('#' + table_id + '_wrapper .dataTables_scrollHead thead th').resizable({ + handles: "e", + alsoResize: '#' + table_id + '_wrapper .dataTables_scrollHead table', //Not essential but makes the resizing smoother + resize: function( event, ui ) { + width_change = ui.size.width - ui.originalSize.width; + }, + stop: function () { + saveColumnSettings(table_id, the_table); + loadDataTable(first_run=false, table_id, table_data); + } + }); + } + } -primary_table.draw(); //ZS: This makes the table adjust its height properly on initial load + var the_table = $('#' + table_id).DataTable(table_settings); -primary_table.on( 'order.dt search.dt draw.dt', function () { - primary_table.column(1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { - cell.innerHTML = i+1; - } ); -} ).draw(); + the_table.draw(); //ZS: This makes the table adjust its height properly on initial load -$('#primary_searchbox').on( 'keyup', function () { - primary_table.search($(this).val()).draw(); -} ); + the_table.on( 'order.dt search.dt draw.dt', function () { + the_table.column(1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) { + cell.innerHTML = i+1; + } ); + } ).draw(); -if (js_data.sample_lists.length > 1){ - var other_table = $('#samples_other').DataTable( { - 'initComplete': function(settings, json) { - $('.edit_sample_value').change(function() { - edit_data_change(); - }); - }, - 'createdRow': function ( row, data, index ) { - $(row).attr('id', "Primary_" + data.this_id) - $(row).addClass("value_se"); - if (data.outlier) { - $(row).addClass("outlier"); - } - $('td', row).eq(1).addClass("column_name-Index") - $('td', row).eq(2).addClass("column_name-Sample") - $('td', row).eq(3).addClass("column_name-Value") - if (js_data.se_exists) { - $('td', row).eq(5).addClass("column_name-SE") - if (js_data.has_num_cases === true) { - $('td', row).eq(6).addClass("column_name-num_cases") - } else { - if (js_data.has_num_cases === true) { - $('td', row).eq(4).addClass("column_name-num_cases") - } - } + if (!first_run){ + $('#' + table_type.toLowerCase() + '_container').css("width", String($('#' + table_id).width() + width_change + 17) + "px"); //ZS : Change the container width by the change in width of the adjusted column, so the overall table size adjusts properly + + let checked_rows = get_checked_rows(table_id); + if (checked_rows.length > 0){ + recheck_rows(the_table, checked_rows); + } + } + + if (first_run){ + $('#' + table_type.toLowerCase() + '_container').css("width", String($('#' + table_id).width() + 17) + "px"); + } + + $('#' + table_type.toLowerCase() + '_searchbox').on( 'keyup', function () { + the_table.search($(this).val()).draw(); + } ); + + $('.toggle-vis').on('click', function (e) { + e.preventDefault(); + + function toggle_column(column) { + //ZS: Toggle column visibility + column.visible( ! column.visible() ); + if (column.visible()){ + $(this).removeClass("active"); } else { - if (js_data.has_num_cases === true) { - $('td', row).eq(4).addClass("column_name-num_cases") - } + $(this).addClass("active"); } + } - for (i=0; i < attr_keys.length; i++) { - $('td', row).eq(attribute_start_pos + i + 1).addClass("column_name-" + js_data.attributes[attr_keys[i]].name) - $('td', row).eq(attribute_start_pos + i + 1).attr("style", "text-align: " + js_data.attributes[attr_keys[i]].alignment + "; padding-top: 2px; padding-bottom: 0px;") - } - }, - 'data': js_data['sample_lists'][1], - 'columns': build_columns(), - 'order': [[1, "asc"]], - 'sDom': "Ztr", - 'autoWidth': true, - 'orderClasses': true, - "scrollY": "100vh", - 'scroller': true, - 'scrollCollapse': true + // Get the column API object + var target_cols = $(this).attr('data-column').split(",") + for (let i = 0; i < target_cols.length; i++){ + var column = the_table.column( target_cols[i] ); + toggle_column(column); + } } ); - other_table.draw(); //ZS: This makes the table adjust its height properly on initial load } -- cgit v1.2.3 From be51132f68ea92c3917c16f1d2962772e8debe04 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 1 Jul 2021 17:51:32 +0000 Subject: Removed width from sample_group div and change table div ID to be distinct when there are both primary and other samplee tables --- wqflask/wqflask/templates/show_trait_edit_data.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/templates/show_trait_edit_data.html b/wqflask/wqflask/templates/show_trait_edit_data.html index 5939c953..c5944d3f 100644 --- a/wqflask/wqflask/templates/show_trait_edit_data.html +++ b/wqflask/wqflask/templates/show_trait_edit_data.html @@ -53,11 +53,11 @@ {% set outer_loop = loop %} -
+

{{ sample_type.header }}

-
+

Loading...
-- cgit v1.2.3 From bbda9eb2eb542b7d90abdfcd1a8f34c35d38491c Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 1 Jul 2021 17:53:05 +0000 Subject: Added imports necessary for resizeable columns and removed unused code --- wqflask/wqflask/templates/show_trait.html | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 3dbf5f57..7074e21e 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -5,9 +5,10 @@ - + + @@ -155,6 +156,7 @@ +

Loading...