CSS changes on Scroll when using handsontable.js - javascript

im using a handsontable https://handsontable.com/ on a webpage.
var hot = new Handsontable(container, {
data: datatable,
colHeaders: true,
rowHeaders: true,
width: 600,
licenseKey: "non-commercial-and-evaluation",
});
Now I want to dynalically highlight some cells by changing it's background color. Like this:
var dataElements = document.querySelectorAll('.handsontable td');
if (row_attr == "ALL") {
for (var k = row * numberOfCols; k < (row + 1) * numberOfCols; k++) {
dataElements[k].style.backgroundColor = color;
}
}
Thia works fine but if a scroll further down on the page and go back up to that cell it is not colored anymore.
Is anyone familliar with the handsontable.js ?
I guess the table dynamically renders the part of the table that is displayed but I'm not sure.

Related

Google Documents AppScript - set cell border style for each side

i have a for loop adding rows and cells. I want these cells to have only bottom border, thickness 1pt and black color. What is the best way to do this? the documentation is lacking examples
for (var r = 0; r < rowdata.length; r++) { //loop through data for each row
var newrow = table.insertTableRow(1+r)
//add cells and values
var cell1 = newrow.appendTableCell(rowdata[r][0])
var cell2 = newrow.appendTableCell(rowdata[r][1])
//align cell text to center
var cellStyle = {};
cellStyle[DocumentApp.Attribute.HORIZONTAL_ALIGNMENT] = DocumentApp.HorizontalAlignment.CENTER;
cell1.getChild(0).asParagraph().setAttributes(cellStyle)
cell2.getChild(0).asParagraph().setAttributes(cellStyle)
//set bottom border line width to 1pt, line color to black
//set the other borders line width to 0pt
???
}
I believe your goal is as follows.
When the rows are appended, you want to set the bottom border as 1 pt width and black color, and want to set the other borders as 0 pt width.
In the current stage, it seems that unfortunately, the Google Document service (DocumentApp) cannot manage each border. But, fortunately, when Docs API is used, your goal can be achieved. In this answer, I would like to propose achieving your goal using Docs API. When your script is modified it becomes as follows.
Modified script:
Before you use this script, please enable Google Docs API at Advanced Google services.
function myFunction() {
var doc = DocumentApp.getActiveDocument(); // Please set your Document.
var body = doc.getBody();
var table = body.getTables()[0]; // Please set your table.
var rowdata = [[,,,],[,,,],,,]; // Please set your values.
// --- This is your showing script.
for (var r = 0; r < rowdata.length; r++) {
var newrow = table.insertTableRow(1 + r);
var cell1 = newrow.appendTableCell(rowdata[r][0]);
var cell2 = newrow.appendTableCell(rowdata[r][1]);
var cellStyle = {};
cellStyle[DocumentApp.Attribute.HORIZONTAL_ALIGNMENT] = DocumentApp.HorizontalAlignment.CENTER;
cell1.getChild(0).asParagraph().setAttributes(cellStyle);
cell2.getChild(0).asParagraph().setAttributes(cellStyle);
}
// ---
doc.saveAndClose();
var docId = doc.getId();
var i = body.getChildIndex(table);
var index = Docs.Documents.get(docId).body.content[i + 1].startIndex;
var requests = [{ updateTableCellStyle: { tableCellStyle: { borderRight: { dashStyle: "SOLID", width: { magnitude: 0, unit: "PT" }, color: { color: {} } }, borderLeft: { dashStyle: "SOLID", width: { magnitude: 0, unit: "PT" }, color: { color: {} } } }, tableStartLocation: { index }, fields: "borderRight,borderLeft" } }];
Docs.Documents.batchUpdate({ requests }, doc.getId());
}
When this script is run, several rows are appended to the table on Document, and the width of vertical borders is changed to 0 pt. By this, only the bottom borders are shown.
References:
Method: documents.get
Method: documents.batchUpdate
UpdateTableCellStyleRequest
Added:
From your following reply,
that is what i am looking for with one difference. The table i am appending to already has some rows that i want to remain unchanged concerning their border style. I want to apply your code to the newly added rows only!
When you wanted to reflect the above request body to the appended rows, how about the following modification?
In your showing script, you are using var newrow = table.insertTableRow(1 + r);. In this case, the rows are put from the 2nd row. Using this script, how about the following sample script?
Sample script:
function myFunction() {
var doc = DocumentApp.getActiveDocument(); // Please set your Document.
var body = doc.getBody();
var table = body.getTables()[0]; // Please set your table.
var rowdata = [[,,,],[,,,],,,]; // Please set your values.
// --- This is your showing script.
for (var r = 0; r < rowdata.length; r++) {
var newrow = table.insertTableRow(1 + r);
var cell1 = newrow.appendTableCell(rowdata[r][0]);
var cell2 = newrow.appendTableCell(rowdata[r][1]);
var cellStyle = {};
cellStyle[DocumentApp.Attribute.HORIZONTAL_ALIGNMENT] = DocumentApp.HorizontalAlignment.CENTER;
cell1.getChild(0).asParagraph().setAttributes(cellStyle);
cell2.getChild(0).asParagraph().setAttributes(cellStyle);
}
// ---
doc.saveAndClose();
var docId = doc.getId();
var i = body.getChildIndex(table);
var index = Docs.Documents.get(docId).body.content[i + 1].startIndex;
// I modified this request body.
var requests = [{ updateTableCellStyle: { tableCellStyle: { borderRight: { dashStyle: "SOLID", width: { magnitude: 0, unit: "PT" }, color: { color: {} } }, borderLeft: { dashStyle: "SOLID", width: { magnitude: 0, unit: "PT" }, color: { color: {} } } }, tableRange: { tableCellLocation: { tableStartLocation: { index }, rowIndex: 1 }, rowSpan: rowdata.length, columnSpan: rowdata[0].length }, fields: "borderRight,borderLeft" } }];
Docs.Documents.batchUpdate({ requests }, doc.getId());
}
When this script is run, the vertical lines are removed from the appended rows from the 2nd row.

