Get coordinates with handsontable wider than the screen - javascript

I have a grid with handsontable but this grid is wider than the screen. Here is a capture of what it looks like :
As you can see, I have a scroll bar because the grid is too wide.
The user insert some data in this grid and I make a request in ajax to test the content (required field, numeric field, ...) When there is an error, I return a number to know which cell is incorrect. I use this number like that :
$(cells).eq(jsonobject[item]-11).css("background-color","red");
With the .eq function I can select the cell I want. But when the grid is wider than the screen, I feel that the index of each cell is moved.
Here is a wonderful sketch of what I think :
So the indexes are dependants of the screen but not of the grid.
How can I overcome this problem please ?
EDIT :
The code where I declare my hot :
var container = document.getElementById('tab_traitement');
var hotTraitement = new Handsontable(container, {
data: data_traitement,
stretchH: 'all',
minSpareRows: 1,
observeChanges : true,
rowHeaders: false,
colHeaders: false,
contextMenu: true,
height: 550,
... //more options
In the ajax return, I get an array of values with some indexes where the data is incorrect and I try to color the cell in question. So I tried like that :
for(var i=1; i<(data_traitement[0].length);i++ )
{
for(var item in jsonobject)
{
if((item % 2 ) == 0) //Si l'indice est pair, on affiche la couleur
{
hotTraitement.getCell(i,jsonobject[item]-j).css("background-color","red"); //Here, firebug tells me "hotTraitement is undefined"
}else
{
$(cells).eq(jsonobject[item-1]-1).qtip({
content : '<div id="bulle">'+jsonobject[item]+'</div>',
position: {
adjust: {
x: -100
}
},
style: {
classes: 'myCustomClass',
def: false
}
});
}
}
j = j+3; //Just to loop through the rows (I have 3 cells in a row)
}

Well to start off, there's virtual rendering happening horizontally meaning that if you were to have a table with many many columns, most aren't being rendered therefore jquery will never find them.
Now, to do this more efficiently, I would simply get the cell using the HOT methods included:
hot.getCell(row,col);
This returns to you the TD after which you could attempt to do the css like you were asking.
I don't think this would be the best way to go, however, because physically modifying the DOM doesn't work well with Handson given that it re-renders pretty frequently. Instead, you should be setting the custom renderers on each cell to respond to your validation efforts. A simplistic solution is to have an array with cell coordinates which should be marked as "invalid". The custom renderer could then ask if the current cell coordinates are in this array and if so, apply your css logic as you did above.
And just FYI, Handson has wonderful validation functionality built in which I highly recommend using. It will apply a class name for you if it fails validation so there wouldn't even be a need to do any fancy cell finding, just add the class you want and in your CSS file attach whatever style you want.

Related

Pagination on filtered rows — Resetting original data set — jQuery Datatables

This is a problem I had with jQuery Datatables that I really don't know why it is happening in the first place!
I have multiple select elements which all filters the original data set. I do the filtering logic on the select change event.
This my Datatables init (using state saving, from the documentation) :
var table = $('#orders-listing').DataTable({
bStateSave: true,
bFilter:true,
paging: true,
bPaginate:true,
language: { url: /* Language File URL */ },
fnStateSave: function(oSettings, oData){
localStorage.setItem('DataTables_'+window.location.pathname, JSON.stringify(oData));
},
fnStateLoad: function(oSettings){
return JSON.parse(localStorage.getItem('DataTables_'+window.location.pathname));
}
});
And this is my filtering logic on the select change event:
$('.filter-select').on('change', function() {
$.fn.dataTable.ext.afnFiltering.push(
function(settings, data, dataIndex) {
// Some logic, return a boolean, wether we keep the row being processed or not.
}
);
table.draw();
$.fn.dataTable.ext.afnFiltering.pop();
});
Now, the filtering works fine. The rows, pagination links, everything changes accordingly.
But, once I click on the 2nd link on the pagination links, the original dataset returns.
Example: I had 200 rows in the first place, after filtering, it was reduced to 150 (So 50 rows were filtered, and removed from the original dataset), then once I click on the second link on the pagination, the original dataset returns, with the first 200 rows.
What am I missing here ? What is causing the original dataset to return when paginating ?
Any help is greatly appreciated. Thanks.
You're doing $.fn.dataTable.ext.afnFiltering.pop() immediately after drawing the table with draw() which removes your custom filter and it will no longer be applied if table is sorted, page is changed, etc.
Try adding $.fn.dataTable.ext.afnFiltering.pop() before $.fn.dataTable.ext.afnFiltering.push() to remove previous custom filter only on filter change but before adding a new filter.

Force frozen column row to resize with handsontable

I have some javascript that changes the content of certain cells in a handsontable grid.
The issue I have found is that when I change the content of one of the cells the frozen column rows don't change accordingly.
Is there a function that can be run to check the sizes of each row and resize accordingly?
I have a Jsfiddle which shows the issue:
http://jsfiddle.net/JammyDodger231/145bL7ej/
var myData = Handsontable.helper.createSpreadsheetData(4, 20);
hot = new Handsontable(container, {
data: myData,
rowHeaders: true,
colHeaders: true,
fixedRowsTop: 2,
fixedColumnsLeft: 2
});
//Hardcoded just to show issue, this isnt where the content would be changed
$('.htCore tbody tr:nth-child(2) td:nth-child(5)').html("Test <br /><br />");
Your problem is that you should NEVER manually change content or CSS on the table that Handsontable renders for you. It is a stateless table which will get overriden as soon as you make any changes that triggers a change event. Read this answer to get a more detailed description:
CSS applied on Handsontable grid row on Scroll is not working properly
What you should be doing instead is using the methods that Handsontable supplies to you. In your case, you can use hot.setDataAtCell(row, col, value). You could also directly change myData since Handson uses a reference to it. Anything but manually changing the DOM.

How to programmatically disable cells in a Ext.grid.EditorGridPanel

I have a web application that uses ExtJS 4 that incorporates a Ext.grid.EditorGridPanel.
One of the columns of the Ext.grid.EditorGridPanel has a combobox editor that I would like to disable programmatically when the store loads based on the value of another field in the store.
It seems like this should be pretty simple - but so far nothing seems to work.
When the Grid's store loads, I have a listener to check each row and disable the combobox in index 4 depending on the value of another field.
The only thing that I can't get to work is actually disabling the combobox.
Any suggestions?
Here is the psuedo-code. Thanks in advance
listeners: {
'load': function(st, records, options) {
var view = getMyEditorGridPanel().getView();
for (var i = 0; i < this.getCount(); i++) {
if (store.getAt(i).get('setDisabled') === 'Y') {
//The cell at index 4 has a combobox editor - I CAN'T GET IT TO DISABLE!!
view.getCell(i,4).setDisabled(true);
}
}
}
From my point of view you have two different things you need to manage here:
Cell Styling, the way a cell looks when not being edited (either is enabled or disabled)
Editor Availability, how to react when a cell is about to be edited (should be possible to edit the cell)
Cell Styling
For the first one I would advice to provide a style to each cell in order to make it look disabled, this can be achieved during rendering time instead trying to do it when the store loads (btw nothing ensures you that the grid items have been fully rendered just after getting the load event callback). You can return a custom class per row by providing an implementation to Ext.grid.ViewView.getRowClass
viewConfig: {
getRowClass: function(record, rowIndex, rowParams, store) {
return record.get("disabled") ? "mail-disabled" : "";
}
}
Editor Availability
You will also need to handle the Ext.grid.plugin.CellEditingView.beforeedit event and provide a custom logic to determine when the editor will be available
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1,
listeners: {
beforeedit: function(editor, e, eOpts) {
return e.record.get("disabled") == false;
}
}
})]
You can find a working example of both solutions here, hope it helps to solve your problem.

