Google Chart - setSelection does not scroll to selected row in Table visualisation - javascript

I am using Google Chart Tools to display a Table visulisation on my webpage along side a Google Map. When the user clicks a map location, the callback automatically selects the corresponding location from a list of locations in the table.
This works fine, but the table does not automatically scroll the table so the selected row is visible (there are a lot of points so only a limited amount are shown with a scrollbar on the right hand side of the Table vis.)
I can't see any way of setting the current 'position' of the viewport to the Table. Is there a way to do this?
Thanks!
Code snippet below:
arrBuoyLocs = new google.visualization.DataTable();
vTable = new google.visualization.Table(document.getElementById('table_div'));
// do initialisation, etc...
.
.
.
function updateSelectedTableItem(buoyid) {
console.log('Searching for %s', buoyid);
idx = -1;
nRows = arrBuoyLocs.getNumberOfRows();
for(iRow = 0; iRow < nRows; iRow++) {
if(arrBuoyLocs.getValue(iRow, 0) == buoyid) {
console.log('Got match for %s at idx %d', buoyid, iRow);
idx = iRow;
break;
}
}
if(idx >= 0) {
vTable.setSelection([{row: idx, column: null}]);
// This highlights the row but does not show it if the row is
// scrolled off the screen. How do I scroll the Table to show
// the selected row?
}
}

I have no idea how to do it with google chart api, but heres a thought that might help:
if you can find the screen height, the table row height and calculate how many table rows can fit into your screen, then you can calculate how much the scrollbar needs to scroll to show your selected table row.
so if you have a screen height that can have 20 rows shown, and you selected row 25, then you scroll the scrollbar 5 * rowHeight + margin. this can probably be done in javascript or in an ajax file.
Basically you already have all the data you need to do it, just need to findout how to scroll the scrollbar programatically in javascript.

I found this, which works.
https://groups.google.com/forum/#!searchin/google-visualization-api/table$20setSelection/google-visualization-api/8_atzTNPmL4/etL7VZWjdVQJ
Edit:
From which, this will scroll to the selected column of table in 'table_div'.
I found this sufficient, with some fine tuning to ensure the row I want is clearly in view.
function on_row_select() {
// get the container div for the overflowed table
var container = $('#table_div').find('.google-visualization-table-table:eq(0)').parent();
// get the container div for the fixed header
var header = $('#table_div').find('.google-visualization-table-table:eq(1)').parent();
// get the selected row
var row = $('.google-visualization-table-tr-sel');
// set the scroll position of the overflowed div based on the offset position of the row and the height of the fixed header
$(container).prop('scrollTop', $(row).prop('offsetTop') - $(header).height());
}

Something like this one. This answer a) no need jQuery and b) do not touch scroller when the selected row already on screen.
scrollOnToSelectPosition=function(element) {
var tableElement=element.querySelectorAll("table.google-visualization-table-table")[0],
selection=tableElement.querySelectorAll("tr.google-visualization-table-tr-sel");
if (selection.length) {
var parentDiv=tableElement.parentElement,
tableHead=tableElement.querySelectorAll("thead")[0],
offset=selection[0].offsetTop-tableHead.clientHeight,
viewHeight=parentDiv.clientHeight-tableHead.clientHeight;
if (offset>parentDiv.scrollTop && offset<parentDiv.scrollTop+viewHeight) {
if (offset+selection[0].clientHeight>parentDiv.scrollTop+viewHeight) {
parentDiv.scrollTop=offset+selection[0].clientHeight-viewHeight;
}
}
else {
parentDiv.scrollTop=offset;
}
}
},

Related

Removing an empty "Row" for a Grid of Nested Divs (not an html table) with JS / jQuery

I made this function to remove rows being looped into in a spec table view when all the cells in that row contain "N/A" instead of a spec. For reasons not worth going into, I need to change my table view from an HTML table to a fake table (html grid) with nested divs. This means that the specs are no longer connected by the tr tag, so I'm not sure how I can connect them to accomplish the same result...
$('.specnacheckrow').each(function() { // for each row in the table
var naTrue = 0;
var totalCells = 0;
var $this = $(this);
totalCells = $this.find('.specnacheckcell').length //count how many cells
naTrue = $this.find('.specnatrue').length //count how many <span class="specnatrue">N/A</span>
if (naTrue < totalCells) { //if the number of cells is greater than the number of N/A's
$this.show(); //show the row
} else {
$this.remove(); //else, hide the entire row - this includes the spec label at the beginning of the row.
}
});
Example of original table - https://codepen.io/genopeppino/pen/PojMero
Example of Grid Divs - https://codepen.io/genopeppino/pen/oNwKyNJ
You can see that in the original table the "Ship Weight - KG" row is correctly removed by the function above.

how to show horizontal scroll bar in empty kendo grid using angularjs

How to show horizontal scroll bar in empty kendo grid using angularjs?. Displaying the kendo grid if there is no record it shows only column header without horizontal scroll bar.
At last i found the solution for applying the horizontal scroll bar empty kendo grid using angularjs.
dataBound: function () {
if (this.dataSource.view().length == 0) {
//insert empty row
var colspan = this.thead.find("th").length;
var emptyRow = "<tr><td colspan='" + colspan + "'></td></tr>";
this.tbody.html(emptyRow);
//workarounds for IE lt 9
this.table.width(800);
$(".k-grid-content").height(2 * kendo.support.scrollbar());
}
else {
//To reset width and height once record filled in the grid
this.table.width('100%');
$(".k-grid-content").height('');
}
}

How to keep adding items to a div until both divs have same height?

I have two divs which are side by side. Currently, I display n+2 items in left div and n items in right one. n varies based on category and is predetermined. My problem is sometimes individual items in left div have more height than usual. How can I keep adding items to the right div until both divs have about same height?
Try this?
var $left_div = $('#left_div');
var $right_div = $('#right_div');
while($left_div.height() > $right_div.height()){
$right_div.append($your_item);
}
Where $your_item is defined as whatever you want to add onto your right div
Alternatively you can check for a threshold
var threshold = 200;
var $left_div = $('#left_div');
var $right_div = $('#right_div');
while(Math.abs($left_div.height() - $right_div.height()) < threshold){
$right_div.append($your_item);
}

Fixed Header for ASP NET Gridview JQuery

I've been searching a lot for ways to make my gridview header fixed I came across this JQuery code:
$(document).ready(function () {
// Code to copy the gridview header with style
var gridHeader = $('#<%=GridView1.ClientID%>').clone(true);
//Code to remove all the rows but the first row which is header row
$(gridHeader).find("tr:gt(0)").remove();
$('#<%=GridView1.ClientID%> tr th').each(function (i) {
// Here Set Width of each th from gridview to new table th
$("th:nth-child(" + (i + 1) + ")", gridHeader).css('width', ($(this).width()).toString() + "px");
});
// Append Header to the div controlHead
$("#controlHead").append(gridHeader); // <-- HERE is WHEN IT DAMAGES OTHER JS FUNCTIONALITY
// Set its position to be fixed
$('#controlHead').css('position', 'fixed');
// Put it on top
$('#controlHead').css('top', $('#<%=GridView1.ClientID%>').offset().top);
It actually works but it makes my other JS functions to malfunction when I append this cloned header to the empty div "gridHeader"
Like this JS Function that is in charge of highlighting the selected row, it just doesn't find the Gridview anymore
// Method that will highlight row
function gridviewManipulation() {
// Get Gridview
var gridView = document.getElementById("<%= GridView1.ClientID %>");
// Loop through the Gridview
for (var i = 1; i < gridView.rows.length; i++) {
// Get the radio button of each row in the gridview and see if its checked
if (gridView.rows[i].cells[0].getElementsByTagName("INPUT")[0].checked == true)
{
// Place the color for selection
gridView.rows[i].style.background = '#9bc27e';
}
else if (gridView.rows[i].cells[0].getElementsByTagName("INPUT")[0].checked == false && i % 2 == 0)
{
// If its even then place white color back
gridView.rows[i].style.background = '#FFFFFF';
}
else
{
// If its odd place the bluish back on
gridView.rows[i].style.background = '#E3EAEB';
}
}
}
Any suggestions?
Thank you!!
I believe the problem is that you are using the ID of the element to identify it.
When you run this line:
var gridHeader = $('#<%=GridView1.ClientID%>').clone(true);
You create a 2nd table element with the same ID. Subsequent calls to that ID are not working as you expect.
I'd try the following to change the id of the cloned table you create:
var gridHeader = $('#<%=GridView1.ClientID%>').clone(true).attr('id', 'newID');

Dynamic width of Table as per column

I have one table which display data as from Dynamic Content, I want to make table width 100% when there is 6 cols. and table width auto if less the 5 cols.
I tried with CSS but, when there is only two cols, it expand two cols to full width while have table 100% width and looks awkward.
Is there any Javascript, jQuery script available to get this result?
Using jQuery and ensuring you choose the first row in the table body in case the thead has a different layout.
function setTableWidth(tableId) {
var $tbl = $('#'+tableId);
var newWidth = $tbl.find('tbody>tr:eq(0)>td').length > 5 ? '100%' : 'auto';
$tbl.width(newWidth)
}
Depending on how you're loading the dynamic content, there might be an easier way, but this function should do what you need:
function setTableWidth(tableId) {
myTable = document.getElementById('tableId');
if (myTable.getElementsByTagName('tr')[0].getElementsByTagName('td').length > 5)
myTable.style.width = '100%';
else
myTable.style.width = 'auto';
}
Note though, that it won't work if any of the cells in the first row have a colspan. It's simply counting the number of columns in the first row and setting the width based on that.

Categories