How to add Handler on Cell in Google Visualization Table in GWT? - gwt

Google Visualization API for GWT provides control over rows only.
How to get control over a particular cell in Visualization Table?
selection.isCell() doesn't give true result in any case.
private SelectHandler createSelectHandler(final PieChart chart) {
return new SelectHandler() {
#Override
public void onSelect(SelectEvent event) {
String message = "";
// May be multiple selections.
JsArray<Selection> selections = chart.getSelections();
for (int i = 0; i < selections.length(); i++) {
// add a new line for each selection
message += i == 0 ? "" : "\n";
Selection selection = selections.get(i);
if (selection.isCell()) {
// isCell() returns true if a cell has been selected.
// getRow() returns the row number of the selected cell.
int row = selection.getRow();
// getColumn() returns the column number of the selected cell.
int column = selection.getColumn();
message += "cell " + row + ":" + column + " selected";
} else if (selection.isRow()) {
// isRow() returns true if an entire row has been selected.
// getRow() returns the row number of the selected row.
int row = selection.getRow();
message += "row " + row + " selected";
} else {
// unreachable
message += "Pie chart selections should be either row selections or cell selections.";
message += " Other visualizations support column selections as well.";
}
}
Window.alert(message);
}
};
}

Google Table has 4 events: ready,select,page,sort.
When you sort or paginate, it stops listening the ready event.
To have the cell click working after pagination or sort you need to add the click listener on all of them.
You can use click instead of mouseover.
On select event I use getSelection to be able to get and set the selected row properties.
var colIndex;
google.visualization.events.addListener(table, 'ready', function () {
$("#table").find("td").each(function() {
$(this).mouseover(function(){
colIndex=$(this).index();
});
});
});
google.visualization.events.addListener(table, 'sort', function () {
$("#table").find("td").each(function() {
$(this).mouseover(function(){
colIndex=$(this).index();
});
});
});
google.visualization.events.addListener(table, 'page', function (event) {
$("#tableGoogle").find("td").each(function() {
$(this).mouseover(function(){
colIndex=$(this).index();
});
});
});
google.visualization.events.addListener(table, 'select', function () {
var selection = table.getSelection();
var item;
if(selection.length!=0){
lastSelection=selection;
}
for (var i = 0; i < lastSelection.length; i++) {
item = lastSelection[i];
}
switch (colIndex){
case 0:
data.setValue(item.row,index,true);
// YOUR CODE FOR COLUMN 0
break;
case 1:
var id=data.getRowProperty(item.row, 'id');
// YOUR CODE FOR COLUMN 1
break;
}
});

The Table Visualization does not pass column information in the selection event, so you cannot identify an individual cell this way. You will need to register a click event handler on the cells of the table and then determine the cell's row and column indices. Here's one way to do it using jQuery:
google.visualization.events.addListener(table, 'ready', function () {
$('#table_div td').click(function () {
var column = $(this).index();
var row = $(this).parent().index() - 1; // subtract 1 for the table header
console.log(row, column);
});
});
You'll have to adapt the event handler to the method used in the GWT Viz API package, but the jQuery code should work.