Resize a <div> within a <td> and affect it to multiple cell

Context
I've got a < table > with column headers that may represent different kinds or states of an object (for example, let's say that it could be animals or people). Row headers represent some characteristics of objects.
In another div in the page, I've got a list of instances (some representing animals or people). I use drag and drop (using JQuery) to put them in cells of my table. After a < div> has been dropped in a < td>, until I left the page (submit the form), I'm still be able to drag it to another < td > (in case I made a mistake and place it to the wrong cell).
The problem
Now, I would like to make my dropped object resizable to fill rows that is adjacent to it (for instance, to give him more than one characteristic). Also, after the resize action, the object must retain draggable in another cell keeping it's new size (which represent characteristics).
I can't find a way to do deal with the resize action to do what I would like to do.
How can I do that with html, javascript and/or Jquery?
Edit:
An example of my current code: http://jsfiddle.net/B99KY/13/ (sorry if the js it's not very clean). I can drag element but I don't know how to handle resize action to do what I'm trying to achieve.
var resizableHandler = {
handles: "s",
start: function(e, ui) {
console.log('resizing started');
},
resize: function(e, ui) {
},
stop: function(e, ui) {
console.log('resizing stopped');
}
}
For example, if I put "instance 1" in cell [charecteristic1, state1] and after that, I resize "instance 1" to fill charecteristic2 and charecteristic3, I would like to have "instance 1" which fill completely the news cell (to use them later after submit of this tab).

SDK2: checkboxes in a RallyGrid column?

I'd like to add a column with checkboxes in a rally grid (something like "Select Default"). It looks like that should be pretty simple using the 'checkcolumn' xtype. But that requires you to link in some additional extjs styles, and I'm not sure how to do that within the Rally extjs framework:
Extjs 4 checkcolumn not visible
Here's an example of such a column in ext-js: http://dev.sencha.com/deploy/ext-3.4.0/examples/grid/edit-grid.html
Is there a way do this with a Rally grid?
I ended up using a quick and dirty solution based on the anwser below:
{text: 'Default', dataIndex:'selected', align: 'center', width: 50, renderer: function(value, style, item, rowIndex) {
return "<input type='radio' name='primaryIndex' alt='"+ rowIndex + "' " + (value ? "checked='checked'" : "") + ">";
}},
AND:
checkRadioClick: function(event) {
var button = event.getTarget('input[type="radio"]');
if (button) {
...
Currently Ext's grid (which the Rally grid extends) doesn't support a checkbox column. The closest thing that comes out of the box is the Boolean column:
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.grid.column.Boolean
This is because the grid expects you to have to click a cell to initiate an edit and a checkbox column is immediately editable without that action.
That given, I think you should be able to render a checkbox column by simply specifying a renderer for that column in your column config. It may be a little challenging to get the values back out of the grid when they change though since the values will not have been committed to the underlying records in the store (because no actual edit was triggered).
There is also a user submitted CheckColumn here that you may be able to use or at least as an example to get started:
http://docs.sencha.com/ext-js/4-1/source/CheckColumn.html#Ext-ux-CheckColumn
Maybe this is new with one of the newer preview versions? I did this:
Ext.create( 'Rally.ui.grid.Grid', {
selType: 'checkboxmodel',
selModel: {
injectCheckbox: 1,
mode: 'SIMPLE',
listeners: {
selectionchange: function( model, selected ) {
// do stuff
},
scope: this
}
}

Categories

Resources