Showing Progress while Child row loads

Coming again with another question :)
This time I had a requirement to show some progress while Child rows are being loaded. Since there is an Api call which relatively takes little time to return data, I do want to show the some progress unless the user who clicks the parent row is totally unaware whether there is a call done to see its child rows.
What I have done:
I wrote a style sheet class which has a
loader-small.gif
image as this:
tr.loading td.details-control {
background: url('/Images/loader-small.gif') no-repeat center center;
}
and applied like this:
$('#accountManagerEarningsDataTable tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
try {
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
//Calling the loading Class ------>
tr.addClass('loading');
// Open this row
var arrForTable1 = [];
var arrForTable2 = [];
totalBrokerage = 0;
totalRetailBrokerage = 0;
totalSelfServiceBrokerage = 0;
console.log('You selected: ' + row.data().AccountManagerID);
var settings = {
"columnDefs": [
{ targets: 1, align: "right", decimals: 0 },
{ targets: 2, align: "right", decimals: 0 },
{ targets: 3, align: "right", decimals: 0 },
{ targets: 4, align: "right", decimals: 2 },
{ targets: 5, align: "right", decimals: 2 }
]
};
//problems with asynchoronus call back
var response = organization_GetAccountManagerDetailEarningsAccountData(row.data(), purl2, pcontext);
if (response.success === "true") {
for (var i = 0; i < response.value.length; i++) {
for (var j = 0; j < response.value[i].Securities.length; j++) {
var itemRow2 = {};
itemRow2["Security ID"] = response.value[i].Securities[j].SecurityId;
itemRow2["Trades"] = response.value[i].Securities[j].Trades;
itemRow2["Buy Qty"] = response.value[i].Securities[j].BuyQuantity;
itemRow2["Sell Qty"] = response.value[i].Securities[j].SellQuantity;
itemRow2["Total Brkg"] = response.value[i].Securities[j].Effective_Brokerage;
itemRow2["Online Brkg"] = response.value[i].Securities[j].Online_Brokerage;
arrForTable2.push(itemRow2);
totalBrokerage = totalBrokerage + parseFloat(response.value[i].Securities[j].Effective_Brokerage);
totalSelfServiceBrokerage = totalSelfServiceBrokerage + parseFloat(response.value[i].Securities[j].Online_Brokerage);
}
totalBrokerage = Math.round(totalBrokerage * 100) / 100;
totalSelfServiceBrokerage = Math.round(totalSelfServiceBrokerage * 100) / 100;
totalRetailBrokerage = Math.round(totalRetailBrokerage * 100) / 100;
var itemRow1 = {};
itemRow1["Account ID"] = response.value[i].AccountId;
itemRow1["Account Name"] = response.value[i].AccountName;
itemRow1["..."] = '<div class="alert alert-info" role="alert">' + buildHtmlTable(arrForTable2, 'table2x' + j, settings) + '<p>Total Brokerage ' + numberWithCommas(totalBrokerage) + '</p></div>';
arrForTable1.push(itemRow1);
arrForTable2 = [];
totalBrokerage = 0;
totalRetailBrokerage = 0;
totalSelfServiceBrokerage = 0;
}
tr.removeClass('loading');
htmlTable1 = buildHtmlTable(arrForTable1, 'table1x' + i);
row.child(htmlTable1).show();
tr.addClass('shown');
}
else {
row.child('<table><tr><td>' + response.value[0].AccountId + '</td></tr></table>').show();
tr.addClass('shown');
};
}
} catch (e) {
console.log(e.message);
}
});
The Problem:
Firefox nicely shows the Progress image after the user clicks it, but Edge and Chrome does not show. Both browsers crossed this piece of code when I was debugging from developer tools of the respective browser.
Its browser compatible problem? Is there a solution for it? Help me please.
In case of chrome there is such an issue while showing the loading bar while making a server call. Please make the following changes where you are making the service call. First add the class loading to the table
tr.addClass('loading');
After that make the service call by giving a timeout function
setTimeout(function(){
var response = organization_GetAccountManagerDetailEarningsAccountData(row.data(), purl2, pcontext);
......
//Your service calls and response call backs
},1);
On providing a timeout (say 1ms), Chrome will get the time to bind the loading bar to DOM, In other case the DOM Object is not available to show the spinner.

