Bug 36557: Convert Cart and Lists controls to buttons and rework logic

This patch tries to address errors in the way features are displayed in
result lists so that controls for holds, tags, lists, etc. are shown or
hidden according to system preferences.

The patch converts the Cart/Lists dropdown to separate buttons, making
the display logic simpler and making the interface more consistent with
updates to the staff interface search results.

To test, apply the patch and rebuild the OPAC CSS.

- In the OPAC, test these pages:
  - Catalog search results
  - List contents
- Test with various combinations of these system preferences:
  - opacbookbag
  - DisplayMultiPlaceHold
  - virtualshelves
  - OPACHoldRequests
  - TagsEnabled
  - TagsInputOnList
  - UseRecalls
  - ArticleRequests

With each different combination of settings the right controls should
appear in the toolbar at the top (if present), and with each search
result.

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Owen Leonard 2024-03-21 17:29:47 +00:00 committed by Katrin Fischer
parent 2d4ab2e1bc
commit 9917b39d9d
Signed by: kfischer
GPG key ID: 0EF6E2C03357A834
9 changed files with 409 additions and 448 deletions

View file

@ -619,6 +619,10 @@ th {
white-space: nowrap;
}
.dropdown-menu > .dropdown-header:first-child {
border-top: 0;
}
.btn-group.open {
.btn-link {
&.dropdown-toggle {
@ -1127,7 +1131,6 @@ fieldset {
.toolbar {
background-color: #EEEEEE;
border: 1px solid #E8E8E8;
font-size: .9rem;
padding: 3px 3px 5px 5px;
vertical-align: middle;
@ -1197,12 +1200,11 @@ fieldset {
.selections-toolbar {
background: linear-gradient( #B2B2B2 0%, #E0E0E0 14%, #E8E8E8 100% );
border-bottom: none;
display: flex;
flex-wrap: wrap;
margin: 0;
padding-left: 10px;
padding-top: .5em;
flex-wrap: wrap;
> div:first-child::before {
content: "";

View file

@ -0,0 +1,90 @@
<div class="selections-toolbar toolbar noprint">
[% IF ( OpacHighlightedWords && results ) %]
<div class="highlight_controls noprint">
<a href="#" class="btn btn-link btn-sm highlight_toggle" id="highlight_toggle_off"><i class="fa-fw fa-solid fa-pencil" aria-hidden="true"></i> Unhighlight</a>
<a href="#" class="btn btn-link btn-sm highlight_toggle" id="highlight_toggle_on"><i class="fa-fw fa-solid fa-pencil" aria-hidden="true"></i> Highlight</a>
</div>
[% END %]
<div class="check_control">
<!-- checkall, clearall are now needed for placehold -->
<span class="clearall">
<a id="CheckAll" class="btn btn-link btn-sm" href="#">Select all</a>
</span>
<span class="checkall">
<a id="CheckNone" class="btn btn-link btn-sm" href="#">Clear all</a>
</span>
</div>
<div class="links">
[% IF ( TagsInputEnabled || CartEnabled || ListsEnabled || MultiHolds ) %]
<span class="selections">Select titles to:</span>
[% END %]
[% IF ( CartEnabled ) %]
<div class="btn-group">
<a id="addtocart" class="btn btn-link btn-xs" href="#"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Add to cart</a>
</div>
[% END %]
[% IF ( ListsEnabled ) %]
<div class="btn-group">
<button type="button" class="btn btn-link btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-list" aria-hidden="true"></i> Add to list <span class="caret"></span>
</button>
<div class="dropdown-menu">
[% IF add_to_some_private_shelves.count %]
<h6 class="dropdown-header">Your lists</h6>
[% SET number_of_private_shelves = 0 %]
[% FOREACH s IN add_to_some_private_shelves %]
[% IF shelfnumber != s.shelfnumber %]
<a href="#" class="dropdown-item addtolist" data-shelfnumber="[% s.shelfnumber | html %]">[% s.shelfname | html %]</a>
[% SET number_of_private_shelves = number_of_private_shelves + 1 %]
[% IF number_of_private_shelves == 10 %][% LAST %][% END %]
[% END %]
[% END %]
[% END %]
[% IF add_to_some_public_shelves.count %]
<h6 class="dropdown-header">Public lists</h6>
[% SET number_of_public_shelves = 0 %]
[% FOREACH s IN add_to_some_public_shelves %]
[% IF shelfnumber != s.shelfnumber %]
<a href="#" data-shelfnumber="[% s.shelfnumber | html %]" class="dropdown-item addtolist">[% s.shelfname | html %]</a>
[% SET number_of_public_shelves = number_of_public_shelves + 1 %]
[% IF number_of_public_shelves == 10 %][% LAST %][% END %]
[% END %]
[% END %]
[% END %]
<div class="dropdown-divider"></div>
[% IF add_to_some_private_shelves.count > 10 or add_to_some_public_shelves.count > 10 %]
<a href="#" class="dropdown-item addtolist morelists">More lists</a>
[% END %]
<a href="#" class="dropdown-item addtolist newlist">New list</a>
</div>
</div>
[% END # /IF virtualshelves %]
[% IF ( MultiHolds ) %]
<button class="btn btn-link btn-sm hold disabled" type="button">
<i class="fa fa-fw fa-bookmark" aria-hidden="true"></i> Place hold
</button>
[% END %]
[% IF ( TagsInputEnabled ) %]
<span id="tagsel_span">
<button id="tagsel_tag" class="btn btn-link btn-sm disabled" type="submit" style="display:none"><i class="fa fa-fw fa-tag" aria-hidden="true"></i> Tag</button>
</span>
[% END %]
</div> <!-- / .links -->
[% IF ( TagsInputEnabled ) %]
<div id="tagsel_form" style="display:none">
<label for="tagsel_new">New tag:</label>
<input type="text" name="tagsel_new" id="tagsel_new" maxlength="100" />
<input id="tagsel_button" name="tagsel_button" class="tagsel_button btn btn-sm btn-primary" title="Add" type="submit" value="Add" />
<a href="#" id="tagsel_cancel">(done)</a>
</div>
<div id="tagsel_status" class="tagsel_tatus" style="display:none;">
Tag status here.
</div>
[% END %]
</div> <!-- / .selections-toolbar -->

View file

@ -1,27 +1,25 @@
<div class="actions-menu noprint">
[% IF Koha.Preference( 'OPACHoldRequests' ) == 1 %]
[% IF ( HoldsEnabled ) %]
[% UNLESS ( items.norequests ) %]
[% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
[% IF ( shelf AND op == 'view' ) # Lists view has more granular checking of hold availability %]
[% IF ( items.allow_onshelf_holds ) %]
<span class="actions"><a class="btn btn-link btn-sm" aria-label="Place a hold on [% items.title | html %]" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% items.biblionumber | html %]"><i class="fa fa-fw fa-bookmark" aria-hidden="true"></i> Place hold</a></span>
[% ELSE %]
[% IF ( items.itemsissued ) %]
<span class="actions"><a class="btn btn-link btn-sm" aria-label="Place a hold on [% items.title | html %]" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% items.biblionumber | html %]"><i class="fa fa-fw fa-bookmark" aria-hidden="true"></i> Place hold</a></span>
[% END %]
[% END %]
[% ELSE %]
[% IF ( shelf AND op == 'view' ) # Lists view has more granular checking of hold availability %]
[% IF ( items.allow_onshelf_holds ) %]
<span class="actions"><a class="btn btn-link btn-sm" aria-label="Place a hold on [% items.title | html %]" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% items.biblionumber | html %]"><i class="fa fa-fw fa-bookmark" aria-hidden="true"></i> Place hold</a></span>
[% ELSE %]
[% IF ( items.itemsissued ) %]
<span class="actions"><a class="btn btn-link btn-sm" aria-label="Place a hold on [% items.title | html %]" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% items.biblionumber | html %]"><i class="fa fa-fw fa-bookmark" aria-hidden="true"></i> Place hold</a></span>
[% END %]
[% END %]
[% END # / IF opacuserlogin %]
[% ELSE %]
<span class="actions"><a class="btn btn-link btn-sm" aria-label="Place a hold on [% items.title | html %]" href="/cgi-bin/koha/opac-reserve.pl?biblionumber=[% items.biblionumber | html %]"><i class="fa fa-fw fa-bookmark" aria-hidden="true"></i> Place hold</a></span>
[% END %]
[% END # / UNLESS items.norequests %]
[% END # / OPACHoldRequests %]
[% IF Koha.Preference('UseRecalls') %]
[% IF ( RecallsEnabled ) %]
<span class="actions"><a class="btn btn-link btn-sm recall" href="/cgi-bin/koha/opac-recall.pl?biblionumber=[% items.biblionumber | html %]"><i class="fa-solid fa-book-bookmark" aria-hidden="true"></i> Place recall</a></span>
[% END %]
[% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) %]
[% IF ( LoginEnabled ) %]
[% IF items.artreqpossible %]
<span class="actions"><a href="/cgi-bin/koha/opac-request-article.pl?biblionumber=[% items.biblionumber | uri %]" class="btn btn-link btn-sm"><i class="fa-solid fa-file-lines" aria-hidden="true"></i> Request article</a></span>
[% END %]
@ -48,7 +46,7 @@
[% END # IF loggedinusername %]
[% END # if TagsInputEnabled %]
[% IF ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && loggedinusername && ( Koha.Preference( 'virtualshelves' ) == 1 ) ) %]
[% IF ( ListsEnabled ) %]
[% IF ( shelf AND op == 'view' ) %]
<span class="actions"><a href="/cgi-bin/koha/opac-addbybiblionumber.pl?biblionumber=[% items.biblionumber | uri %]" class="addtoshelf btn btn-link btn-sm"><i class="fa fa-list" aria-hidden="true"></i> Save to another list</a></span>
[% IF can_remove_biblios %]
@ -59,7 +57,7 @@
[% END # /IF ( shelf AND op == 'view' ) %]
[% END # /IF Koha.Preference( 'opacuserlogin' ) %]
[% IF Koha.Preference( 'opacbookbag' ) == 1 %]
[% IF ( CartEnabled ) %]
[% IF ( items.incart ) %]
<span class="actions cart-actions"><a data-biblionumber="[% items.biblionumber | html %]" class="btn btn-link btn-sm addtocart cart[% items.biblionumber | html %]" href="#"><i class="fa fa-shopping-cart" aria-hidden="true"></i> In your cart</a> <a data-biblionumber="[% items.biblionumber | html %]" class="btn btn-link btn-sm remove cartRemove cartR[% items.biblionumber | html %]" href="#">(remove)</a></span>
[% ELSE %]

View file

@ -3,9 +3,17 @@
[% USE Koha %]
[% USE KohaPlugins %]
[% USE To %]
[% SET TagsShowEnabled = ( ( Koha.Preference( 'TagsEnabled' ) == 1 ) && TagsShowOnList ) %]
[% SET TagsInputEnabled = ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'TagsEnabled' ) == 1 ) && TagsInputOnList ) %]
[% SET CoverImagePlugins = KohaPlugins.get_plugins_opac_cover_images %]
[% SET LoginEnabled = ( Koha.Preference('opacuserlogin') == 1 ) %]
[% IF ( Koha.Preference('TagsEnabled') ) %]
[% SET TagsShowEnabled = ( ( Koha.Preference('TagsEnabled') == 1 ) && ( Koha.Preference('TagsShowOnList') > 0 ) ) %]
[% SET TagsInputEnabled = LoginEnabled && TagsShowEnabled && ( Koha.Preference('TagsInputOnList') > 0 ) %]
[% END %]
[% SET CartEnabled = ( Koha.Preference('opacbookbag') == 1 ) %]
[% SET ListsEnabled = ( Koha.Preference('virtualshelves') == 1 ) && LoginEnabled %]
[% SET HoldsEnabled = ( Koha.Preference('OPACHoldRequests') == 1 ) && LoginEnabled %]
[% SET RecallsEnabled = ( Koha.Preference('UseRecalls') == 1 ) && LoginEnabled %]
[% SET ArticleRequestsEnabled = ( Koha.Preference('ArticleRequests') == 1 ) && LoginEnabled %]
[% SET MultiHolds = ( Koha.Preference('DisplayMultiPlaceHold') == 1 ) && HoldsEnabled %]
[% IF firstPage %]
[% SET OverDriveEnabled = Koha.Preference('OverDriveLibraryID') && Koha.Preference('OverDriveClientKey') && Koha.Preference('OverDriveClientSecret') %]
@ -192,94 +200,7 @@
[% END # /UNLESS tag %]
</div> <!-- / #toolbar -->
<div class="selections-toolbar toolbar noprint">
[% IF ( OpacHighlightedWords ) %]
<div class="highlight_controls noprint">
<a href="#" class="btn btn-link btn-sm highlight_toggle" id="highlight_toggle_off"><i class="fa-fw fa-solid fa-pencil" aria-hidden="true"></i> Unhighlight</a>
<a href="#" class="btn btn-link btn-sm highlight_toggle" id="highlight_toggle_on"><i class="fa-fw fa-solid fa-pencil" aria-hidden="true"></i> Highlight</a>
</div>
[% END %]
<div class="check_control">
<!-- checkall, clearall are now needed for placehold -->
<span class="clearall">
<a id="CheckAll" class="btn btn-link btn-sm" href="#">Select all</a>
</span>
<span class="checkall">
<a id="CheckNone" class="btn btn-link btn-sm" href="#">Clear all</a>
</span>
</div>
<div class="links">
[% IF ( ( Koha.Preference( 'opacbookbag' ) == 1 ) || ( Koha.Preference( 'opacuserlogin' ) == 1 && Koha.Preference('virtualshelves') ) || loggedinusername ) %]
<span class="selections">Select titles to:</span>
[% END %]
[% IF ( ( Koha.Preference( 'opacbookbag' ) == 1 ) || ( Koha.Preference( 'opacuserlogin' ) == 1 && Koha.Preference('virtualshelves') ) ) %]
<span class="addto">
<select class="disabled form-control form-control-sm" name="addto" id="addto">
<option>Add to...</option>
[% IF Koha.Preference( 'opacbookbag' ) == 1 %]
<option value="addtocart">Cart</option>
[% END %]
[% IF Koha.Preference('virtualshelves') && Koha.Preference('opacuserlogin') == 1 %]
[% IF loggedinusername AND add_to_some_private_shelves.count %]
<optgroup label="Your lists:">
[% SET number_of_private_shelves = 0 %]
[% FOREACH s IN add_to_some_private_shelves %]
[% IF shelfnumber != s.shelfnumber %]
<option id="s[% s.shelfnumber | html %]" value="addtolist">[% s.shelfname | html %]</option>
[% SET number_of_private_shelves = number_of_private_shelves + 1 %]
[% IF number_of_private_shelves == 10 %][% LAST %][% END %]
[% END %]
[% END %]
</optgroup>
[% END %]
[% IF add_to_some_public_shelves.count %]
<optgroup label="Public lists:">
[% SET number_of_public_shelves = 0 %]
[% FOREACH s IN add_to_some_public_shelves %]
[% IF shelfnumber != s.shelfnumber %]
<option id="s[% s.shelfnumber | html %]" value="addtolist">[% s.shelfname | html %]</option>
[% SET number_of_public_shelves = number_of_public_shelves + 1 %]
[% IF number_of_public_shelves == 10 %][% LAST %][% END %]
[% END %]
[% END %]
</optgroup>
[% END %]
[% IF ( add_to_some_private_shelves and add_to_some_private_shelves.count > 10 ) or ( add_to_some_public_shelves and add_to_some_public_shelves.count > 10 ) %]
<option value="morelists">[ More lists ]</option>
[% END %]
<option value="newlist">[ New list ]</option>
[% END # /IF virtualshelves and opacuserlogin %]
</select>
<input type="submit" class="btn btn-sm btn-primary" value="Save" />
</span>
[% END # /IF opacbookbag || virtualshelves %]
[% IF ( ( Koha.Preference( 'OPACHoldRequests' ) == 1 ) && ( Koha.Preference( 'opacuserlogin' ) == 1 ) && DisplayMultiPlaceHold ) %]
<button class="btn btn-link btn-sm hold disabled" type="button">
<i class="fa fa-fw fa-bookmark" aria-hidden="true"></i> Place hold
</button>
[% END %]
[% IF ( TagsInputEnabled && loggedinusername ) %]
<span id="tagsel_span">
<button id="tagsel_tag" class="btn btn-link btn-sm disabled" type="submit" style="display:none"><i class="fa fa-fw fa-tag" aria-hidden="true"></i> Tag</button>
</span>
[% END %]
</div> <!-- / .links -->
[% IF ( TagsInputEnabled && loggedinusername ) %]
<div id="tagsel_form" style="display:none">
<label for="tagsel_new">New tag:</label>
<input type="text" name="tagsel_new" id="tagsel_new" maxlength="100" />
<input id="tagsel_button" name="tagsel_button" class="tagsel_button btn btn-sm btn-primary" title="Add" type="submit" value="Add" />
<a href="#" id="tagsel_cancel">(done)</a>
</div>
<div id="tagsel_status" class="tagsel_tatus" style="display:none;">
Tag status here.
</div>
[% END %]
</div> <!-- / .selections-toolbar -->
[% INCLUDE 'result-batch-controls.inc' results=1 %]
</div> <!-- /#floating -->
<!-- TABLE RESULTS START -->
@ -531,7 +452,6 @@
</form> <!-- / #bookbag_form -->
<form id="hold_form" name="hold_form" method="get" action="/cgi-bin/koha/opac-reserve.pl">
<legend class="sr-only">Pages</legend>
<!-- The value will be set by holdBiblioNums() in basket.js -->
<input id="hold_form_biblios" type="hidden" name="biblionumbers" value=""/>
</form>
@ -581,91 +501,12 @@
[% END %]
[% CoverImagePlugins | $raw %]
<script>
[% IF ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'OPACHoldRequests' ) == 1 ) %]
function holdMultiple() {
var checkedBiblioNums = ""; // Separated by "/"
var checkedCount = 0;
if(document.bookbag_form.biblionumber.length > 0) {
for (var i=0; i < document.bookbag_form.biblionumber.length; i++) {
if (document.bookbag_form.biblionumber[i].checked) {
checkedBiblioNums += (document.bookbag_form.biblionumber[i].value + "/");
checkedCount++;
}
}
}
if (checkedCount > 0) {
holdBiblioNums(checkedBiblioNums);
} else {
alert( _("No item was selected") );
}
}
function holdBiblioNums(numList) {
// numList: biblio numbers separated by "/"
$("#hold_form_biblios").attr("value", numList);
$("#hold_form").submit();
}
[% END # /IF opacuserlogin && OPACHoldRequests %]
[% IF ( TagsInputEnabled && loggedinusername ) %]
function tagSelected() {
var checkedBoxes = $(".searchresults :checkbox:checked");
if ($(checkedBoxes).size() == 0) {
alert( _("No item was selected") );
} else {
$("#tagsel_tag").hide();
$(".resort").hide();
$("#tagsel_form").show();
}
}
function tagCanceled() {
$("#tagsel_form").hide();
$("#tagsel_tag").show();
$(".resort").show();
$("#tagsel_new").val("");
$("#tagsel_status, .tagstatus").empty().hide();
}
function tagAdded() {
var checkedBoxes = $(".searchresults :checkbox:checked");
if ($(checkedBoxes).size() == 0) {
alert( _("No item was selected") );
return false;
}
var tag = $("#tagsel_new").val();
if (!tag || (tag == "")) {
alert( _("No tag was specified.") );
return false;
}
var bibs = [];
for (var i = 0; i < $(checkedBoxes).size(); i++) {
var box = $(checkedBoxes).get(i);
bibs[i] = $(box).val();
}
KOHA.Tags.add_multitags_button(bibs, tag);
return false;
}
[% END # /IF TagsInputEnabled && loggedinusername %]
function enableCheckboxActions(){
// Enable/disable controls if checkboxes are checked
var checkedBoxes = $(".cb:checked");
var controls = $(".selections-toolbar .links a, .selections-toolbar .links input, .selections-toolbar .links select, .selections-toolbar .links label, .selections-toolbar .links button");
if ($(checkedBoxes).size()) {
$(".selections").html(_("With selected titles: "));
$(controls).removeClass("disabled");
} else {
$(".selections").html(_("Select titles to: "));
$(controls).addClass("disabled");
}
}
const loggedinusername = [% ( loggedinusername ) ? 1 : 0 | html %];
const opacbookbag = [% ( opacbookbag ) ? 1 : 0 | html %];
const virtualshelves = [% ( virtualshelves ) ? 1 : 0 | html %];
</script>
[% Asset.js("js/results-list.js") | $raw %]
<script>
[% IF ( OpacHighlightedWords ) %]
var q_array = new Array(); // holds search terms if available
@ -704,11 +545,6 @@
});
[% END %]
$(".cb").click(function(){
enableCheckboxActions();
});
enableCheckboxActions();
$(".br-readonly a").on("click", function(e){
e.preventDefault();
});
@ -721,70 +557,6 @@
$('#bookbag_form').submit();
});
[% IF ( ( Koha.Preference( 'opacbookbag' ) == 1 ) || ( Koha.Preference( 'virtualshelves' ) == 1 ) ) %]
[% IF Koha.Preference( 'virtualshelves' ) == 1 %]
$("#addto").on("change",function(){
cartList();
});
$(".addto").find("input:submit").click(function(){
cartList();
return false;
});
[% ELSE %]
$("#addto").on("click",function(){
cartList();
return false;
});
[% END %]
[% END %]
function cartList(){
addtoOption = $("#addto").find("option:selected");
addtoval = addtoOption.val();
if(addtoval == "addtolist"){
var shelfnumber = addtoOption.attr("id").replace("s","");
if (vShelfAdd()) {
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?selectedshelf='+shelfnumber+'&' + vShelfAdd());
}
return false;
} else if(addtoval == "newlist"){
[% IF ( loggedinusername ) %]if (vShelfAdd()) {
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?newshelf=1&' + vShelfAdd());
}[% ELSE %]
alert(_("You must be logged in to create or add to lists"));
[% END %]
return false;
} else if(addtoval == "morelists"){
[% IF ( loggedinusername ) %]
if (vShelfAdd()) {
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?' + vShelfAdd());
}
[% ELSE %]
alert(_("You must be logged in to create or add to lists"));
[% END %]
return false;
}
if(addtoval == "addtocart" || $("#addto").attr("class") == "addtocart"){
addMultiple();
return false;
}
}
$("#CheckAll").on("click",function(e){
e.preventDefault();
$(".cb").prop("checked", true);
enableCheckboxActions();
});
$("#CheckNone").on("click",function(e){
e.preventDefault();
$(".cb").prop("checked", false);
enableCheckboxActions();
});
$(".hold").on("click", function(e){
e.preventDefault();
holdMultiple();
});
[% IF ( query_desc ) %]
[% IF ( OpacHighlightedWords ) %]
q_array = query_desc.split(" ");
@ -842,50 +614,6 @@
[% END # /IF OpenLibrarySearch %]
[% END # /IF query_desc %]
[% IF ( TagsInputEnabled && loggedinusername ) %]
$("#tagsel_tag").show().click(function(){
tagSelected();
return false;
});
$("#tagsel_cancel").click(function(){
tagCanceled();
return false;
});
$("#tagsel_button").click(function(){
tagAdded();
return false;
});
$(".tag_add").click(function(){
var thisid = $(this).attr("id");
thisid = thisid.replace("tag_add","");
$(this).addClass("hidden");
$("#tagform"+thisid).show();
$("#newtag"+thisid).focus();
$("#newtag"+thisid+"_status").empty().hide();
return false;
});
$(".cancel_tag_add").click(function(){
var thisid = $(this).attr("id");
thisid = thisid.replace("cancel","");
$("#tagform"+thisid).hide();
$("#tag_add"+thisid).removeClass("hidden");
$("#newtag"+thisid).val("");
$("#newtag"+thisid+"_status").empty().hide();
return false;
});
$(".tagbutton").click(function(){
var thisid = $(this).attr("title");
var tag = $("#newtag"+thisid).val();
if (!tag || (tag == "")) {
alert( _("No tag was specified.") );
return false;
}
KOHA.Tags.add_tag_button(thisid, tag);
return false;
});
[% END # /IF TagsInputEnabled && loggedinusername %]
[% IF OpenLibraryCovers %]KOHA.OpenLibrary.GetCoverFromIsbn();[% END %]
[% IF OPACLocalCoverImages %]KOHA.LocalCover.GetCoverFromBibnumber(false);[% END %]
[% IF ( GoogleJackets ) %]KOHA.Google.GetCoverFromIsbn();[% END %]
@ -903,13 +631,6 @@
$("input.newtag").on('keydown', function(e){
if (e.keyCode == 13) { e.preventDefault(); }
});
Sticky = $("#floating");
Sticky.hcSticky({
stickTo: ".searchresults",
stickyClass: "floating"
});
});
</script>
[% END %]

View file

@ -5,8 +5,17 @@
[% USE AdditionalContents %]
[% SET OpacNav = AdditionalContents.get( location => "OpacNav", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %]
[% SET OpacNavBottom = AdditionalContents.get( location => "OpacNavBottom", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %]
[% SET TagsShowEnabled = ( ( Koha.Preference( 'TagsEnabled' ) == 1 ) && Koha.Preference('TagsShowOnList') ) %]
[% SET TagsInputEnabled = ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'TagsEnabled' ) == 1 ) && Koha.Preference('TagsInputOnList') ) %]
[% SET LoginEnabled = ( Koha.Preference('opacuserlogin') == 1 ) %]
[% IF ( Koha.Preference('TagsEnabled') ) %]
[% SET TagsShowEnabled = ( ( Koha.Preference('TagsEnabled') == 1 ) && ( Koha.Preference('TagsShowOnList') > 0 ) ) %]
[% SET TagsInputEnabled = LoginEnabled && TagsShowEnabled && ( Koha.Preference('TagsInputOnList') > 0 ) %]
[% END %]
[% SET CartEnabled = ( Koha.Preference('opacbookbag') == 1 ) %]
[% SET ListsEnabled = ( Koha.Preference('virtualshelves') == 1 ) && LoginEnabled %]
[% SET HoldsEnabled = ( Koha.Preference('OPACHoldRequests') == 1 ) && LoginEnabled %]
[% SET RecallsEnabled = ( Koha.Preference('UseRecalls') == 1 ) && LoginEnabled %]
[% SET ArticleRequestsEnabled = ( Koha.Preference('ArticleRequests') == 1 ) && LoginEnabled %]
[% SET MultiHolds = ( Koha.Preference('DisplayMultiPlaceHold') == 1 ) && HoldsEnabled %]
[% BLOCK delete_shelf %]
<form action="/cgi-bin/koha/opac-shelves.pl" method="post" id="deleteshelf[% shelf.shelfnumber | html %]" class="d-inline">
@ -345,48 +354,7 @@
</form> <!-- /#sorting-form -->
</div> <!-- / #toolbar -->
<div class="selections-toolbar toolbar noprint">
<div class="check_control">
<span class="checkall">
<a id="CheckAll" class="btn btn-link btn-sm" href="#">Select all</a>
</span>
<span class="clearall">
<a id="CheckNone" class="btn btn-link btn-sm" href="#">Clear all</a>
</span>
</div>
<div class="links">
<span class="selections">Select titles to: </span>
[% IF ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'OPACHoldRequests' ) == 1 ) ) %]
<span id="placehold">
<a href="#" class="btn btn-link hold tag_hides disabled"><i class="fa fa-fw fa-bookmark" aria-hidden="true"></i> Place hold</a>
</span>
[% END %]
[% IF Koha.Preference( 'opacbookbag' ) == 1 %]
<a href="#" class="btn btn-link listaddtocart disabled"><i class="fa fa-shopping-cart" aria-hidden="true"></i> Add to cart</a>
[% END %]
[% IF Koha.Preference('virtualshelves') %]
<a href="#" class="btn btn-link addtolist disabled"><i class="fa fa-list" aria-hidden="true"></i> Add to list</a>
[% END %]
[% IF ( TagsInputEnabled && loggedinusername ) %]
<span id="addtags">
<a id="tagsel_tag" href="#" class="btn btn-link disabled"><i class="fa fa-fw fa-tag" aria-hidden="true"></i> Tag</a>
</span>
<span id="tagsel_form" class="form-inline" style="display:none">
<label for="tagsel_new">New tag(s), separated by a comma:</label>
<input class="form-control form-control-sm" type="text" name="tagsel_new" id="tagsel_new" maxlength="100" />
<input id="tagsel_button" name="tagsel_button" class="tagsel_button btn btn-primary btn-sm" title="tagsel_button" type="submit" value="Add" />
<a href="#" id="tagsel_cancel">Cancel</a>
</span>
[% END %]
[% IF loggedinusername && can_remove_biblios %]
<a href="#" class="btn btn-link disabled removeitems tag_hides"><i class="fa fa-fw fa-remove" aria-hidden="true"></i> Remove from list</a>
[% END %]
</div> <!-- / .links -->
</div> <!-- / .selections-toolbar -->
[% INCLUDE 'result-batch-controls.inc' %]
</div> <!-- /#floating -->
<form action="/cgi-bin/koha/opac-shelves.pl" method="post" id="myform" name="bookbag_form">
@ -556,6 +524,10 @@
<input type="hidden" name="modifyshelfcontents" value="1" />
</form>
[% END %]
<form id="hold_form" name="hold_form" method="get" action="/cgi-bin/koha/opac-reserve.pl">
<!-- The value will be set by holdBiblioNums() in basket.js -->
<input id="hold_form_biblios" type="hidden" name="biblionumbers" value=""/>
</form>
[% ELSE %]
<div id="toolbar" class="toolbar clearfix">
<div class="list-actions">
@ -846,21 +818,12 @@
[% Asset.js("js/openlibrary.js") | $raw %]
[% END %]
<script>
[% IF ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'OPACHoldRequests' ) == 1 ) ) %]
function holdSelections() {
var checkedBoxes = $("input:checkbox:checked");
if ($(checkedBoxes).size() == 0) {
alert( _("No item was selected") );
} else {
var bibs = "";
$(checkedBoxes).each(function(){
bibs += $(this).val() + "/";
});
document.location = "/cgi-bin/koha/opac-reserve.pl?biblionumbers="+bibs;
}
}
[% END %]
const loggedinusername = [% ( loggedinusername ) ? 1 : 0 | html %];
const opacbookbag = [% ( opacbookbag ) ? 1 : 0 | html %];
const virtualshelves = [% ( virtualshelves ) ? 1 : 0 | html %];
</script>
[% Asset.js("js/results-list.js") | $raw %]
<script>
[% IF ( TagsInputEnabled && loggedinusername ) %]
function tagSelected() {
var checkedBoxes = $("input:checkbox:checked");
@ -905,46 +868,9 @@
}
[% END %]
function enableCheckboxActions(){
// Enable/disable controls if checkboxes are checked
var checkedBoxes = $(".cb:checked");
if ($(checkedBoxes).size()) {
$(".selections").html(_("With selected titles: "));
$(".selections-toolbar .links a").removeClass("disabled");
} else {
$(".selections").html(_("Select titles to: "));
$(".selections-toolbar .links a").addClass("disabled");
}
}
$(function() {
[% IF Koha.Preference( 'opacbookbag' ) == 1 %]$(".addtocart,.cartRemove").removeClass("hidden");[% END %]
[% IF ( ( Koha.Preference( 'opacuserlogin' ) == 1 ) && ( Koha.Preference( 'OPACHoldRequests' ) == 1 ) ) %]
$(".selections-toolbar a.hold").click(function(e){
e.preventDefault();
holdSelections();
});
[% END %]
$("a.print").show();
$("#CheckAll").on("click",function(e){
e.preventDefault();
$(".cb").prop("checked", true);
enableCheckboxActions();
});
$("#CheckNone").on("click",function(e){
e.preventDefault();
$(".cb").prop("checked", false);
enableCheckboxActions();
});
$(".cb").click(function(){
enableCheckboxActions();
});
enableCheckboxActions();
[% IF ( TagsInputEnabled && loggedinusername ) %]
var tagAdd = $(".tag_add");
tagAdd.removeClass("hidden");
@ -1057,12 +983,6 @@ $(function() {
AdjustRemark();
Sticky = $("#floating");
Sticky.hcSticky({
stickTo: "#usershelves",
stickyClass: "floating"
});
[% IF itemsloop %]
sortMenu( $("#sorting-form") );
@ -1121,27 +1041,6 @@ $(function() {
Dopop( link );
});
$(".listaddtocart").on("click", function(e){
e.preventDefault();
addMultiple();
});
$(".addtolist").on("click", function(e){
e.preventDefault();
cartList();
});
function cartList(){
[% IF ( loggedinusername ) %]
if (vShelfAdd()) {
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?' + vShelfAdd());
}
[% ELSE %]
alert(_("You must be logged in to create or add to lists"));
[% END %]
return false;
}
}); // document.ready
function sortMenu( sorting_form ){

View file

@ -4,6 +4,17 @@
[% USE AdditionalContents %]
[% SET OpacNav = AdditionalContents.get( location => "OpacNav", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %]
[% SET OpacNavBottom = AdditionalContents.get( location => "OpacNavBottom", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %]
[% SET LoginEnabled = ( Koha.Preference('opacuserlogin') == 1 ) %]
[% IF ( Koha.Preference('TagsEnabled') ) %]
[% SET TagsShowEnabled = ( ( Koha.Preference('TagsEnabled') == 1 ) && ( Koha.Preference('TagsShowOnList') > 0 ) ) %]
[% SET TagsInputEnabled = LoginEnabled && TagsShowEnabled && ( Koha.Preference('TagsInputOnList') > 0 ) %]
[% END %]
[% SET CartEnabled = ( Koha.Preference('opacbookbag') == 1 ) %]
[% SET ListsEnabled = ( Koha.Preference('virtualshelves') == 1 ) && LoginEnabled %]
[% SET HoldsEnabled = ( Koha.Preference('OPACHoldRequests') == 1 ) && LoginEnabled %]
[% SET RecallsEnabled = ( Koha.Preference('UseRecalls') == 1 ) && LoginEnabled %]
[% SET ArticleRequestsEnabled = ( Koha.Preference('ArticleRequests') == 1 ) && LoginEnabled %]
[% SET MultiHolds = ( Koha.Preference('DisplayMultiPlaceHold') == 1 ) && HoldsEnabled %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Tags &rsaquo; [% IF ( LibraryNameTitle ) %][% LibraryNameTitle | html %][% ELSE %]Koha online[% END %] catalog</title>
[% INCLUDE 'doc-head-close.inc' %]
@ -195,6 +206,13 @@
[% INCLUDE 'opac-bottom.inc' %]
[% BLOCK jsinclude %]
[% INCLUDE 'datatables.inc' %]
[% Asset.js("lib/hc-sticky/hc-sticky.js") | $raw %]
<script>
const loggedinusername = [% ( loggedinusername ) ? 1 : 0 | html %];
const opacbookbag = [% ( opacbookbag ) ? 1 : 0 | html %];
const virtualshelves = [% ( virtualshelves ) ? 1 : 0 | html %];
</script>
[% Asset.js("js/results-list.js") | $raw %]
<script>
$(document).ready(function(){

View file

@ -0,0 +1,223 @@
/* global __ */
function holdMultiple() {
var checkedBiblioNums = ""; // Separated by "/"
var checkedCount = 0;
if(document.bookbag_form.biblionumber.length > 0) {
for (var i=0; i < document.bookbag_form.biblionumber.length; i++) {
if (document.bookbag_form.biblionumber[i].checked) {
checkedBiblioNums += (document.bookbag_form.biblionumber[i].value + "/");
checkedCount++;
}
}
}
if (checkedCount > 0) {
holdBiblioNums(checkedBiblioNums);
} else {
alert( __("No item was selected") );
}
}
function holdBiblioNums(numList) {
// numList: biblio numbers separated by "/"
$("#hold_form_biblios").attr("value", numList);
$("#hold_form").submit();
}
function enableCheckboxActions(){
// Enable/disable controls if checkboxes are checked
var checkedBoxes = $(".cb:checked");
var controls = $(".selections-toolbar .links a, .selections-toolbar .links input, .selections-toolbar .links select, .selections-toolbar .links label, .selections-toolbar .links button");
if ($(checkedBoxes).size()) {
$(".selections").html(__("With selected titles: "));
$(controls).removeClass("disabled");
} else {
$(".selections").html(__("Select titles to: "));
$(controls).addClass("disabled");
}
}
function cartList(){
let addtoOption = $("#addto").find("option:selected");
let addtoval = addtoOption.val();
if(addtoval == "addtolist"){
var shelfnumber = addtoOption.attr("id").replace("s","");
if (vShelfAdd()) {
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?selectedshelf='+shelfnumber+'&' + vShelfAdd());
}
return false;
} else if(addtoval == "newlist"){
if( loggedinusername ) {
if (vShelfAdd()) {
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?newshelf=1&' + vShelfAdd());
}
} else {
alert(__("You must be logged in to create or add to lists"));
}
return false;
} else if(addtoval == "morelists"){
if( loggedinusername ){
if (vShelfAdd()) {
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?' + vShelfAdd());
}
} else {
alert(__("You must be logged in to create or add to lists"));
}
return false;
}
if(addtoval == "addtocart" || $("#addto").attr("class") == "addtocart"){
addMultiple();
return false;
}
}
function tagSelected() {
var checkedBoxes = $(".searchresults :checkbox:checked");
if ($(checkedBoxes).size() == 0) {
alert( __("No item was selected") );
} else {
$("#tagsel_tag").hide();
$(".resort").hide();
$("#tagsel_form").show();
}
}
function tagCanceled() {
$("#tagsel_form").hide();
$("#tagsel_tag").show();
$(".resort").show();
$("#tagsel_new").val("");
$("#tagsel_status, .tagstatus").empty().hide();
}
function tagAdded() {
var checkedBoxes = $(".searchresults :checkbox:checked");
if ($(checkedBoxes).size() == 0) {
alert( __("No item was selected") );
return false;
}
var tag = $("#tagsel_new").val();
if (!tag || (tag == "")) {
alert( __("No tag was specified.") );
return false;
}
var bibs = [];
for (var i = 0; i < $(checkedBoxes).size(); i++) {
var box = $(checkedBoxes).get(i);
bibs[i] = $(box).val();
}
KOHA.Tags.add_multitags_button(bibs, tag);
return false;
}
$(document).ready(function(){
$(".cb").click(function(){
enableCheckboxActions();
});
enableCheckboxActions();
if( opacbookbag == 1 || virtualshelves == 1 ){
if( virtualshelves == 1 ){
$("#addto").on("change",function(){
cartList();
});
$(".addto").find("input:submit").click(function(){
cartList();
return false;
});
} else {
$("#addto").on("click",function(){
cartList();
return false;
});
}
}
$("#addtocart").on("click", function(e){
e.preventDefault();
addMultiple();
});
$(".addtolist").on("click",function(e){
e.preventDefault();
var shelfnumber = $(this).data("shelfnumber");
var vshelf = vShelfAdd();
if( vshelf ){
if( $(this).hasClass("morelists") ){
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?' + vshelf );
} else if( $(this).hasClass("newlist") ){
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?newshelf=1&' + vshelf );
} else {
Dopop('/cgi-bin/koha/opac-addbybiblionumber.pl?selectedshelf='+shelfnumber+'&' + vshelf);
}
}
});
$("#CheckAll").on("click",function(e){
e.preventDefault();
$(".cb").prop("checked", true);
enableCheckboxActions();
});
$("#CheckNone").on("click",function(e){
e.preventDefault();
$(".cb").prop("checked", false);
enableCheckboxActions();
});
$(".hold").on("click", function(e){
e.preventDefault();
holdMultiple();
});
$("#tagsel_tag").show().click(function(){
tagSelected();
return false;
});
$("#tagsel_cancel").click(function(){
tagCanceled();
return false;
});
$("#tagsel_button").click(function(){
tagAdded();
return false;
});
$(".tag_add").click(function(){
var thisid = $(this).attr("id");
thisid = thisid.replace("tag_add","");
$(this).addClass("hidden");
$("#tagform"+thisid).show();
$("#newtag"+thisid).focus();
$("#newtag"+thisid+"_status").empty().hide();
return false;
});
$(".cancel_tag_add").click(function(){
var thisid = $(this).attr("id");
thisid = thisid.replace("cancel","");
$("#tagform"+thisid).hide();
$("#tag_add"+thisid).removeClass("hidden");
$("#newtag"+thisid).val("");
$("#newtag"+thisid+"_status").empty().hide();
return false;
});
$(".tagbutton").click(function(){
var thisid = $(this).attr("title");
var tag = $("#newtag"+thisid).val();
if (!tag || (tag == "")) {
alert( __("No tag was specified.") );
return false;
}
KOHA.Tags.add_tag_button(thisid, tag);
return false;
});
Sticky = $("#floating");
Sticky.hcSticky({
stickTo: ".searchresults",
stickyClass: "floating",
bottom: 0
});
});

View file

@ -70,7 +70,6 @@ use URI::Escape;
use JSON qw/decode_json encode_json/;
use Business::ISBN;
my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold");
# create a new CGI object
# FIXME: no_undef_params needs to be tested
use CGI qw('-no_undef_params' -utf8);
@ -176,13 +175,6 @@ if (C4::Context->preference('BakerTaylorEnabled')) {
);
}
if (C4::Context->preference('TagsEnabled')) {
$template->param(TagsEnabled => 1);
foreach (qw(TagsShowOnList TagsInputOnList)) {
C4::Context->preference($_) and $template->param($_ => 1);
}
}
## URI Re-Writing
# Deprecated, but preserved because it's interesting :-)
# The same thing can be accomplished with mod_rewrite in
@ -792,7 +784,6 @@ for (my $i=0;$i<@servers;$i++) {
$template->param(query_desc => $query_desc);
$template->param(limit_desc => $limit_desc);
$template->param(offset => $offset);
$template->param(DisplayMultiPlaceHold => $DisplayMultiPlaceHold);
if ($query_desc || $limit_desc) {
$template->param(searchdesc => 1);
}

View file

@ -464,6 +464,25 @@ if ( $op eq 'view' ) {
),
);
}
my $some_private_shelves = Koha::Virtualshelves->get_some_shelves(
{
borrowernumber => $loggedinuser,
add_allowed => 1,
public => 0,
}
);
my $some_public_shelves = Koha::Virtualshelves->get_some_shelves(
{
borrowernumber => $loggedinuser,
add_allowed => 1,
public => 1,
}
);
$template->param(
add_to_some_private_shelves => $some_private_shelves,
add_to_some_public_shelves => $some_public_shelves,
);
} else {
push @messages, { type => 'error', code => 'unauthorized_on_view' };
undef $shelf;