View | Details | Raw Unified | Return to bug 17170
Collapse All | Expand All

(-)a/Koha/SearchFilter.pm (-1 / +1 lines)
Lines 15-21 package Koha::SearchFilter; Link Here
15
# along with Koha; if not, see <http://www.gnu.org/licenses>.
15
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
16
17
use Modern::Perl;
17
use Modern::Perl;
18
18
use JSON qw( encode_json decode_json );
19
19
20
use Koha::Database;
20
use Koha::Database;
21
21
(-)a/catalogue/search.pl (+24 lines)
Lines 156-163 use Koha::SearchEngine::Search; Link Here
156
use Koha::SearchEngine::QueryBuilder;
156
use Koha::SearchEngine::QueryBuilder;
157
use Koha::Virtualshelves;
157
use Koha::Virtualshelves;
158
use Koha::SearchFields;
158
use Koha::SearchFields;
159
use Koha::SearchFilters;
159
160
160
use URI::Escape;
161
use URI::Escape;
162
use JSON qw( decode_json encode_json );
161
163
162
my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold");
164
my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold");
163
# create a new CGI object
165
# create a new CGI object
Lines 477-482 $template->param ( QUERY_INPUTS => \@query_inputs, Link Here
477
479
478
## parse the limit_cgi string and put it into a form suitable for <input>s
480
## parse the limit_cgi string and put it into a form suitable for <input>s
479
my @limit_inputs;
481
my @limit_inputs;
482
my %active_filters;
480
if ($limit_cgi) {
483
if ($limit_cgi) {
481
    for my $this_cgi ( split('&', $limit_cgi) ) {
484
    for my $this_cgi ( split('&', $limit_cgi) ) {
482
        next unless $this_cgi;
485
        next unless $this_cgi;
Lines 490-495 if ($limit_cgi) { Link Here
490
        my $input_value = $2;
493
        my $input_value = $2;
491
        $input_name =~ s/=$//;
494
        $input_name =~ s/=$//;
492
        push @limit_inputs, { input_name => $input_name, input_value => Encode::decode_utf8( uri_unescape($input_value) ) };
495
        push @limit_inputs, { input_name => $input_name, input_value => Encode::decode_utf8( uri_unescape($input_value) ) };
496
        if( $input_value =~ /search_filter/ ){
497
            my ($filter_id) = ( uri_unescape($input_value) =~ /^search_filter:(.*)$/ );
498
            $active_filters{$filter_id} = 1;
499
        }
500
493
    }
501
    }
494
}
502
}
495
$template->param ( LIMIT_INPUTS => \@limit_inputs );
503
$template->param ( LIMIT_INPUTS => \@limit_inputs );
Lines 574-582 for (my $i=0;$i<@servers;$i++) { Link Here
574
        $template->param (z3950_search_params => C4::Search::z3950_search_args($z3950par || $query_desc));
582
        $template->param (z3950_search_params => C4::Search::z3950_search_args($z3950par || $query_desc));
575
        $template->param(limit_cgi => $limit_cgi);
583
        $template->param(limit_cgi => $limit_cgi);
576
        $template->param(query_cgi => $query_cgi);
584
        $template->param(query_cgi => $query_cgi);
585
        $template->param(query_json => encode_json({
586
            operators => \@operators,
587
            operands => \@operands,
588
            indexes => \@indexes
589
        }));
590
        $template->param(limit_json => encode_json({
591
            limits => \@limits
592
        }));
577
        $template->param(query_desc => $query_desc);
593
        $template->param(query_desc => $query_desc);
578
        $template->param(limit_desc => $limit_desc);
594
        $template->param(limit_desc => $limit_desc);
579
        $template->param(offset     => $offset);
595
        $template->param(offset     => $offset);
596
        $template->param(offset     => $offset);
597
580
598
581
        if ($hits) {
599
        if ($hits) {
582
            $template->param(total => $hits);
600
            $template->param(total => $hits);
Lines 665-670 for my $facet ( @$facets ) { Link Here
665
    }
683
    }
666
}
684
}
667
685
686
687
$template->param(
688
    search_filters => Koha::SearchFilters->search({ staff_client => 1 }, { order_by => "name" }),
689
    active_filters => \%active_filters,
690
) if C4::Context->preference('SavedSearchFilters');
691
668
$template->param(
692
$template->param(
669
            #classlist => $classlist,
693
            #classlist => $classlist,
670
            total => $total,
694
            total => $total,
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/facets.inc (+18 lines)
Lines 1-11 Link Here
1
[% USE raw %]
1
[% USE raw %]
2
[% USE AuthorisedValues %]
2
[% USE AuthorisedValues %]
3
[% USE Languages %]
3
[% USE Languages %]
4
4
[% IF ( opacfacets ) %]
5
[% IF ( opacfacets ) %]
5
[% IF ( facets_loop ) %]
6
[% IF ( facets_loop ) %]
6
<div id="search-facets">
7
<div id="search-facets">
7
<h4>Refine your search</h4>
8
<h4>Refine your search</h4>
8
<ul>
9
<ul>
10
[% IF Koha.Preference("SavedSearchFilters") && search_filters.count > 0 %]
11
<li id="search-filters">
12
<span id="filter_facets">Custom search filters</span>
13
<ul>
14
    [% SET base_url = "/cgi-bin/koha/catalogue/search.pl?" _ query_cgi _ limit_cgi %]
15
    [% FOREACH search_filter IN search_filters %]
16
    <li>
17
        [% IF active_filters.${search_filter.id} %]
18
            <span class="filter_label">[% search_filter.name | html %]<a href="[% base_url _ '&nolimit=search_filter:' _ search_filter.id | url %]">[X]</a></span>
19
        [% ELSE %]
20
            <span class="filter_label"><a href="[% base_url _ '&limit=search_filter:' _ search_filter.id | url %]">[% search_filter.name | html %]</a></span>
21
        [% END %]
22
    </li>
23
    [% END %]
24
</ul>
25
</li>
26
[% END %]
9
    <li id="availability_facet">Availability<ul><li>[% IF ( available ) %]<strong>Showing only available items</strong></li><li><a href="/cgi-bin/koha/catalogue/search.pl?[% query_cgi | $raw %][% limit_cgi_not_availablity | $raw %][% IF ( sort_by ) %]&amp;sort_by=[% sort_by | uri %][% END %]">Show all items</a>[% ELSE %]<a href="/cgi-bin/koha/catalogue/search.pl?[% query_cgi | $raw %][% limit_cgi | $raw %][% IF ( sort_by ) %]&amp;sort_by=[% sort_by | uri %][% END %]&amp;limit=available">Limit to currently available items</a>[% END %]</li></ul>
27
    <li id="availability_facet">Availability<ul><li>[% IF ( available ) %]<strong>Showing only available items</strong></li><li><a href="/cgi-bin/koha/catalogue/search.pl?[% query_cgi | $raw %][% limit_cgi_not_availablity | $raw %][% IF ( sort_by ) %]&amp;sort_by=[% sort_by | uri %][% END %]">Show all items</a>[% ELSE %]<a href="/cgi-bin/koha/catalogue/search.pl?[% query_cgi | $raw %][% limit_cgi | $raw %][% IF ( sort_by ) %]&amp;sort_by=[% sort_by | uri %][% END %]&amp;limit=available">Limit to currently available items</a>[% END %]</li></ul>
10
	[% IF ( related ) %] <li>(related searches: [% FOREACH relate IN related %][% relate.related_search | html %][% END %])</li>[% END %]
28
	[% IF ( related ) %] <li>(related searches: [% FOREACH relate IN related %][% relate.related_search | html %][% END %])</li>[% END %]
11
	</li>
29
	</li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt (+120 lines)
Lines 69-74 Link Here
69
                        [% total | html %] result(s) found [% IF ( query_desc ) %]for <span class="results_query_desc">'[% query_desc | html %]'</span>[% END %][% IF limit_desc  %]&nbsp;with limit(s): <span class="results_limit_desc">'[% limit_desc | html %]'</span>[% END %][% IF ( LibraryName ) %] in [% LibraryName | html %] Catalog[% END %].
69
                        [% total | html %] result(s) found [% IF ( query_desc ) %]for <span class="results_query_desc">'[% query_desc | html %]'</span>[% END %][% IF limit_desc  %]&nbsp;with limit(s): <span class="results_limit_desc">'[% limit_desc | html %]'</span>[% END %][% IF ( LibraryName ) %] in [% LibraryName | html %] Catalog[% END %].
70
                    </h3>
70
                    </h3>
71
                    <a href="/cgi-bin/koha/catalogue/search.pl?advsearch=1&edit_search=1&[% query_cgi | $raw %]&[% limit_cgi | $raw %]&sort_by=[% sort_by | $raw %]">Edit this search</a>
71
                    <a href="/cgi-bin/koha/catalogue/search.pl?advsearch=1&edit_search=1&[% query_cgi | $raw %]&[% limit_cgi | $raw %]&sort_by=[% sort_by | $raw %]">Edit this search</a>
72
                    [% IF ( Koha.Preference('SavedSearchFilters') && CAN_user_parameters_manage_search_filters ) %]
73
                        | <a href="#" id="save_search_filter">Save search as filter</a>
74
                    [% END %]
72
75
73
                    <div class="searchheader" id="searchheader">
76
                    <div class="searchheader" id="searchheader">
74
                        <div id="selection_ops">
77
                        <div id="selection_ops">
Lines 331-336 Link Here
331
                                <p><a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% searchtoorder_basketno | uri %]">View basket<a></p>
334
                                <p><a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% searchtoorder_basketno | uri %]">View basket<a></p>
332
                            [% END %]
335
                            [% END %]
333
                            <a href="/cgi-bin/koha/catalogue/search.pl?advsearch=1&edit_search=1&[% query_cgi | $raw %]&[% limit_cgi | $raw %]&sort_by=[% sort_by | $raw %]">Edit this search</a>
336
                            <a href="/cgi-bin/koha/catalogue/search.pl?advsearch=1&edit_search=1&[% query_cgi | $raw %]&[% limit_cgi | $raw %]&sort_by=[% sort_by | $raw %]">Edit this search</a>
337
                            [% IF ( Koha.Preference('SavedSearchFilters') &&CAN_user_parameters_manage_search_filters ) %]
338
                                | <a href="#" id="save_search_filter">Save search as filter</a>
339
                            [% END %]
334
                        [% ELSE %]
340
                        [% ELSE %]
335
                            <p>You did not specify any search criteria.</p>
341
                            <p>You did not specify any search criteria.</p>
336
                        [% END %]
342
                        [% END %]
Lines 687-692 Link Here
687
                </div>
693
                </div>
688
                [% END #/IF outer_sup_results_loop %]
694
                [% END #/IF outer_sup_results_loop %]
689
695
696
                [% IF ( Koha.Preference('SavedSearchFilters') && CAN_user_parameters_manage_search_filters ) %]
697
                    <div id="search_filters_modal" class="modal" role="dialog" aria-hidden="true">
698
                        <div class="modal-dialog">
699
                        <div class="modal-content">
700
                            <div class="modal-header">
701
                                <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
702
                                <h3 id="search_filters_label">Save: '[% query_desc | html %]' with limits '[% limit_desc | html %]' as filter</h3>
703
                            </div>
704
                            <div class="modal-body">
705
                                <h6>Visibility:</h6>
706
                                <label for="show_filter_opac">Show in OPAC?</label>
707
                                <input type="checkbox" id="show_filter_opac" name="show_filter_opac">
708
                                <label for="show_filter_staff_client">Show in Staff client?</label>
709
                                <input type="checkbox" id="show_filter_staff_client" name="show_filter_staff_client">
710
                                <hr>
711
                                <h6>Save as new search filter:</h6>
712
                                <label for="new_filter">Name:</label>
713
                                <input id="new_filter" name="new_filter" type="text">
714
                                <a id="save_new_filter" class="btn btn-default btn-xs" href="#">Save</a>
715
                                </br>OR</br>
716
                                <h6>Replace existing search filter:</h6>
717
                                <label for="existing_filters">Choose</label>
718
                                <select id="existing_filters" name="existing_filters" class="search_filters_list"></select>
719
                                <a id="replace_existing_filter" class="btn btn-default btn-xs" href="#">Replace</a>
720
                            </div>
721
                            <div class="modal-footer">
722
                                <a href="#" data-dismiss="modal" aria-hidden="true" class="cancel">Cancel</a>
723
                            </div>
724
                        </div>
725
                        </div>
726
                    </div>
727
                [% END %]
728
690
                <form id="hold_form" method="get" action="/cgi-bin/koha/reserve/request.pl">
729
                <form id="hold_form" method="get" action="/cgi-bin/koha/reserve/request.pl">
691
                    <!-- Value will be set here by placeHold() -->
730
                    <!-- Value will be set here by placeHold() -->
692
                    <input type="hidden" name="findborrower" id="holdFor" value="" />
731
                    <input type="hidden" name="findborrower" id="holdFor" value="" />
Lines 712-717 Link Here
712
    [% Asset.js("js/browser.js") | $raw %]
751
    [% Asset.js("js/browser.js") | $raw %]
713
    [% Asset.js("lib/hc-sticky.js") | $raw %]
752
    [% Asset.js("lib/hc-sticky.js") | $raw %]
714
    [% Asset.js("js/coce.js") | $raw %]
753
    [% Asset.js("js/coce.js") | $raw %]
754
    [% Asset.css("css/humanmsg.css") | $raw %]
755
    [% Asset.js("lib/jquery/plugins/humanmsg.js") | $raw %]
756
    [% INCLUDE 'select2.inc' %]
715
    <script>
757
    <script>
716
        var PREF_AmazonCoverImages = parseInt( "[% Koha.Preference('AmazonCoverImages') | html %]", 10);
758
        var PREF_AmazonCoverImages = parseInt( "[% Koha.Preference('AmazonCoverImages') | html %]", 10);
717
        var q_array = new Array();  // will hold search terms, if present
759
        var q_array = new Array();  // will hold search terms, if present
Lines 745-750 Link Here
745
            query_desc: "[% To.json( query_desc ) | html %]",
787
            query_desc: "[% To.json( query_desc ) | html %]",
746
            query_cgi: "[% query_cgi | html %]",
788
            query_cgi: "[% query_cgi | html %]",
747
            limit_cgi: "[% limit_cgi | html %]",
789
            limit_cgi: "[% limit_cgi | html %]",
790
            query_json: [% query_json | $raw %],
791
            limit_json: [% limit_json | $raw %],
748
            sort_by: "[% sort_by | html %]",
792
            sort_by: "[% sort_by | html %]",
749
            gotoPage: "[% gotoPage | html %]",
793
            gotoPage: "[% gotoPage | html %]",
750
            gotoNumber: "[% gotoNumber | html %]",
794
            gotoNumber: "[% gotoNumber | html %]",
Lines 754-759 Link Here
754
            first_biblionumber: "[% SEARCH_RESULTS.first.biblionumber | html %]",
798
            first_biblionumber: "[% SEARCH_RESULTS.first.biblionumber | html %]",
755
            last_biblionumber: "[% SEARCH_RESULTS.last.biblionumber | html %]",
799
            last_biblionumber: "[% SEARCH_RESULTS.last.biblionumber | html %]",
756
        }
800
        }
801
        [% IF ( CAN_user_parameters_manage_search_filters ) %]
802
            function getFilters(id) {
803
                const select = $("#existing_filters");
804
                $("option[value!='']", select).remove();
805
                return new Promise(function(resolve, reject) {
806
                    $.ajax("/api/v1/search_filters")
807
                    .then(resolve, reject);
808
                })
809
                .then(function(filters) {
810
                    filters.forEach(function(filter) {
811
                        const opt = $("<option/>");
812
                        select.append(opt);
813
                        if(id && filter.search_filter_id == id) {
814
                            opt.prop('selected', true);
815
                        }
816
                        opt.attr("value", filter.search_filter_id);
817
                        opt.attr("title", "Query:" + filter.filter_query + " Limit:"+filter.filter_limits);
818
                        opt.text(filter.name);
819
                        opt.data("filter", filter);
820
                    });
821
                })
822
                .then(function(){
823
                    select.change();
824
                });
825
            }
826
            $("#save_search_filter").click(function(){
827
                getFilters();
828
                $("#search_filters_modal").modal('show');
829
            });
830
            $("#save_new_filter").click(function(){
831
                let name = $("#new_filter").val().trim();
832
                if(!name){
833
                    humanMsg.displayAlert( _("You must provide a name for the new filter"), { className: 'human Error' } );
834
                    return;
835
                }
836
                let opac = $("#show_filter_opac").prop('checked');
837
                let staff = $("#show_filter_staff_client").prop('checked');
838
                save_search_filter(name,null,opac,staff);
839
            });
840
            $("#replace_existing_filter").click(function(){
841
                let id = $("#existing_filters").val();
842
                let name = $("#existing_filters option[value="+id+"]").text();
843
                console.log(id,name);
844
                save_search_filter(name,id);
845
            });
846
            function save_search_filter(name,id,opac,staff){
847
                let options = {
848
                    url: '/api/v1/search_filters',
849
                    contentType: "application/json",
850
                    data: JSON.stringify({
851
                        name: name,
852
                        filter_query: JSON.stringify(search_result.query_json),
853
                        filter_limits: JSON.stringify(search_result.limit_json),
854
                        opac: opac,
855
                        staff_client: staff,
856
                    })
857
                };
858
                if (id){
859
                    options.method = "PUT";
860
                    options.url = options.url+"/"+id
861
                } else {
862
                    options.method = "POST";
863
                }
864
                $.ajax(options)
865
                    .then(function(result) {
866
                        $("#search_filters_modal").modal('hide');
867
                        humanMsg.displayAlert( _("Saved filter: ") + name  , { className: 'human Success' } );
868
                        getFilters();
869
                    })
870
                    .fail(function(err) {
871
                        console.log(err);
872
                        humanMsg.displayAlert( _("There was an error during saving:") + err.responseText, { className: 'humanError' } );
873
                    });
874
            }
875
876
        [% END %]
757
    </script>
877
    </script>
758
    [% Asset.js("js/pages/results.js") | $raw %]
878
    [% Asset.js("js/pages/results.js") | $raw %]
759
[% END %]
879
[% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-facets.inc (+17 lines)
Lines 5-10 Link Here
5
    <div id="search-facets">
5
    <div id="search-facets">
6
        <h2><a href="#" class="menu-collapse-toggle">Refine your search</a></h2>
6
        <h2><a href="#" class="menu-collapse-toggle">Refine your search</a></h2>
7
        <ul class="menu-collapse">
7
        <ul class="menu-collapse">
8
            [% IF Koha.Preference("SavedSearchFilters") && search_filters.size > 0 %]
9
            <li id="search-filters">
10
            <h3 id="filter_facets">Custom search filters</h3>
11
            <ul>
12
                [% SET base_url = "/cgi-bin/koha/opac-search.pl?" _ query_cgi _ limit_cgi %]
13
                [% FOREACH search_filter IN search_filters %]
14
                <li>
15
                    [% IF active_filters.${search_filter.id} %]
16
                        <span class="filter_label">[% search_filter.name | html %]<a href="[% base_url _ '&nolimit=search_filter:' _ search_filter.id | url %]">[X]</a></span>
17
                    [% ELSE %]
18
                        <span class="filter_label"><a href="[% base_url _ '&limit=search_filter:' _ search_filter.id | url %]">[% search_filter.name | html %]</a></span>
19
                    [% END %]
20
                </li>
21
                [% END %]
22
            </ul>
23
            </li>
24
            [% END %]
8
            <li id="availability_facet"><h3 id="facet-availability">Availability</h3>
25
            <li id="availability_facet"><h3 id="facet-availability">Availability</h3>
9
                <ul>
26
                <ul>
10
                    <li>
27
                    <li>
(-)a/opac/opac-search.pl (-1 / +10 lines)
Lines 833-838 for my $facet ( @$facets ) { Link Here
833
    }
833
    }
834
}
834
}
835
835
836
my @search_filters = Koha::SearchFilters->search({ opac => 1 }, { order_by => "name" })->as_list;
837
my %active_filters;
838
foreach my $sf (@search_filters){
839
    $active_filters{$sf->id} = 1 if grep { "search_filter:".$sf->id eq $_->{input_value} } @limit_inputs;
840
}
841
$template->param(
842
    search_filters => \@search_filters,
843
    active_filters => \%active_filters,
844
) if C4::Context->preference('SavedSearchFilters');
845
836
846
837
$template->param(
847
$template->param(
838
            #classlist => $classlist,
848
            #classlist => $classlist,
839
- 

Return to bug 17170