omines / datatables-bundle

DataTables bundle for Symfony
https://omines.github.io/datatables-bundle/
MIT License
252 stars 113 forks source link

How to pass custom parameters to AJAX request? #160

Closed nanawel closed 3 years ago

nanawel commented 4 years ago

Hi, I've been searching around for a while now but I can't figure out how to pass custom parameters to the datatable upon building, so that every consecutive AJAX call would have those in the POST.

In my example, the user gets to a search page with a query parameter ?q=..., then the controller builds the datatable and embed this query in its options. The page is displayed, the AJAX call is performed, and I can retrieve this query to use it inside the criteria option of the adapter when the results are built.

I've tried searching for options on the PHP side but found none. Then I've tried using the preXhr in JS but it seems to be ignored by the custom wrapper of the bundle.

Any hint?

nanawel commented 4 years ago

As a workaround, I'm currently using the Referer header while processing the POST request to know what query was passed to the original page. It's working but it's clearly not a good practice IMHO, as there's no guarantee this header would be present (even if it is 99% of the time).

Still open to a better solution.

pluk77 commented 3 years ago

We have opted for storing the parameter in session in the initial request. Thereafter the callback can use the parameter from session and add to the query builder.

nanawel commented 3 years ago

We have opted for storing the parameter in session in the initial request. Thereafter the callback can use the parameter from session and add to the query builder.

Ah yes. But in my case I can't go this way as there's no guarantee that one and only one grid will be used at the same time in the same session. I suppose you're using unique IDs in your implementation?

g-balas commented 3 years ago

Any news about this 😄 ?

johnvanham commented 3 years ago

We have opted for storing the parameter in session in the initial request. Thereafter the callback can use the parameter from session and add to the query builder.

Have done the same thanks for the tip.

Haven't looked into it, but the global search/paging seems to work via hash parameters - I wonder if anything can be passed to the ajax request that way? It would be nice to know what is recommended by the devs of this bundle on the 'right way' of going about passing params to the query builder for custom filters - which is what I'm using it for.

maxhelias commented 3 years ago

You can easily overload the datatables.js file provided by the bundle and add your own on the compilation assets.

johnvanham commented 3 years ago

Thanks @maxhelias It looks like the URL used in the ajax calls is specified in datatables.js and it misses off window.location.search - if that was included in the URL then the same parameters from the initial page load would be accessible in the controller for including in the criteria without needing to use the session. Can the URL be specified somewhere to override this without needing to overload datatables.js from the bundle?

https://github.com/omines/datatables-bundle/blob/5ccdc1283ff1931c8259796447b8e69f48ea5302/src/Resources/public/js/datatables.js#L18

maxhelias commented 3 years ago

To simplify myself personally, I overloaded the file. It's small enough for me to take care of maintenance and to add the need of my project. But maybe you can to something with that : https://github.com/omines/datatables-bundle/blob/master/src/Resources/public/js/datatables.js#L45

johnvanham commented 3 years ago

Ah yes so in twig you can do:

<script>
    var datatableSettings = {{ datatable_settings(datatable) }};
    datatableSettings.url = window.location.origin + window.location.pathname + window.location.search;
    $('#datatable').initDataTables(datatableSettings);
</script>

Then the query parameters are carried through to the ajax call and not missed off.

Does that help @nanawel @pluk77 @g-balas?

nanawel commented 3 years ago

I would have thought this should be the default behavior, but yes I guess it works. I'll stick with the Referer thing for now anyway. Thanks @johnvanham

pluk77 commented 3 years ago

We have opted to use a standard symfony form for the filter / search. We prevent the default behavior of the submit button via the on-click event. We then add the values of the form fields to the data that gets submitted via ajax after which we re-initialize the data-tables:

e.preventDefault(); 
$.ajaxSetup({
    beforeSend: function(jqXHR, settings) {
        settings.data = settings.data+'&appointment_picklist_report_form[healthService]='+$('#healthService :selected').val()+'&appointment_picklist_report_form[startDate]='+$('#startDate').val()+'&appointment_picklist_report_form[btnFilter]=&appointment_picklist_report_form[btnExport]=';
        return true;
    }
});

If you use the form naming convention when adding the data to the ajax request, symfony can process the form as per normal and add the validated and cleaned values to the session for further use thereafter.

This way, no full page refresh happens when the filter is applied.

If you use a Data Transfer Object for the form, you can set the stored data from the session as the defaults so the filters are restored when you return to the page later on.