var rowIndex;
var colIndex;
google.visualization.events.addListener(table, 'ready', function () {
jQuery("#table").on("click", "td:not(.google-visualization-table-th)", function() {
colIndex = jQuery(this).index();
rowIndex = jQuery(this).parent().index() - 1;
alert("row "+rowIndex+" col "+colIndex);
//put rest of function here
});
This gets rowindex based on the row of the html. To get the rowindex based on the data (where the row's index won't change even if you sort the table and it's position changes) use
google.visualization.events.addListener(table, 'select', function() {
var selected=table.getChart().getSelection();
var item=selected[0];
rowIndex=item.row;
});
This will run before the code in the .on("click", ...) function in the ready function.

Related

Word Addin is getting crashed when trying to delete a row which contains a content control in a table

I'm developing a Word Add-in (Word API + Office.js) where i am working with content controls, I am trying to read the table content inside a content control where I need remove the empty rows
Sample: I have this table inside a content control I have to remove the blank rows
i am able to achieve this functionality with this code, but if the table contains a content control which is blank then when i try to delete that row the addin itself is getting crashed.
function checktable(element) {
Word.run(function (context) {
// Queue a command to get the current selection and then
// create a proxy range object with the results.
var contentControl = context.document.contentControls.getByTag('control1').getFirst();
var table = contentControl.tables.getFirst();
context.load(contentControl, 'tables');
table.load('values');
return context.sync()
.then(function () {
// Get the longest word from the selection.
if (contentControl.tables.items.length === 0) {
document.getElementById('lblstatus').innerText += "No Tables found";
}
else {
document.getElementById('lblstatus').innerText += " Tables found";
var Tablevaules = table.values;
for (var i = 0, len = Tablevaules.length; i < len; i++)
{
var nullcheck = "";
var inner=Tablevaules[i];
// inner loop applies to sub-arrays
for (var j = 0, len2 = inner.length; j < len2; j++) {
// accesses each element of each sub-array in turn
if (inner[j] == "") {
if (nullcheck != "False") {
nullcheck = "True";
}
}
else {
nullcheck = "False";
}
}
if (nullcheck == "True") {
table.deleteRows(i);
}
}
}
})
.then(context.sync)
.then(function () {
// Queue a command to highlight the search results.
document.getElementById('lblstatus').innerText += element + ":" + "Successs";
});
})
.catch(errorHandler);
}
Please let me know whether i am missing something or its a known bug!!

Problem inserting checkbox in select using DataTables

I'm looking for a way to insert a checkbox into a select and fetch each column individually, all using DataTables. I found an excellent example in https://jsfiddle.net/Lxytynm3/2/ but for some reason, when selecting all records, filtering does not display the data as expected. Would anyone have a solution to work properly?
Thanks in advance.
The link application code is as follows:
$(document).ready(function() {
function cbDropdown(column) {
return $('<ul>', {
'class': 'cb-dropdown'
}).appendTo($('<div>', {
'class': 'cb-dropdown-wrap'
}).appendTo(column));
}
$('#example').DataTable({
initComplete: function() {
this.api().columns().every(function() {
var column = this;
var ddmenu = cbDropdown($(column.header()))
// -------------------------------------------------------
.on('change', ':checkbox', function() {
var active;
var vals = $(':checked', ddmenu).map(function(index, element) {
active = true;
return $.fn.dataTable.util.escapeRegex($(element).val());
}).toArray().join('|');
column
.search(vals.length > 0 ? '^(' + vals + ')$' : '', true, false)
.draw();
// -------------------------------------------------------
// Highlight the current item if selected.
if (this.checked) {
$(this).closest('li').addClass('active');
// If 'Select all / none' clicked ON
if ($(this).val() === "1") {
$(ddmenu).find('input[type="checkbox"]').prop('checked', this.checked)
//$(".cb-dropdown li").prop('checked', true);
//$('.cb-dropdown').closest('li').find('input[type="checkbox"]').prop('checked', true);
// $('this input[type="checkbox"]').prop('checked', true); works!
// $( 'input[type="checkbox"]' ).prop('checked', this.checked);
// $(this).find('input[type="checkbox"]').prop('checked', this.checked)
//$('div.cb-dropdown-wrap.active').children().find('input[type="checkbox"]').prop('checked', this.checked)
}
} else // 'Select all / none' clicked OFF
{
$(this).closest('li').removeClass('active');
// test if select none
if ($(this).val() === "1") {
// code to untick all
$(ddmenu).find('input[type="checkbox"]').prop('checked', false)
}
}
// Highlight the current filter if selected.
var active2 = ddmenu.parent().is('.active');
if (active && !active2) {
ddmenu.parent().addClass('active');
// Change Container title to "Filter on" and green
//$(this).parent().find('.cb-dropdown li:nth-child(n+1)').css('color','red');
$('active2 li label:contains("Filter OFF")').text('Yeees');
} else if (!active && active2) {
ddmenu.parent().removeClass('active');
}
});
// -------------------------------------------------------
var mytopcount = '0'; // Counter that ensures only 1 entry per container
// loop to assign all options in container filter
column.data().unique().sort().each(function(d, j) {
// Label
var $label = $('<label>'),
$text = $('<span>', {
text: d
}),
// Checkbox
$cb = $('<input>', {
type: 'checkbox',
value: d
});
$text.appendTo($label);
$cb.appendTo($label);
ddmenu.append($('<li>').append($label));
// -----------------
// Add 'Select all / none' to each dropdown container
if (mytopcount == '0') // Counter that ensures only 1 entry per container
{
$label = $('<label>'), $text = $('<span>', {
text: "Select all / none"
}),
$cb = $('<input>', {
type: 'checkbox',
value: 1
});
$text.prependTo($label).css('margin-bottom', '6px');
$cb.prependTo($label);
ddmenu.prepend($('<li>').prepend($label).css({
'border-bottom': '1px solid grey',
'margin-bottom': '6px'
}));
mytopcount = '1' // This stops this section running again in cotainer
}
});
});
}
});
});
It seems as though the issue was with the select all checkbox. One solution would be to check for "1" within the vals initialisation, this seems to work:
var vals = $(':checked', ddmenu).map(function(index, element) {
if($(element).val() !== "1"){
return $.fn.dataTable.util.escapeRegex($(element).val());
}
}).toArray().join('|');
That should see you with some results upon the top checkbox being checked. Hope that helps.

How can I export AgGrid data in case of infinite row model (infinite scrolling) in react

How can I export AgGrid data in case of infinite row model (infinite scrolling) in react.
For the normal row models it is being done in this way:
this.gridOptions.api.exportDataAsCsv(params);
What about infinite row model case?
Here is the solution that I've implemented.
Grid footers, multiple headers is not considered here.
This code is for simple grid with headers and rows under it.
In case of infinite scrolling and dynamic columns (in some cases columns can be changed).
var LINE_SEPARATOR = '\r\n';
var COLUMN_SEPARATOR = ',';
var fileName = 'export.csv';
let csvString = '';
let columnsToExport = this.gridOptions.api.columnController.getAllDisplayedColumns();
// adding column headers.
columnsToExport.map((column) => {
csvString+= column.colDef.headerName;
csvString+= COLUMN_SEPARATOR;
});
csvString+= LINE_SEPARATOR;
// adding content of data currently loaded in the grid.
this.gridOptions.api.forEachNode( function(node) {
node.columnController.allDisplayedColumns.map((column) => {
let cellContent = node.valueService.getValue(column, node);
csvString+= (cellContent != null) ? cellContent : "";
csvString+= COLUMN_SEPARATOR;
});
csvString+= LINE_SEPARATOR;
});
// for Excel, we need \ufeff at the start
var blobObj = new Blob(["\ufeff", csvString], {
type: "text/csv;charset=utf-8;"
});
// Internet Explorer
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blobObj, fileName);
}
else {
// Chrome
var downloadLink = document.createElement("a");
downloadLink.href = window.URL.createObjectURL(blobObj);
downloadLink.download = fileName;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}

How to block the execution until function returns value?

In protractor, I'm trying to fetch the text of a button from a collection of buttons and based on the button returned perform some action on the item returned
/**
* Function to return the element button with matching text
* #param {buttonsObject} element which matches multiple button objects.
* #param {buttonTextToSearch} button text which can be found in a collection of button objects.
* #return {buttonObject} this will retrun the button object which matches the text being searched for.
*/
var buttons = function(buttonsObject, buttonTextToSearch) {
var obj = buttonsObject.then(function(buttonElements) {
//Iterate each button object and populate the array with the resulting object
var foundbuttons = buttonElements.map(function(item) {
return item.getText().then(function(text) {
if(text.length > 0 && text.charCodeAt(0) !== 32 && text == buttonTextToSearch) {
console.log('new text: '+ text);
return item;
}
});
});
//Wait until var foundbuttons is populated
return protractor.promise.all(foundbuttons).then(function(allButtons){
return allButtons.reduce(function(all, item, index) {
if(item !== undefined && item !== '' && item !== ' ') {
console.log('item !== undefined '+ item);
item.getText().then(function(text) {
console.log('REDUCE '+ text);
});
all.push(item);
}
return all;
}, []);
});
});
//Wait until var obj is populated and return the element at 0th index.
return protractor.promise.all(obj).then(function(obj1) {
return obj1[0];
});
}
var BTN_OBJS = element.all(by.css('[ng-hide=multiEditMode] [class*=button]'));
//Get element matching button text 'My Order'
var btn = buttons(BTN_OBJS, 'My Orders');
btn.then(function(args) {
console.log('args '+ args);
});
Now when I'm executing the above piece of code snippet, the below line
buttons(BTN_OBJS, 'My Orders');
executes much ahead, even before the below function returns any value
btn.then(function(args) {
console.log('args '+ args);
});
PS: I'm new to protractor and hence ignore my poor knowledge and also any typos.

Autocomplete with multiple value

I am using autocomplete which returns ID and Value, when i am selecting the item from autocomplete drop down the ID part, i am saving in hidden field, but suppose if item is there but i am not selecting from drop down simply i am writing whole text into autocomplte text box the ID is not saved into hidden field(it should not be) but i want that so please provide some hint to accomplish that.
function AutoComplete(id, url) {
$(item).focus().autocomplete(url, {
dataType: 'json',
parse: function (data) {
var rows = new Array();
for (var i = 0; i < data.length; i++) {
rows[i] = { data: data[i], value: data[i].ID, result: data[i].Name };
}
return rows;
},
formatItem: function (row, i, n) {
return row.Name;
}
}).result(function (evt, data, formatted) {
$(hiddenfield).val(data.ID)
});
}
Try this demo here with Autcomplete with multiple selection.
[http://jsfiddle.net/jcxbgomd/][1]