Bug 9420 [Revised] Work on Bootstrap for Koha

YUI JS is deprecated as far as Koha is concerned, and jQueryUI menus
don't seem to be as robust as they should be. This makes Twitter
Bootstrap very attrative for its menus features as well as other
aspects.

This patch revises the staff client header menu to include features from
Bootstrap, including replacement of the YUI-driven "More..." menu with a
Bootstrap version, and a new user menu taken from Corey Fuimaono's
similar patch.

To test, be sure to clear your cache after applying the patch. Load any
page in the staff client and confirm that the menu at the top of the
screen looks correct and works as normal, including functionality of the
"more" menu. Confirm that the username/logged-in branch triggers a menu
with "set library" and "log out" options. Confirm that Cart operations
trigger the correct confirmation popup.

Revision moves the Bootstrap assets out of the prog template into
koha-tmpl/intranet-tmpl/lib.

Signed-off-by: Bernardo Gonzalez Kriegel <bgkriegel@gmail.com>

Works great. No errors.

Signed-off-by: Jonathan Druart <jonathan.druart@biblibre.com>
Signed-off-by: Jared Camins-Esakov <jcamins@cpbibliography.com>
This commit is contained in:
Owen Leonard 2013-01-25 13:57:28 -05:00 committed by Jared Camins-Esakov
parent a386df2c78
commit ecf42ffbd0
9 changed files with 841 additions and 140 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -143,6 +143,7 @@ em strong {
#login_controls {
position : absolute;
right : .5em;
padding: .4em .5em;
}
ul {
@ -165,15 +166,6 @@ ol li {
list-style : decimal;
}
#header {
background-color : #e6f0f2;
line-height : 2em;
}
#header a.toplinks {
font-weight: bold;
}
.gradient {
background-image: linear-gradient(top, rgb(230,240,242) 1%, rgb(255,255,255) 99%);
background-image: -o-linear-gradient(top, rgb(230,240,242) 1%, rgb(255,255,255) 99%);
@ -1114,6 +1106,8 @@ div.alert {
background: linear-gradient(top, #fef8d3 0%,#ffec91 9%,#ffed87 89%,#f9dc00 100%); /* W3C */
text-align : center;
border: 1px solid #E0C726;
color : inherit;
text-shadow : none;
}
div.alert strong {
@ -1617,16 +1611,16 @@ a.yuimenuitemlabel:hover {
vertical-align : top;
}
#toplevelnav {
ul#toplevelmenu {
padding : 0;
}
/*#toplevelnav {
float : left;
margin-left : .5em;
width: 40%;
}
ul#toplevelmenu {
padding : 0;
}
ul#toplevelmenu li {
display: inline;
padding : 0 .6em;
@ -1735,7 +1729,7 @@ div.lang {
* html div#doc3{
height:100%;
overflow:auto;
}
}*/
#CheckAll, #CheckNone, #CheckPending {
font-weight : normal;
@ -1845,7 +1839,7 @@ span.permissiondesc {
z-index : 50;
}
#cartmenulink {
background: transparent url("../../img/cart-small.gif") 0 3px no-repeat;
background: transparent url("../../img/cart-small.gif") left center no-repeat;
padding-left : 15px;
}
#cartmenulink span#basketcount span {
@ -2401,3 +2395,117 @@ div.authorizedheading {
video {
width: 480px;
}
/* Bootstrap overrides */
.btn {
border-color : #ADADAD #ADADAD #949494;
}
#toolbar .btn,
#toolbar .dropdown-menu {
font-size: 13px;
}
a.btn:link,
a.btn:visited{
color: #333333;
}
.dropdown-menu li {
list-style: none outside none;
}
[class^="icon-"],[class*=" icon-"]{background-image:url("../../img/glyphicons-halflings.png");}
.icon-white,.nav-tabs>.active>a>[class^="icon-"],.nav-tabs>.active>a>[class*=" icon-"],.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"]{background-image:url("../../img/glyphicons-halflings-white.png");}
a.disabled {
color : #999999;
}
.navbar {
color: #333;
}
.navbar .nav > li > a {
color: #004D99;
font-weight: bold;
padding : .4em .2em;
}
.navbar .nav > li {
list-style: none outside none;
padding : 0 .6em;
}
.navbar .nav > li > a:focus,
.navbar .nav > li > a:hover {
color: #538200;
}
.navbar .nav li.dropdown.open > .dropdown-toggle,
.navbar .nav li.dropdown.active > .dropdown-toggle,
.navbar .nav li.dropdown.open.active > .dropdown-toggle {
background: transparent none;
}
.navbar-static-top .navbar-inner {
background: #E6F0F2 none;
border: 0;
box-shadow: none;
min-height: 0;
padding-left: 0;
}
.navbar-fixed-bottom .navbar-inner {
min-height: 0;
padding : .4em 0;
}
.navbar-fixed-bottom .nav > li > a {
font-weight: normal;
padding : .05em .3em;
}
.navbar-fixed-bottom .nav > li {
border-right : 1px solid #CCC;
}
.navbar-fixed-bottom .nav > li:last-child {
border-right : 0;
}
.navbar-fixed-bottom .nav > li.navbar-text {
line-height: normal;
padding : 0.4em 0.7em;
}
.navbar .nav > li {
list-style: none outside none;
padding : 0 .6em;
}
.navbar .nav > li > a {
color: #004D99;
font-weight: bold;
padding : .4em .3em;
}
.navbar .nav li.dropdown.open > .dropdown-toggle, .navbar .nav li.dropdown.active > .dropdown-toggle, .navbar .nav li.dropdown.open.active > .dropdown-toggle {
background: transparent none;
}
.navbar .nav > li > a:focus,
.navbar .nav > li > a:hover {
color: #538200;
}
.navbar .nav li.dropdown.open > .dropdown-toggle,
.navbar .nav li.dropdown.active > .dropdown-toggle,
.navbar .nav li.dropdown.open.active > .dropdown-toggle {
background: transparent none;
}
.tooltip.bottom .tooltip-arrow {
border-bottom-color: #EEE;
}
.tooltip.bottom .tooltip-inner {
background-color : #FFF;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
color: #000;
padding : 1em;
font-size : 120%;
}
.separator { color : #666; padding : 0 .2em; }

View file

@ -1,6 +1,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% themelang %]/includes/favicon.ico[% END %]" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="[% interface %]/lib/jquery/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="[% interface %]/lib/bootstrap/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" media="print" href="[% themelang %]/css/print.css" />
[% IF ( intranetstylesheet ) %]
<link rel="stylesheet" type="text/css" href="[% intranetstylesheet %]" />
@ -13,6 +14,8 @@
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.hotkeys.min.js"></script>
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.cookie.min.js"></script>
<script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.highlight-3.js"></script>
<script type="text/javascript" src="[% interface %]/lib/bootstrap/bootstrap.min.js"></script>
[% IF ( login ) %]
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/login.css" />
[% END %]

View file

@ -1,20 +1,16 @@
[% IF ( intranetbookbag ) %]<div id="cartDetails">Your cart is empty.</div>[% END %]
<div id="header" class="clearfix">
<div id="toplevelnav">
<ul id="toplevelmenu">
[% IF ( CAN_user_circulate ) %]<li><a class="toplinks" href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a></li>[% END %]
[% IF ( CAN_user_borrowers ) %]<li><a class="toplinks" href="/cgi-bin/koha/members/members-home.pl">Patrons</a></li>[% END %]
[% IF ( CAN_user_catalogue ) %]<li><a class="toplinks" href="/cgi-bin/koha/catalogue/search.pl">Search</a></li>[% END %]
<div id="header" class="navbar navbar-static-top">
<div class="navbar-inner">
<ul id="toplevelmenu" class="nav">
[% IF ( CAN_user_circulate ) %]<li><a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a></li>[% END %]
[% IF ( CAN_user_borrowers ) %]<li><a href="/cgi-bin/koha/members/members-home.pl">Patrons</a></li>[% END %]
[% IF ( CAN_user_catalogue ) %]<li><a href="/cgi-bin/koha/catalogue/search.pl">Search</a></li>[% END %]
[% IF ( intranetbookbag ) %]
<li><a class="toplinks" href="#" id="cartmenulink">Cart<span id="basketcount"></span></a></li>
<li><a href="#" id="cartmenulink">Cart<span id="basketcount"></span></a></li>
[% END %]
[% IntranetNav %]
<li class="more">
<a class="toplinks" id="showmore" href="/cgi-bin/koha/mainpage.pl">More</a>
<div id="moremenu">
<div class="bd">
<ul>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">More <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/cgi-bin/koha/virtualshelves/shelves.pl">Lists</a></li>
[% IF ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items ) %]
<li><a href="/cgi-bin/koha/cataloguing/addbooks.pl">Cataloging</a></li>
@ -39,45 +35,62 @@
[% END %]
<li><a href="/cgi-bin/koha/about.pl">About Koha</a></li>
</ul>
</div>
</div>
</li>
</ul>
</div>
<div id="login_controls">
[% IF ( AutoLocation ) %]
<strong>
[% LoginBranchname %]
</strong>
[% ELSE %]
<strong>
[% IF ( LoginBranchname == 'NO_LIBRARY_SET' ) %]
NO LIBRARY SET
[% ELSE %]
[% LoginBranchname %]
[% END %]
</strong>
[% IF ( IndependantBranches ) %]
[% IF ( CAN_user_management || CAN_user_editcatalogue_edit_catalogue ) %]
( <a class="toplinks" href="/cgi-bin/koha/circ/selectbranchprinter.pl">Set library</a> )
[% END %]
[% ELSE %]
( <a class="toplinks" href="/cgi-bin/koha/circ/selectbranchprinter.pl">Set library</a> )
[% END %]
|
[% END %]
[% IF ( loggedinusername ) %]
<span class="loggedinusername">
[% loggedinusername %]
</span>
[% IF ( intranetbookbag ) %]
( <a class="toplinks" href="/cgi-bin/koha/mainpage.pl?logout.x=1" onclick="clearHoldFor(); delBasket('main', true);">Log out</a> ) |
[% ELSE %]
( <a class="toplinks" href="/cgi-bin/koha/mainpage.pl?logout.x=1" onclick="clearHoldFor();">Log out</a> ) |
[% END %]
[% ELSE %]
You are not logged in |
[% END %]
<a class="toplinks" href="/cgi-bin/koha/help.pl" id="helper" onclick="var link=window.open('','Koha_Help','width=600,height=600,toolbar=false,scrollbars=yes'); link.location='/cgi-bin/koha/help.pl'; return false;">Help</a>
</div>
<ul class="nav pull-right">
<li class="dropdown">
<a href="#" id="drop3" role="button" class="dropdown-toggle" data-toggle="dropdown">
[% IF ( loggedinusername ) %]
<span class="loggedinusername">
[% loggedinusername %]
</span>
<span class="separator">|</span>
[% IF ( AutoLocation ) %]
<brand>
[% LoginBranchname %]
</brand>
[% ELSE %]
<strong>
[% IF ( LoginBranchname == 'NO_LIBRARY_SET' ) %]
NO LIBRARY SET
[% ELSE %]
[% LoginBranchname %]
[% END %]
</strong>
[% END %]
<b class="caret"></b>
</a>
<ul class="dropdown-menu" role="menu" aria-labelledby="drop3">
[% IF ( IndependantBranches ) %]
[% IF ( CAN_user_management || CAN_user_editcatalogue_edit_catalogue ) %]
<li>
<a class="toplinks" href="/cgi-bin/koha/circ/selectbranchprinter.pl">Set library</a>
</li>
[% END %]
[% ELSE %]
<li>
<a class="toplinks" href="/cgi-bin/koha/circ/selectbranchprinter.pl">Set library</a>
</li>
[% END %]
[% IF ( intranetbookbag ) %]
<li>
<a class="toplinks" href="/cgi-bin/koha/mainpage.pl?logout.x=1" onclick="clearHoldFor(); delBasket('main', true);">Log out</a>
</li>
[% ELSE %]
<li>
<a class="toplinks" href="/cgi-bin/koha/mainpage.pl?logout.x=1" onclick="clearHoldFor();">Log out</a>
</li>
[% END %]
[% ELSE %]
You are not logged in |
[% END %]
</ul>
<li>
<a class="toplinks" href="/cgi-bin/koha/help.pl" id="helper" onclick="var link=window.open('','Koha_Help','width=600,height=600,toolbar=false,scrollbars=yes'); link.location='/cgi-bin/koha/help.pl'; return false;">Help</a>
</li>
</li>
</ul>
</div>
</div>
[% IF ( intranetbookbag ) %]<div id="cartDetails">Your cart is empty.</div>[% END %]
</div>

