Question

Handsontable makes it very easy to send table values from a server an array:

$('#dataTable').handsontable( data: serverdataarray )

So far, so good. However, I would like to format some of the columns in the array.

If I have a fixed number of columns I can easyly do this:

$('#dataTable').handsontable({
    data: serverdataarray ,
    columns: [
        { data: "Entity", type: 'text', renderer: orangeFF9900 },
        { data: "Geography", type: 'text', renderer: orangeFF9900 },
        { data: "Description", type: 'text', renderer: orangeFF9900 },
        { data: "cost_month1", type: 'numeric' },
        { data: "cost_month1", type: 'numeric' }
    ]
});

My problem is that the data sent from the server will have a varying number of columns depending on a number of factors. Thus, I would like to be able to generate the columns formating array dynamicaly on the server and send it as an array too. I.e.:

var cols = [
        { data: "Entity", type: 'text', renderer: orangeFF9900 },
        { data: "Geography", type: 'text', renderer: orangeFF9900 },
        { data: "Description", type: 'text', renderer: orangeFF9900 },
        { data: "cost_month1", type: 'numeric' },
        { data: "cost_month1", type: 'numeric' }
    ]; // Strictly speaking this would be a string sent form the server, but you catch my drift

 $('#dataTable').handsontable({
    data: serverdataarray ,
    columns: cols
 });

However, on doing so, I end up with the following error TypeError: method is not a function jquery.handsontable-0.9.9-full.js Line: 3028

The line in question (3028) is the return line of the following function:

Handsontable.TableView.prototype.applyCellTypeMethod = function (methodName, td, row, col) {
    var prop = this.instance.colToProp(col)
    , cellProperties = this.instance.getCellMeta(row, col)
    , method = Handsontable.helper.getCellMethod(methodName, cellProperties[methodName]); //methodName is 'renderer' or 'editor'

    return method(this.instance, td, row, col, prop, this.instance.getDataAtRowProp(row, prop), cellProperties);
};

Handsontable actualy manages to render correct number of columns on screen, although they are blank, unformatted and there is only one row so I'm gessing it is infering this much form the serverdataarray and not cols.

Any suggestions on how to achive what I am looking for?

I am open to changing the Handsontable sourcecode if need be.

Thanks

Était-ce utile?

La solution 2

I don't see anything wrong with your approach. In one of my projects, I'm successfully using:

var myCols = [...];

$('#dataTable').handsontable({
    data: serverdataarray,
    columns: myCols
});

In you sample code, the comment line "// Strictly speaking ...": At the beginning of the line you seem to have too many closing brackets. var cols = [...]}); should just be var cols = [...]; I'm assuming its a typo.

Except for that I suggest checking that the the columns data is set to exactly the same ID/name as the column has from the server and not i.e. what you want as a heading. Example:

var cols = [{ data: "RefNum" }, { data: "Qty"}];

Add headers using:

 colHeaders: ["Reference", "Quantity"]

The last thing I can think of is that there is something wrong with the renderer. Try removing the renderer for each column and see if it works first. Its kind of hard to help without more code on this.

Autres conseils

This answer is just intended as an expansion on @PostureOfLearning 's correct response:

It turns out the problem was caused by the following mistake and the fact that I simplified the code in the hope of making the post more readable:

  var orangeFF9900= function (instance, td, row, col, prop, value, cellProperties) {
    Handsontable.TextCell.renderer.apply(this, arguments);
    $(td).css({
        background: '#ff9900'
    });
  };

  $.post('/AJAX/columns', function (data) {
        var cellData = JSON.parse(data.Cells);
        var colsData = JSON.parse(data.Cols);
        $('#dataTable').handsontable({
            data: cellData ,
            columns: colsData 
        });
  });

Now the colsData array looks like described above (or perhaps more precisely as):

[
    { "data": "Entity", "type": "text", "renderer": "orangeFF9900" },
    { "data": "Geography", "type": "text", "renderer": "orangeFF9900" },
    { "data": "Description", "type": "text", "renderer": "orangeFF9900" },
    { "data": "cost_month1", "type": "numeric" },
    { "data": "cost_month1", "type": "numeric" }
]

Now, because of the way text is transmitted in JSON via quote marks " ", orangeFF9900 is resolved as a string and not a function call.

Fortunately however, it appears we can teach HandOnTable to recognise a renderer function name passed as a string by using the following line:

Handsontable.cellLookup.renderer.orangeFF9900 = finction(…) {…};

Thus our final code can look like:

Handsontable.cellLookup.renderer.orangeFF9900 = function (instance, td, row, col, prop, value, cellProperties) {
    Handsontable.TextCell.renderer.apply(this, arguments);
    $(td).css({
        background: '#ff9900'
    });
  };

  $.post('/AJAX/columns', function (data) {
        var cellData = JSON.parse(data.Cells);
        var colsData = JSON.parse(data.Cols);
        $('#dataTable').handsontable({
            data: cellData ,
            columns: colsData 
        });
  });

Hope this helps someone in the future

Cheers

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top