Browse Source

Bug 29821: Add interface for generating barcodes using svc/barcode

This patch adds a new page providing an interface for generating
barcodes using svc/barcode. A form allows the user to choose various
parameters and see the resulting barcode image.

To test, apply the patch and rebuild the staff interface SCSS
(https://wiki.koha-community.org/wiki/Working_with_SCSS_in_the_OPAC_and_staff_client).

- Go to the "Tools" home page. Follow the link to "Barcode image
  generator."
- On the barcode image generator page, confirm that there is a "Barcode
  image generator" link in the sidebar and that it is displayed with
  bold text.
- Test the features of the form:
  - Enter a numeric value in the "Barcode" field and tab out of the
    field or click "Show barcode" button. A barcode of type "Code39"
    should be shown with the text of the barcode included in the
    image below the barcode.
  - A text area below the barcode image should show the HTML used to
    generate the preview image.
    - Clicking in this textarea should automatically add the contents to
    the clipboard. You should be shown a message, "HTML copied to the
    clipboard."
  - Check the "hide text" checkbox. The barcode should be redisplayed
    without the text.
  - Check that changing the "barcode height" value is reflected
    correctly in the barcode image.
  - Try adding non-numeric data in the "Barcode" field. You should be
    shown an error message, "Barcodes of type [type]  must be numeric."
  - Test these other numeric barcode types: Code39, COOP2of5, EAN13,
    EAN8, IATA2of5, Industrial2of5, ITF, Matrix2of5, NW7, UPCA, and
    UPCE.

    Note that EAN13, EAN8, UPCA, and UPCE expect specific patterns. Test
    values (found here: https://barcode.tec-it.com/en/UPCE):

    EAN13: 978020137962
    EAN8: 9031101
    UPCA: 72527273070
    UPCE: 0123456

  - Change the barcode type to "QRcode."
    - The form should change, hiding the "Hide text" checkbox and
      showing a new ranger slider for "QR Code module size."
    - The barcode field should now be labeled "Text, URL, or barcode,
      etc"
    - The barcode field hint should change to a hint about QRcode
      dimensions.
    - Changing the "module size" slider should change the size of the
      generated QR code. As you change the slider the selected value
      should be reflected in the box.

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
master
Owen Leonard 4 months ago
committed by Fridolin Somers
parent
commit
cb195553d3
  1. 11
      koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss
  2. 1
      koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc
  3. 212
      koha-tmpl/intranet-tmpl/prog/en/modules/labels/barcode-print.tt
  4. 7
      koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt
  5. 2
      koha-tmpl/intranet-tmpl/prog/js/tools-menu.js
  6. 33
      labels/barcode-print.pl

11
koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss

@ -712,6 +712,12 @@ fieldset {
}
li {
margin-top: 1em;
&:first-child {
margin-top: 0;
}
&[aria-disabled="true"] {
color: #999;
}
@ -908,10 +914,6 @@ fieldset {
padding-left: 0;
}
}
legend {
margin-bottom: 0;
}
}
ol {
@ -1037,6 +1039,7 @@ legend {
border-radius: 3px;
font-size: 123.1%;
font-weight: bold;
margin-bottom: 0;
padding: .2em .5em;
width: auto;
}

1
koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc

@ -73,6 +73,7 @@
[% IF ( CAN_user_tools_label_creator ) %]
<li><a href="/cgi-bin/koha/labels/label-home.pl">Label creator</a></li>
<li><a href="/cgi-bin/koha/labels/spinelabel-home.pl">Quick spine label creator</a></li>
<li><a href="/cgi-bin/koha/labels/barcode-print.pl">Barcode image generator</a></li>
[% END %]
[% IF ( CAN_user_tools_rotating_collections ) %]
<li><a href="/cgi-bin/koha/rotating_collections/rotatingCollections.pl">Rotating collections</a></li>

212
koha-tmpl/intranet-tmpl/prog/en/modules/labels/barcode-print.tt

@ -0,0 +1,212 @@
[% USE raw %]
[% USE Asset %]
[% SET footerjs = 1 %]
[% INCLUDE 'doc-head-open.inc' %]<title>Barcode image generator &rsaquo; Tools &rsaquo; Koha</title>
[% INCLUDE 'doc-head-close.inc' %]
[% Asset.css("css/humanmsg.css") | $raw %]
[% FILTER collapse %]
<style>
input[type='range'] {
display: inline-block;
width: auto;
}
#barcode_container {
background-color:#FFF;
min-height:200px;
overflow: scroll;
padding:2em;
text-align:center;
}
#barcode_image {
border:1px dashed #B9D8D9;
display: block;
margin: 1em auto;
padding: 1em;
}
#modulesize_text {
background-color: #FFF;
border: 1px solid #EEE;
border-radius: 2px;
padding: .2em .4em;
}
#urltext {
border:1px solid #B9D8D9;
border-radius:2px;
margin:1em 0;
padding:.5em;
}
</style>
[% END %]
</head>
<body id="labels_spinelabel-home" class="tools labels">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'cat-search.inc' %]
<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="/cgi-bin/koha/mainpage.pl">Home</a>
</li>
<li>
<a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a>
</li>
<li>
<a href="#" aria-current="page">
Barcode image generator
</a>
</li>
</ol>
</nav>
<div class="main container-fluid">
<div class="row">
<div class="col-sm-10 col-sm-push-2">
<main>
<h2>Barcode image generator</h2>
<form action="/cgi-bin/koha/svc/barcode" method="post" id="barcodegen">
<fieldset class="brief">
<div class="row">
<div class="col-sm-6">
<ol>
<li>
<label for="type">Barcode type:</label>
<select name="type" id="type">
<option value="Code39">Code39</option>
<option value="COOP2of5">COOP2of5</option>
<option value="EAN13">EAN13</option>
<option value="EAN8">EAN8</option>
<option value="IATA2of5">IATA2of5</option>
<option value="Industrial2of5">Industrial2of5</option>
<option value="ITF">ITF</option>
<option value="Matrix2of5">Matrix2of5</option>
<option value="NW7">NW7</option>
<option value="QRcode">QRcode</option>
<option value="UPCA">UPCA</option>
<option value="UPCE">UPCE</option>
</select>
</li>
<li class="qrcode">
<label for="modulesize">QR Code module size:</label>
<input name="modulesize" id="modulesize" type="range" min="1" max="10" value="3" />
<span id="modulesize_text">3</span>
<div class="hint">Module size refers to the pixel dimensions of each black or white square in the generated QR code.</div>
</li>
<li class="bcode">
<label for="notext">Hide text <input type="checkbox" id="notext" name="notext" value="1" /></label>
</li>
<li class="bcode">
<label for="height">Barcode height:</label>
<input type="text" id="height" name="height" value="50" />
</li>
<li>
<label class="bcode" for="barcode">Barcode: </label>
<label class="qrcode" for="barcode">Text, URL, or barcode, etc: </label>
<input type="text" name="barcode" id="barcode" size="50" />
<div class="hint qrcode">Actual dimensions of the QR code depend on the amount of characters being encoded.</div>
<div class="hint bcode">Barcode text must be numeric (0-9)</div>
</li>
</ol>
<fieldset class="action">
<input type="submit" value="Show barcode" />
</fieldset>
</div>
<div class="col-sm-6">
<div id="barcode_container">
<img id="barcode_image" />
<textarea readonly="readonly" rows="5" cols="40" id="urltext"></textarea>
</div>
</div>
</div>
</fieldset>
</form>
</main>
</div> <!-- /.col-sm-10.col-sm-push-2 -->
<div class="col-sm-2 col-sm-pull-10">
<aside>
[% INCLUDE 'tools-menu.inc' %]
</aside>
</div> <!-- /.col-sm-2.col-sm-pull-10 -->
</div> <!-- /.row -->
[% MACRO jsinclude BLOCK %]
[% Asset.js("js/tools-menu.js") | $raw %]
[% Asset.js("lib/jquery/plugins/humanmsg.js") | $raw %]
<script>
var base_url = "[% Koha.Preference('staffClientBaseURL') | html %]";
function showBarcodeText( path, dimensions ){
var params = new URLSearchParams( path );
var tag = '<img src="' + path + '" alt="' + params.get("barcode") + '" width="' + dimensions.width + '" height="' + dimensions.height + '" />';
$("#urltext").show().text( tag );
if( Number( dimensions.width ) > 250 ){
$("#urltext").css("width", dimensions.width )
}
}
function showBarcode( barcodeform ){
if( $("#barcode").val() == "" ){
$("#barcode_container").hide();
} else {
var url = barcodeform.attr("action");
var params = barcodeform.serialize();
$("#barcode_container").show();
$("#barcode_image").attr("src", url + "?" + params );
}
}
function showQrcodeOptions( type ){
if( type.val() == "QRcode" ){
$(".qrcode").show().find("input,range").prop("disabled", false );
$(".bcode").hide().find("input").prop("disabled", true );
} else {
$(".qrcode").hide().find("input,range").prop("disabled", true );
$(".bcode").show().find("input").prop("disabled", false );
}
}
$(document).ready(function(){
showQrcodeOptions( $("#type") );
showBarcode( $("#barcodegen") );
$("#type").on("change", function(){
showQrcodeOptions( $(this) );
})
$("#barcodegen").on("change submit", function(e){
e.preventDefault();
showBarcode( $(this) );
});
$("#modulesize").on("input", function(){
$("#modulesize_text").text( $(this).val() );
});
$("#urltext").on("click", function(){
$(this).select();
var text = $(this).text();
navigator.clipboard.writeText( text ).then(function() {
/* clipboard successfully set */
humanMsg.displayAlert( _("HTML copied to the clipboard") );
}, function() {
/* clipboard write failed */
humanMsg.displayAlert( _("Could not copy HTML automatically to the clipboard") );
});
});
$("#barcode_image")[0].onload = function (){
showBarcodeText( this.src, { width: this.width, height: this.height } );
}
$("#barcode_image")[0].onerror = function(){
var barcodetype = $("#type").val();
if( barcodetype !== "QRcode" ){
if( Number.isNaN( Number( $("#barcode").val() ) ) ){
humanMsg.displayAlert( _("Barcodes of type %s must be numeric").format( barcodetype ) );
} else {
humanMsg.displayAlert( _("There was an unknown error generating the barcode image. Please check that your barcode is correct for the barcode type" ) );
}
} else {
humanMsg.displayAlert( _("There was an unknown error generating the barcode image") );
}
}
});
</script>
[% END %]
[% INCLUDE 'intranet-bottom.inc' %]

