Very simple question: how do I access Handsontable.Dom.addEvent when using jquery

1,737 views
Skip to first unread message

Justin Robinson

unread,
May 4, 2015, 8:44:47 AM5/4/15
to handso...@googlegroups.com
There are lots of holes in the jquery and certainly Handsontable knowledge, I've been using Handsontable for a few hours. I'm rushing to finish a POC.
var hotInstance = $("#hot").handsontable('getInstance');
hotInstance.Dom.addEvent doesn't work

The api has doesn't have a Dom or addEvent that I can access with $("#hot").handsontable( ... ) 

Lukazar

unread,
May 4, 2015, 2:51:31 PM5/4/15
to handso...@googlegroups.com
What exactly are you trying to accomplish? HOT might support something intrinsically you're trying to do, but its hard to tell from the description.

Justin Robinson

unread,
May 4, 2015, 6:28:56 PM5/4/15
to handso...@googlegroups.com, luke....@getalma.com
I'd like to link the save button to a function similar to the afterChange that only sends a GET of the changed rows.
But for starters I just wanted to know how to add an event to the save button (I suppose I could use jquery ui)

I also have an issues with the fact that I need to use an array of arrays in order to enable add column but when I send changes to the server they need to be json. So was using buildArrayFromObjs in the pager (server side paging page size 100 0000 rows - 10 pages) Then using the index on the array of arrays to look up the object in the original array - but there must be an easier way (besides I also have a the search obviously cases issues with that - though I haven't read all the docs yet there was something about index mapping somewhere).

All that I imagine I'll figure out in time. Though if you have any off the top of your head advice that would be cool.

Otherwise should I just use jquery ui for button clicks instead of Handsontable.Dom.addEvent ?

<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<title>Handson</title>
<link rel="stylesheet" href="lib/enhancementpager/libs/dropkick.css"
type="text/css" />
<link rel="stylesheet"
href="lib/enhancementpager/libs/enhancementpager.css" type="text/css" />

<!-- this version of jquery is needed for enhancementpager - server-side paging -->
<script src="lib/enhancementpager/jquery-1.7.min.js"></script>
<script type="text/javascript"
src="lib/enhancementpager/libs/jquery.json-2.3.min.js"></script>
<script type="text/javascript"
src="lib/enhancementpager/libs/jquery.dropkick-1.0.0.js"
charset="utf-8"></script>
<script type="text/javascript"
src="lib/enhancementpager/enhancementpager.js"></script>

<link rel="stylesheet" media="screen"
href="lib/dist/handsontable.full.css">
<link rel="stylesheet" media="screen"
href="lib/dist/css/samples.css?20140331">
<script src="lib/js/jquery.min.js"></script>
<script type="text/javascript">
var jQuery = $.noConflict(true);
</script>
<script src="lib/dist/handsontable.full.js"></script>

<script>
jQuery(function() {

var container = jQuery('#table'), 
autosave = jQuery('#autosave'), 
save = jQuery('#save'), 
autosaveNotification,
dataChanged;
    
      //transform array of objects into array of arrays to allow col add on obj ds
    var buildArrayFromObjs = function(dataObjsArr){
var 
dataArray = [], cycle =0;
for(var i in dataObjsArr){
    cycle++;
    var objRow = dataObjsArr[i];
if (objRow) {
var arrayRow = [];
for(var prop in objRow){
arrayRow.push(objRow[prop]);
}
dataArray.push(arrayRow);
}
    }
var paramObj = {
container : jQuery("#pager"),
remoteUrl : "/list",
table : jQuery("#table"),
pagerType : "", //type of the Enhancement Pager, set "slider" - which doesn't seem to work
waiting : 5000
//set ajax timeout
//params: obj,   //other params for http post
};

//modified to ingregrate server side paging
var pager = new Slick.Controls.EnhancementPager(paramObj);
var loadSearchResults = function(results) {
jQuery('#table').handsontable('loadData', results);
   return results;
}
var getRow = function(rowIndex, handsonDataObjects){
var handsonDsRow = jQuery('#table').handsontable('getSourceDataAtRow', rowIndex);
console.log("getSourceDataAtRow: "+JSON.stringify(handsonDsRow));
var objectRow = handsonDataObjects[rowIndex];
console.log("handsonDataObjects[rowIndex]: "+JSON.stringify(objectRow));
return objectRow;
};

container
.handsontable({
colWidths : [ 55, 80, 80, 80, 80, 80, 80 ], //can also be a number or a function
rowHeaders : true,
colHeaders : true,
fixedColumnsLeft : 1,
fixedRowsTop : 1,
minSpareRows : 1,
colHeaders : [ "id", "col1", "col2", "col3", "col4",
"col5", "col6" ],
contextMenu: true,
// change: 10,col3,253,555
//changed gives row index not record, need to send whole record
afterChange : function(change, source) {
console.log("afterchange: change: "
+ JSON.stringify(change) + ", source: "
+ JSON.stringify(source));
if (change === null) {
console.log("change === null not auto saving");
return;
}else{
dataChanged = change;
}
//need a better for to send data to the server an array of arrays is messy
var rowdata = getRow(change[0][0], paramObj.handsonDataObjects);
if(!autosave.prop("checked")){
console.log("autosave not checked, not auto saving");
return;
}
clearTimeout(autosaveNotification);
jQuery.ajax('/save?data='+JSON.stringify(rowdata), 'GET', function(data) {
console.log('Autosaved (' + change.length + ' '
+ 'cell' + (change.length > 1 ? 's' : '')
+ ')');
autosaveNotification = setTimeout(function() {
console.log('Changes will be autosaved');
}, 1000);
});
},
manualColumnMove : true,
manualColumnResize : true,
groups : [ {
rows : [ 0, 4 ]
}, {
rows : [ 5, 7 ]
} ],
  columnSorting: true
/*persistentState: true */
});

         jQuery('#searchgrid')
.on(
'keyup',
function(event) {
var searchStr = ('' + this.value).toLowerCase(), row, col, r_len, c_len, td, cycle = 0, noMatchCnt = 0;
//search through full page's data
var data = paramObj.handsonDataArrays;
var searcharray = [];

if (searchStr) {
console.log("start search for value: "
+ searchStr + ", with data.length: "
+ data.length);

for ( var i in data) {
cycle++;
var row = data[i];
if (row) {
//console.log(JSON.stringify(row));
for ( var prop in row) {
var val = row[prop];
if (val !== null
&& searchStr == val) {
console.log("found "
+ searchStr + " in "
+ JSON.stringify(row))
searcharray.push(row);
break;
} else {
noMatchCnt++;
}
}
}

}

//replace table data with search results
console
.log("searcharray.length: "
+ searcharray.length
+ ", tot cycles of cell search loop: "
+ cycle + ", noMatchCnt: "
+ noMatchCnt);
loadSearchResults(searcharray);
} else {
console
.log("empty value therefore, load all from pager paramObj.handsonData with len: "
+ paramObj.handsonDataArrays.length)
//replace table data with full page data
loadSearchResults(paramObj.handsonDataArrays);
}
});
// This way, you can access Handsontable api methods by passing their names as an argument, e.g.:
var hot = jQuery("#table").handsontable('getInstance');

Handsontable.Dom.addEvent(save, 'click', function() {
   // save all cell's data
   ajax('save', 'GET', JSON.stringify({data: hot.getData()}), function (res) {
     var response = JSON.parse(res.response);

     if (response.result === 'ok') {
      console.log('Data saved');
     }
     else {
     console.log('Save error');
     }
   });
 });


});
</script>

</head>
<body>

<p>
<button name="save" id="save">Save</button>
<label><input type="checkbox" name="autosave" id="autosave"
checked="checked" autocomplete="off"> Autosave</label>
</p>
<div id="table" style="width: 800px; height: 600px; overflow: hidden"></div>
<div id="pager" style="width: 800px;" class="slick-enhancement-pager"></div>
</body>
</html>

Luke Jones

unread,
May 4, 2015, 6:46:41 PM5/4/15
to Justin Robinson, handso...@googlegroups.com
I see.  I suspect you were using this from the docs as an example?  http://docs.handsontable.com/tutorial-load-and-save.html

The Handsontable.Dom.addEvent, I believe, is just a util wrapper for normal javascript event handling.  The DOM in question is actually outside the context of what the handsontable library is actually meant to support.  I would even argue the use of it in the docs is wrong as you should really only use the Handsontable.Dom.addEvent within the context of the handsontable container.

All that said, you should just use jQuery's event handler on the save button to do what you require and use the reference of your handsontable to pull what you want.

Justin Robinson

unread,
May 4, 2015, 7:52:07 PM5/4/15
to handso...@googlegroups.com, jus...@fluidnotions.com, luke....@getalma.com
Ok thanks for that. Maybe I should have just stuck to the plain js.

Anyway the index mapping I'll figure out but do you have any idea how to get afterChange : function(change, source) attached an click event ... what I mean is change is an array that only contains 1 element when parsed into afterChange : function(change, source) is there anywhere to get a list of changes since the last loadData?

Maybe I should post the question other a new heading 

Luke Jones

unread,
May 4, 2015, 8:17:11 PM5/4/15
to Justin Robinson, handso...@googlegroups.com
There isn't anything that I know of be default that will return you just the changes.  However, it would be easy enough to keep track of the changes in the afterChange callback and then upon save, send back your custom array.  IE:

afterChange: function(changes, source) {
  changes.forEach(function(change) {
     globalChanges[change[0]][change[1]] = changes[3]; 
  });
}

Then when a user hits save, send back globalChanges. 
Reply all
Reply to author
Forward
0 new messages