flot legend, how to hide yet use the color tiles

I have custom legend for my flot plot, which i added check boxes to allow a user to turn the series on and off. The default legend has to be set to true in order for my legend to have color swatches. I am interested if there is a way to get rid of the default legend, yet retain the color swatches for my custom legend? Below are a few snippets to show what I am doing:
var options = {
legend: {
show: true,
container: legendcontainer,
noColumns: 2,
sorted: false
},
series: {
points: {
show: false
},
lines: {
show: true
}
},
grid: {
hoverable: true
},
xaxes: [{
axisLabel: 'Frequency (Hz)',
}],
yaxes: [{
axisLabel: 'Power (dB)',
}],
crosshair: {
mode: "xy",
color: 001,
lineWidth: .5
}
};
$.each(results, function(key, val) {
track = track + 1;
val.color = i;
++i;
l = val.label;
if (track == 1){
temp.append(row);
row.append(cell);
cell.append('Left Channel');
} else if(track == numtracks){
row = $('<tr/>');
temp.append(row);
cell = $('<td width=\"100\">');
row.append(cell);
cell.append('Right Channel');
} //else if ((track == 7) or (track == 14) or (track == 21) or (track == 28) or (track == 35)){
//}
cell = $('<td width=\"70\"/>');
row.append(cell);
var bar = $('<div style=\"width:18px; white-space:nowrap; float:left\"><bar />');
cell.append(bar);
var inp = $('<input name="' + l + '" id="' + l + '" type="checkbox" checked="checked">');
cell.append(inp);
var bits = $('<label>', {
text: l,
'for': l
});
cell.append(bits);
choiceContainer.append(temp);
I have tried sending the custom legend to a div that's non existent, and sending it to an arbitrarily small div, neither of which worked out. If I set the legend to 'false' then all the swatches go away, including the ones I am using in my custom legend. Below is an image of what I have currently rendered:
example http://skylinedrifter.homeip.net/2.0/tmp5.jpg
Thanks again for the expert communities help!
You have two options.
One, just hide the flot generated legend after you are done with building your legend. A simple:
$('.legend').hide();
should be all you need.
Two, since you are already 90% of the way there, just remove your need for the flot legend entirely. There's nothing fancy about the color 'tiles', just a div in a div in a td.
<td>
<div style="border:1px solid #ccc;padding:1px">
<div style="width:4px;height:0;border:5px solid rgb(175,216,248);overflow:hidden">
</div>
</div>
</td>
Just replace the rgb(175,216,248) with the color of the series. If you are letting flot auto assign the colors, you can get them from the plot object's series:
var colorArray = $.map(myPlot.getData(), function(s){return s.color});

Adding dgrids with variable widths to TabContainer

I'm populating a TabContainer with grids (Dojo 1.8, dgrid) that are showing the results of a query for different datasets. Each tab is the result of a single dataset. The different datasets will have a varying number of fields, so I'm dynamically building each grid and adding it to a ContentPane, which gets added to the TabContainer.
My current problem is seting the width of the grids when they are built. The datasets could have from two fields to upwards of 100 fields to be shown in the grid. I've set a default width in CSS for the grid of 600px, but the grid will only show the first six fields of the dataset. If I set the width to "auto", it is only as wide as the TabContainer, removing the scroll bar and cutting off the data. Is it possible to set a width for each grid separately?
This is what the result looks like
This is the code for populating the TabContainer
function buildColumns(feature) {
var attributes = feature.attributes;
var columns = [];
for (attribute in attributes) {
if (attribute != "Shape") {
var objects = {};
objects.label = attribute;
objects.field = attribute;
columns.push(objects);
}
}
return columns;
}
function populateTC(results, evt) {
try {
if (dijit.byId('tabs').hasChildren) {
dijit.byId('tabs').destroyDescendants();
}
if (results.length == 0) {
console.log('Nothing found.');
return;
}
var combineResults = {};
for (var i = 0, len = results.length; i < len; i++) {
var result = results[i];
var feature = result.feature;
var lyrName = result.layerName.replace(' ', '');
if (combineResults.hasOwnProperty(lyrName)) {
combineResults[lyrName].push(result);
}
else {
combineResults[lyrName] = [result];
}
}
for (result in combineResults) {
var columns = buildColumns(combineResults[result][0].feature);
var features = [];
for (i = 0, len = combineResults[result].length; i < len; i++) {
features.push(combineResults[result][i].feature);
}
var data = array.map(features, function (feature) {
return lang.clone(feature.attributes);
});
var dataGrid = new (declare([Grid, Selection]))({
id: "dgrid_" + combineResults[result][0].layerId,
bufferRows: Infinity,
columns: columns,
"class": "resultsGrid"
});
dataGrid.renderArray(data);
dataGrid.resize();
dataGrid.on(".dgrid-row:click", gridSelect);
var cp = new ContentPane({
id: result,
content: "<b>" + combineResults[result][0].layerName + "\b",
//content: dataGrid,
title: combineResults[result][0].layerId
}).placeAt(dijit.byId('tabs'));
cp.addChild(dataGrid);
cp.startup();
cp.resize();
}
tc.startup();
tc.resize();
map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));
}
catch (e) { console.log(e.message); }
}
The problem is not with the grid width, it's the column widths. They fit the container.
If you give a column a fixed width, you will get the desired effect.
You should be able to style .dgrid-cell or .dgrid-column-[index]
I've also had a need for more control depending on the column data. You can control the style by providing a column with its own renderHeaderCell and renderCell method as well. (style refers to dom-style)
renderHeaderCell: function(node) {
style.set(node, 'width', '50px');
}
renderCell: function(object, value, node) {
style.set(node, 'width', '50px');
}
I was able to use the AddCssRule to dynamically change the size of the grids
var dataGrid = new (declare([Grid, Selection]))({
id: "dgrid_" + combineResults[result][0].layerId,
bufferRows: Infinity,
columns: columns,
"class": "resultsGrid"
});
dataGrid.renderArray(data);
var gridWidth = "width: " + String(columns.length * 100) + "px";
dataGrid.addCssRule("#" + dataGrid.id, gridWidth);
dataGrid.resize();
dataGrid.refresh();
Here is a Fiddle that shows the result. Click on a colored polygon to show the different grids (although the content is sometimes being shoved into the header of the grid). Also, the tabs aren't being rendered correctly, but there should be 0, 224, and 227 (if you also clicked on a point).

