Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Names to DataTable ColumnDefs / Columns [Column Filtering] #314

Open
arlenreyb opened this issue Oct 24, 2023 · 5 comments
Open

Add Names to DataTable ColumnDefs / Columns [Column Filtering] #314

arlenreyb opened this issue Oct 24, 2023 · 5 comments

Comments

@arlenreyb
Copy link

I guess this isn't really an issue, but I don't know enough about git to make this a pull request or whatever, and I wanted to share this in case others were looking for something like this:

Thanks to this bundle, you can apply a server-side table search from javascript very easily:
datatable.column(0).search('2023-10-12').draw();

When this Ajax call from the datatable goes back to the controller, it's already POSTing columns. In Symfony's debug profiler, you can even see the POSTed columns array contains a field for name, though it's empty. But the name you gave it in PHP is there, under the 'data' key instead. You can also see the "search" key for that column, with the search setting applied to that column, and only that column. It's up to us to intercept that in the PHP controller and apply it to the datatable, and I won't get in to that (unless you want me to), but so far this is pretty nice ...

... except for the fact that you need to somehow communicate which column is which, by index number, between PHP and JS. That's not so great.

But check this out: https://datatables.net/reference/option/columns.name

Naming columns during datatable init allows you to access columns by name in JS. Since names defined in the PHP file are already passed to this bundle's JS config, it should be easy to add those same names to the column config.

If you do this, not only can you now do the following in JS (assuming column 0 was named 'createdAt' in the PHP controller):
datatable.column('createdAt:name').search('2023-10-12').draw();

But now you can also see that the POST parameters from the ajax call now have the "name" key filled in. Which means you can easily get to search values in your PHP controller with:

$columnData = $request->request->all('columns');
$createdAtIndex = array_search('createdAt', array_column($columnData, 'name'));
$createdAtSearchValue = $columnData[$createdAtIndex]['search']['value'];

(Granted, before you could have array_searched by the 'data' column, but actually using the previously-empty name field feels better.)

I accomplished this by adding a single line of code at line 100 in datatables.js (the included supplementary js file for this bundle):
dtOpts.columns.forEach(column => column.name = column.data);

Maybe you have a more elegant solution, or would rather put it somewhere else, but I figured I'd share this because (at least in my use case) it massively increased the usability of this bundle. I figured it might be useful for others, too.

Copy link

Stale issue message

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Dec 31, 2023
@curry684 curry684 reopened this Jan 3, 2024
Copy link

github-actions bot commented Mar 4, 2024

Stale issue message

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Mar 11, 2024
@arlenreyb
Copy link
Author

Hi. Bumping this because I found that "more elegant solution" I was looking for.

Again, here's DataTable's amazing "by name" API system: https://datatables.net/reference/option/columns.name
In order to utilize this, you need to name the columns at init, which I was accomplishing by modifying that omines datatable.js file. This wasn't ideal, since every time packages updated or I pulled my project to a different workstation, those changes would be reset.

But then I stumbled upon this: https://datatables.net/examples/advanced_init/html5-data-options.html
You can very easily add the name to the init through html 5 data attributes.

So, all you need to do now is grab a copy of the Omines twig template, drop it in your project template folder, and make this one, very simple change:

{% for column in datatable.columns %}
  <th data-name="{{ column.name }}">{{ column.label|trans }}</th>
{% endfor %}

More info on that, here: https://omines.github.io/datatables-bundle/#configuration
Update your datatables.yaml file to point to the new template:
template: 'datatable/datatable_modified.html.twig' (or whatever you called it)

So now all you have to do in your stimulus controller is eventually say:

datatable.column('columnName:name').search('searchValue').draw();

Then get that searchValue from the request in your controller, which is now named correctly so it's 100x easier to take that and apply it directly to the Omines adapter and apply specific column filters, or other advanced query shenanigans. I like this, because it lets me filter by a specific column (or multiple columns), and then do the global search on top of it.

Anyway, just wanted to share, in case anyone else was looking for DataTable's name API integration.

@curry684
Copy link
Member

Interesting approach, thanks for sharing 👍

@Shotman
Copy link

Shotman commented May 15, 2024

Hi. Bumping this because I found that "more elegant solution" I was looking for.

Again, here's DataTable's amazing "by name" API system: https://datatables.net/reference/option/columns.name In order to utilize this, you need to name the columns at init, which I was accomplishing by modifying that omines datatable.js file. This wasn't ideal, since every time packages updated or I pulled my project to a different workstation, those changes would be reset.

But then I stumbled upon this: https://datatables.net/examples/advanced_init/html5-data-options.html You can very easily add the name to the init through html 5 data attributes.

So, all you need to do now is grab a copy of the Omines twig template, drop it in your project template folder, and make this one, very simple change:

{% for column in datatable.columns %}
  <th data-name="{{ column.name }}">{{ column.label|trans }}</th>
{% endfor %}

More info on that, here: https://omines.github.io/datatables-bundle/#configuration Update your datatables.yaml file to point to the new template: template: 'datatable/datatable_modified.html.twig' (or whatever you called it)

So now all you have to do in your stimulus controller is eventually say:

datatable.column('columnName:name').search('searchValue').draw();

Then get that searchValue from the request in your controller, which is now named correctly so it's 100x easier to take that and apply it directly to the Omines adapter and apply specific column filters, or other advanced query shenanigans. I like this, because it lets me filter by a specific column (or multiple columns), and then do the global search on top of it.

Anyway, just wanted to share, in case anyone else was looking for DataTable's name API integration.

Do you have any example for a minimal repository on how it might work ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants