Bug 40013 - Allow custom/plugable filtering options for OPAC ILL table
Summary: Allow custom/plugable filtering options for OPAC ILL table
Status: In Discussion
Alias: None
Product: Koha
Classification: Unclassified
Component: ILL (show other bugs)
Version: Main
Hardware: All All
: P5 - low enhancement
Assignee: HKS3 Tadeusz Sośnierz
QA Contact: Testopia
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-05-28 09:35 UTC by HKS3 Tadeusz Sośnierz
Modified: 2025-06-05 08:23 UTC (History)
6 users (show)

See Also:
GIT URL:
Change sponsored?: ---
Patch complexity: ---
Documentation contact:
Documentation submission:
Text to go in the release notes:
Version(s) released in:
Circulation function:


Attachments
Bug 40013: Add a way to inject custom filters for OPAC ILL table (3.15 KB, patch)
2025-05-28 09:40 UTC, HKS3 Tadeusz Sośnierz
Details | Diff | Splinter Review
Bug 40013: Add a way to inject custom filters for OPAC ILL table (3.15 KB, patch)
2025-06-04 11:24 UTC, HKS3 Tadeusz Sośnierz
Details | Diff | Splinter Review
Bug 40013: Allow plugging in custom dataFilters to OPAC kohaTable (2.04 KB, patch)
2025-06-04 11:26 UTC, HKS3 Tadeusz Sośnierz
Details | Diff | Splinter Review
Bug 40013: [ALTERNATIVE WIP] Add 'searchable' option to OPAC table columns (9.75 KB, patch)
2025-06-04 12:13 UTC, Pedro Amorim
Details | Diff | Splinter Review

Note You need to log in before you can comment on or make changes to this bug.
Description HKS3 Tadeusz Sośnierz 2025-05-28 09:35:03 UTC
Switching the OPAC ILL table in https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=39600 to client-side rendering gives us an opportunity to have plugins (or just using OPACUserJS) introduce custom filtering behaviour to the new table. All we need to allow this to happen is to have an editable additional_filters specified in there somewhere.
Comment 1 HKS3 Tadeusz Sośnierz 2025-05-28 09:40:37 UTC
Created attachment 182813 [details] [review]
Bug 40013: Add a way to inject custom filters for OPAC ILL table

Test plan:

1. In KTD, go to http://localhost:8081/cgi-bin/koha/admin/preferences.pl?tab=&op=search&searchfield=master+switch and enable the ILL module
2. Set the following OPACUserJS:

    document.addEventListener('DOMContentLoaded', function() {
        const listInfo = document.querySelector('#illrequestlist_info');
        if (listInfo) {
            const statusFilters = document.createElement('div');
            listInfo.parentElement.appendChild(statusFilters);

            const shortcuts = [
                ['Show new requests', 'NEW'],
                ['Show ordered requests', 'ORDERED'],
                ['Show all requests', ''],
            ];

            for (const [label, status] of shortcuts) {
                const button = document.createElement('button');
                button.textContent = label;
                button.className = 'btn btn-secondary';
                button.onclick = () => {
                    if (status) {
                        opac_illrequests_additional_filters['me.status'] = { '=': status };
                    } else {
                        delete opac_illrequests_additional_filters['me.status'];
                    }
                    $('#illrequestlist').DataTable().draw();
                };
                statusFilters.parentElement.appendChild(button);
            }
        }
    });

2. Run the following in koha-shell to populate the request list for user `koha`:

    perl -Mt::lib::TestBuilder -e '
      my $builder = t::lib::TestBuilder->new;

      do {
        $builder->build_sample_ill_request({borrowernumber => 51, status => ($_ > 10 ? "NEW" : "ORDERED")});
      } for (1..50);
    '
3. Navigate to http://localhost:8080/cgi-bin/koha/opac-illrequests.pl, log in as `koha` as needed
4. Observe the new buttons affecting the requests displayed in the table

Sponsored-by: Wiko <https://www.wiko-berlin.de/>
Comment 2 Pedro Amorim 2025-05-28 11:56:31 UTC
This makes sense, but I wonder if we should tackle it differently?

kohaTable is defined twice, once for Intra, once for OPAC (another example where bug 35716 would prevent it):
/koha/koha-tmpl/intranet-tmpl/prog/js/datatables.js
/koha/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js

Intra kohaTable implements _dt_add_filters, OPAC does not.
I suppose it was never implemented for OPAC kohaTable because there was no need for it, not until now anyway.