JQuery Gridster with HTML/Javascript Windows 8 Store App

I decided to create my first windows store app with html/javascript and since you cannot do drag and drop with javascript and listview i have looked for alternatives. Windows store apps support jquery so I found Gridster. It is a jquery plugin to display stuff in a grid with draggable reordering. Each item can be resized as well. I want to use this in my windows store app. Here is a fiddle of the code i inputted into blend, into the html page
var layout;
var grid_size = 100;
var grid_margin = 5;
var block_params = {
max_width: 6,
max_height: 6
};
$(function() {
layout = $('.layouts_grid ul').gridster({
widget_margins: [grid_margin, grid_margin],
widget_base_dimensions: [grid_size, grid_size],
serialize_params: function($w, wgd) {
return {
x: wgd.col,
y: wgd.row,
width: wgd.size_x,
height: wgd.size_y,
id: $($w).attr('data-id'),
name: $($w).find('.block_name').html(),
};
},
min_rows: block_params.max_height
}).data('gridster');
$('.layout_block').resizable({
grid: [grid_size + (grid_margin * 2), grid_size + (grid_margin * 2)],
animate: false,
minWidth: grid_size,
minHeight: grid_size,
containment: '#layouts_grid ul',
autoHide: true,
stop: function(event, ui) {
var resized = $(this);
setTimeout(function() {
resizeBlock(resized);
}, 300);
}
});
$('.ui-resizable-handle').hover(function() {
layout.disable();
}, function() {
layout.enable();
});
function resizeBlock(elmObj) {
var elmObj = $(elmObj);
var w = elmObj.width() - grid_size;
var h = elmObj.height() - grid_size;
for (var grid_w = 1; w > 0; w -= (grid_size + (grid_margin * 2))) {
grid_w++;
}
for (var grid_h = 1; h > 0; h -= (grid_size + (grid_margin * 2))) {
grid_h++;
}
layout.resize_widget(elmObj, grid_w, grid_h);
}
});​
The js references and css can be seen in the source here (where i got the code)
http://jsfiddle.net/maxgalbu/UfyjW/show
I got it working and can drag the boxes around and reorder and resize them...my issue now is how to get it to expand horizontal instead of vertically..the more stuff i put into it, they all go to the bottom. I would like it to expand to the right as new items get added (like the start menu)...it would be perfect if i could turn the grid counter clockwise and keep the items the same orientation..but i know it may not be that easy
i have tried changing some values in the script (in the above code sample) in the html and got some more columns for the boxes to snap to..but eventually they all just revert to snapping to the bottom of one of the first columns...do i have to edit the referenced js files? There's like 4 of them, which one?

Categories

Resources