View file

@ -2,14 +2,15 @@
[% IF ( languages_loop ) %]
[% UNLESS ( one_language_enabled ) %]
<div id="changelanguage" class="ft">
<ul id="i18nMenu" class="footermenu">
<div id="changelanguage" class="navbar navbar-fixed-bottom">
<div class="navbar-inner">
<ul id="i18nMenu" class="nav">
[% FOREACH languages_loo IN languages_loop %]
[% IF ( languages_loo.group_enabled ) %]
[% IF ( languages_loo.plural ) %]
<li class="more"><a class="sublangs" id="show[% languages_loo.rfc4646_subtag %]" href="#">[% languages_loo.native_description %] ([% languages_loo.rfc4646_subtag %])</a><div id="sub[% languages_loo.rfc4646_subtag %]">
<div class="bd"><ul>
<li class="dropdown"><a class="dropdown-toggle dropup" data-toggle="dropdown" id="show[% languages_loo.rfc4646_subtag %]" href="#">[% languages_loo.native_description %] ([% languages_loo.rfc4646_subtag %]) <span class="caret"></span></a>
<ul id="sub[% languages_loo.rfc4646_subtag %]" class="dropdown-menu">
[% FOREACH sublanguages_loo IN languages_loo.sublanguages_loop %]
[% IF ( sublanguages_loo.enabled ) %]
[% IF ( sublanguages_loo.sublanguage_current ) %]
@ -20,14 +21,26 @@
[% END %]
[% END %]
</ul></div></div></li>
</ul></li>
[% ELSE %]
[% IF ( languages_loo.group_enabled ) %]
[% IF ( languages_loo.current ) %]
<li>[% IF ( languages_loo.native_description ) %][% languages_loo.native_description %][% ELSE %][% languages_loo.rfc4646_subtag %][% END %]</li>
<li class="navbar-text">
[% IF ( languages_loo.native_description ) %]
[% languages_loo.native_description %]
[% ELSE %]
<li><a href="/cgi-bin/koha/changelanguage.pl?language=[% languages_loo.rfc4646_subtag %]">[% IF ( languages_loo.native_description ) %][% languages_loo.native_description %][% ELSE %][% languages_loo.rfc4646_subtag %][% END %]</a></li>
[% languages_loo.rfc4646_subtag %]
[% END %]
</li>
[% ELSE %]
<li><a href="/cgi-bin/koha/changelanguage.pl?language=[% languages_loo.rfc4646_subtag %]">
[% IF ( languages_loo.native_description ) %]
[% languages_loo.native_description %]
[% ELSE %]
[% languages_loo.rfc4646_subtag %]
[% END %]
</a></li>
[% END %]
[% END %]
[% END %]
@ -36,6 +49,7 @@
[% END %]
</ul>
</div>
</div>
[% END %]
[% END %]
</body>

