yii2-datatables icon indicating copy to clipboard operation
yii2-datatables copied to clipboard

How can I refer to custom functions and related data in model ?

Open skiiiks opened this issue 6 years ago • 15 comments

Hi: I'm using last version (1.1.0) I need to do a custom render of a field, using 2 variables of the model, and one function of the model ... how can I do it ?

I've tried with QueryParams but I think this works only with LinkColumn, not with DataTableColumn...

in my view:

                    [
                        'class' => 'nullref\datatable\LinkColumn',
                        'data' => 'name',
                        'title' => 'x',
                        'queryParams' => ['name', 'manager.username', 'age'],
                        'render' => new JsExpression('function render(data, type, row, meta ){
                            console.log(row);
                            return row.name  + " " + row["manager.username"] + " " + row["age"];
                        }'),
                    ],

in my model:

public function age() {
   return date("Y") - $this->year_birth;
}

I've tried also with getAge() as function name.

There are twi problems; (althought the console.log(row) shows the correct data)

  1. I can not refer to use two variables in the render (it renders "undefined")
  2. I can not refer to use a model function in the render (it renders "undefined")

Thank you !

P.D. If i don't use "title" when using "LinkColumn" it returns a javascript error: jquery.js:3841 jQuery.Deferred exception: Cannot read property 'replace' of null TypeError: Cannot read property 'replace' of null

skiiiks avatar Jul 28 '19 19:07 skiiiks

Hint... in the console log I see two groups:

  1. first group of output showing the console.log(row) output with all the data
  2. then a second group of output with just name values (all other values are undefined)

skiiiks avatar Jul 29 '19 01:07 skiiiks

Ok, the problem is that when using serverSide, the variable $columns just have the columns defined in the DataTable::widget, and not include the "queryParams" (extra data used for some columns), therefore the DataTableAction init function does not receive all the columns to build the rows

skiiiks avatar Jul 29 '19 01:07 skiiiks

hello @skiiiks could you show your source code?

ZAYEC77 avatar Jul 29 '19 09:07 ZAYEC77

I pasted it in the original message. Anyway, if you take your example code in the Readme it happens the same ... when you use serverSide, you can not refer to other variables or other model functions.

skiiiks avatar Jul 29 '19 11:07 skiiiks

But don't worry ... and don't offend, but this is too difficult when you want custom cells with other data from the model ... I think i'm going to move to krajee gridview :-(

skiiiks avatar Jul 29 '19 11:07 skiiiks

in your case of method age, you should rename the method to getAge to have property age at your model.

ZAYEC77 avatar Jul 29 '19 14:07 ZAYEC77

If you used render you could use row argument that contains all data for a particular row.

ZAYEC77 avatar Jul 29 '19 14:07 ZAYEC77

If you have an issue with serverSide, you could redefine formatData at DataTableAction to add custom columns.

ZAYEC77 avatar Jul 29 '19 14:07 ZAYEC77

Hi @ZAYEC77 Thank you for your response

As I told in the original message I've tried also with getAge() as function name. But it does not work. It does take nothing from the model EXCEPT the variable name you put in the 'data' attribute.

An as I told in the original message too, the "console.log(row)" shows me (in the console, obviously) ALL the data of the row (as you told), but it's the "second time" it loads (when the '/model/datatables' action runs with ajax) when it can't access to all row, and that's exactly because the explanation I put here: https://github.com/NullRefExcep/yii2-datatables/issues/53#issuecomment-515817672

Again... when using your code in the Controller to "listen" to the datatables method :


    public function actions()
     {
        return [
             'datatables' => [
                 'class' => 'nullref\datatable\DataTableAction',
                 'query' => Client::find()->with('manager'),
                 'applyOrder' => function($query, $columns, $order) {
                    //custom ordering logic
                    $orderBy = [];
                    foreach ($order as $orderItem) {
                        $orderBy[$columns[$orderItem['column']]['data']] = $orderItem['dir'] == 'asc' ? SORT_ASC : SORT_DESC;
                    }
                    return $query->orderBy($orderBy);
                 },
                 'applyFilter' => function($query, $columns, $search) {
                    //custom search logic
                    $modelClass = $query->modelClass;
                    $schema = $modelClass::getTableSchema()->columns;
                    foreach ($columns as $column) {
                        if ($column['searchable'] == 'true' && array_key_exists($column['data'], $schema) !== false) {
                            $value = empty($search['value']) ? $column['search']['value'] : $search['value'];
                            $query->orFilterWhere(['like', $column['data'], $value]);
                        }
                    }
                    return $query;
                 },
             ],
        ];

    }

this uses the DataTableAction class.

There, in the init() function $columns just refer to the columns defined in the widget, but in each iteration you just take the data attribute:

... if ($column['data']) { ...

so the row will never contain nor the queryParams extra data, neither the complete row.

skiiiks avatar Jul 29 '19 15:07 skiiiks

If you have an issue with serverSide, you could redefine formatData at DataTableAction to add custom columns.

Yes, I know I can do it ... but need more powerful yet, and for this project I can not invest more R+D ... I will come back soon to do it and provide a pull request, but can't now :-(

skiiiks avatar Jul 29 '19 15:07 skiiiks

@skiiiks I have added extraColumns property Please, check readme to more info

You coud check additional example here

ZAYEC77 avatar Aug 01 '19 11:08 ZAYEC77

Hello, I am sorry, but the principle of "extraColumns" and its ability to use is not clear from the above example. Please, specify a small but more detailed example in the description for receiving "serverSide" data.

YevhenIvanovych avatar Oct 16 '19 08:10 YevhenIvanovych

extraColumns -- it's a list of columns that you could use inside other columns.

e.g.

'extraColumns' => ['id2'],

it means that I could use column id2 inside some render functions, like this:

$customColumnRender1 = <<<JS
function customRender1(data, type, row, meta ){
    return "ID: " + row["id2"] + ", Price: " + row["price"];
}
JS;

ZAYEC77 avatar Oct 21 '19 09:10 ZAYEC77

Ok. And how to join the data of several separate tables?

YevhenIvanovych avatar Feb 20 '20 15:02 YevhenIvanovych

You could use any custom query that you need. In the case of DataTableAction you have `query property.

ZAYEC77 avatar Feb 28 '20 09:02 ZAYEC77

Is this issue solved and can be closed ?

Radon8472 avatar Oct 07 '22 11:10 Radon8472

Is this issue solved and can be closed ?

yeah, good point

ZAYEC77 avatar Oct 07 '22 11:10 ZAYEC77