2

I have below code to create column:

DTColumnBuilder.newColumn(null).withTitle('Validation').renderWith(validationRenderer)

and render function:

function validationRenderer(data, type, full, meta) {
    .......
}

Now, I want to pass custom parameters to validationRenderer so that I can access it inside the function, like below:

DTColumnBuilder.newColumn(null).withTitle('Validation').renderWith(validationRenderer('abc'))

function validationRenderer(data, type, full, meta, additionalParam) {
    // do something with additionalParam
}

I could not find it in the documentation but there must be something to pass additional parameters in meta as per the reference from here

2
  • I dont think it is possible, afaik you cannot monkey patch the render() method. But I would love to see a solution for this :) Commented Mar 23, 2017 at 11:16
  • @davidkonrad: Kinda late, but I've found a possible workaround using self invoking anonymous functions. It seems the only possible way so far. Commented Aug 16, 2017 at 13:38

1 Answer 1

2

Yes, you can. Or, better, you technically can, but you may use a clever workaround to handle your issue.

I had this issue today, and found a pretty sad (but working) solution.

Basically, the big problem is that the render function is a parameter passed to the datatable handler, which is (of course) isolated.

In my case, to make a pratical example, I had to add several dynamic buttons, each with a different action, to a dynamic datatable.

Apparently, there was no solution, until I thought the following: the problem seems to be that the renderer function scope is somewhat isolated and unaccessible. However, since the "return" of the function is called only when the datatable effectively renders the field, you may wrap the render function in a custom self-invoking-anonymous-function, providing arguments there to use them once the cell is being rendered.

Here is what I did with my practical example, considering the following points:

  • The goal was to pass the ID field of each row to several different custom functions, so the problem was passing the ID of the button to call when the button is effectively clicked (since you can't get any external reference of it when it is rendered).
  • I'm using a custom class, which is the following:

    hxDatatableDynamicButton = function(label, onClick, classNames) { this.label = label; this.onClick = onClick; this.classNames = this.classNames || 'col5p text-center'; }

Basically, it just creates an instance that I'm later using.

In this case, consider having an array of 2 different instances of these, one having a "test" label, and the other one having a "test2" label.

  • I'm injecting these instances through a for loop, hence I need to pass the "i" to my datatable to know which of the buttons is being pressed.

Since the code is actually quite big (the codebase is huge), here is the relevant snippet that you need to accomplish the trick:

scope.datatableAdditionalActionButtons.reverse();
scope._abstractDynamicClick = function(id, localReferenceID) {
    scope.datatableAdditionalActionButtons[localReferenceID].onClick.call(null, id);
};
for (var i = 0; i < scope.datatableAdditionalActionButtons.length; i++) {
    var _localReference = scope.datatableAdditionalActionButtons[i];
    var hax = (function(i){
        var _tmp = function (data, type, full, meta) {
            var _label = scope.datatableAdditionalActionButtons[i].label;
            return '<button class="btn btn-default" ng-click="_abstractDynamicClick('+full.id+', '+i+')">'+_label+'</button>';
        }
        return _tmp;
    })(i);

    dtColumns.unshift(DTColumnBuilder.newColumn(null).notSortable().renderWith(hax).withClass(_localReference.classNames));
}

So, where is the trick? the trick is entirely in the hax function, and here is why it works: instead of passing the regular renderWith function prototype, we are using a "custom" render, which has the same arguments (hence same parameters) as the default one. However, it is isolated in a self invoking anonymous function, which allows us to arbitrarely inject a parameter inside it and, so, allows us to distinguish, when rendering, which "i" it effectively is, since the isolated scope of the function is never lost in this case.

Basically, the output is as follow: enter image description here

And the inspection actually shows that elements are effectively rendered differently, hence each "i" is being rendered properly, while it wouldn't have if the function wouldn't have been wrapped in a self invoking anonymous function:

enter image description here

So, basically, in your case, you would do something like this:

var _myValidator = (function(myAbcParam){
   var _validate = function (data, type, full, meta) {
      console.log("additional param is: ", myAbcParam); // logs "abc"
      return '<button id="'+myAbcParam+'">Hello!</button>'; // <-- renders id ="abc"
   }
   return _validate ;
})('abc');

DTColumnBuilder.newColumn(null).withTitle('Validation').renderWith(_myValidator);
// <-- note that _myValidator is passed instead of "_myValidator()", since it is already executed and already returns a function.

I know this is not exactly the answer someone may be expecting, but if you need to accomplish something that complex in datatable it really looks like the only possible way to do this is using a self invoking anonymous function.

Hope this helps someone who is still having issues with this.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.