7
koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt

@ -224,7 +224,12 @@
<dt><a href="/cgi-bin/koha/labels/label-home.pl">Label creator</a></dt>
<dd>Create printable labels and barcodes from catalog data</dd>
[% END %]
[% IF ( CAN_user_tools_label_creator ) %]
<dt><a href="/cgi-bin/koha/labels/barcode-print.pl">Barcode image generator</a></dt>
<dd>Configure and create barcodes of various types to be output as an image</dd>
[% END %]
[% IF ( CAN_user_tools_label_creator ) %]
<dt><a href="/cgi-bin/koha/labels/spinelabel-home.pl">Quick spine label creator</a></dt>
<dd>Enter a barcode to generate a printable spine label. For use with dedicated label printers</dd>

2
koha-tmpl/intranet-tmpl/prog/js/tools-menu.js

@ -1,6 +1,6 @@
$(document).ready(function() {
var path = location.pathname.substring(1);
if (path.indexOf("labels") >= 0 && path.indexOf("spine") < 0 ) {
if (path.indexOf("labels") >= 0 && path.indexOf("spine") < 0 && path.indexOf("barcode") < 0 ) {
$('#navmenulist a[href$="/cgi-bin/koha/labels/label-home.pl"]').addClass("current");
} else if (path.indexOf("patroncards") >= 0 ) {
$('#navmenulist a[href$="/cgi-bin/koha/patroncards/home.pl"]').addClass("current");

33
labels/barcode-print.pl

@ -0,0 +1,33 @@
#!/usr/bin/perl
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use CGI qw ( -utf8 );
use C4::Auth qw( get_template_and_user );
use C4::Output qw( output_html_with_http_headers );
use C4::Context;
my $query = CGI->new;
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{ template_name => "labels/barcode-print.tt",
query => $query,
type => "intranet",
flagsrequired => { catalogue => 1 },
}
);
output_html_with_http_headers $query, $cookie, $template->output;
Loading…
Cancel
Save