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

(-)a/C4/Auth.pm (-4 / +2 lines)
Lines 387-395 sub get_template_and_user { Link Here
387
        my $opac_name = '';
387
        my $opac_name = '';
388
        if (($opac_search_limit && $opac_search_limit =~ /branch:(\w+)/ && $opac_limit_override) || ($in->{'query'}->param('limit') && $in->{'query'}->param('limit') =~ /branch:(\w+)/)){
388
        if (($opac_search_limit && $opac_search_limit =~ /branch:(\w+)/ && $opac_limit_override) || ($in->{'query'}->param('limit') && $in->{'query'}->param('limit') =~ /branch:(\w+)/)){
389
            $opac_name = $1;   # opac_search_limit is a branch, so we use it.
389
            $opac_name = $1;   # opac_search_limit is a branch, so we use it.
390
        } elsif ( $in->{'query'}->param('multibranchlimit') ) {
390
        } elsif (C4::Context->preference("SearchableBranches") ne "all" && C4::Context->userenv && C4::Context->userenv->{'branch'}) {
391
            $opac_name = $in->{'query'}->param('multibranchlimit');
392
        } elsif (C4::Context->preference("SearchMyLibraryFirst") && C4::Context->userenv && C4::Context->userenv->{'branch'}) {
393
            $opac_name = C4::Context->userenv->{'branch'};
391
            $opac_name = C4::Context->userenv->{'branch'};
394
        }
392
        }
395
        $template->param(
393
        $template->param(
Lines 435-441 sub get_template_and_user { Link Here
435
            RequestOnOpac             => C4::Context->preference("RequestOnOpac"),
433
            RequestOnOpac             => C4::Context->preference("RequestOnOpac"),
436
            'Version'                 => C4::Context->preference('Version'),
434
            'Version'                 => C4::Context->preference('Version'),
437
            hidelostitems             => C4::Context->preference("hidelostitems"),
435
            hidelostitems             => C4::Context->preference("hidelostitems"),
438
            mylibraryfirst            => (C4::Context->preference("SearchMyLibraryFirst") && C4::Context->userenv) ? C4::Context->userenv->{'branch'} : '',
436
            mylibraryfirst            => (C4::Context->preference("SearchableBranches") ne 'all' && C4::Context->userenv) ? C4::Context->userenv->{'branch'} : '',
439
            opaclayoutstylesheet      => "" . C4::Context->preference("opaclayoutstylesheet"),
437
            opaclayoutstylesheet      => "" . C4::Context->preference("opaclayoutstylesheet"),
440
            opacbookbag               => "" . C4::Context->preference("opacbookbag"),
438
            opacbookbag               => "" . C4::Context->preference("opacbookbag"),
441
            opaccredits               => "" . C4::Context->preference("opaccredits"),
439
            opaccredits               => "" . C4::Context->preference("opaccredits"),
(-)a/C4/Branch.pm (-1 / +25 lines)
Lines 20-25 use strict; Link Here
20
#use warnings; FIXME - Bug 2505
20
#use warnings; FIXME - Bug 2505
21
require Exporter;
21
require Exporter;
22
use C4::Context;
22
use C4::Context;
23
use C4::Members::Attributes;
24
use C4::Members;
23
25
24
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
26
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
25
27
Lines 113-123 sub GetBranches { Link Here
113
    my $sth;
115
    my $sth;
114
    my $query="SELECT * FROM branches";
116
    my $query="SELECT * FROM branches";
115
    my @bind_parameters;
117
    my @bind_parameters;
118
    my $borrowernumber;
119
    if(C4::Context->userenv){$borrowernumber = C4::Context->userenv->{number}};
120
116
    if ($onlymine && C4::Context->userenv && C4::Context->userenv->{branch}){
121
    if ($onlymine && C4::Context->userenv && C4::Context->userenv->{branch}){
117
      $query .= ' WHERE branchcode = ? ';
122
      $query .= ' WHERE branchcode = ? ';
118
      push @bind_parameters, C4::Context->userenv->{branch};
123
      push @bind_parameters, C4::Context->userenv->{branch};
124
    } elsif(C4::Context->preference("SearchableBranches") eq 'securehome' && C4::Context->userenv && $borrowernumber !=0) { # Preference is set to search only the branches specified in patron record.
125
      my %borrower_branches;
126
      if(C4::Context->preference("multibranch")) {
127
         my $value = C4::Members::Attributes::GetBorrowerAttributeValue($borrowernumber, "branchcode",1); #calling for an arrayref with all values.
128
         foreach my $branchcode (@{$value}) {
129
            $borrower_branches{$$branchcode[0]} = 1;
130
         }
131
     }
132
     my $members = GetMember( 'borrowernumber' => $borrowernumber );
133
     my $homebranch = $members->{'branchcode'};
134
     $borrower_branches{$homebranch} = 1 if $homebranch;
135
     if($ENV{'OPAC_SEARCH_LIMIT'} =~ m/^branch:(.*)/){
136
        $borrower_branches{$1} = 1;
137
     }
138
     my @allowedbranches;
139
     foreach my $branch (keys %borrower_branches) {
140
       push @allowedbranches, $branch;
141
     }
142
     $query .= ' WHERE branchcode in (\''.join('\',\'',@allowedbranches).'\')';;
119
    }
143
    }
120
        $query.=" ORDER BY branchname";
144
    $query.=" ORDER BY branchname";
121
    $sth = $dbh->prepare($query);
145
    $sth = $dbh->prepare($query);
122
    $sth->execute( @bind_parameters );
146
    $sth->execute( @bind_parameters );
123
147
(-)a/C4/Koha.pm (-2 / +2 lines)
Lines 716-722 sub getFacets { Link Here
716
            ];
716
            ];
717
717
718
            my $library_facet;
718
            my $library_facet;
719
            unless ( C4::Context->preference("singleBranchMode") || GetBranchesCount() == 1 ) {
719
            unless ( C4::Context->preference("singleBranchMode") || C4::Branch::GetBranchesCount() == 1 ) {
720
                $library_facet = {
720
                $library_facet = {
721
                    idx  => 'branch',
721
                    idx  => 'branch',
722
                    label => 'Libraries',
722
                    label => 'Libraries',
Lines 777-783 sub getFacets { Link Here
777
            ];
777
            ];
778
778
779
            my $library_facet;
779
            my $library_facet;
780
            unless ( C4::Context->preference("singleBranchMode") || GetBranchesCount() == 1 ) {
780
            unless ( C4::Context->preference("singleBranchMode") || C4::Branch::GetBranchesCount() == 1 ) {
781
                $library_facet = {
781
                $library_facet = {
782
                    idx  => 'branch',
782
                    idx  => 'branch',
783
                    label => 'Libraries',
783
                    label => 'Libraries',
(-)a/C4/Members/Attributes.pm (-5 / +9 lines)
Lines 120-143 sub GetAttributes { Link Here
120
120
121
=head2 GetBorrowerAttributeValue
121
=head2 GetBorrowerAttributeValue
122
122
123
  my $value = C4::Members::Attributes::GetBorrowerAttributeValue($borrowernumber, $attribute_code);
123
  my $value = C4::Members::Attributes::GetBorrowerAttributeValue($borrowernumber, $attribute_code, $as_array);
124
124
125
Retrieve the value of an extended attribute C<$attribute_code> associated with the
125
Retrieve the value of an extended attribute C<$attribute_code> associated with the
126
patron specified by C<$borrowernumber>.
126
patron specified by C<$borrowernumber>. If $as_array is true, gets all available values, and returns it as an arrayref.
127
127
128
=cut
128
=cut
129
129
130
sub GetBorrowerAttributeValue {
130
sub GetBorrowerAttributeValue {
131
    my $borrowernumber = shift;
131
    my $borrowernumber = shift;
132
    my $code = shift;
132
    my $code = shift;
133
133
    my $as_array = shift;
134
    my $dbh = C4::Context->dbh();
134
    my $dbh = C4::Context->dbh();
135
    my $query = "SELECT attribute
135
    my $query = "SELECT attribute
136
                 FROM borrower_attributes
136
                 FROM borrower_attributes
137
                 WHERE borrowernumber = ?
137
                 WHERE borrowernumber = ?
138
                 AND code = ?";
138
                 AND code = ?";
139
    my $value = $dbh->selectrow_array($query, undef, $borrowernumber, $code);
139
    if ($as_array){
140
    return $value;
140
      return $dbh->selectall_arrayref($query,undef, $borrowernumber, $code);
141
    } else {
142
      my $value = $dbh->selectrow_array($query, undef, $borrowernumber, $code);
143
      return $value;
144
    }
141
}
145
}
142
146
143
=head2 SearchIdMatchingAttribute
147
=head2 SearchIdMatchingAttribute
(-)a/installer/data/mysql/sysprefs.sql (-1 / +3 lines)
Lines 182-187 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
182
('maxreserves','50','','Define maximum number of holds a patron can place','Integer'),
182
('maxreserves','50','','Define maximum number of holds a patron can place','Integer'),
183
('memberofinstitution','0',NULL,'If ON, patrons can be linked to institutions','YesNo'),
183
('memberofinstitution','0',NULL,'If ON, patrons can be linked to institutions','YesNo'),
184
('minPasswordLength','3',NULL,'Specify the minimum length of a patron/staff password','free'),
184
('minPasswordLength','3',NULL,'Specify the minimum length of a patron/staff password','free'),
185
('multibranch',0,NULL,'If ON, patrons having borrower_attribute's of branchcode, will have them added to their branches allowed, list. Filters all branch lists and opac searches.','YesNo'),
186
('MultiBranchSelect',0,NULL,'If ON, Shows a muiltibranch dropdown instead of a single branch, in advanced search by branch','YesNo'),
185
('NewItemsDefaultLocation','','','If set, all new items will have a location of the given Location Code ( Authorized Value type LOC )',''),
187
('NewItemsDefaultLocation','','','If set, all new items will have a location of the given Location Code ( Authorized Value type LOC )',''),
186
('noissuescharge','5','','Define maximum amount withstanding before check outs are blocked','Integer'),
188
('noissuescharge','5','','Define maximum amount withstanding before check outs are blocked','Integer'),
187
('noItemTypeImages','0',NULL,'If ON, disables item-type images','YesNo'),
189
('noItemTypeImages','0',NULL,'If ON, disables item-type images','YesNo'),
Lines 328-335 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
328
('RoutingSerials','1',NULL,'If ON, serials routing is enabled','YesNo'),
330
('RoutingSerials','1',NULL,'If ON, serials routing is enabled','YesNo'),
329
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
331
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
330
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
332
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
333
('SearchableBranches','all','all|preferhome|securehome','Sets level of security, and search preference. all - default koha search all, or one specified library, all libraries is the default. preferhome - sets the patrons home library as the default search limit. securehome - Only patrons home library, and others specified by enviroment, and borrower extended attributes (If Patron - Multibranch is enabled), can be searched. Home library set by default.','Choice'),
331
('SearchEngine','Zebra','Solr|Zebra','Search Engine','Choice'),
334
('SearchEngine','Zebra','Solr|Zebra','Search Engine','Choice'),
332
('SearchMyLibraryFirst','0',NULL,'If ON, OPAC searches return results limited by the user\'s library by default if they are logged in','YesNo'),
333
('SelfCheckHelpMessage','','70|10','Enter HTML to include under the basic Web-based Self Checkout instructions on the Help page','Textarea'),
335
('SelfCheckHelpMessage','','70|10','Enter HTML to include under the basic Web-based Self Checkout instructions on the Help page','Textarea'),
334
('SelfCheckTimeout','120','','Define the number of seconds before the Web-based Self Checkout times out a patron','Integer'),
336
('SelfCheckTimeout','120','','Define the number of seconds before the Web-based Self Checkout times out a patron','Integer'),
335
('SeparateHoldings','0',NULL,'Separate current branch holdings from other holdings','YesNo'),
337
('SeparateHoldings','0',NULL,'Separate current branch holdings from other holdings','YesNo'),
(-)a/installer/data/mysql/updatedatabase.pl (-1 / +13 lines)
Lines 7214-7220 if ( CheckVersion($DBversion) ) { Link Here
7214
    print "Upgrade to $DBversion done (Bug 10854: Add the default CSV profile for claiming issues)\n";
7214
    print "Upgrade to $DBversion done (Bug 10854: Add the default CSV profile for claiming issues)\n";
7215
    SetVersion($DBversion);
7215
    SetVersion($DBversion);
7216
}
7216
}
7217
7218
$DBversion = "3.13.00.030";
7217
$DBversion = "3.13.00.030";
7219
if ( CheckVersion($DBversion) ) {
7218
if ( CheckVersion($DBversion) ) {
7220
    $dbh->do(qq{
7219
    $dbh->do(qq{
Lines 7750-7755 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { Link Here
7750
    SetVersion($DBversion);
7749
    SetVersion($DBversion);
7751
}
7750
}
7752
7751
7752
$DBversion = "XXX";
7753
if (  CheckVersion($DBversion) ) {
7754
    $dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('SearchableBranches','all','Sets level of security, and search preference. all - default koha search all, or one specified library, all libraries is the default. preferhome - sets the patrons home library as the default search limit. securehome - Only patrons home library, and others specified by enviroment, and borrower extended attributes (If Patron - Multibranch is enabled), can be searched. Home library set by default.','all|preferhome|securehome','Choice');");
7755
    $dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('multibranch',0,'If ON, patrons having borrower_attributes of branchcode, will have them added to their branches allowed, list. Filters all branch lists and opac searches.',NULL,'YesNo');");
7756
    $dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('MultiBranchSelect',0,'If ON, Shows a muiltibranch dropdown instead of a single branch, in advanced search by branch',NULL,'YesNo');");
7757
    if (C4::Context->preference("SearchMyLibraryFirst")){
7758
       $dbh->do(qq{UPDATE systempreferences SET value='preferhome' WHERE variable="SearchableBranches"});
7759
    } else {
7760
       $dbh->do(qq{UPDATE systempreferences SET value='all' WHERE variable="SearchableBranches"});
7761
    }
7762
    print "Upgrade to $DBversion done (Bug 9055: Mandumah.com's multiple branch search, multiple branch security mod)";
7763
    SetVersion($DBversion);
7764
}
7753
7765
7754
=head1 FUNCTIONS
7766
=head1 FUNCTIONS
7755
7767
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (-5 / +7 lines)
Lines 434-444 OPAC: Link Here
434
                  no: Allow
434
                  no: Allow
435
            - patrons to select their branch on the OPAC or show branch names with callnumbers.
435
            - patrons to select their branch on the OPAC or show branch names with callnumbers.
436
        -
436
        -
437
            - pref: SearchMyLibraryFirst
437
             - Search
438
              choices:
438
             - pref: SearchableBranches
439
                  yes: Limit
439
               choices:
440
                  no: "Don't limit"
440
                  all: All libraries
441
            - "patrons' searches to the library they are registered at."
441
                  preferhome: Prefers patrons' home library (others may be searched)
442
                  securehome:  Only patrons' home library and other assigned libraries (if any) can be searched
443
             - Note, Other assigned libraries are only accessable by logged-in users. Otherwise, in Only mode, Home library is set via virtualhost option, and no other libraries are available. Multiple libraries can only be assigned when Multibranch is enabled, found in the Patron syspref page.
442
#        -
444
#        -
443
#            This system preference does not actually affect anything
445
#            This system preference does not actually affect anything
444
#            - pref: OpacBrowser
446
#            - pref: OpacBrowser
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref (+6 lines)
Lines 91-96 Patrons: Link Here
91
           class: integer
91
           class: integer
92
         - characters long.
92
         - characters long.
93
     -
93
     -
94
         - pref: multibranch
95
           choices:
96
                yes: "ON"
97
                no: "off"
98
         - If ON, patrons having borrower_attribute's of branchcode, will have them added to their branches allowed, list. Filters all branch lists and opac searches.
99
     -
94
         - Show a notice that a patron is about to expire
100
         - Show a notice that a patron is about to expire
95
         - pref: NotifyBorrowerDeparture
101
         - pref: NotifyBorrowerDeparture
96
           class: integer
102
           class: integer
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/searching.pref (+7 lines)
Lines 79-84 Searching: Link Here
79
            - "fields (separate values with |). Tabs appear in the order listed.<br/>"
79
            - "fields (separate values with |). Tabs appear in the order listed.<br/>"
80
            - "<em>Currently supported values</em>: Item types (<strong>itemtypes</strong>), Collection Codes (<strong>ccode</strong>) and Shelving Location (<strong>loc</strong>)."
80
            - "<em>Currently supported values</em>: Item types (<strong>itemtypes</strong>), Collection Codes (<strong>ccode</strong>) and Shelving Location (<strong>loc</strong>)."
81
        -
81
        -
82
            - pref: MultiBranchSelect
83
              type: boolean
84
              choices:
85
                  yes: Show
86
                  no: "Don't show"
87
            - 'a multibranch dropdown instead of single branch.'
88
        -
82
            - By default,
89
            - By default,
83
            - pref: expandedSearchOption
90
            - pref: expandedSearchOption
84
              type: boolean
91
              type: boolean
(-)a/koha-tmpl/opac-tmpl/lib/jquery/plugins/css/jquery.multiSelect.css (+85 lines)
Line 0 Link Here
1
a.multiSelect {
2
	background: #FFF url(../images/dropdown.blue.png) right center no-repeat;
3
	border: solid 1px #BBB;
4
	padding-right: 20px;
5
	position: relative;
6
	cursor: default;
7
	text-decoration: none;
8
	color: black;
9
	display: -moz-inline-stack;
10
	display: inline-block;
11
	vertical-align: top;
12
}
13
14
a.multiSelect:link, a.multiSelect:visited, a.multiSelect:hover, a.multiSelect:active {
15
	color: black;
16
	text-decoration: none;
17
}
18
19
a.multiSelect span
20
{
21
	margin: 1px 0px 1px 3px;
22
	overflow: hidden;
23
	display: -moz-inline-stack;
24
	display: inline-block;
25
	white-space: nowrap;
26
}
27
28
a.multiSelect.hover {
29
	background-image: url(../images/dropdown.blue.hover.png);
30
}
31
32
a.multiSelect.active, 
33
a.multiSelect.focus {
34
	border: inset 1px #000;
35
}
36
37
a.multiSelect.active {
38
	background-image: url(../images/dropdown.blue.active.png);
39
}
40
41
.multiSelectOptions {
42
	margin-top: -1px;
43
	overflow-y: auto;
44
	overflow-x: hidden;
45
	border: solid 1px #B2B2B2;
46
	background: #FFF;
47
}
48
49
.multiSelectOptions LABEL {
50
	padding: 0px 2px;
51
	display: block;
52
	white-space: nowrap;
53
}
54
55
.multiSelectOptions LABEL.optGroup
56
{
57
	font-weight: bold;
58
}
59
60
.multiSelectOptions .optGroupContainer LABEL
61
{
62
	padding-left: 10px;
63
}
64
65
.multiSelectOptions.optGroupHasCheckboxes .optGroupContainer LABEL
66
{
67
	padding-left: 18px;
68
}
69
70
.multiSelectOptions input{
71
	vertical-align: middle;
72
}
73
74
.multiSelectOptions LABEL.checked {
75
	background-color: #dce5f8;
76
}
77
78
.multiSelectOptions LABEL.selectAll {
79
	border-bottom: dotted 1px #CCC;
80
}
81
82
.multiSelectOptions LABEL.hover {
83
	background-color: #3399ff;
84
	color: white;
85
}
(-)a/koha-tmpl/opac-tmpl/lib/jquery/plugins/jquery.bgiframe.min.js (+7 lines)
Line 0 Link Here
1
/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
2
 * Licensed under the MIT License (LICENSE.txt).
3
 *
4
 * Version 2.1.3-pre
5
 */
6
7
(function($){$.fn.bgiframe=($.browser.msie&&/msie 6\.0/i.test(navigator.userAgent)?function(s){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s);var html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+'style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+'"/>';return this.each(function(){if($(this).children('iframe.bgiframe').length===0)this.insertBefore(document.createElement(html),this.firstChild)})}:function(){return this});$.fn.bgIframe=$.fn.bgiframe;function prop(n){return n&&n.constructor===Number?n+'px':n}})(jQuery);
(-)a/koha-tmpl/opac-tmpl/lib/jquery/plugins/jquery.multiSelect.js (+554 lines)
Line 0 Link Here
1
/*
2
// jQuery multiSelect
3
//
4
// Version 1.2.2 beta
5
//
6
// Cory S.N. LaViska
7
// A Beautiful Site (http://abeautifulsite.net/)
8
// 09 September 2009
9
//
10
// Visit http://abeautifulsite.net/notebook/62 for more information
11
//
12
// (Amended by Andy Richmond, Letters & Science Deans' Office, University of California, Davis)
13
//
14
// Usage: $('#control_id').multiSelect( options, callback )
15
//
16
// Options:  selectAll          - whether or not to display the Select All option; true/false, default = true
17
//           selectAllText      - text to display for selecting/unselecting all options simultaneously
18
//           noneSelected       - text to display when there are no selected items in the list
19
//           oneOrMoreSelected  - text to display when there are one or more selected items in the list
20
//                                (note: you can use % as a placeholder for the number of items selected).
21
//                                Use * to show a comma separated list of all selected; default = '% selected'
22
//           optGroupSelectable - whether or not optgroups are selectable if you use them; true/false, default = false
23
//           listHeight         - the max height of the droptdown options
24
//
25
// Dependencies:  jQuery 1.2.6 or higher (http://jquery.com/)
26
//
27
// Change Log:
28
//
29
//		1.0.1	- Updated to work with jQuery 1.2.6+ (no longer requires the dimensions plugin)
30
//				- Changed $(this).offset() to $(this).position(), per James' and Jono's suggestions
31
//
32
//		1.0.2	- Fixed issue where dropdown doesn't scroll up/down with keyboard shortcuts
33
//				- Changed '$' in setTimeout to use 'jQuery' to support jQuery.noConflict
34
//				- Renamed from jqueryMultiSelect.* to jquery.multiSelect.* per the standard recommended at
35
//				  http://docs.jquery.com/Plugins/Authoring (does not affect API methods)
36
//
37
//		1.0.3	- Now uses the bgiframe plugin (if it exists) to fix the IE6 layering bug.
38
//              - Forces IE6 to use a min-height of 200px (this needs to be added to the options)
39
//
40
//		1.1.0	- Added the ability to update the options dynamically via javascript: multiSelectOptionsUpdate(JSON)
41
//              - Added a title that displays the whole comma delimited list when using oneOrMoreSelected = *
42
//              - Moved some of the functions to be closured to make them private
43
//              - Changed the way the keyboard navigation worked to more closely match how a standard dropdown works
44
//              - ** by Andy Richmond **
45
//
46
//		1.2.0	- Added support for optgroups
47
//              - Added the ability for selectable optgroups (i.e. select all for an optgroup)
48
//              - ** by Andy Richmond **
49
//
50
//		1.2.1	- Fixed bug where input text overlapped dropdown arrow in IE (i.e. when using oneOrMoreSelected = *)
51
//              - Added option "listHeight" for min-height of the dropdown
52
//              - Fixed bug where bgiframe was causing a horizontal scrollbar and on short lists extra whitespace below the options
53
//              - ** by Andy Richmond **
54
//
55
//		1.2.2	- Fixed bug where the keypress stopped showing the dropdown because in jQuery 1.3.2 they changed the way ':visible' works
56
//              - Fixed some other bugs in the way the keyboard interface worked
57
//              - Changed the main textbox to an <a> tag (with 'display: inline-block') to prevent the display text from being selected/highlighted
58
//              - Added the ability to jump to an option by typing the first character of that option (simular to a normal drop down)
59
//              - ** by Andy Richmond **
60
//				- Added [] to make each control submit an HTML array so $.serialize() works properly
61
//
62
// Licensing & Terms of Use
63
//
64
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
65
// is copyright 2008 A Beautiful Site, LLC.
66
//
67
*/
68
if(jQuery) (function($){
69
70
	// render the html for a single option
71
	function renderOption(id, option)
72
	{
73
		var html = '<label><input type="checkbox" name="' + id + '[]" value="' + option.value + '"';
74
		if( option.selected ){
75
			html += ' checked="checked"';
76
		}
77
		html += ' />' + option.text + '</label>';
78
79
		return html;
80
	}
81
82
	// render the html for the options/optgroups
83
	function renderOptions(id, options, o)
84
	{
85
		var html = "";
86
87
		for(var i = 0; i < options.length; i++) {
88
			if(options[i].optgroup) {
89
				html += '<label class="optGroup">';
90
91
				if(o.optGroupSelectable) {
92
					html += '<input type="checkbox" class="optGroup" />' + options[i].optgroup;
93
				}
94
				else {
95
					html += options[i].optgroup;
96
				}
97
98
				html += '</label><div class="optGroupContainer">';
99
100
				html += renderOptions(id, options[i].options, o);
101
102
				html += '</div>';
103
			}
104
			else {
105
				html += renderOption(id, options[i]);
106
			}
107
		}
108
109
		return html;
110
	}
111
112
	// Building the actual options
113
	function buildOptions(options)
114
	{
115
		var multiSelect = $(this);
116
		var multiSelectOptions = multiSelect.next('.multiSelectOptions');
117
		var o = multiSelect.data("config");
118
		var callback = multiSelect.data("callback");
119
120
		// clear the existing options
121
		multiSelectOptions.html("");
122
		var html = "";
123
124
		// if we should have a select all option then add it
125
		if( o.selectAll ) {
126
			html += '<label class="selectAll"><input type="checkbox" class="selectAll" />' + o.selectAllText + '</label>';
127
		}
128
129
		// generate the html for the new options
130
		html += renderOptions(multiSelect.attr('id'), options, o);
131
132
		multiSelectOptions.html(html);
133
134
		// variables needed to account for width changes due to a scrollbar
135
		var initialWidth = multiSelectOptions.width();
136
		var hasScrollbar = false;
137
138
		// set the height of the dropdown options
139
		if(multiSelectOptions.height() > o.listHeight) {
140
			multiSelectOptions.css("height", o.listHeight + 'px');
141
			hasScrollbar = true;
142
		} else {
143
			multiSelectOptions.css("height", '');
144
		}
145
146
		// if the there is a scrollbar and the browser did not already handle adjusting the width (i.e. Firefox) then we will need to manaually add the scrollbar width
147
		var scrollbarWidth = hasScrollbar && (initialWidth == multiSelectOptions.width()) ? 17 : 0;
148
149
		// set the width of the dropdown options
150
		if((multiSelectOptions.width() + scrollbarWidth) < multiSelect.outerWidth()) {
151
			multiSelectOptions.css("width", multiSelect.outerWidth() - 2/*border*/ + 'px');
152
		} else {
153
			multiSelectOptions.css("width", (multiSelectOptions.width() + scrollbarWidth) + 'px');
154
		}
155
156
		// Apply bgiframe if available on IE6
157
		if( $.fn.bgiframe ) multiSelect.next('.multiSelectOptions').bgiframe( { width: multiSelectOptions.width(), height: multiSelectOptions.height() });
158
159
		// Handle selectAll oncheck
160
		if(o.selectAll) {
161
			multiSelectOptions.find('INPUT.selectAll').click( function() {
162
				// update all the child checkboxes
163
				multiSelectOptions.find('INPUT:checkbox').attr('checked', $(this).attr('checked')).parent("LABEL").toggleClass('checked', $(this).attr('checked'));
164
			});
165
		}
166
167
		// Handle OptGroup oncheck
168
		if(o.optGroupSelectable) {
169
			multiSelectOptions.addClass('optGroupHasCheckboxes');
170
171
			multiSelectOptions.find('INPUT.optGroup').click( function() {
172
				// update all the child checkboxes
173
				$(this).parent().next().find('INPUT:checkbox').attr('checked', $(this).attr('checked')).parent("LABEL").toggleClass('checked', $(this).attr('checked'));
174
			});
175
		}
176
177
		// Handle all checkboxes
178
		multiSelectOptions.find('INPUT:checkbox').click( function() {
179
			// set the label checked class
180
			$(this).parent("LABEL").toggleClass('checked', $(this).attr('checked'));
181
182
			updateSelected.call(multiSelect);
183
			multiSelect.focus();
184
			if($(this).parent().parent().hasClass('optGroupContainer')) {
185
				updateOptGroup.call(multiSelect, $(this).parent().parent().prev());
186
			}
187
			if( callback ) {
188
				callback($(this));
189
			}
190
		});
191
192
		// Initial display
193
		multiSelectOptions.each( function() {
194
			$(this).find('INPUT:checked').parent().addClass('checked');
195
		});
196
197
		// Initialize selected and select all
198
		updateSelected.call(multiSelect);
199
200
		// Initialize optgroups
201
		if(o.optGroupSelectable) {
202
			multiSelectOptions.find('LABEL.optGroup').each( function() {
203
				updateOptGroup.call(multiSelect, $(this));
204
			});
205
		}
206
207
		// Handle hovers
208
		multiSelectOptions.find('LABEL:has(INPUT)').hover( function() {
209
			$(this).parent().find('LABEL').removeClass('hover');
210
			$(this).addClass('hover');
211
		}, function() {
212
			$(this).parent().find('LABEL').removeClass('hover');
213
		});
214
215
		// Keyboard
216
		multiSelect.keydown( function(e) {
217
218
			var multiSelectOptions = $(this).next('.multiSelectOptions');
219
220
			// Is dropdown visible?
221
			if( multiSelectOptions.css('visibility') != 'hidden' ) {
222
				// Dropdown is visible
223
				// Tab
224
				if( e.keyCode == 9 ) {
225
					$(this).addClass('focus').trigger('click'); // esc, left, right - hide
226
					$(this).focus().next(':input').focus();
227
					return true;
228
				}
229
230
				// ESC, Left, Right
231
				if( e.keyCode == 27 || e.keyCode == 37 || e.keyCode == 39 ) {
232
					// Hide dropdown
233
					$(this).addClass('focus').trigger('click');
234
				}
235
				// Down || Up
236
				if( e.keyCode == 40 || e.keyCode == 38) {
237
					var allOptions = multiSelectOptions.find('LABEL');
238
					var oldHoverIndex = allOptions.index(allOptions.filter('.hover'));
239
					var newHoverIndex = -1;
240
241
					// if there is no current highlighted item then highlight the first item
242
					if(oldHoverIndex < 0) {
243
						// Default to first item
244
						multiSelectOptions.find('LABEL:first').addClass('hover');
245
					}
246
					// else if we are moving down and there is a next item then move
247
					else if(e.keyCode == 40 && oldHoverIndex < allOptions.length - 1)
248
					{
249
						newHoverIndex = oldHoverIndex + 1;
250
					}
251
					// else if we are moving up and there is a prev item then move
252
					else if(e.keyCode == 38 && oldHoverIndex > 0)
253
					{
254
						newHoverIndex = oldHoverIndex - 1;
255
					}
256
257
					if(newHoverIndex >= 0) {
258
						$(allOptions.get(oldHoverIndex)).removeClass('hover'); // remove the current highlight
259
						$(allOptions.get(newHoverIndex)).addClass('hover'); // add the new highlight
260
261
						// Adjust the viewport if necessary
262
						adjustViewPort(multiSelectOptions);
263
					}
264
265
					return false;
266
				}
267
268
				// Enter, Space
269
				if( e.keyCode == 13 || e.keyCode == 32 ) {
270
					var selectedCheckbox = multiSelectOptions.find('LABEL.hover INPUT:checkbox');
271
272
					// Set the checkbox (and label class)
273
					selectedCheckbox.attr('checked', !selectedCheckbox.attr('checked')).parent("LABEL").toggleClass('checked', selectedCheckbox.attr('checked'));
274
275
					// if the checkbox was the select all then set all the checkboxes
276
					if(selectedCheckbox.hasClass("selectAll")) {
277
						multiSelectOptions.find('INPUT:checkbox').attr('checked', selectedCheckbox.attr('checked')).parent("LABEL").addClass('checked').toggleClass('checked', selectedCheckbox.attr('checked'));
278
					}
279
280
					updateSelected.call(multiSelect);
281
282
					if( callback ) callback($(this));
283
					return false;
284
				}
285
286
				// Any other standard keyboard character (try and match the first character of an option)
287
				if( e.keyCode >= 33 && e.keyCode <= 126 ) {
288
					// find the next matching item after the current hovered item
289
					var match = multiSelectOptions.find('LABEL:startsWith(' + String.fromCharCode(e.keyCode) + ')');
290
291
					var currentHoverIndex = match.index(match.filter('LABEL.hover'));
292
293
					// filter the set to any items after the current hovered item
294
					var afterHoverMatch = match.filter(function (index) {
295
						return index > currentHoverIndex;
296
					});
297
298
					// if there were no item after the current hovered item then try using the full search results (filtered to the first one)
299
					match = (afterHoverMatch.length >= 1 ? afterHoverMatch : match).filter("LABEL:first");
300
301
					if(match.length == 1) {
302
						// if we found a match then move the hover
303
						multiSelectOptions.find('LABEL.hover').removeClass('hover');
304
						match.addClass('hover');
305
306
						adjustViewPort(multiSelectOptions);
307
					}
308
				}
309
			} else {
310
				// Dropdown is not visible
311
				if( e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13 || e.keyCode == 32 ) { //up, down, enter, space - show
312
					// Show dropdown
313
					$(this).removeClass('focus').trigger('click');
314
					multiSelectOptions.find('LABEL:first').addClass('hover');
315
					return false;
316
				}
317
				//  Tab key
318
				if( e.keyCode == 9 ) {
319
					// Shift focus to next INPUT element on page
320
					multiSelectOptions.next(':input').focus();
321
					return true;
322
				}
323
			}
324
			// Prevent enter key from submitting form
325
			if( e.keyCode == 13 ) return false;
326
		});
327
	}
328
329
	// Adjust the viewport if necessary
330
	function adjustViewPort(multiSelectOptions)
331
	{
332
		// check for and move down
333
		var selectionBottom = multiSelectOptions.find('LABEL.hover').position().top + multiSelectOptions.find('LABEL.hover').outerHeight();
334
335
		if(selectionBottom > multiSelectOptions.innerHeight()){
336
			multiSelectOptions.scrollTop(multiSelectOptions.scrollTop() + selectionBottom - multiSelectOptions.innerHeight());
337
		}
338
339
		// check for and move up
340
		if(multiSelectOptions.find('LABEL.hover').position().top < 0){
341
			multiSelectOptions.scrollTop(multiSelectOptions.scrollTop() + multiSelectOptions.find('LABEL.hover').position().top);
342
		}
343
	}
344
345
	// Update the optgroup checked status
346
	function updateOptGroup(optGroup)
347
	{
348
		var multiSelect = $(this);
349
		var o = multiSelect.data("config");
350
351
		// Determine if the optgroup should be checked
352
		if(o.optGroupSelectable) {
353
			var optGroupSelected = true;
354
			$(optGroup).next().find('INPUT:checkbox').each( function() {
355
				if( !$(this).attr('checked') ) {
356
					optGroupSelected = false;
357
					return false;
358
				}
359
			});
360
361
			$(optGroup).find('INPUT.optGroup').attr('checked', optGroupSelected).parent("LABEL").toggleClass('checked', optGroupSelected);
362
		}
363
	}
364
365
	// Update the textbox with the total number of selected items, and determine select all
366
	function updateSelected() {
367
		var multiSelect = $(this);
368
		var multiSelectOptions = multiSelect.next('.multiSelectOptions');
369
		var o = multiSelect.data("config");
370
371
		var i = 0;
372
		var selectAll = true;
373
		var display = '';
374
		multiSelectOptions.find('INPUT:checkbox').not('.selectAll, .optGroup').each( function() {
375
			if( $(this).attr('checked') ) {
376
				i++;
377
				display = display + $(this).parent().text() + ', ';
378
			}
379
			else selectAll = false;
380
		});
381
382
		// trim any end comma and surounding whitespace
383
		display = display.replace(/\s*\,\s*$/,'');
384
385
		if( i == 0 ) {
386
			multiSelect.find("span").html( o.noneSelected );
387
		} else {
388
                  if( o.TwoOrMoreSelected != undefined )  {
389
                    if( i == 1 ) {
390
                       multiSelect.find("span").html( display );
391
                       multiSelect.attr( "title", display );
392
                    }
393
                    else {
394
                       multiSelect.find("span").html( o.TwoOrMoreSelected.replace('%', i) );
395
                    }
396
                }
397
                    if( o.oneOrMoreSelected == '*' ) {
398
                       multiSelect.find("span").html( display );
399
                       multiSelect.attr( "title", display );
400
                    } else {
401
                       if ( o.oneOrMoreSelected != "^"){
402
                          multiSelect.find("span").html( o.oneOrMoreSelected.replace('%', i) );
403
                       }
404
                    }
405
                }
406
407
		// Determine if Select All should be checked
408
		if(o.selectAll) {
409
			multiSelectOptions.find('INPUT.selectAll').attr('checked', selectAll).parent("LABEL").toggleClass('checked', selectAll);
410
		}
411
	}
412
413
	$.extend($.fn, {
414
		multiSelect: function(o, callback) {
415
			// Default options
416
			if( !o ) o = {};
417
			if( o.selectAll == undefined ) o.selectAll = true;
418
			if( o.selectAllText == undefined ) o.selectAllText = "Select All";
419
			if( o.noneSelected == undefined ) o.noneSelected = 'Select options';
420
			if( o.oneOrMoreSelected == undefined ) o.oneOrMoreSelected = '% selected';
421
			if( o.optGroupSelectable == undefined ) o.optGroupSelectable = false;
422
			if( o.listHeight == undefined ) o.listHeight = 150;
423
424
			// Initialize each multiSelect
425
			$(this).each( function() {
426
				var select = $(this);
427
				var html = '<a href="javascript:;" class="multiSelect"><span></span></a>';
428
				html += '<div class="multiSelectOptions" style="position: absolute; z-index: 99999; visibility: hidden;"></div>';
429
				$(select).after(html);
430
431
				var multiSelect = $(select).next('.multiSelect');
432
				var multiSelectOptions = multiSelect.next('.multiSelectOptions');
433
434
				// if the select object had a width defined then match the new multilsect to it
435
				multiSelect.find("span").css("width", $(select).width() + 'px');
436
437
				// Attach the config options to the multiselect
438
				multiSelect.data("config", o);
439
440
				// Attach the callback to the multiselect
441
				multiSelect.data("callback", callback);
442
443
				// Serialize the select options into json options
444
				var options = [];
445
				$(select).children().each( function() {
446
					if(this.tagName.toUpperCase() == 'OPTGROUP')
447
					{
448
						var suboptions = [];
449
						options.push({ optgroup: $(this).attr('label'), options: suboptions });
450
451
						$(this).children('OPTION').each( function() {
452
							if( $(this).val() != '' ) {
453
								suboptions.push({ text: $(this).html(), value: $(this).val(), selected: $(this).attr('selected') });
454
							}
455
						});
456
					}
457
					else if(this.tagName.toUpperCase() == 'OPTION')
458
					{
459
						if( $(this).val() != '' ) {
460
							options.push({ text: $(this).html(), value: $(this).val(), selected: $(this).attr('selected') });
461
						}
462
					}
463
				});
464
465
				// Eliminate the original form element
466
				$(select).remove();
467
468
				// Add the id that was on the original select element to the new input
469
				multiSelect.attr("id", $(select).attr("id"));
470
471
				// Build the dropdown options
472
				buildOptions.call(multiSelect, options);
473
474
				// Events
475
				multiSelect.hover( function() {
476
					$(this).addClass('hover');
477
				}, function() {
478
					$(this).removeClass('hover');
479
				}).click( function() {
480
					// Show/hide on click
481
					if( $(this).hasClass('active') ) {
482
						$(this).multiSelectOptionsHide();
483
					} else {
484
						$(this).multiSelectOptionsShow();
485
					}
486
					return false;
487
				}).focus( function() {
488
					// So it can be styled with CSS
489
					$(this).addClass('focus');
490
				}).blur( function() {
491
					// So it can be styled with CSS
492
					$(this).removeClass('focus');
493
				});
494
495
				// Add an event listener to the window to close the multiselect if the user clicks off
496
				$(document).click( function(event) {
497
					// If somewhere outside of the multiselect was clicked then hide the multiselect
498
					if(!($(event.target).parents().andSelf().is('.multiSelectOptions'))){
499
						multiSelect.multiSelectOptionsHide();
500
					}
501
				});
502
			});
503
		},
504
505
		// Update the dropdown options
506
		multiSelectOptionsUpdate: function(options) {
507
			buildOptions.call($(this), options);
508
		},
509
510
		// Hide the dropdown
511
		multiSelectOptionsHide: function() {
512
			$(this).removeClass('active').removeClass('hover').next('.multiSelectOptions').css('visibility', 'hidden');
513
		},
514
515
		// Show the dropdown
516
		multiSelectOptionsShow: function() {
517
			var multiSelect = $(this);
518
			var multiSelectOptions = multiSelect.next('.multiSelectOptions');
519
			var o = multiSelect.data("config");
520
521
			// Hide any open option boxes
522
			$('.multiSelect').multiSelectOptionsHide();
523
			multiSelectOptions.find('LABEL').removeClass('hover');
524
			multiSelect.addClass('active').next('.multiSelectOptions').css('visibility', 'visible');
525
			multiSelect.focus();
526
527
			// reset the scroll to the top
528
			multiSelect.next('.multiSelectOptions').scrollTop(0);
529
530
			// Position it
531
			var offset = multiSelect.position();
532
			multiSelect.next('.multiSelectOptions').css({ top:  offset.top + $(this).outerHeight() + 'px' });
533
			multiSelect.next('.multiSelectOptions').css({ left: offset.left + 'px' });
534
		},
535
536
		// get a coma-delimited list of selected values
537
		selectedValuesString: function() {
538
			var selectedValues = "";
539
			$(this).next('.multiSelectOptions').find('INPUT:checkbox:checked').not('.optGroup, .selectAll').each(function() {
540
				selectedValues += $(this).attr('value') + ",";
541
			});
542
			// trim any end comma and surounding whitespace
543
			return selectedValues.replace(/\s*\,\s*$/,'');
544
		}
545
	});
546
547
	// add a new ":startsWith" search filter
548
	$.expr[":"].startsWith = function(el, i, m) {
549
		var search = m[3];
550
		if (!search) return false;
551
		return eval("/^[/s]*" + search + "/i").test($(el).text());
552
	};
553
554
})(jQuery);
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt (+12 lines)
Lines 3-11 Link Here
3
[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %]
3
[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %]
4
    catalog &rsaquo; Advanced search
4
    catalog &rsaquo; Advanced search
5
[% INCLUDE 'doc-head-close.inc' %]
5
[% INCLUDE 'doc-head-close.inc' %]
6
[% IF (MultiBranchSelect) %]
7
<script type="text/javascript" language="javascript" src="/opac-tmpl/lib/jquery/plugins/jquery.bgiframe.min.js"></script>
8
<script type="text/javascript" language="javascript" src="/opac-tmpl/lib/jquery/plugins/jquery.multiSelect.js"></script>
9
<link href="/opac-tmpl/lib/jquery/plugins//css/jquery.multiSelect.css" rel="stylesheet" type="text/css" />
10
[% END %]
6
<script type="text/javascript" language="javascript">//<![CDATA[
11
<script type="text/javascript" language="javascript">//<![CDATA[
7
            $(document).ready(function() {
12
            $(document).ready(function() {
8
            $('#advsearches').tabs();
13
            $('#advsearches').tabs();
14
            [% IF (MultiBranchSelect) %]
15
            $('#branchloop').multiSelect({ TwoOrMoreSelected: 'Multiple Libraries', oneOrMoreSelected: '^' });
16
            [% END %]
9
});
17
});
10
    //]]>
18
    //]]>
11
</script>
19
</script>
Lines 297-303 Link Here
297
    <div id="location" class="container"><fieldset><legend>Location and availability: </legend>
305
    <div id="location" class="container"><fieldset><legend>Location and availability: </legend>
298
306
299
        <label for="branchloop">Library:</label>
307
        <label for="branchloop">Library:</label>
308
        [% IF ( MultiBranchSelect ) %]
309
        <select name="limit" id="branchloop" multiple="multiple"> 
310
        [% ELSE %]
300
        <select name="limit" id="branchloop">
311
        <select name="limit" id="branchloop">
312
        [% END %]
301
        <option value="">All libraries</option>
313
        <option value="">All libraries</option>
302
        [% FOREACH BranchesLoo IN BranchesLoop %]
314
        [% FOREACH BranchesLoo IN BranchesLoop %]
303
        [% IF ( BranchesLoo.selected ) %]
315
        [% IF ( BranchesLoo.selected ) %]
(-)a/opac/opac-search.pl (-6 / +58 lines)
Lines 51-56 use C4::Tags qw(get_tags); Link Here
51
use C4::Branch; # GetBranches
51
use C4::Branch; # GetBranches
52
use C4::SocialData;
52
use C4::SocialData;
53
use C4::Ratings;
53
use C4::Ratings;
54
use C4::Members;
55
use C4::Members::Attributes;
54
use C4::External::OverDrive;
56
use C4::External::OverDrive;
55
57
56
use POSIX qw(ceil floor strftime);
58
use POSIX qw(ceil floor strftime);
Lines 123-129 else { Link Here
123
if ($template_name eq 'opac-results.tmpl') {
125
if ($template_name eq 'opac-results.tmpl') {
124
   $template->param('COinSinOPACResults' => C4::Context->preference('COinSinOPACResults'));
126
   $template->param('COinSinOPACResults' => C4::Context->preference('COinSinOPACResults'));
125
}
127
}
126
127
# get biblionumbers stored in the cart
128
# get biblionumbers stored in the cart
128
my @cart_list;
129
my @cart_list;
129
130
Lines 309-314 if ( $template_type && $template_type eq 'advsearch' ) { Link Here
309
            $template->param( expanded_options => $cgi->param('expanded_options'));
310
            $template->param( expanded_options => $cgi->param('expanded_options'));
310
        }
311
        }
311
    }
312
    }
313
    
314
    # If Multiple Branch Select is enabled, tell the template.
315
    if (C4::Context->preference("MultiBranchSelect")){
316
       $template->param( MultiBranchSelect => 1 )
317
    }
312
318
313
    if (C4::Context->preference('OPACNumbersPreferPhrase')) {
319
    if (C4::Context->preference('OPACNumbersPreferPhrase')) {
314
        $template->param('numbersphr' => 1);
320
        $template->param('numbersphr' => 1);
Lines 400-419 if ($operands[0] && !$operands[1]) { Link Here
400
406
401
# limits are use to limit to results to a pre-defined category such as branch or language
407
# limits are use to limit to results to a pre-defined category such as branch or language
402
my @limits = $cgi->param('limit');
408
my @limits = $cgi->param('limit');
403
@limits = map { uri_unescape($_) } @limits;
409
my @branches;
404
405
if($params->{'multibranchlimit'}) {
410
if($params->{'multibranchlimit'}) {
406
    my $multibranch = '('.join( " or ", map { "branch: $_ " } @{ GetBranchesInCategory( $params->{'multibranchlimit'} ) } ).')';
411
  @branches = @{GetBranchesInCategory($params->{'multibranchlimit'})};
407
    push @limits, $multibranch if ($multibranch ne  '()');
412
@limits = map { uri_unescape($_) } @limits;
408
}
413
}
409
414
410
my $available;
415
my $available;
416
my @newlimit;
411
foreach my $limit(@limits) {
417
foreach my $limit(@limits) {
412
    if ($limit =~/available/) {
418
    if ($limit =~/available/) {
413
        $available = 1;
419
        $available = 1;
414
    }
420
    }
421
    if ($limit =~ m/^branch:(.*)/){
422
      push @branches, $1;
423
    } else {
424
      push @newlimit, $limit;
425
    }
426
}
427
@limits = @newlimit;
428
429
my @branchloop = $params->{'branchloop[]'};
430
foreach my $line(@branchloop){
431
 if ($line =~ m/^branch:(.*)/){
432
   push @branches, $1;
433
 }
415
}
434
}
435
416
$template->param(available => $available);
436
$template->param(available => $available);
437
my @finalbranches;
438
if(C4::Context->preference("SearchableBranches") ne 'all') {
439
if(C4::Context->preference("SearchableBranches") eq 'securehome') { # Preference is set to search only the branches specified in patron record.
440
   my %borrower_branches;
441
   if(C4::Context->preference("multibranch")) {
442
      my $value = C4::Members::Attributes::GetBorrowerAttributeValue($borrowernumber, "branchcode",1); #calling for an arrayref with all values.
443
      foreach my $branchcode (@{$value}) {
444
         $borrower_branches{$$branchcode[0]} = 1;
445
      }
446
   }
447
   my $members = GetMember( 'borrowernumber' => $borrowernumber );
448
   my $homebranch = $members->{'branchcode'};
449
   $borrower_branches{$homebranch} = 1 if $homebranch;
450
   if($ENV{'OPAC_SEARCH_LIMIT'} =~ m/^branch:(.*)/){
451
      $borrower_branches{$1} = 1;
452
   }
453
454
   foreach my $branchcode (@branches) {
455
      if ($borrower_branches{$branchcode}) {push @finalbranches, $branchcode};
456
  }
457
458
  if (!@finalbranches) {
459
    foreach my $branchcode (keys %borrower_branches) {
460
      push @finalbranches, $branchcode;
461
    }
462
  } 
463
}
464
 else { 
465
  push (@finalbranches, @branches); 
466
  }
467
} else {push (@finalbranches, @branches);}
468
push @limits, "(". join(" or ", map { "branch: $_ "}  @finalbranches) .")" if @finalbranches;
469
417
470
418
# append year limits if they exist
471
# append year limits if they exist
419
if ($params->{'limit-yr'}) {
472
if ($params->{'limit-yr'}) {
420
- 

Return to bug 9055