My suggestion here would be to implement _dt_add_filters in the OPAC kohaTable, adding the possibility of column filters and enabling the REST API based filtering we're aiming for here.

This would also enable any future REST driven OPAC table to have searchable columns.

I may be completely wrong here, or this can also be considered as a follow-up. Up for discussion.
Comment 3 Jonathan Druart 2025-05-28 14:22:36 UTC
(In reply to Pedro Amorim from comment #2)
> This makes sense, but I wonder if we should tackle it differently?
> 
> kohaTable is defined twice, once for Intra, once for OPAC (another example
> where bug 35716 would prevent it):
> /koha/koha-tmpl/intranet-tmpl/prog/js/datatables.js
> /koha/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js
> 
> Intra kohaTable implements _dt_add_filters, OPAC does not.
> I suppose it was never implemented for OPAC kohaTable because there was no
> need for it, not until now anyway.
> 
> My suggestion here would be to implement _dt_add_filters in the OPAC
> kohaTable, adding the possibility of column filters and enabling the REST
> API based filtering we're aiming for here.
> 
> This would also enable any future REST driven OPAC table to have searchable
> columns.
> 
> I may be completely wrong here, or this can also be considered as a
> follow-up. Up for discussion.

The two versions of datatables.js are not identical. You could move and centralize most of the code, not everything.
Comment 4 David Nind 2025-06-01 20:17:35 UTC
Added assignee.

I changed the status to In Disussion.
Comment 5 HKS3 Tadeusz Sośnierz 2025-06-04 08:48:13 UTC
Is there a good reason why they're not identical, and/or do not have feature parity? I'm not sure what the historical reasons are, but is there a good reasons why they *shouldn't* be functionally identical?
Comment 6 HKS3 Tadeusz Sośnierz 2025-06-04 11:24:52 UTC
Created attachment 182944 [details] [review]
Bug 40013: Add a way to inject custom filters for OPAC ILL table

Test plan:

1. In KTD, go to http://localhost:8081/cgi-bin/koha/admin/preferences.pl?tab=&op=search&searchfield=master+switch and enable the ILL module
2. Set the following OPACUserJS:

    document.addEventListener('DOMContentLoaded', function() {
        const listInfo = document.querySelector('#illrequestlist_info');
        if (listInfo) {
            const statusFilters = document.createElement('div');
            listInfo.parentElement.appendChild(statusFilters);

            const shortcuts = [
                ['Show new requests', 'NEW'],
                ['Show ordered requests', 'ORDERED'],
                ['Show all requests', ''],
            ];

            for (const [label, status] of shortcuts) {
                const button = document.createElement('button');
                button.textContent = label;
                button.className = 'btn btn-secondary';
                button.onclick = () => {
                    if (status) {
                        opac_illrequests_additional_filters['me.status'] = { '=': status };
                    } else {
                        delete opac_illrequests_additional_filters['me.status'];
                    }
                    $('#illrequestlist').DataTable().draw();
                };
                statusFilters.parentElement.appendChild(button);
            }
        }
    });

2. Run the following in koha-shell to populate the request list for user `koha`:

    perl -Mt::lib::TestBuilder -e '
      my $builder = t::lib::TestBuilder->new;

      do {
        $builder->build_sample_ill_request({borrowernumber => 51, status => ($_ > 10 ? "NEW" : "ORDERED")});
      } for (1..50);
    '
3. Navigate to http://localhost:8080/cgi-bin/koha/opac-illrequests.pl, log in as `koha` as needed
4. Observe the new buttons affecting the requests displayed in the table

Sponsored-by: Wiko <https://www.wiko-berlin.de/>
Comment 7 HKS3 Tadeusz Sośnierz 2025-06-04 11:26:02 UTC
Created attachment 182945 [details] [review]
Bug 40013: Allow plugging in custom dataFilters to OPAC kohaTable

This allows plugins/opacJS to alter the response data before it's displayed to the user.
Comment 8 HKS3 Tadeusz Sośnierz 2025-06-04 11:31:54 UTC
I'm really not stoked on the "API" of this – manipulating carefully named globals to alter the behaviour is not something I'm fond of, but it seems to me like it'd require a massive overhaul to make it better. Ideally I'd see it as something like `$("#illrequestlist").kohaTable().addDataFiltter(...)` instead, but we're not really working with fully-fledged objects here that we can add methods to. There is a precedent like he aforementioned _dt_add_filters, but in case of dataFilter (see second patch) that quickly gets very awkward, since those dataFilters are established at _dt_default_ajax time, so not easily accesible to modify it at a later time.

Any ideas for what an elegant and future-proof solution could look like here?
Comment 9 Pedro Amorim 2025-06-04 12:13:41 UTC
Created attachment 182947 [details] [review]
Bug 40013: [ALTERNATIVE WIP] Add 'searchable' option to OPAC table columns

This is a WIP of my suggestion. It provides column search inputs for each of the 'searchable': true columns.
This provides value to all OPAC tables, as it adds the functionality at the datatables layer.
This is a copy paste from the datatables.js in intranet-tmpl, ideally it'd be DRY, but we don't live in an ideal world.
More work needs to be done:
1) Clicking on the input sorts the column (it shouldnt)
2) Columns like 'status' ideally would have a dropdown of values, not a text input.
3) Searching on extended_attributes requires additional work so my suggestion for now would be to have 'searchable': false for these cases.
Comment 10 Pedro Amorim 2025-06-04 12:16:22 UTC
(In reply to HKS3 Tadeusz Sośnierz from comment #8)

> Any ideas for what an elegant and future-proof solution could look like here?

I've provided a patch illustrating my suggestion. With a bit more work it should satisfy your use case of filtering on 'status', and done at the datatables.js layer.
The code not being DRY is something that imo should be discussed (and fixed someday) in bug 35716 as it's a perpetual problem in Koha far exceeding this particular OPAC ILL table.
Comment 11 HKS3 Tadeusz Sośnierz 2025-06-04 12:21:57 UTC
(In reply to Pedro Amorim from comment #10)
> (In reply to HKS3 Tadeusz Sośnierz from comment #8)
> 
> > Any ideas for what an elegant and future-proof solution could look like here?
> 
> I've provided a patch illustrating my suggestion. With a bit more work it
> should satisfy your use case of filtering on 'status', and done at the
> datatables.js layer.
> The code not being DRY is something that imo should be discussed (and fixed
> someday) in bug 35716 as it's a perpetual problem in Koha far exceeding this
> particular OPAC ILL table.

Ah, I don't think that covers the second case though – introducing a dataFilter-like functionality, where we process the data between the response arriving and the table being rendered. A customer over here is interested in "streamlining" the statuses of requests, so they either show "New", "In progress" or "Completed" without going into further details – dataFilter fills that purpose nicely, and my second patch enables that – and I don't think it's a pattern we use with kohaTables anywhere else so far, neither in opac or intranet.
Comment 12 Jonathan Druart 2025-06-04 14:04:23 UTC
Did you try to pass functions to additional_filters?
Comment 13 HKS3 Tadeusz Sośnierz 2025-06-05 08:21:14 UTC
> Did you try to pass functions to additional_filters?

There is no such parameter, but there is a default_filters that later gets assigned to a (local) additional_filters – but that only gets used when building the DBIC query (here: https://gitlab.com/koha-community/Koha/-/blob/main/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js?ref_type=heads#L318), not doing the postprocessing of the HTTP response, which is what I'm after.

My goal is to sneak my way into dataFilter (here: https://gitlab.com/koha-community/Koha/-/blob/main/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js?ref_type=heads#L92) which is currently not exposed in kohaTable.

Part of the underlying issue, in my opinion, is that kohaTable limits the underlying dataTable rather than extending it. Its `ajax`, for instance, forces a default behaviour on top of user preferences rather than just providing sensible (but extensible) defaults: see the order of arguments in https://gitlab.com/koha-community/Koha/-/blob/main/koha-tmpl/opac-tmpl/bootstrap/js/datatables.js?ref_type=heads#L609 – the default implementation "wins". A kohaTable user cannot provide their own implementation of dataFilter (or data, or beforeSend...), since _dt_default_ajax() always has the last word.

Every potential dataTable usage that might be needed in the future (like the ones in this issue) therefore requires additional APIs to be built to expose the functionality that dataTables already provides – and the fact that we have *two* independent kohaTables (opac and intranet) makes this even worse.

In (my) ideal world, kohaTable would be a subclass of the dataTable rather than a (leaky) abstraction on top of it – and LSP would then ensure that I have everything I might need :)

Some of the customer code I've written before has used dataTables directly (and copying code from kohaTable) for this exact reason – bending and twisting kohaTables just wasn't worth it (this is why my initial patch for https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=39600 used dataTables instead of kohaTable). In fancy terms,
Comment 14 HKS3 Tadeusz Sośnierz 2025-06-05 08:23:23 UTC
(In reply to HKS3 Tadeusz Sośnierz from comment #13)
> In fancy terms,

(there are no fancy terms, but I have that you can't edit bugzilla comments :F)