View file

@ -1,7 +1,7 @@
// staff-global.js
if ( KOHA === undefined ) var KOHA = {};
function _(s) { return s } // dummy function for gettext
function _(s) { return s; } // dummy function for gettext
$(document).ready(function() {
$('#header_search').tabs().bind('tabsshow', function(e, ui) { $('#header_search > div:not(.ui-tabs-hide)').find('input').eq(0).focus(); });
@ -10,69 +10,9 @@ function _(s) { return s } // dummy function for gettext
if($("#header_search #circ_search").length > 0){ $(document).bind('keydown','Alt+u',function (){ $("#header_search").tabs("select","#circ_search"); $("#findborrower").focus(); }); } else { $(document).bind('keydown','Alt+u',function(){ location.href="/cgi-bin/koha/circ/circulation.pl"; }); }
if($("#header_search #catalog_search").length > 0){ $(document).bind('keydown','Alt+q',function (){ $("#header_search").tabs("select","#catalog_search"); $("#search-form").focus(); }); } else { $(document).bind('keydown','Alt+q',function(){ location.href="/cgi-bin/koha/catalogue/search.pl"; }); }
$(".focus").focus();
});
YAHOO.util.Event.onContentReady("header", function () {
var oMoremenu = new YAHOO.widget.Menu("moremenu", { zindex: 2 });
function positionoMoremenu() {
oMoremenu.align("tl", "bl");
}
oMoremenu.subscribe("beforeShow", function () {
if (this.getRoot() == this) {
positionoMoremenu();
}
});
oMoremenu.render();
oMoremenu.cfg.setProperty("context", ["showmore", "tl", "bl"]);
function onShowMoreClick(p_oEvent) {
// Position and display the menu
positionoMoremenu();
$("#moremenu").show();
oMoremenu.show();
// Stop propagation and prevent the default "click" behavior
YAHOO.util.Event.stopEvent(p_oEvent);
}
YAHOO.util.Event.addListener("showmore", "click", onShowMoreClick);
YAHOO.widget.Overlay.windowResizeEvent.subscribe(positionoMoremenu);
});
// build Change Language menus
YAHOO.util.Event.onContentReady("changelanguage", function () {
$(".sublangs").each(function(){
var menuid = $(this).attr("id");
var menuid = menuid.replace("show","");
var oMenu = new YAHOO.widget.Menu("sub"+menuid, { zindex: 2 });
function positionoMenu() {
oMenu.align("bl", "tl");
}
oMenu.subscribe("beforeShow", function () {
if (this.getRoot() == this) {
positionoMenu();
}
});
oMenu.render();
oMenu.cfg.setProperty("context", ["show"+menuid, "bl", "tl"]);
function onYahooClick(p_oEvent) {
// Position and display the menu
positionoMenu();
oMenu.show();
// Stop propagation and prevent the default "click" behavior
YAHOO.util.Event.stopEvent(p_oEvent);
}
YAHOO.util.Event.addListener("show"+menuid, "click", onYahooClick);
YAHOO.widget.Overlay.windowResizeEvent.subscribe(positionoMenu);
});
});
// http://jennifermadden.com/javascript/stringEnterKeyDetector.html
function checkEnter(e){ //e is event object passed from function invocation
var characterCode; // literal character code will be stored in this variable