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 479-484 $template->param ( QUERY_INPUTS => \@query_inputs, Link Here
479
481
480
## parse the limit_cgi string and put it into a form suitable for <input>s
482
## parse the limit_cgi string and put it into a form suitable for <input>s
481
my @limit_inputs;
483
my @limit_inputs;
484
my %active_filters;
482
if ($limit_cgi) {
485
if ($limit_cgi) {
483
    for my $this_cgi ( split('&', $limit_cgi) ) {
486
    for my $this_cgi ( split('&', $limit_cgi) ) {
484
        next unless $this_cgi;
487
        next unless $this_cgi;
Lines 492-497 if ($limit_cgi) { Link Here
492
        my $input_value = $2;
495
        my $input_value = $2;
493
        $input_name =~ s/=$//;
496
        $input_name =~ s/=$//;
494
        push @limit_inputs, { input_name => $input_name, input_value => Encode::decode_utf8( uri_unescape($input_value) ) };
497
        push @limit_inputs, { input_name => $input_name, input_value => Encode::decode_utf8( uri_unescape($input_value) ) };
498
        if( $input_value =~ /search_filter/ ){
499
            my ($filter_id) = ( uri_unescape($input_value) =~ /^search_filter:(.*)$/ );
500
            $active_filters{$filter_id} = 1;
501
        }
502
495
    }
503
    }
496
}
504
}
497
$template->param ( LIMIT_INPUTS => \@limit_inputs );
505
$template->param ( LIMIT_INPUTS => \@limit_inputs );
Lines 576-584 for (my $i=0;$i<@servers;$i++) { Link Here
576
        $template->param (z3950_search_params => C4::Search::z3950_search_args($z3950par || $query_desc));
584
        $template->param (z3950_search_params => C4::Search::z3950_search_args($z3950par || $query_desc));
577
        $template->param(limit_cgi => $limit_cgi);
585
        $template->param(limit_cgi => $limit_cgi);
578
        $template->param(query_cgi => $query_cgi);
586
        $template->param(query_cgi => $query_cgi);
587
        $template->param(query_json => encode_json({
588
            operators => \@operators,
589
            operands => \@operands,
590
            indexes => \@indexes
591
        }));
592
        $template->param(limit_json => encode_json({
593
            limits => \@limits
594
        }));
579
        $template->param(query_desc => $query_desc);
595
        $template->param(query_desc => $query_desc);
580
        $template->param(limit_desc => $limit_desc);
596
        $template->param(limit_desc => $limit_desc);
581
        $template->param(offset     => $offset);
597
        $template->param(offset     => $offset);
598
        $template->param(offset     => $offset);
599
582
600
583
        if ($hits) {
601
        if ($hits) {
584
            $template->param(total => $hits);
602
            $template->param(total => $hits);
Lines 667-672 for my $facet ( @$facets ) { Link Here
667
    }
685
    }
668
}
686
}
669
687
688
689
$template->param(
690
    search_filters => Koha::SearchFilters->search({ staff_client => 1 }, { order_by => "name" }),
691
    active_filters => \%active_filters,
692
) if C4::Context->preference('SavedSearchFilters');
693
670
$template->param(
694
$template->param(
671
            #classlist => $classlist,
695
            #classlist => $classlist,
672
            total => $total,
696
            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 67-72 Link Here
67
                        [% 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 %].
67
                        [% 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 %].
68
                    </h3>
68
                    </h3>
69
                    <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>
69
                    <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>
70
                    [% IF ( Koha.Preference('SavedSearchFilters') && CAN_user_parameters_manage_search_filters ) %]
71
                        | <a href="#" id="save_search_filter">Save search as filter</a>
72
                    [% END %]
70
73
71
                    <div class="searchheader" id="searchheader">
74
                    <div class="searchheader" id="searchheader">
72
                        <div id="selection_ops">
75
                        <div id="selection_ops">
Lines 323-328 Link Here
323
                                <p><a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% searchtoorder_basketno | uri %]">View basket<a></p>
326
                                <p><a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% searchtoorder_basketno | uri %]">View basket<a></p>
324
                            [% END %]
327
                            [% END %]
325
                            <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>
328
                            <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>
329
                            [% IF ( Koha.Preference('SavedSearchFilters') &&CAN_user_parameters_manage_search_filters ) %]
330
                                | <a href="#" id="save_search_filter">Save search as filter</a>
331
                            [% END %]
326
                        [% ELSE %]
332
                        [% ELSE %]
327
                            <p>You did not specify any search criteria.</p>
333
                            <p>You did not specify any search criteria.</p>
328
                        [% END %]
334
                        [% END %]
Lines 679-684 Link Here
679
                </div>
685
                </div>
680
                [% END #/IF outer_sup_results_loop %]
686
                [% END #/IF outer_sup_results_loop %]
681
687
688
                [% IF ( Koha.Preference('SavedSearchFilters') && CAN_user_parameters_manage_search_filters ) %]
689
                    <div id="search_filters_modal" class="modal" role="dialog" aria-hidden="true">
690
                        <div class="modal-dialog">
691
                        <div class="modal-content">
692
                            <div class="modal-header">
693
                                <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
694
                                <h3 id="search_filters_label">Save: '[% query_desc | html %]' with limits '[% limit_desc | html %]' as filter</h3>
695
                            </div>
696
                            <div class="modal-body">
697
                                <h6>Visibility:</h6>
698
                                <label for="show_filter_opac">Show in OPAC?</label>
699
                                <input type="checkbox" id="show_filter_opac" name="show_filter_opac">
700
                                <label for="show_filter_staff_client">Show in Staff client?</label>
701
                                <input type="checkbox" id="show_filter_staff_client" name="show_filter_staff_client">
702
                                <hr>
703
                                <h6>Save as new search filter:</h6>
704
                                <label for="new_filter">Name:</label>
705
                                <input id="new_filter" name="new_filter" type="text">
706
                                <a id="save_new_filter" class="btn btn-default btn-xs" href="#">Save</a>
707
                                </br>OR</br>
708
                                <h6>Replace existing search filter:</h6>
709
                                <label for="existing_filters">Choose</label>
710
                                <select id="existing_filters" name="existing_filters" class="search_filters_list"></select>
711
                                <a id="replace_existing_filter" class="btn btn-default btn-xs" href="#">Replace</a>
712
                            </div>
713
                            <div class="modal-footer">
714
                                <a href="#" data-dismiss="modal" aria-hidden="true" class="cancel">Cancel</a>
715
                            </div>
716
                        </div>
717
                        </div>
718
                    </div>
719
                [% END %]
720
682
                <form id="hold_form" method="get" action="/cgi-bin/koha/reserve/request.pl">
721
                <form id="hold_form" method="get" action="/cgi-bin/koha/reserve/request.pl">
683
                    <!-- Value will be set here by placeHold() -->
722
                    <!-- Value will be set here by placeHold() -->
684
                    <input type="hidden" name="findborrower" id="holdFor" value="" />
723
                    <input type="hidden" name="findborrower" id="holdFor" value="" />
Lines 704-709 Link Here
704
    [% Asset.js("js/browser.js") | $raw %]
743
    [% Asset.js("js/browser.js") | $raw %]
705
    [% Asset.js("lib/hc-sticky.js") | $raw %]
744
    [% Asset.js("lib/hc-sticky.js") | $raw %]
706
    [% Asset.js("js/coce.js") | $raw %]
745
    [% Asset.js("js/coce.js") | $raw %]
746
    [% Asset.css("css/humanmsg.css") | $raw %]
747
    [% Asset.js("lib/jquery/plugins/humanmsg.js") | $raw %]
748
    [% INCLUDE 'select2.inc' %]
707
    <script>
749
    <script>
708
        var PREF_AmazonCoverImages = parseInt( "[% Koha.Preference('AmazonCoverImages') | html %]", 10);
750
        var PREF_AmazonCoverImages = parseInt( "[% Koha.Preference('AmazonCoverImages') | html %]", 10);
709
        var q_array = new Array();  // will hold search terms, if present
751
        var q_array = new Array();  // will hold search terms, if present
Lines 737-742 Link Here
737
            query_desc: "[% To.json( query_desc ) | html %]",
779
            query_desc: "[% To.json( query_desc ) | html %]",
738
            query_cgi: "[% query_cgi | html %]",
780
            query_cgi: "[% query_cgi | html %]",
739
            limit_cgi: "[% limit_cgi | html %]",
781
            limit_cgi: "[% limit_cgi | html %]",
782
            query_json: [% query_json | $raw %],
783
            limit_json: [% limit_json | $raw %],
740
            sort_by: "[% sort_by | html %]",
784
            sort_by: "[% sort_by | html %]",
741
            gotoPage: "[% gotoPage | html %]",
785
            gotoPage: "[% gotoPage | html %]",
742
            gotoNumber: "[% gotoNumber | html %]",
786
            gotoNumber: "[% gotoNumber | html %]",
Lines 746-751 Link Here
746
            first_biblionumber: "[% SEARCH_RESULTS.first.biblionumber | html %]",
790
            first_biblionumber: "[% SEARCH_RESULTS.first.biblionumber | html %]",
747
            last_biblionumber: "[% SEARCH_RESULTS.last.biblionumber | html %]",
791
            last_biblionumber: "[% SEARCH_RESULTS.last.biblionumber | html %]",
748
        }
792
        }
793
        [% IF ( CAN_user_parameters_manage_search_filters ) %]
794
            function getFilters(id) {
795
                const select = $("#existing_filters");
796
                $("option[value!='']", select).remove();
797
                return new Promise(function(resolve, reject) {
798
                    $.ajax("/api/v1/search_filters")
799
                    .then(resolve, reject);
800
                })
801
                .then(function(filters) {
802
                    filters.forEach(function(filter) {
803
                        const opt = $("<option/>");
804
                        select.append(opt);
805
                        if(id && filter.search_filter_id == id) {
806
                            opt.prop('selected', true);
807
                        }
808
                        opt.attr("value", filter.search_filter_id);
809
                        opt.attr("title", "Query:" + filter.filter_query + " Limit:"+filter.filter_limits);
810
                        opt.text(filter.name);
811
                        opt.data("filter", filter);
812
                    });
813
                })
814
                .then(function(){
815
                    select.change();
816
                });
817
            }
818
            $("#save_search_filter").click(function(){
819
                getFilters();
820
                $("#search_filters_modal").modal('show');
821
            });
822
            $("#save_new_filter").click(function(){
823
                let name = $("#new_filter").val().trim();
824
                if(!name){
825
                    humanMsg.displayAlert( _("You must provide a name for the new filter"), { className: 'human Error' } );
826
                    return;
827
                }
828
                let opac = $("#show_filter_opac").prop('checked');
829
                let staff = $("#show_filter_staff_client").prop('checked');
830
                save_search_filter(name,null,opac,staff);
831
            });
832
            $("#replace_existing_filter").click(function(){
833
                let id = $("#existing_filters").val();
834
                let name = $("#existing_filters option[value="+id+"]").text();
835
                console.log(id,name);
836
                save_search_filter(name,id);
837
            });
838
            function save_search_filter(name,id,opac,staff){
839
                let options = {
840
                    url: '/api/v1/search_filters',
841
                    contentType: "application/json",
842
                    data: JSON.stringify({
843
                        name: name,
844
                        filter_query: JSON.stringify(search_result.query_json),
845
                        filter_limits: JSON.stringify(search_result.limit_json),
846
                        opac: opac,
847
                        staff_client: staff,
848
                    })
849
                };
850
                if (id){
851
                    options.method = "PUT";
852
                    options.url = options.url+"/"+id
853
                } else {
854
                    options.method = "POST";
855
                }
856
                $.ajax(options)
857
                    .then(function(result) {
858
                        $("#search_filters_modal").modal('hide');
859
                        humanMsg.displayAlert( _("Saved filter: ") + name  , { className: 'human Success' } );
860
                        getFilters();
861
                    })
862
                    .fail(function(err) {
863
                        console.log(err);
864
                        humanMsg.displayAlert( _("There was an error during saving:") + err.responseText, { className: 'humanError' } );
865
                    });
866
            }
867
868
        [% END %]
749
    </script>
869
    </script>
750
    [% Asset.js("js/pages/results.js") | $raw %]
870
    [% Asset.js("js/pages/results.js") | $raw %]
751
[% END %]
871
[% 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 832-837 for my $facet ( @$facets ) { Link Here
832
    }
832
    }
833
}
833
}
834
834
835
my @search_filters = Koha::SearchFilters->search({ opac => 1 }, { order_by => "name" })->as_list;
836
my %active_filters;
837
foreach my $sf (@search_filters){
838
    $active_filters{$sf->id} = 1 if grep { "search_filter:".$sf->id eq $_->{input_value} } @limit_inputs;
839
}
840
$template->param(
841
    search_filters => \@search_filters,
842
    active_filters => \%active_filters,
843
) if C4::Context->preference('SavedSearchFilters');
844
835
845
836
$template->param(
846
$template->param(
837
            #classlist => $classlist,
847
            #classlist => $classlist,
838
- 

Return to bug 17170