From oleonard at myacpl.org Tue Mar 4 18:20:31 2014 From: oleonard at myacpl.org (Owen Leonard) Date: Tue, 4 Mar 2014 12:20:31 -0500 Subject: [Koha-patches] [PATCH] Bug 11878 - Eliminate use of deprecated jQuery .toggle() method usage Message-ID: <1393953631-10182-1-git-send-email-oleonard@myacpl.org> jQuery's .toggle() method can no longer be used to trigger a pair of specified functions. .toggle() can only be used to change the visibility of an element. This patch fixes a few places in Koha where the deprecated functionality was used. To test, apply the patch and clear your browser cache. - View the system preferences page in the staff client. Clicking a heading ("Appearance" under OPAC preferences, for instance) should collapse that section. Clicking again should expand it. - View the MARC detail page for a record in the OPAC. Clicking the "view plain" link should display the plain MARC view. Clicking the "view labeled" view should return to the original view. Test in both prog and bootstrap themes. --- .../intranet-tmpl/prog/en/js/pages/preferences.js | 14 ++++----- .../bootstrap/en/modules/opac-MARCdetail.tt | 33 +++++++++++--------- .../opac-tmpl/prog/en/modules/opac-MARCdetail.tt | 33 +++++++++++--------- 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/pages/preferences.js b/koha-tmpl/intranet-tmpl/prog/en/js/pages/preferences.js index 8fe6369..80b8429 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/js/pages/preferences.js +++ b/koha-tmpl/intranet-tmpl/prog/en/js/pages/preferences.js @@ -95,16 +95,16 @@ $( document ).ready( function () { $("h3").attr("class","expanded").attr("title",MSG_CLICK_TO_EXPAND); var collapsible = $(".collapsed,.expanded"); - $(collapsible).toggle( - function () { + $(collapsible).on("click",function(){ + var panel = $(this).next("div"); + if(panel.is(":visible")){ $(this).addClass("collapsed").removeClass("expanded").attr("title",MSG_CLICK_TO_EXPAND); - $(this).next("div").hide(); - }, - function () { + panel.hide(); + } else { $(this).addClass("expanded").removeClass("collapsed").attr("title",MSG_CLICK_TO_COLLAPSE); - $(this).next("div").show(); + panel.show(); } - ); + }); if ( to_highlight ) { var words = to_highlight.split( ' ' ); diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-MARCdetail.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-MARCdetail.tt index d731c7d..004eecd 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-MARCdetail.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-MARCdetail.tt @@ -182,23 +182,26 @@ $(document).ready(function(){ }); var loaded = 0; - $("#switchview").toggle( - function () { - $(this).text(_("view labeled")); - $("#labeledmarc").hide(); - if(!loaded){ - $("#plainmarc").show().html("
z#q3SJt`vArvD6+V$9E%6js~mnOqptV!kO_PpUy0CK((~%uDqosl!5k+F9F>aE%v>U z#&yLqAVo;Z%Z=`o%OJ*(tlYVU21a}ki;1=wDaCSHtTF7xlb(%-_GMGELvB zaV3Ry#nxH7#3EFDv1An 1o;2F${_JLUB~*U;joGRS{nOZ>l`aw!&U9BJC7V%l&q41^Z!VhPgM^Wp z$7MSDiE?hiAN-i-u#gDwgQbJIhJ$>%v%~?`Ms2{`Y1U1Jx%SRO0=g|+D0w%sEDafu zA|&PICU at o#3E~m)Mvia}ET#}wUC+dFLOh1Sr7ASt65harZMB9nJr%2w*JdnwG+l*~ z at l!Q;YLYylqF3xge8u at _@LVPM(b at jQd3 6yS(l1L z>H*`?EEP5&K5x~X!|~MbUtOW%b~Qi7S%<#rFo>gVI{|RT!ovXv^kY14q#hui&l`m! zgg5h6`8gb89PR!f4Y%vx#xFcPhvz(`V0^3p2!7#tXr-}M$w+J(y}w_V3bMXb#_qJ_ zVOry1TJkWh^Dqtb3JvieCJUC*f!}OpSsd(d%1XZC4`?0cKS0Z$Vu$%v5x|${`1pT~ zzxd!B-+HI`(mTax-Wi_WJ%9&j$pbXNOB&=Q4fB!)d7XxNNyEHK!@Q(n1#Ove`WNX^ z(Z5sG#GRHrOlv$$OCF|m9;RVlp&|ambU9*@hww^lRsi`;?c)adBk at UCmwax;!z$^R zLw{#Qfc;RR0Q-rB&jJ3j|3~>rL4g#PDI{ROlMHNM?kNH71JADHAz&M_FKxs2rES>0 zv<=#qwqYequ?_m8*@pd*wqbr^9Z3INmo8l@; 4OB)(@!MnSWR5 zTEcH8y;Iq!;XAjfUv3)eBj{YE&>M+s*(d|GSVU|8(~p$CkYUpxlCHPg5o$`aU?7{P zhDO V$-nz*X2d3Z(lZlJt4fX8Z=ELFE0 ze;Q#m8Z((M(~Qx#!4h@*iLU0cF at e-wJY4LhcOy(1-g-A4>cc;{xqbQ}w(zrp12 at r# zB;9Pk8Y98D%Zq;VXv-iPyUiZ#wrPaJ7;X~g8{1{iy=Y0tqVHeQME}Lv_GfXkNQ_mu z^_HE)Pda1i>Nx0K)dx~GioC-((FRhVrh kTHOx zu?ZEJC6?uZ^IIh_xjd|kukap?viN?5E?v5m5kPyKu7LD!%~(zU=r~ }=-X`=H{wbvZD#z+vlg%@sIVmvXh OM`VqLn_MS#@ZGk`Qaw7hgY^vvr2IgS~|EOf?aA%Q;>-45^& )*st$CY?R_f=!T8^o1+gY0YvJL7`OfoWXvq~Ut}A!nx7o*m?Z%a9pe at nU$r zT=5>W=L? xV_Rdx*^K$WBBzKHehh}ab`sfrc}#EJEY at tR zMYm8aZOez!&RD}{yA)4HRP~WXRpR}h=+dQymL%XnKqyT?dTkfVHv_~aU9xonaGLRh z3}{hMI(S}20leh)f;C;%z;nRcG7z~|%P%W401xQ86#U+H>J3X-`VJ?P(Ar;1emk4k z>0n8hW#Ofik|!wS*+`ebGK#<*?H`B``hD$Mtp{u=DV5f5!7u#2(X-`mTR#_}U-6>E zu60e*h5s&HLYVar4m^5{8;I`a3SpM>8?G2tGXikjdESU|QQ&BNUW@@e ?a`4MnsupIKd{4W zT|c~ou2$=7YTK$pG at K~L0qd);9J!)dH+!?Jp!IBn6TrISJk_mJBYtSguj at M9{JC4c zsH8Lot!`bONRlqu<`o-!7rZjO%1#)aSKp>eIBNX3<1-~50X|jw3h at 4RaezEk4pasB z1t={_USCfI0eEG#`qaRCFFrdsf8 Y z8Q+ZOCP*AOI8 at RaK34}tA`3nzYA P zIe_ k5u7IMeZ4vzP3u?kF<`t!`bONYZp2l7A9|?}FEcmu>f+=)C$iR>D!^haKN3 z at u>5~mT#240`_m)#R1yKp47l*$UXu}i_*Tfp7@(~`?*pR#m9UlOjVwuT)M9=qhX2$ z0fF`ra2}1i*~g;1-@|ACKi)qsg*{&qux@#Rn&jFTbV+Wz at ZHE_5GhQ+S3XD&g!%)| zsk8f?kh{a-kFV|h;x7WlXMOS{mrR(JIg?%ViIF%<`DG=ruEsd!Mzc0v2 =By9;*id4$x5T+e)}?W z=RiSRzW9>fy at B_QWMJXI=KvM+nAPP<+LDv)VhDnEo9xAz9}i+fK)jeX7f3DbTJj`Q zx(#Nm?b2rBAxg4^3O7hgzq}7U^^>K9Wa&F at W9Ss5tffm$%9PXP-GlJ at wequ;0#OyW zoTk|#CM*-4TO{z71A)Lv46L at brrhLra44`O+N?|$Lemw%@2vpZv?Yt6EeBN>^h1=C z at KG0wBes96IG;f^mMhIl_YbbRejn>AdkLz3yAL`eBaPg}LP;T5V)v579;_fE;^Wiz zE?xR=yBOWbq7W%e&i@;xdwd&sPTh at T51#@#%`;=~t^UV_1xvEtxt%RJGnvQRg`ZfT zR87bI0el~G?hNj#1Vx +V6?u_#;gp;IuBt`h at WzxZ6g{CmP at p!i!I;?0yRW}@>QH8MRRX^bm9x9QdXZ{`P zqpk@>2aJyNAG*S*=~=^RHhKUaHjGDVRbk%n%t|Vb Phyib7D zHaGaeUE|IGiz4Dc)iH!7+{^$zP6DW!sYggDL~1JJ)I>ddr~Or=IB%=a=;*#egS${E zh+5P suLQ~^rf?sL9 at ar8c;cXGq4H#RapD4-r)#D?!D$fZlcB7igiQIXyVAaf~; zjOF^lUCIi}D)AL|r`_VI3r at awY6* |1=vZ{~eroO=yE&ZeW~y})4i)0LYB_g`O3`Yc z5tlAKkO0ulg-%!}fQ~(2dSLShpD~Q1S>iKne%j*51 at FI4Y)mfr+z+q4D=s(^DQM2z z3NFoOV?I~zkhMrn9;h5RtihDlhZ9W8{J4 at +1iRk3r8qYR9#yR0b5A at sRi}0bAuR=k zPo#(jH~PUi4J;ug?G9bLIsM6Q8Xj!2Re;#djUKUH27^m~j&vuY(2;IVbu$mOiV_^+ z`Kb_ZPC4FrXF{d-T!oY~R{#|in;za at txNtw=t|qgDJ){LIl2JSkgX>Y?SKN$Rs%;m z#*Q?6cQaTI6a(p`qSlrp=qjxVh%Voj?(3?-`^oUo-&Y8SjT at 6Me?5gS3IlYN0=Tm; zs}D>OJgdZvx4?!Kc-Th)&@5XrwbOwi(6iv($ROA2{i;ua5LnhSHk8rshXIorR!Vyu zUxA at Y7aZX=G0ZYCoLH(4m96-aYC&PGGsJ=_WPn;L2mae={pq?>fh6WrTf{`rflCGG z6K%xzK>6)=qu}6p3M{21Nw4iESH+^oA)b&^*d%>83$X at -i%!{&VO5ULeC 5(zqY zsQ|I?9Y8k^)a^4rtaB^u OMdr4cf$V%IE9{|4fPJODxhPBf~$<51y>^q3RDyauq z_tgRl;CnHA)k@!;N9N?XE3;aAH888E^@E74LI2m2tI2(>rpm-;2PGj=e#MPJpEGfq z)~Wc1=z(AzHl +89-n(VJS y#P6_8Zh{ z0E7qGcb K&YPH(8-+j{h_Wk1>wZD&l&dE9FS=V*l oPdG5L#W+H;DSx|S?q&CeckJUD|`aK&C~pOX-hUHrEN_R zu0r{&+$dN at 4_cp)yee{4!pd!%F0Jx{kNDxCQT|O$O+9y-POHn|Z*$G;@$qpN7nh|H z(!G24dU|^9j`U<7 va+%Q0|S>XT{<;2WnyBo=hT{{Qj0Zf)*SgZYhrS6 z>h(n7vB-Dtet!M))b5t$OLAZU)NjB2wjk Srn3orB0p}l}P;h5a8k*Y1_ z!~n?r(PHP;R+S@=(kxsaBtSsD#XLVp^W;pd&otYvW|V9|i$HG>8JpSBqyUR&jCo#{ zAq~Oos^kij9jKmEM#1_Eg%8l!?@(km$4MKH;b8#iujDwIJ~U|%nz~4IG%dul3bM &Yram#Nwet^{EYYWnnjOY^ z?!6YHL?~s{RnhpYgkUW!`LG04vcruEYdS1!*x_NZ6GZd7gwsfHHy#b7GwA?jkB{hFCPzj>_amzX-F^FOi;Lvt zu+q48`d-?i&+CUqsuKN9gV3qr<<@VcKFFBZC0G0G@)yuY#e6jk8T_gPFTMT?#jE*- zk2hgDT|`$OBFFg}UwSRCCv4)L#lqB!>qEjM22HuU4Op9e{YcOqIYHulsVCo^L)2Rg zR{kFSh+vl%P9lIsq6Zzl(L3B(42Js-bcA mdn-e9reSafDhhP#QOe&JNY*v zAsiRl1sNI!*&%F+{oAo8b312cI|9l)S%~0SrZ04w;FQeysnT^j0_joO(StK{8ALL> zT3z ED)*^!Lm|rsCF&b12a}}zzl5dn4qe|@r6}o1qEfXIz`6N zt;1NkarU-oY z#)MRvgF5u=i$l zmNdzh;m79(*}jHW4RYdYqi{;RcKEDt#`S=YYUtH#*%=ZbURG@=aPSCL!i2;^$GB>t z%v8H~5#bRC+qWItD#W5318uD|a&XP$R9~M~dNY(Bfd!(d*I(w at R;r3+Awc6csXooh zp*tiuPg<@86A7eHlHOof#gE8HWOlFmP~6HJ6qBk3XWiB>U`pXvam7|mj82zaR}5Xm zSDSZSG7V&_3l&CoY?Mz$k QLX0zF`1z}1^v3ooU%HMbQtr-tYh zF_{I#5Mi67xveervV at _90$1#u3{ZYTAQIm!7+z`0rwE1 9E(sY)T$2v;bM$7{wuB^KSh8bP&PqG?2=88rgp6 at JJr_j4UAB4Thb9p{ TPu7XE=k=Wqp;Umg5uVm9pw*DRy`Kmn#4#lqYPky`vpNdbH=ml0f)&7 zffxV9E1Pp5zDcvp`tii=K v4~fexE?9deslb8{$H!wIT&4^U z3B+?x <)1 zzmIxFFzBNfkh1eKEEeOt$0A{xLr^P!-6ljrN?}~OokV9-_}ZkgRf3K_F(RJwn*KO( z7yaNO>taPOxr5t at Je+l0%O+0CYpo(@e>r%Q_AW+W$*qOBu>e_%IT^ysEn$E>BDA_7 zWSaY0R4YCj*c^1M%&=u%0U*xL(r^B`z3d at C^j3GFB(ot6 P+)( z|C9xX{{);4!L&b;{QCM&pl zaS0W1Z06$v{s27;Sx2qDkx}Gd%F;DR_4 at tbn-QI>?FN%<_Z%8fX)7?15D^8@;Jp8L zrvE3}+ at f4vv}#IYG5ytAS!c;Fw04M4S~CM{zN35uvzJ@%%WN>!MuKw>mU|VFEX_tD zv|U1_&}u(Rwnoy}YN6dp29Ac{c35t>z8IAcn+D}Eng^0$BKF%VTpoZ`l$io4L9E&8 z`M9Tlq|1__MNj?KXz # z!hy^O&EjPX(>{ZoHNiBKcf0e>39yvPIYvd9Z+Do$` Bu6r^YF1SKZ z7Zd>zrRN_*j7*ii;7&xmxeJX>OrTC!ZCPjlhSRjLcH(Y$>=uX-&(-)Qt1rGH!_%XC zJ+b1q*JF$SPUxUsAG66`7VYu?R3Sn8&HEknqtgx`2r25Pm1?esr+uTj9-DRqt~s;& z=wSe;kE~NBnVM5DfS~B0_PI={p4{{Mt)HQhh6M-ps*wn at 1Bu5#^- =4KWofbu9`**n1IWLggO6;QA(+Su?h z at Fcurr$pX65(&rQ^IJKX(#+nq)8Wa? cIP%kr9>MwI at Cj@{YSb0Y2ECy-VQza*qWN7ID$0rnL1M z!cDYx>Z^$FUja8)?_t(@>#ntct#)dxJO9;{$EL{bvhe1308FRv99Re+5Ddg6{uz zcc1VXq5V)#hqKP|gVyREh12XV?NQgw^iejDGt-Q7_a_^BwK|*kxwXy eS^5MgruVUCu62lxZrj2&!Eph5x0%Wtk1$L=CU;QscLUw>nAO#4s)57;3n;|nsFGe!$8kLyW@|Cej zvz;jyy~CM{Q+NFXrgHjeM|VeIW$eJI8PMo*mR43I+rWCx^qWs-0XfyD{=a$o6qd#D z<5P2pxt}dFHcd3H8Z*olR%evyEQHmjxS0k#aVCaLDyu4+bvuiq5M#VeNlcanG${?U zx9kT)c<++cn^Aa%(Cq?dkmF#MKc9mo at q4(bOzTbbAK9SZdbvgGYxL>*71LVtR$!k7 z5((PEG)Sg8-rS{^bPos;42ScI7yFnU<}y5i_!#|rPtlK>&_BFm%(zl=axLNfd8 %+F6&ZKZKfF09I3p z?VEK);;oPVOaT {GQ(M8Wg|DVWTOaT*Wg(&b4*q}C>;8=5|Fx|5UqAD8 z7#p at nu?qp%I{AtcN#1RkMm_D;GG!hE%p0l?WUIheejh_Ap-HZX9npl?-uEeVbsUSw zk{ZtZy*y|pNTlRAnJMR+8$?444j=tM_~unXy%v5Yk}DmheSQBAU5e}E=2 at MDBVGm* z5ADN|mvwS<+8#$Y`?p+!hEr(GqwkoJJS1z_DfC{Q%8!K(scKfo_8p$74q)O&mJpe! zYMf$kdi5sc0clj)U at h@O5;%t{EsT{W5AkCy@|-s;gwoOAPfl-mV1%SmTEE9lAEaYn zmc`sX3O^H)C$hRUheAEhBqgj2G-FYyHN(;Syt*SDUZgk#%cj3bV&cbFgXd!^0uPT6 zj6?Vp at Ex WJxb&HTP@^#2 z^vn}$p8aqg!tAklqrr4$f-${Qf)sIGD~7i$_ at fI~nOpWo>R|bp&xQBcW5`QcuD;tU z!4PixlkAi3DCAM dExfpnRvzB) z2Txv+{Es|gk0iyHfHBIKcUc|R$iVDQ uXcln zngK;Jac0$F+H>>u1SI!PGy#=tY+;*IeTV3luAtAxtt;v4=a79L2~kke_+6+0tjJri zhKXkk?Bb6G_WMraA+j$y3)OwDrU azaOyj qcJXo5V&>HZkWJdCv!K at IIWHrF#|}gl)*bMK(&D)KuFvDC zRySsL=>`R|7aUjTb&S15 at 6(%5yeh2S8VFim)-IMfQw$o9cQ{<@RJr8*@FfVXSXwrK zzp|#SE%$I6bE7>h&v>+Usb6)qt ZJ5wll-SR3|TkoZ6S(5RQv z5Jm%ug{=;pzZ( U*gNtF}UjuC%ae zamc?m2l`Fhz$+06dDD%d?$S&x at n=2VZ-ne@$D}rmw25g*^5H&_>(5Ff=z at p)tfT7$ zZGHpT6p1I-ulcQKA{M at 2|9G)ugl8U(p8F6wzmvE=FC%r8H at LmE^M493!Y6s#62b^D zncL6EuW7ui3RpoC0~39%bQ>K`E|`4VKwf=??>Tofnx@!SV`cdGV59bNkfK+9Yi*4| z*gV)B(n~MTTm9JYtO}NR;UD<-L->`i7?^zMHhH6I;k)Y}uw-`gvbUZwMIBf2^#x#M z7y-%TTxRcWr{-2LvjLp8cF8I8oLXzbj#&`vnDo*cM$@KMRDl_f+%NVgPM-xmG}@eM zwA%UbLoOEd{8iSN=)fgsTSf6`C3q=i(?TqZ1xF^VhUO##V7A5S;~xJnX74Ve=ZoX} z%OMX-xS$ piGr0zw2->}+cm=D;0305PN9w7krQ7JTQP~wm zmyM$IHPt-6#p{lG+I%r`);XR~;>SwkLJCi9_OzVyTWK^zRA%k#9=>`8H3EGL;uCg( zgt8?NcU4mfnP-`4L$ujVHNx6s0l|rMN#=6rWIo8G`<;S2(atmwBY~=TL=rx`Ygbtz zG9kBx*0&DEx9OH3+LD6AoFC`5(P5b0VWHlhchXItLBO(lZf_mZo7JmeK-zM5Z=S$= z?jpz=o4Pt?6+Oxtr`tiU+j<&Xq8pvZ2 XDct{`^ z8S2{a_jl at YZ!2Eegt0{6 4gy9R8i ~{f&(k%r1!amKNjA81FdhEBqjx8SY zm at r4lY?k4#9K_R9G`;1FirM=@Z&@tYv`s3F7RAX7PEkSsP<@Uxp1 x1+F}W3M0 sMV4^q#sT|c+ z9U+y}k{7*6lmi;iE+%;IV65Q~bBKRWcbgABs(>haW+}}}>OyMVSGu|dFmoC8Dt9)D zto1%see$I3kSXlAm51W-X%m>V 9di;0nduudsF4{%3|r} z>HK qz?P^Bx;9j7br5WSEFU`zPbE5iKrZ58 $)@a~pvq;{#H^K$ zf*WwoQ1{?49TUbd8aVN-?VVgt1S5Kw>6&eh(ns)r0R}YiGUdX_oG(qeUOJf9!8r!W z{Hg>&pe;B9fkLu%b#iG)sJtlO@@a^R3P{liuzF?x-5H$gFLpwrVmmrS&F86Ii3cr@ z6OgUi&;#Z5DKEnybEpMVL-N3pURdYSjU{avXP7uwYhOboI8nW~+Etfwuz}ETX3guK z4YP`7EwFie-5?>sbYwS2iUQB{SsyCjx`^u8cZQ={+4A5QU8ImfFqdv`?-DaEWHt+f zLXo5o6TD&fs+H)kuNx)#SoI_Id-3UYi+Q2qf}ovw5vEA#I4Abyoa+(V0p>w=c754g z2hbC*2xB;V#rvjW; zW1^{`-|J!JdGlA8e!njSMmi=ZW(Iyua)CrfC5kA?kp&f{CNAoRI at 0y$7N)~H8~oxu zN}=yhKC+s$++y%-f-(CV%r#5 Pg;OHjEFFh-4GLL3)9|nUS zkH(|oSm!$-M7@>y&3|9J+#^dD>g jkd=&D!oHQj% zf!Eeufs tZFgJ7QS#oamE4(RIu68IFGyfY#05D_C>0zMKq)crm3 zUqi*Z(f$n@;#8vjs%=w9%|j)sR1xD1^fbho{gb#d+mFO0l-VJYCT}n^Ei<&|c_3xv zPdFHcJVEWOuv6J7iYuK#Vm(*#Bt;1kCIH2qii27G-z1_S1SdpX?bx|}J)FuJZpPV0 z8UW&wcD~V?bPBR9+{|A(vC9?Mq&BD9Gr!;GrwQ6W&P)6 at Py-ISho^Ptq18)G#(wBr z>8O!$wGN h?K+ ze>AXQ?0i7R#%VB^WRtEn?EEB+OHvK}A^_&_k}*OM2M^v at 75BsSg>G3{eOW1I *Gy#Ky!>=txFrE=AWTB_SCioBH{;^>*RtC^x{-(cc$G zmA;zwOR5=6-!!wfaddDbaH&2HQZBTEgZ`^12B6To7i+r6H>-LVbfS#0OqH~@ z5U1Su>k|Hszf5&BOD 15<2EoAuYR*F?Dv^zw}-x!CKF=kfr?UAAeRl=kV0-wrrXV97h`P!dbr;tQ) zB-bi+W_}>-W*Dy>rsUrfUVI6<#V|McsGz{XtTp&~;No@@WM5TByJlD}A!(7>67-hw z{pL)j9rLG^1>?v*7xPkKdX5_98&5j-9sFYeq1~g{YpqhUunl~0 n$XZudib0Ccz6R7&Uhz`Z>>O`4%#zfPw at xsd zp0M8uc8JyL8T=_5>z%A-*ai0=!z at oQH8tE2kaCa>aR1knWem!ZwguI#W7LI$zaalG K&Iw533 at VC7P-DPJl!T~JW0bCTi9`)Tqb4j9&={Xj3JSL@ zf>_T0aU0Z8QCtEl7$-rqnT(EzC?gsm2~8_1vIrD5blo}kR 3XK6g2^D+AS`}&6t z4e=j7a;UGbal}wR|1kfd#!(|i`VIFF4fPx0BW=~p at qBiKzprt=FCFL`{@)DD>BsrF zIcfb~nm9$rv2C7^LV7$Z{h^1BUVVY}*t4D)ct?0#fO>(mw7$pl4gkp~Dd;yrI at 7~j zlO;9xn1lBjkFCag>0?Bbl~eloN1FaU*h-E#61w0dW at s1uj>pRt&`LD;R!&kcPfn=m z(`4OSP+yr8eL1Z>=iBFw6fL+jc4^7yQzz9_Dn~3Xg(d={H|#CjePOEp(B at wIk7Z^3 zzG%#jJxlkktcfeX`qq(k*N+pZ-&@m=Ilyv!)mU<_+C5TOw7kN@^wG!97goik9JsQe z>WifENoS(#XI>VzD<4`WSoclzyD`gnK)52zX?k~VvE_ at 6Wq*v#O%4n%FcX+?!$P3Y zI<|IR_ at xa=tNwF$_4VW(r0_~~VAa^8S>F-Zl yzq(@Blx=l$ zQ>)y9!uw6MX2!-{NxK P0so8S3gP{YJCqFCu>v8MY;C| utkd(8e^szV?vEli*3`x zr0WCLN;iM^lr&+$7%9L1V^Y5XUQ)cLyL6%daA{!w{?Z%$J$k 93mY7vg=fmc^}6+&Pc7$F9IF#=f1jEIVj!9HC?$g&tVe%YchD$_ZV$Iv%N2dFs} z0#Xd9qkp@cV8o=NOi}f5bBUSFsHLAF(`2v2<(4vcWMY{h4u|f-~5G3p@(l z!41FZryDro?k;$zmm}U?u~(Hj)O5qP3)0~R&aCAC&aGglIYyG4{cd3XtZD^#tDIOt z`$Qu-Z;sb(AQkb8P at F@^3w3w`$R4^sko5po;8FxqT?ZOXK_lT_VVZ1mzE&NRN%~NY zb`5FJm_Zjs at K8e0K*$UfN0Ti~bh}2bnh)u6N$sK3R_HQ?5T&5TL|UNB2j>jX?Wp-2 z94kS`xfK393dU5LuR*F6Dc-6OsKB#DIDt!!C*&)0n(oh}AT1chG;;fKGjIZ#*#g`d z@@XY-IaW7p-zFOn+Ys4LV=l3 BN;p?zIsdu|h*tDUH>n~&?hPB+cK zP3v(}+>-(_1;S*(tRgA_hIlS?KTZ)Ng;NxwDU(f zoX};|MfjS=PG#y+N9H&u)ZzP|BO8FeV?MRRL3FSy%FZ|$k99Oa 8QWR7%z6{r +SXyh;kyX*={#opIMGZqU8veNkRvglw4{8i8qPA^2Tsqj=lC%kDkB( zSMOS#j=lC%Z`%Dn_HwT1r>@Q!QgY0GoGZS6cJK7lraOi+O exqKnN;SKBYLdo|OoZM^hMS-%aNof)=G z*Y78``%K)wBe o#9B|~&8j^U!ft&V6EpGJUOrkDalF?-P=GoX at cwC_PT1=Cy#WHNCdKqiXc zz jhPyT!wvX6)xiz-yI+dzGtZ zk|RV42)0N*rRhCDw)LYq=59@(QO9V*aRId1BFkKux`_6ux=8?TvWsDuix`|#3=EuL0Z-?@s=C!(&{G7GvEF at 0jdr9nE z6Jo%S*dF^WX zA5A*b<8XwfWcU?=+% zRr at g{Yy^F$5~QW{(U6Ff=Ww%B4mp+Na`}5MP9>Q`KcHa;c;*Bxbrf1%s5(h&bL2MF zk%%A<0S8wg02UG=zqj?Ok-0y&FjV8I$!+z~+#LQeTRhAb j!z~=ZQU9%&3r PRwJuAy51eAGc2$Mficqd&D%9 z>4+?`o at qW8*I*cbFJ7dQwpbJ|Vi;G5*-UI&Cx}Uykp3jTpLv9BUZRMaPd+dq0t9wE zy_i^bnbTpXEmbt9udgIOC7aj55%!p7<2&_wd}+;KnW0n^x0w&?c8H%GKF<_~#kCE% z+ez^POAedFJqTrYViS|rin$0?sFF>Zq>U_9U_Yjc+iRLcjXFk47eI at xatoKEE~34n zZjynU6fq2k5W`v(1Ez}R^yD&fIY~vxQpNG~LL%=_jlc($8n|IKH4y3eh5a1_{Y at o^ zL-r74hWtLaT4j(^8NMc8;xcRuqYu!muSMnoEp-ywT&6mx&56fUC$dz9a4S at PcZw(N zt<}lQ^E6M49w{AcedJ-5c$g)AnI#^+W ^L}bt*ILSk*P|W#zDAqR|QUiJFEt$ zfaUHg98+}E;W(_rwc;3B9kP|-;1#B5FT-(IhNBu=8IHp;923 V)~R_WLr>L at HkzN|Xwt|Fc4VYN($ZT#0B7GT>dbxLYong)M? WJd6poR{Q at mCfx6i35?;6&))&Fn!RrT delta 1518 zcmaJ=X;4#F6n;SjqzIG&L?R)@5W;2wSpqbmptT?rFp2_33`tldBm+sbg_7rt16Er> zxgfF#odHFOtN~I%r8=F`v9$^$1d<{;I r$4R=9i(57|BE4stw7={oS7?{4>KOo&ZD3B50?d!|(^CtTQ z)4iEKeq^REGbk`Pz!%hEXd6Vv{}IK`Mm{!MG31D-SYso at 7zaSN-R1-t5HkZ3gL-r= zqdn^eS%7le&w#?#6B7?i>}aTG+7+W-Wrtwm#VY&nF|O8zatpK&+H8foHC3BYJByk% zgi1oyy%X0u5RBmYl*BVi+&j4 58H at 4rJ5?4hXk9k@(5PK)losR7fr~s`C?k%csZBbpuKrj z-=f6QsERkb)Is6H={Ma7G$@qm wOyZFIyxEFw}}!{dhD=MPF;Dvu)cL#Ln&D; zP+tvSZoD%3_-SfyhbDhenj&qsyr)2*&g$dJg^UDN{}Vl_^(l4R at R(}s2>i!tk*l)` zE{L2f3wR47L$k@@w9a$#(cI!}ubhaH!XL=GK3&1=_ fmyDMe=HgdP(q2No@$LMcrHEM3FC?`7znA zo`yhw`Hx>>6jJmQECQ+Ai9)fi|6%})NT*dQFv4xr)TWIH95ZcALzQ={LffzFK0PSA z+a1IxjEkGIP1416HHwwz2Oo^lDO+CFcZo8&qAT;TDErS>aq7fQ5qx at brS!~bA+{_& zm(f<8f mF1EXiu7Ml?&5CLlpO7qyzaeJr>Lo!ekoDc0R*}}Mzfemi_yrZCKiX^A3lXZ z$jDrkJcQSKfAmt)3^aMPB9U^f32q$HE%Y>FGn%G#+E>GZg(U=vzIkt7MRfZuC)gE% z+MBa!HKiE}O6QXK;EG$$EE) zk6(zdKi=0j#NRK(pA0H+B=krg;OsVoLj(d?bj5+^1Txt?i^FH-vFQvJGmXn-qxS)s z(*=C)Ar at 1>U~NEKID(u=E}NUjV{
6JBGKm84wY$;FN0-$ahNu)}+`nk~J81a{@V}Pe3dQ4 at yWx5b2HuiJsd* z7YPSWxO;&vk33NA;RvEU62L|Gen9l}0Yju<2b%-|m(SYEX7A;rGtvZnmO%vs%-r!H z&dV;) From: Owen Leonard Bug 10649 introduced a new include file for adding DataTables-related JavaScript assets. This patch adds use of this include file to all circ-related pages which use DataTables. Apply the patch and test the following pages to confirm that table sorting works correctly: - Circulation - The UseTablesortForCirc system preference must be enabled. - Check out to a patron with existing checkouts. Choose a patron who is a guarantor to another patron with checkouts in order to test the relatives' checkouts table. - The checkouts and relatives' checkouts tables have been modified to exclude articles when sorting of titles. - Hold ratios - The title column has been configured to exclude articles from sorting - Transfer to receive - Holds queue - The title column has been configured to exclude articles when sorting - The date column has been modified to use the title-string filter for sorting. An unformatted date is now passed from C4::HoldsQueue.pm to the template, where the KohaDates filter is used for formatting. Sorting is based on the unformatted date. - Holds awaiting pickup - The "available since" column has been configured for sorting on an unformatted date. waitingreserves.pl now passes the unformatted date to the template, and formatting is done using the KohaDates filter. - The title column has been configured to exclude articles when sorting. Edit: Rebased on current master following commit of Bug 11605 Signed-off-by: A. Sassmannshausen --- C4/HoldsQueue.pm | 1 - circ/waitingreserves.pl | 2 +- .../prog/en/modules/circ/circulation.tt | 8 +++----- .../prog/en/modules/circ/reserveratios.tt | 7 +++---- .../prog/en/modules/circ/transferstoreceive.tt | 6 ++---- .../prog/en/modules/circ/view_holdsqueue.tt | 20 +++++++++----------- .../prog/en/modules/circ/waitingreserves.tt | 14 ++++++++------ 7 files changed, 26 insertions(+), 32 deletions(-) diff --git a/C4/HoldsQueue.pm b/C4/HoldsQueue.pm index 6c36402..63f159a 100755 --- a/C4/HoldsQueue.pm +++ b/C4/HoldsQueue.pm @@ -135,7 +135,6 @@ sub GetHoldsQueueItems { $sth->execute(@bind_params); my $items = []; while ( my $row = $sth->fetchrow_hashref ){ - $row->{reservedate} = format_date($row->{reservedate}); my $record = GetMarcBiblio($row->{biblionumber}); if ($record){ $row->{subtitle} = GetRecordValue('subtitle',$record,'')->[0]->{subfield}; diff --git a/circ/waitingreserves.pl b/circ/waitingreserves.pl index 1ec6b2d..fb7a3d1 100755 --- a/circ/waitingreserves.pl +++ b/circ/waitingreserves.pl @@ -105,7 +105,7 @@ foreach my $num (@getreserves) { $gettitle->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $gettitle->{'itype'} : $gettitle->{'itemtype'}; my $getborrower = GetMember(borrowernumber => $num->{'borrowernumber'}); my $itemtypeinfo = getitemtypeinfo( $gettitle->{'itemtype'} ); # using the fixed up itype/itemtype - $getreserv{'waitingdate'} = format_date( $num->{'waitingdate'} ); + $getreserv{'waitingdate'} = $num->{'waitingdate'}; my ( $waiting_year, $waiting_month, $waiting_day ) = split (/-/, $num->{'waitingdate'}); ( $waiting_year, $waiting_month, $waiting_day ) = Add_Delta_Days( $waiting_year, $waiting_month, $waiting_day, diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index e667bc3..1c536b5 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -14,9 +14,7 @@ [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'calendar.inc' %] [% IF ( UseTablesortForCirc ) %] - -[% INCLUDE 'datatables-strings.inc' %] -[% END %] +[% INCLUDE 'datatables.inc' %][% END %] [% INCLUDE 'timepicker.inc' %] @@ -47,7 +45,7 @@ var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export"); { "aTargets": [ -1, -2[% IF ( exports_enabled ) %], -3[% END %] ], "bSortable": false, "bSearchable": false } ], "aoColumns": [ - { "sType": "title-string" },{ "sType": "html" },null,{ "sType": "title-string" },null,null,null,null,null,null[% IF ( exports_enabled ) %],null[% END %] + { "sType": "title-string" },{ "sType": "anti-the" },null,{ "sType": "title-string" },null,null,null,null,null,null[% IF ( exports_enabled ) %],null[% END %] ], "bPaginate": false })); @@ -56,7 +54,7 @@ var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export"); "sDom": 't', "aaSorting": [], "aoColumns": [ - { "sType": "title-string" },{ "sType": "html" },null,{ "sType": "title-string" },null,null,null,null,{ "sType": "html" } + { "sType": "title-string" },{ "sType": "anti-the" },null,{ "sType": "title-string" },null,null,null,null,{ "sType": "html" } ], "bPaginate": false })); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/reserveratios.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/reserveratios.tt index 521a8d8..7672c26 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/reserveratios.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/reserveratios.tt @@ -3,9 +3,7 @@ [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'calendar.inc' %] - -[% INCLUDE 'datatables-strings.inc' %] - +[% INCLUDE 'datatables.inc' %] -[% INCLUDE 'datatables-strings.inc' %] - + +[% INCLUDE 'datatables.inc' %] -[% INCLUDE 'datatables-strings.inc' %] - + +[% INCLUDE 'datatables.inc' %] -[% INCLUDE 'datatables-strings.inc' %] - + +[% INCLUDE 'datatables.inc' %] -[% END %] \ No newline at end of file +[% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt index 4c1c552..00693fe 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-advsearch.tt @@ -114,8 +114,6 @@ [% IF ( expanded_options ) %] [% IF ( numbersphr) %] - [% ELSE %] - [% END %] -- 1.7.10.4 From dpavlin at rot13.org Wed Mar 12 18:34:16 2014 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Wed, 12 Mar 2014 18:34:16 +0100 Subject: [Koha-patches] [PATCH] Bug 7844 - plack intranet tooling for developers Message-ID: <1394645656-13936-1-git-send-email-dpavlin@rot13.org> koha.psgi example and plackup.sh script to run any Koha site intranet or opac interface under plack with optional multi-process Starman server plackup.sh site-name [intranet] site-name is used to find config /etc/koha/sites/site-name/koha-conf.xml All configuration is specified in koha.psgi, which you are welcomed to edit and tune according to your development needs (enable memcache, enable/disable debugging modules for plack and so on). For deployment of opac or intranet you would probably want to take a look in plackup.sh and enable starman as web server (which is pre-forking server written in perl) and put some web server in front of it to serve static web files (e.g. ngnix, apache) When you are happy with it, rename koha.psgi and plackup.sh it to site name and save it for safe-keeping. This commit message is included in patch as README.plack because it includes useful information for people using plack for first time. Test scenario: 1. install plack and dependencies, as documented at http://wiki.koha-community.org/wiki/Plack 2. start ./plackup.sh sitename i[ntranet] 3. open intranet page http://localhost:5001/ and verify that it redirects to http://localhost:5001/cgi-bin/koha/mainpage.pl 4. start ./plackup.sh sitename 5. open OPAC http://localhost:5000/ and verify that it redirects to http://localhost:5000/cgi-bin/koha/opac-main.pl 6. next step is to take a look into koha.psgi and enable additional debug modules, save file and reload page (plackup will reload code automatically) --- misc/plack/README.plack | 43 +++++++++++++++++++++++ misc/plack/koha.psgi | 86 +++++++++++++++++++++++++++++++++++++++++++++++ misc/plack/plackup.sh | 54 +++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 0 deletions(-) create mode 100644 misc/plack/README.plack create mode 100644 misc/plack/koha.psgi create mode 100755 misc/plack/plackup.sh diff --git a/misc/plack/README.plack b/misc/plack/README.plack new file mode 100644 index 0000000..6296d08 --- /dev/null +++ b/misc/plack/README.plack @@ -0,0 +1,43 @@ +Bug 7844 - plack intranet tooling for developers + +koha.psgi example and plackup.sh script to run any Koha site +intranet or opac interface under plack with optional multi-process +Starman server + + plackup.sh site-name [intranet] + +site-name is used to find config /etc/koha/sites/site-name/koha-conf.xml + +All configuration is specified in koha.psgi, which you are welcomed to edit +and tune according to your development needs (enable memcache, enable/disable +debugging modules for plack and so on). + +For deployment of opac or intranet you would probably want to take a look +in plackup.sh and enable starman as web server (which is pre-forking server +written in perl) and put some web server in front of it to serve static web +files (e.g. ngnix, apache) + +When you are happy with it, rename koha.psgi and plackup.sh it to site name +and save it for safe-keeping. + +This commit message is included in patch as README.plack because it includes +useful information for people using plack for first time. + +Test scenario: +1. install plack and dependencies, as documented at + http://wiki.koha-community.org/wiki/Plack + +2. start ./plackup.sh sitename i[ntranet] + +3. open intranet page http://localhost:5001/ and verify that it redirects + to http://localhost:5001/cgi-bin/koha/mainpage.pl + +4. start ./plackup.sh sitename + +5. open OPAC http://localhost:5000/ and verify that it redirects to + http://localhost:5000/cgi-bin/koha/opac-main.pl + +6. next step is to take a look into koha.psgi and enable additional + debug modules, save file and reload page (plackup will reload + code automatically) + diff --git a/misc/plack/koha.psgi b/misc/plack/koha.psgi new file mode 100644 index 0000000..7acb567 --- /dev/null +++ b/misc/plack/koha.psgi @@ -0,0 +1,86 @@ +#!/usr/bin/perl +use Plack::Builder; +use Plack::App::CGIBin; +use lib qw( ./lib ); +use Plack::Middleware::Debug; +use Plack::App::Directory; + +BEGIN { + +# override configuration from startup script below: +# (requires --reload option) + +$ENV{PLACK_DEBUG} = 1; # toggle debugging + +# memcache change requires restart +$ENV{MEMCACHED_SERVERS} = "localhost:11211"; +#$ENV{MEMCACHED_DEBUG} = 0; + +$ENV{PROFILE_PER_PAGE} = 1; # reset persistant and profile counters after each page, like CGI +#$ENV{INTRANET} = 1; # usually passed from script + +#$ENV{DBI_AUTOPROXY}='dbi:Gofer:transport=null;cache=DBI::Util::CacheMemory' + +} # BEGIN + +use C4::Context; +use C4::Languages; +use C4::Members; +use C4::Dates; +use C4::Boolean; +use C4::Letters; +use C4::Koha; +use C4::XSLT; +use C4::Branch; +use C4::Category; +=for preload +use C4::Tags; # FIXME +=cut + +use Devel::Size 0.77; # 0.71 doesn't work for Koha +my $watch_capture_regex = '(C4|Koha)'; + +sub watch_for_size { + my @watch = + map { s/^.*$watch_capture_regex/$1/; s/\//::/g; s/\.pm$//; $_ } # fix paths + grep { /$watch_capture_regex/ } + keys %INC + ; + warn "# watch_for_size ",join(' ', at watch); + return @watch; +}; + +my $CGI_ROOT = $ENV{INTRANET} ? $ENV{INTRANETDIR} : $ENV{OPACDIR}; +warn "# using Koha ", $ENV{INTRANET} ? 'intranet' : 'OPAC', " CGI from $CGI_ROOT\n"; +my $app=Plack::App::CGIBin->new(root => $CGI_ROOT); +my $home = sub { + return [ 302, [ Location => '/cgi-bin/koha/' . ( $ENV{INTRANET} ? 'mainpage.pl' : 'opac-main.pl' ) ] ]; +}; + +builder { + + # please don't use plugins which are under enable_if $ENV{PLACK_DEBUG} in production! + # they are known to leek memory + enable_if { $ENV{PLACK_DEBUG} } 'Debug', panels => [ + qw(Environment Response Timer Memory), + # optional plugins (uncomment to enable) are sorted according to performance implact +# [ 'Devel::Size', for => \&watch_for_size ], # https://github.com/dpavlin/p5-plack-devel-debug-devel-size +# [ 'DBIProfile', profile => 2 ], +# [ 'DBITrace', level => 1 ], # a LOT of fine-graded SQL trace +# [ 'Profiler::NYTProf', exclude => [qw(.*\.css .*\.png .*\.ico .*\.js .*\.gif)] ], + ]; + + # don't enable this plugin in production, since stack traces reveal too much information + # about system to potential attackers! + enable_if { $ENV{PLACK_DEBUG} } 'StackTrace'; + + # this enables plackup or starman to serve static files and provide working plack + # setup without need for front-end web server to serve static files + enable_if { $ENV{INTRANETDIR} } "Plack::Middleware::Static", + path => qr{^/(intranet|opac)-tmpl/}, + root => "$ENV{INTRANETDIR}/koha-tmpl/"; + + mount "/cgi-bin/koha" => $app; + mount "/" => $home; + +}; diff --git a/misc/plack/plackup.sh b/misc/plack/plackup.sh new file mode 100755 index 0000000..2c7f599 --- /dev/null +++ b/misc/plack/plackup.sh @@ -0,0 +1,54 @@ +#!/bin/sh -e + +# This is plack startup script for Koha + +# ./plackup.sh [site] [intranet] + +site=$1 +test ! -z "$site" && shift || ( echo "usage: $0 [site] [i[tranet]]" ; exit 1 ) + +# extract useful paths from koha-conf.xml +export KOHA_CONF=/etc/koha/sites/$site/koha-conf.xml +export LOGDIR="$( sudo -u $site-koha xmlstarlet sel -t -v 'yazgfs/config/logdir' $KOHA_CONF )" +export INTRANETDIR="$( sudo -u $site-koha xmlstarlet sel -t -v 'yazgfs/config/intranetdir' $KOHA_CONF )" +export OPACDIR="$( sudo -u $site-koha xmlstarlet sel -t -v 'yazgfs/config/opacdir' $KOHA_CONF | sed 's,/cgi-bin/opac,,' )" + +dir=`dirname $0` + +# enable memcache - it's safe even on installation which don't have it +# since Koha has check on C4::Context +#export MEMCACHED_SERVERS=localhost:11211 +# pass site name as namespace to perl code +export MEMCACHED_NAMESPACE=$site +#export MEMCACHED_DEBUG=1 + +if [ ! -e "$INTRANETDIR/C4" ] ; then + echo "intranetdir in $KOHA_CONF doesn't point to Koha git checkout" + exit 1 +fi + +if [ -z "$1" ] ; then # type anything after site name for intranet! + INTRANET=0 + PORT=5000 +else + INTRANET=1 + PORT=5001 + shift # pass rest of arguments to plackup +fi +export INTRANET # pass to plack + +# uncomment to enable logging +#opt="$opt --access-log $LOGDIR/opac-access.log --error-log $LOGDIR/opac-error.log" + +# --max-requests 50 decreased from 1000 to keep memory usage sane +# --workers 4 number of cores on machine +#test "$INTRANET" != 1 && \ # don't use Starman for intranet +opt="$opt --server Starman -M FindBin --max-requests 50 --workers 4" + +# -E deployment turn off access log on STDOUT +opt="$opt -E deployment" + +# comment out reload in production! +opt="$opt --reload -R $INTRANETDIR/C4 -R $INTRANETDIR/Koha" + +sudo -E -u $site-koha plackup --port $PORT -I $INTRANETDIR -I $INTRANETDIR/installer $opt $* $dir/koha.psgi -- 1.7.2.5 From dpavlin at rot13.org Thu Mar 13 11:19:08 2014 From: dpavlin at rot13.org (Dobrica Pavlinusic) Date: Thu, 13 Mar 2014 11:19:08 +0100 Subject: [Koha-patches] [PATCH] Bug 11703 - Convert checkouts table to ajax datatable Message-ID: <1394705948-12049-1-git-send-email-dpavlin@rot13.org> From: Kyle M Hall When a patron has many checked out items, circulation.pl can take a very long time to load ( on the order of minutes in some cases ). This is primarily due to the processing of the previous checkouts list. If we convert to this table to a datatable that fetches its data via ajax, we can make circulation.pl far more responsive. The same should be done with relative's checkouts as well. Test Plan: 1) Apply this patch 2) Observe that the checkouts and relatives' checkouts tables are now loaded asynchronously 3) Observe and verify the renew and return actions are now ajax based and function in a manner equivilent to how they used to. This bug had quite a few followups, so I squashed all of them into one change so that code is easier to follow. Original commit messages are below: Bug 11703 - Use the ajax datatables on patron details page Bug 11703 - Convert holds tables to ajax datatables Bug 11703 [QA Followup 1] - Center bProcessing message over table Bug 11703 [QA Followup 2] - Remove icons from checkout and clear buttons Bug 11703 [QA Followup 3] - Remove references to UseTablesortForCirc Bug 11703 [QA Followup 4] - Add back in Today's checkouts/Previous checkouts rows Bug 11703 [QA Followup 5] Bug 11703 [QA Followup 6] - Move strings to an include file for translation purposes Bug 11703 [QA Followup 7] - Fix issues spotted by koha-qa.pl Bug 11703 [QA Followup 8] - Speed up api/checkouts.pl as much as possible Bug 11703 [QA Followup 9] - Move scripts from api directory to svc directory Bug 11703 [QA Followup 10] - Fix errors caused by rebase Bug 11703 [QA Followup 11] - Prevent multiple fetchs from ajax source Bug 11703 [QA Followup 12] - Fix problem detected by koha-qa.pl Bug 11703 [QA Followup 13] - Removed uneccessary data from renewal box during renewal Bug 11703 [QA Followup 14] - Fix table column span Signed-off-by: Dobrica Pavlinusic --- Koha/Schema/Result/Issue.pm | 32 +- Koha/Schema/Result/Reserve.pm | 24 +- circ/circulation.pl | 212 +------ installer/data/mysql/sysprefs.sql | 1 - .../plugins/jquery.dataTables.rowGrouping.js | 690 ++++++++++++++++++++ .../intranet-tmpl/prog/en/css/staff-global.css | 2 +- .../prog/en/includes/checkouts-table-footer.inc | 2 +- .../intranet-tmpl/prog/en/includes/strings.inc | 30 + koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js | 435 ++++++++++++ koha-tmpl/intranet-tmpl/prog/en/js/holds.js | 133 ++++ .../intranet-tmpl/prog/en/js/pages/circulation.js | 73 +-- .../en/modules/admin/preferences/circulation.pref | 6 - .../prog/en/modules/circ/circulation.tt | 554 ++++------------- .../prog/en/modules/members/moremember.tt | 400 ++++-------- members/moremember.pl | 203 +------ svc/checkin.pl | 75 +++ svc/checkouts.pl | 167 +++++ svc/holds.pl | 143 ++++ svc/renew.pl | 69 ++ 19 files changed, 2071 insertions(+), 1180 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc create mode 100644 koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js create mode 100644 koha-tmpl/intranet-tmpl/prog/en/js/holds.js create mode 100755 svc/checkin.pl create mode 100755 svc/checkouts.pl create mode 100755 svc/holds.pl create mode 100755 svc/renew.pl diff --git a/Koha/Schema/Result/Issue.pm b/Koha/Schema/Result/Issue.pm index 282c802..e1838b6 100644 --- a/Koha/Schema/Result/Issue.pm +++ b/Koha/Schema/Result/Issue.pm @@ -184,10 +184,34 @@ __PACKAGE__->belongs_to( # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZEh31EKBmURMKxDxI+H3EA __PACKAGE__->belongs_to( - "borrower", - "Koha::Schema::Result::Borrower", - { borrowernumber => "borrowernumber" }, - { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" }, + "borrower", + "Koha::Schema::Result::Borrower", + { borrowernumber => "borrowernumber" }, + { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" }, +); + +__PACKAGE__->belongs_to( + "item", + "Koha::Schema::Result::Item", + { itemnumber => "itemnumber" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "CASCADE", + on_update => "CASCADE", + }, +); + +__PACKAGE__->belongs_to( + "branch", + "Koha::Schema::Result::Branch", + { branchcode => "branchcode" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "CASCADE", + on_update => "CASCADE", + }, ); 1; diff --git a/Koha/Schema/Result/Reserve.pm b/Koha/Schema/Result/Reserve.pm index 527651d..184a854 100644 --- a/Koha/Schema/Result/Reserve.pm +++ b/Koha/Schema/Result/Reserve.pm @@ -288,6 +288,28 @@ __PACKAGE__->belongs_to( # Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ig/fobzvZf1OgAHZFtkyyQ +__PACKAGE__->belongs_to( + "item", + "Koha::Schema::Result::Item", + { itemnumber => "itemnumber" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "CASCADE", + on_update => "CASCADE", + }, +); + +__PACKAGE__->belongs_to( + "biblio", + "Koha::Schema::Result::Biblio", + { biblionumber => "biblionumber" }, + { + is_deferrable => 1, + join_type => "LEFT", + on_delete => "CASCADE", + on_update => "CASCADE", + }, +); -# You can replace this text with custom content, and it will be preserved on regeneration 1; diff --git a/circ/circulation.pl b/circ/circulation.pl index cdc40e3..ed3763d 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -42,6 +42,7 @@ use CGI::Session; use C4::Members::Attributes qw(GetBorrowerAttributes); use Koha::Borrower::Debarments qw(GetDebarments); use Koha::DateUtils; +use Koha::Database; use Date::Calc qw( Today @@ -96,14 +97,6 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user ( my $branches = GetBranches(); -my @failedrenews = $query->param('failedrenew'); # expected to be itemnumbers -our %renew_failed = (); -for (@failedrenews) { $renew_failed{$_} = 1; } - -my @failedreturns = $query->param('failedreturn'); -our %return_failed = (); -for (@failedreturns) { $return_failed{$_} = 1; } - my $findborrower = $query->param('findborrower') || q{}; $findborrower =~ s|,| |g; my $borrowernumber = $query->param('borrowernumber'); @@ -121,10 +114,6 @@ if (C4::Context->preference("DisplayClearScreenButton")) { $template->param(DisplayClearScreenButton => 1); } -if (C4::Context->preference("UseTablesortForCirc")) { - $template->param(UseTablesortForCirc => 1); -} - my $barcode = $query->param('barcode') || q{}; $barcode =~ s/^\s*|\s*$//g; # remove leading/trailing whitespace @@ -354,9 +343,8 @@ if ($barcode) { } } - # FIXME If the issue is confirmed, we launch another time GetMemberIssuesAndFines, now display the issue count after issue - my ( $od, $issue, $fines ) = GetMemberIssuesAndFines( $borrowernumber ); - $template->param( issuecount => $issue ); + my ( $od, $issue, $fines ) = GetMemberIssuesAndFines($borrowernumber); + $template->param( issuecount => $issue ); } # reload the borrower info for the sake of reseting the flags..... @@ -368,188 +356,13 @@ if ($borrowernumber) { # BUILD HTML # show all reserves of this borrower, and the position of the reservation .... if ($borrowernumber) { + $template->param( + holds_count => Koha::Database->new()->schema()->resultset('Reserve') + ->count( { borrowernumber => $borrowernumber } ) ); - # new op dev - # now we show the status of the borrower's reservations - my @borrowerreserv = GetReservesFromBorrowernumber($borrowernumber ); - my @reservloop; - my @WaitingReserveLoop; - - foreach my $num_res (@borrowerreserv) { - my %getreserv; - my %getWaitingReserveInfo; - my $getiteminfo = GetBiblioFromItemNumber( $num_res->{'itemnumber'} ); - my $itemtypeinfo = getitemtypeinfo( (C4::Context->preference('item-level_itypes')) ? $getiteminfo->{'itype'} : $getiteminfo->{'itemtype'} ); - my ( $transfertwhen, $transfertfrom, $transfertto ) = - GetTransfers( $num_res->{'itemnumber'} ); - - $getreserv{waiting} = 0; - $getreserv{transfered} = 0; - $getreserv{nottransfered} = 0; - - $getreserv{reservedate} = format_date( $num_res->{'reservedate'} ); - $getreserv{reserve_id} = $num_res->{'reserve_id'}; - $getreserv{title} = $getiteminfo->{'title'}; - $getreserv{subtitle} = GetRecordValue('subtitle', GetMarcBiblio($getiteminfo->{biblionumber}), GetFrameworkCode($getiteminfo->{biblionumber})); - $getreserv{itemtype} = $itemtypeinfo->{'description'}; - $getreserv{author} = $getiteminfo->{'author'}; - $getreserv{barcodereserv} = $getiteminfo->{'barcode'}; - $getreserv{itemcallnumber} = $getiteminfo->{'itemcallnumber'}; - $getreserv{biblionumber} = $getiteminfo->{'biblionumber'}; - $getreserv{waitingat} = GetBranchName( $num_res->{'branchcode'} ); - $getreserv{suspend} = $num_res->{'suspend'}; - $getreserv{suspend_until} = $num_res->{'suspend_until'}; - # check if we have a waiting status for reservations - if ( $num_res->{'found'} && $num_res->{'found'} eq 'W' ) { - $getreserv{color} = 'reserved'; - $getreserv{waiting} = 1; -# genarate information displaying only waiting reserves - $getWaitingReserveInfo{title} = $getiteminfo->{'title'}; - $getWaitingReserveInfo{biblionumber} = $getiteminfo->{'biblionumber'}; - $getWaitingReserveInfo{itemtype} = $itemtypeinfo->{'description'}; - $getWaitingReserveInfo{author} = $getiteminfo->{'author'}; - $getWaitingReserveInfo{itemcallnumber} = $getiteminfo->{'itemcallnumber'}; - $getWaitingReserveInfo{reservedate} = format_date( $num_res->{'reservedate'} ); - $getWaitingReserveInfo{waitingat} = GetBranchName( $num_res->{'branchcode'} ); - $getWaitingReserveInfo{waitinghere} = 1 if $num_res->{'branchcode'} eq $branch; - } - # check transfers with the itemnumber foud in th reservation loop - if ($transfertwhen) { - $getreserv{color} = 'transfered'; - $getreserv{transfered} = 1; - $getreserv{datesent} = format_date($transfertwhen); - $getreserv{frombranch} = GetBranchName($transfertfrom); - } elsif ($getiteminfo->{'holdingbranch'} ne $num_res->{'branchcode'}) { - $getreserv{nottransfered} = 1; - $getreserv{nottransferedby} = GetBranchName( $getiteminfo->{'holdingbranch'} ); - } - -# if we don't have a reserv on item, we put the biblio infos and the waiting position - if ( $getiteminfo->{'title'} eq '' ) { - my $getbibinfo = GetBiblioData( $num_res->{'biblionumber'} ); - - $getreserv{color} = 'inwait'; - $getreserv{title} = $getbibinfo->{'title'}; - $getreserv{subtitle} = GetRecordValue('subtitle', GetMarcBiblio($num_res->{biblionumber}), GetFrameworkCode($num_res->{biblionumber})); - $getreserv{nottransfered} = 0; - $getreserv{itemtype} = $itemtypeinfo->{'description'}; - $getreserv{author} = $getbibinfo->{'author'}; - $getreserv{biblionumber} = $num_res->{'biblionumber'}; - } - $getreserv{waitingposition} = $num_res->{'priority'}; - $getreserv{expirationdate} = $num_res->{'expirationdate'}; - push( @reservloop, \%getreserv ); - -# if we have a reserve waiting, initiate waitingreserveloop - if ($getreserv{waiting} == 1) { - push (@WaitingReserveLoop, \%getWaitingReserveInfo) - } - - } - - # return result to the template - $template->param( - countreserv => scalar @reservloop, - reservloop => \@reservloop , - WaitingReserveLoop => \@WaitingReserveLoop, - ); $template->param( adultborrower => 1 ) if ( $borrower->{'category_type'} eq 'A' ); } -# make the issued books table. -my $todaysissues = ''; -my $previssues = ''; -our @todaysissues = (); -our @previousissues = (); -our @relissues = (); -our @relprevissues = (); -my $displayrelissues; - -our $totalprice = 0; - -sub build_issue_data { - my $issueslist = shift; - my $relatives = shift; - - # split in 2 arrays for today & previous - foreach my $it ( @$issueslist ) { - my $itemtypeinfo = getitemtypeinfo( (C4::Context->preference('item-level_itypes')) ? $it->{'itype'} : $it->{'itemtype'} ); - - # set itemtype per item-level_itype syspref - FIXME this is an ugly hack - $it->{'itemtype'} = ( C4::Context->preference( 'item-level_itypes' ) ) ? $it->{'itype'} : $it->{'itemtype'}; - - ($it->{'charge'}, $it->{'itemtype_charge'}) = GetIssuingCharges( - $it->{'itemnumber'}, $it->{'borrowernumber'} - ); - $it->{'charge'} = sprintf("%.2f", $it->{'charge'}); - my ($can_renew, $can_renew_error) = CanBookBeRenewed( - $it->{'borrowernumber'},$it->{'itemnumber'} - ); - $it->{"renew_error_${can_renew_error}"} = 1 if defined $can_renew_error; - my $restype = C4::Reserves::GetReserveStatus( $it->{'itemnumber'} ); - $it->{'can_renew'} = $can_renew; - $it->{'can_confirm'} = !$can_renew && !$restype; - $it->{'renew_error'} = ( $restype eq "Waiting" or $restype eq "Reserved" ) ? 1 : 0; - $it->{'checkoutdate'} = C4::Dates->new($it->{'issuedate'},'iso')->output('syspref'); - $it->{'issuingbranchname'} = GetBranchName($it->{'branchcode'}); - - $totalprice += $it->{'replacementprice'} || 0; - $it->{'itemtype'} = $itemtypeinfo->{'description'}; - $it->{'itemtype_image'} = $itemtypeinfo->{'imageurl'}; - $it->{'dd_sort'} = $it->{'date_due'}; - $it->{'dd'} = output_pref($it->{'date_due'}); - $it->{'displaydate_sort'} = $it->{'issuedate'}; - $it->{'displaydate'} = output_pref($it->{'issuedate'}); - #$it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ; - $it->{'od'} = $it->{'overdue'}; - $it->{'subtitle'} = GetRecordValue('subtitle', GetMarcBiblio($it->{biblionumber}), GetFrameworkCode($it->{biblionumber})); - $it->{'renew_failed'} = $renew_failed{$it->{'itemnumber'}}; - $it->{'return_failed'} = $return_failed{$it->{'barcode'}}; - - if ( ( $it->{'issuedate'} && $it->{'issuedate'} gt $todaysdate ) - || ( $it->{'lastreneweddate'} && $it->{'lastreneweddate'} gt $todaysdate ) ) { - (!$relatives) ? push @todaysissues, $it : push @relissues, $it; - } else { - (!$relatives) ? push @previousissues, $it : push @relprevissues, $it; - } - ($it->{'renewcount'},$it->{'renewsallowed'},$it->{'renewsleft'}) = C4::Circulation::GetRenewCount($it->{'borrowernumber'},$it->{'itemnumber'}); #Add renewal count to item data display - } -} - -if ($borrower) { - - # Getting borrower relatives - my @relborrowernumbers = GetMemberRelatives($borrower->{'borrowernumber'}); - #push @borrowernumbers, $borrower->{'borrowernumber'}; - - # get each issue of the borrower & separate them in todayissues & previous issues - my $issueslist = GetPendingIssues($borrower->{'borrowernumber'}); - my $relissueslist = []; - if ( @relborrowernumbers ) { - $relissueslist = GetPendingIssues(@relborrowernumbers); - } - - build_issue_data($issueslist, 0); - build_issue_data($relissueslist, 1); - - $displayrelissues = scalar($relissueslist); - - if ( C4::Context->preference( "todaysIssuesDefaultSortOrder" ) eq 'asc' ) { - @todaysissues = sort { $a->{'timestamp'} cmp $b->{'timestamp'} } @todaysissues; - } - else { - @todaysissues = sort { $b->{'timestamp'} cmp $a->{'timestamp'} } @todaysissues; - } - - if ( C4::Context->preference( "previousIssuesDefaultSortOrder" ) eq 'asc' ){ - @previousissues = sort { $a->{'date_due'} cmp $b->{'date_due'} } @previousissues; - } - else { - @previousissues = sort { $b->{'date_due'} cmp $a->{'date_due'} } @previousissues; - } -} - - my @values; my %labels; my $CGIselectborrower; @@ -682,6 +495,11 @@ if (C4::Context->preference('ExtendedPatronAttributes')) { ); } +my @relatives = GetMemberRelatives( $borrower->{'borrowernumber'} ); +my $relatives_issues_count = + Koha::Database->new()->schema()->resultset('Issue') + ->count( { borrowernumber => \@relatives } ); + $template->param( lib_messages_loop => $lib_messages_loop, bor_messages_loop => $bor_messages_loop, @@ -719,13 +537,7 @@ $template->param( duedatespec => $duedatespec, message => $message, CGIselectborrower => $CGIselectborrower, - totalprice => sprintf('%.2f', $totalprice), totaldue => sprintf('%.2f', $total), - todayissues => \@todaysissues, - previssues => \@previousissues, - relissues => \@relissues, - relprevissues => \@relprevissues, - displayrelissues => $displayrelissues, inprocess => $inprocess, is_child => ($borrower->{'category_type'} eq 'C'), circview => 1, @@ -736,6 +548,8 @@ $template->param( SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'), AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'), RoutingSerials => C4::Context->preference('RoutingSerials'), + relatives_issues_count => $relatives_issues_count, + relatives_borrowernumbers => \@relatives, ); # save stickyduedate to session diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 661910b..e957dec 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -411,7 +411,6 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('UseICU','0','1','Tell Koha if ICU indexing is in use for Zebra or not.','YesNo'), ('UseKohaPlugins','0','','Enable or disable the ability to use Koha Plugins.','YesNo'), ('UseQueryParser','0',NULL,'If enabled, try to use QueryParser for queries.','YesNo'), -('UseTablesortForCirc','0','','If on, use the JQuery tablesort function on the list of current borrower checkouts on the circulation page. Note that the use of this function may slow down circ for patrons with may checkouts.','YesNo'), ('UseTransportCostMatrix','0','','Use Transport Cost Matrix when filling holds','YesNo'), ('viewISBD','1','','Allow display of ISBD view of bibiographic records','YesNo'), ('viewLabeledMARC','0','','Allow display of labeled MARC view of bibiographic records','YesNo'), diff --git a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js new file mode 100644 index 0000000..40ee66b --- /dev/null +++ b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js @@ -0,0 +1,690 @@ +/* +* File: jquery.dataTables.grouping.js +* Version: 1.2.9. +* Author: Jovan Popovic +* +* Copyright 2013 Jovan Popovic, all rights reserved. +* +* This source file is free software, under either the GPL v2 license or a +* BSD style license, as supplied with this software. +* +* This source file 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. +* Parameters: +* @iGroupingColumnIndex Integer Index of the column that will be used for grouping - default 0 +* @sGroupingColumnSortDirection Enumeration Sort direction of the group +* @iGroupingOrderByColumnIndex Integer Index of the column that will be used for ordering groups +* @sGroupingClass String Class that will be associated to the group row. Default - "group" +* @sGroupItemClass String Class that will be associated to the group row of group items. Default - "group-item" +* @bSetGroupingClassOnTR Boolean If set class will be set to the TR instead of the TD withing the grouping TR +* @bHideGroupingColumn Boolean Hide column used for grouping once results are grouped. Default - true +* @bHideGroupingOrderByColumn Boolean Hide column used for ordering groups once results are grouped. Default - true +* @sGroupBy Enumeration Type of grouping that should be applied. Values "name"(default), "letter", "year" +* @sGroupLabelPrefix String Prefix that will be added to each group cell +* @bExpandableGrouping Boolean Attach expand/collapse handlers to the grouping rows +* @bExpandSingleGroup Boolean Use accordon grouping +* @iExpandGroupOffset Integer Number of pixels to set scroll position above the currently selected group. If -1 scroll will be alligned to the table +* General settings +* @sDateFormat: "dd/MM/yyyy" String Date format used for grouping +* @sEmptyGroupLabel String Lable that will be placed as group if grouping cells are empty. Default "-" + +* Parameters used in the second level grouping +* @iGroupingColumnIndex2 Integer Index of the secondary column that will be used for grouping - default 0 +* @sGroupingColumnSortDirection2 Enumeration Sort direction of the secondary group +* @iGroupingOrderByColumnIndex2 Integer Index of the column that will be used for ordering secondary groups +* @sGroupingClass2 String Class that will be associated to the secondary group row. Default "subgroup" +* @sGroupItemClass2 String Class that will be associated to the secondary group row of group items. Default "subgroup-item" +* @bHideGroupingColumn2 Boolean Hide column used for secondary grouping once results are grouped. Default - true, +* @bHideGroupingOrderByColumn2 Boolean Hide column used for ordering secondary groups once results are grouped. Default - true, +* @sGroupBy2 Enumeration Type of grouping that should be applied to secondary column. Values "name"(default), "letter", "year", +* @sGroupLabelPrefix2 String Prefix that will be added to each secondary group cell +* @fnOnGrouped Function Function that is called when grouping is finished. Function has no parameters. +*/ +(function ($) { + + "use strict"; + + $.fn.rowGrouping = function (options) { + + function _fnOnGrouped() { + + } + + function _fnOnGroupCreated(oGroup, sGroup, iLevel) { + /// + ///Function called when a new grouping row is created(it should be overriden in properties) + /// + } + + function _fnOnGroupCompleted(oGroup, sGroup, iLevel) { + ///+ ///Function called when a new grouping row is created(it should be overriden in properties) + /// + } + + function _getMonthName(iMonth) { + var asMonths = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; + return asMonths[iMonth - 1]; + } + + var defaults = { + + iGroupingColumnIndex: 0, + sGroupingColumnSortDirection: "", + iGroupingOrderByColumnIndex: -1, + sGroupingClass: "group", + sGroupItemClass: "group-item", + bHideGroupingColumn: true, + bHideGroupingOrderByColumn: true, + sGroupBy: "name", + sGroupLabelPrefix: "", + fnGroupLabelFormat: function (label) { return label; }, + bExpandableGrouping: false, + bExpandSingleGroup: false, + iExpandGroupOffset: 100, + asExpandedGroups: null, + + sDateFormat: "dd/MM/yyyy", + sEmptyGroupLabel: "-", + bSetGroupingClassOnTR: false, + + iGroupingColumnIndex2: -1, + sGroupingColumnSortDirection2: "", + iGroupingOrderByColumnIndex2: -1, + sGroupingClass2: "subgroup", + sGroupItemClass2: "subgroup-item", + bHideGroupingColumn2: true, + bHideGroupingOrderByColumn2: true, + sGroupBy2: "name", + sGroupLabelPrefix2: "", + fnGroupLabelFormat2: function (label) { return label; }, + bExpandableGrouping2: false, + + fnOnGrouped: _fnOnGrouped, + + fnOnGroupCreated: _fnOnGroupCreated, + fnOnGroupCompleted: _fnOnGroupCompleted, + + oHideEffect: null, // { method: "hide", duration: "fast", easing: "linear" }, + oShowEffect: null,//{ method: "show", duration: "slow", easing: "linear" } + + bUseFilteringForGrouping: false // This is still work in progress option + }; + return this.each(function (index, elem) { + + var oTable = $(elem).dataTable(); + + var aoGroups = new Array(); + $(this).dataTableExt.aoGroups = aoGroups; + + function fnCreateGroupRow(sGroupCleaned, sGroup, iColspan) { + var nGroup = document.createElement('tr'); + var nCell = document.createElement('td'); + nGroup.id = "group-id-" + oTable.attr("id") + "_" + sGroupCleaned; + + var oGroup = { id: nGroup.id, key: sGroupCleaned, text: sGroup, level: 0, groupItemClass: ".group-item-" + sGroupCleaned, dataGroup: sGroupCleaned, aoSubgroups: new Array() }; + + + + if (properties.bSetGroupingClassOnTR) { + nGroup.className = properties.sGroupingClass + " " + sGroupCleaned; + } else { + nCell.className = properties.sGroupingClass + " " + sGroupCleaned; + } + + nCell.colSpan = iColspan; + nCell.innerHTML = properties.sGroupLabelPrefix + properties.fnGroupLabelFormat(sGroup == "" ? properties.sEmptyGroupLabel : sGroup, oGroup ); + if (properties.bExpandableGrouping) { + + if (!_fnIsGroupCollapsed(sGroupCleaned)) { + nCell.className += " expanded-group"; + oGroup.state = "expanded"; + } else { + nCell.className += " collapsed-group"; + oGroup.state = "collapsed"; + } + nCell.className += " group-item-expander"; + $(nCell).attr('data-group', oGroup.dataGroup); //Fix provided by mssskhalsa (Issue 5) + $(nCell).attr("data-group-level", oGroup.level); + $(nCell).click(_fnOnGroupClick); + } + nGroup.appendChild(nCell); + aoGroups[sGroupCleaned] = oGroup; + oGroup.nGroup = nGroup; + properties.fnOnGroupCreated(oGroup, sGroupCleaned, 1); + return oGroup; + } + + function _fnCreateGroup2Row(sGroup2, sGroupLabel, iColspan, oParentGroup) { + + var nGroup2 = document.createElement('tr'); + nGroup2.id = oParentGroup.id + "_" + sGroup2; + var nCell2 = document.createElement('td'); + var dataGroup = oParentGroup.dataGroup + '_' + sGroup2; + + var oGroup = { id: nGroup2.id, key: sGroup2, text: sGroupLabel, level: oParentGroup.level + 1, groupItemClass: ".group-item-" + dataGroup, + dataGroup: dataGroup, aoSubgroups: new Array() + }; + + if (properties.bSetGroupingClassOnTR) { + nGroup2.className = properties.sGroupingClass2 + " " + sGroup2; + } else { + nCell2.className = properties.sGroupingClass2 + " " + sGroup2; + } + + nCell2.colSpan = iColspan; + nCell2.innerHTML = properties.sGroupLabelPrefix2 + properties.fnGroupLabelFormat2(sGroupLabel == "" ? properties.sEmptyGroupLabel : sGroupLabel, oGroup); + + if (properties.bExpandableGrouping) { + + nGroup2.className += " group-item-" + oParentGroup.dataGroup; + } + + + if (properties.bExpandableGrouping && properties.bExpandableGrouping2) { + + if (!_fnIsGroupCollapsed(oGroup.dataGroup)) { + nCell2.className += " expanded-group"; + oGroup.state = "expanded"; + } else { + nCell2.className += " collapsed-group"; + oGroup.state = "collapsed"; + } + nCell2.className += " group-item-expander"; + $(nCell2).attr('data-group', oGroup.dataGroup); + $(nCell2).attr("data-group-level", oGroup.level); + $(nCell2).click(_fnOnGroupClick); + } + + nGroup2.appendChild(nCell2); + + oParentGroup.aoSubgroups[oGroup.dataGroup] = oGroup; + aoGroups[oGroup.dataGroup] = oGroup; + oGroup.nGroup = nGroup2; + properties.fnOnGroupCreated(oGroup, sGroup2, 2); + return oGroup; + } + + function _fnIsGroupCollapsed(sGroup) { + if (aoGroups[sGroup] != null) + return (aoGroups[sGroup].state == "collapsed"); + else + if (sGroup.indexOf("_") > -1) + true; + else + if(bInitialGrouping && (asExpandedGroups==null || asExpandedGroups.length == 0)) + return false;// initially if asExpandedGroups is empty - no one is collapsed + else + return ($.inArray(sGroup, asExpandedGroups) == -1); //the last chance check asExpandedGroups + } + + function _fnGetYear(x) { + if(x.length< (iYearIndex+iYearLength) ) + return x; + else + return x.substr(iYearIndex, iYearLength); + } + function _fnGetGroupByName(x) { + return x; + } + + function _fnGetGroupByLetter(x) { + return x.substr(0, 1); + } + + function _fnGetGroupByYear(x) { + return _fnGetYear(x); + //return Date.parseExact(x, properties.sDateFormat).getFullYear();//slooooow + } + + function _fnGetGroupByYearMonth(x) { + //var date = Date.parseExact(x, "dd/MM/yyyy"); + //return date.getFullYear() + " / " + date.getMonthName(); + //return x.substr(iYearIndex, iYearLength) + '/' + x.substr(iMonthIndex, iMonthLength); + return x.substr(iYearIndex, iYearLength) + ' ' + _getMonthName(x.substr(iMonthIndex, iMonthLength)); + } + + function _fnGetCleanedGroup(sGroup) { + + if (sGroup === "") return "-"; + return sGroup.toLowerCase().replace(/[^a-zA-Z0-9\u0080-\uFFFF]+/g, "-"); //fix for unicode characters (Issue 23) + //return sGroup.toLowerCase().replace(/\W+/g, "-"); //Fix provided by bmathews (Issue 7) + } + + function _rowGroupingRowFilter(oSettings, aData, iDataIndex) { + ///Used to expand/collapse groups with DataTables filtering + if (oSettings.nTable.id !== oTable[0].id) return true; + var sColData = aData[properties.iGroupingColumnIndex]; + if (typeof sColData === "undefined") + sColData = aData[oSettings.aoColumns[properties.iGroupingColumnIndex].mDataProp]; + if (_fnIsGroupCollapsed(_fnGetCleanedGroup(sColData))) { + if (oTable.fnIsOpen(oTable.fnGetNodes(iDataIndex))) + { + if (properties.fnOnRowClosed != null) { + properties.fnOnRowClosed(this); // $(this.cells[0].children[0]).attr('src', '../../Images/details.png'); + } + oTable.fnClose(oTable.fnGetNodes(iDataIndex)); + } + return false; + }; + return true; + } //end of function _rowGroupingRowFilter + + + function fnExpandGroup(sGroup) { + ///Expand group if expanadable grouping is used + + aoGroups[sGroup].state = "expanded"; + + $("td[data-group^='" + sGroup + "']").removeClass("collapsed-group"); + $("td[data-group^='" + sGroup + "']").addClass("expanded-group"); + + + if(properties.bUseFilteringForGrouping) + { + oTable.fnDraw(); + return;//Because rows are expanded with _rowGroupingRowFilter function + } + + if (jQuery.inArray(sGroup, asExpandedGroups)==-1) + asExpandedGroups.push(sGroup); + + if (properties.oHideEffect != null) + $(".group-item-" + sGroup, oTable) + [properties.oShowEffect.method](properties.oShowEffect.duration, + properties.oShowEffect.easing, + function () { }); + else + $(".group-item-" + sGroup, oTable).show(); + + + } //end of function fnExpandGroup + + function fnCollapseGroup(sGroup) { + ///Collapse group if expanadable grouping is used + + aoGroups[sGroup].state = "collapsed"; + $("td[data-group^='" + sGroup + "']").removeClass("expanded-group"); + $("td[data-group^='" + sGroup + "']").addClass("collapsed-group"); + + if(properties.bUseFilteringForGrouping) + { + oTable.fnDraw(); + return;//Because rows are expanded with _rowGroupingRowFilter function + } + //var index = $.inArray(sGroup, asExpandedGroups); + //asExpandedGroups.splice(index, 1); + + $('.group-item-' + sGroup).each(function () { + //Issue 24 - Patch provided by Bob Graham + if (oTable.fnIsOpen(this)) { + if (properties.fnOnRowClosed != null) { + properties.fnOnRowClosed(this); // $(this.cells[0].children[0]).attr('src', '../../Images/details.png'); + } + oTable.fnClose(this); + } + }); + + if (properties.oHideEffect != null) + $(".group-item-" + sGroup, oTable) + [properties.oHideEffect.method](properties.oHideEffect.duration, + properties.oHideEffect.easing, + function () { }); + else + $(".group-item-" + sGroup, oTable).hide(); + + } //end of function fnCollapseGroup + + function _fnOnGroupClick(e) { + ///+ ///Function that is called when user click on the group cell in order to + ///expand of collapse group + /// + + //var sGroup = $(this).attr("rel"); + var sGroup = $(this).attr("data-group"); + var iGroupLevel = $(this).attr("data-group-level"); + + var bIsExpanded = !_fnIsGroupCollapsed(sGroup); + if (properties.bExpandSingleGroup) { + if (!bIsExpanded) { + var sCurrentGroup = $("td.expanded-group").attr("data-group"); + fnCollapseGroup(sCurrentGroup); + fnExpandGroup(sGroup); + + if (properties.iExpandGroupOffset != -1) { + var position = $("#group-id-" + oTable.attr("id") + "_" + sGroup).offset().top - properties.iExpandGroupOffset; + window.scroll(0, position); + } else { + var position = oTable.offset().top; + window.scroll(0, position); + } + } + } else { + if (bIsExpanded) { + fnCollapseGroup(sGroup); + } else { + fnExpandGroup(sGroup); + } + } + e.preventDefault(); + + }; //end function _fnOnGroupClick + + + function _fnDrawCallBackWithGrouping (oSettings) { + + if (oTable.fnSettings().oFeatures.bServerSide) + bInitialGrouping = true; + var bUseSecondaryGrouping = false; + + if (properties.iGroupingColumnIndex2 != -1) + bUseSecondaryGrouping = true; + + //-----Start grouping + + if (oSettings.aiDisplayMaster.length == 0) { //aiDisplay + return; + } + + var nTrs = $('tbody tr', oTable); + var iColspan = 0; //nTrs[0].getElementsByTagName('td').length; + for (var iColIndex = 0; iColIndex < oSettings.aoColumns.length; iColIndex++) { + if (oSettings.aoColumns[iColIndex].bVisible) + iColspan += 1; + } + var sLastGroup = null; + var sLastGroup2 = null; + if (oSettings.aiDisplay.length > 0) { + for (var i = 0; i < nTrs.length; i++) { + + + var iDisplayIndex = oSettings._iDisplayStart + i; + if (oTable.fnSettings().oFeatures.bServerSide) + iDisplayIndex = i; + var sGroupData = ""; + var sGroup = null; + var sGroupData2 = ""; + var sGroup2 = null; + + //Issue 31 - Start fix provided by Fabien Taysse +// sGroupData = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[properties.iGroupingColumnIndex]; +// if (sGroupData == undefined) +// sGroupData = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[oSettings.aoColumns[properties.iGroupingColumnIndex].mDataProp]; + sGroupData = this.fnGetData(nTrs[i], properties.iGroupingColumnIndex); + //Issue 31 - End fix provided by Fabien Taysse + + var sGroup = sGroupData; + if (properties.sGroupBy != "year") + sGroup = fnGetGroup(sGroupData); + + if (bUseSecondaryGrouping) { + sGroupData2 = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[properties.iGroupingColumnIndex2]; + if (sGroupData2 == undefined) + sGroupData2 = oSettings.aoData[oSettings.aiDisplay[iDisplayIndex]]._aData[oSettings.aoColumns[properties.iGroupingColumnIndex2].mDataProp]; + if (properties.sGroupBy2 != "year") + sGroup2 = fnGetGroup(sGroupData2); + } + + + if (sLastGroup == null || _fnGetCleanedGroup(sGroup) != _fnGetCleanedGroup(sLastGroup)) { // new group encountered (or first of group) + var sGroupCleaned = _fnGetCleanedGroup(sGroup); + + if(sLastGroup != null) + { + properties.fnOnGroupCompleted(aoGroups[_fnGetCleanedGroup(sLastGroup)]); + } + /* + if (properties.bExpandableGrouping && bInitialGrouping) { + if (properties.bExpandSingleGroup) { + if (asExpandedGroups.length == 0) + asExpandedGroups.push(sGroupCleaned); + } else { + asExpandedGroups.push(sGroupCleaned); + } + } + */ + if(properties.bAddAllGroupsAsExpanded && jQuery.inArray(sGroupCleaned,asExpandedGroups) == -1) + asExpandedGroups.push(sGroupCleaned); + + var oGroup = fnCreateGroupRow(sGroupCleaned, sGroup, iColspan); + var nGroup = oGroup.nGroup; + + if(nTrs[i].parentNode!=null) + nTrs[i].parentNode.insertBefore(nGroup, nTrs[i]); + else + $(nTrs[i]).before(nGroup); + + sLastGroup = sGroup; + sLastGroup2 = null; //to reset second level grouping + + + + + + } // end if (sLastGroup == null || sGroup != sLastGroup) + + $(nTrs[i]).attr("data-group", aoGroups[sGroupCleaned].dataGroup); + + $(nTrs[i]).addClass(properties.sGroupItemClass); + $(nTrs[i]).addClass("group-item-" + sGroupCleaned); + if (properties.bExpandableGrouping) { + if (_fnIsGroupCollapsed(sGroupCleaned) && !properties.bUseFilteringForGrouping) { + $(nTrs[i]).hide(); + } + } + + + if (bUseSecondaryGrouping) { + + if (sLastGroup2 == null || _fnGetCleanedGroup(sGroup2) != _fnGetCleanedGroup(sLastGroup2)) { + var sGroup2Id = _fnGetCleanedGroup(sGroup) + '-' + _fnGetCleanedGroup(sGroup2); + var oGroup2 = _fnCreateGroup2Row(sGroup2Id, sGroup2, iColspan, aoGroups[sGroupCleaned]) + var nGroup2 = oGroup2.nGroup; + nTrs[i].parentNode.insertBefore(nGroup2, nTrs[i]); + + sLastGroup2 = sGroup2; + } + + $(nTrs[i]).attr("data-group", oGroup2.dataGroup) + .addClass(properties.sGroupItemClass2) + .addClass("group-item-" + oGroup2.dataGroup); + } //end if (bUseSecondaryGrouping) + + + + } // end for (var i = 0; i < nTrs.length; i++) + }; // if (oSettings.aiDisplay.length > 0) + + if(sLastGroup != null) + { + properties.fnOnGroupCompleted(aoGroups[_fnGetCleanedGroup(sLastGroup)]); + } + + + //-----End grouping + properties.fnOnGrouped(aoGroups); + + bInitialGrouping = false; + + }; // end of _fnDrawCallBackWithGrouping = function (oSettings) + + + //var oTable = this; + var iYearIndex = 6; + var iYearLength = 4; + var asExpandedGroups = new Array(); + var bInitialGrouping = true; + + var properties = $.extend(defaults, options); + + if (properties.iGroupingOrderByColumnIndex == -1) { + properties.bCustomColumnOrdering = false; + properties.iGroupingOrderByColumnIndex = properties.iGroupingColumnIndex; + } else { + properties.bCustomColumnOrdering = true; + } + + if (properties.sGroupingColumnSortDirection == "") { + if (properties.sGroupBy == "year") + properties.sGroupingColumnSortDirection = "desc"; + else + properties.sGroupingColumnSortDirection = "asc"; + } + + + if (properties.iGroupingOrderByColumnIndex2 == -1) { + properties.bCustomColumnOrdering2 = false; + properties.iGroupingOrderByColumnIndex2 = properties.iGroupingColumnIndex2; + } else { + properties.bCustomColumnOrdering2 = true; + } + + if (properties.sGroupingColumnSortDirection2 == "") { + if (properties.sGroupBy2 == "year") + properties.sGroupingColumnSortDirection2 = "desc"; + else + properties.sGroupingColumnSortDirection2 = "asc"; + } + + + + iYearIndex = properties.sDateFormat.toLowerCase().indexOf('yy'); + iYearLength = properties.sDateFormat.toLowerCase().lastIndexOf('y') - properties.sDateFormat.toLowerCase().indexOf('y') + 1; + + var iMonthIndex = properties.sDateFormat.toLowerCase().indexOf('mm'); + var iMonthLength = properties.sDateFormat.toLowerCase().lastIndexOf('m') - properties.sDateFormat.toLowerCase().indexOf('m') + 1; + + var fnGetGroup = _fnGetGroupByName; + switch (properties.sGroupBy) { + case "letter": fnGetGroup = _fnGetGroupByLetter; + break; + case "year": fnGetGroup = _fnGetGroupByYear; + break; + case "month": fnGetGroup = _fnGetGroupByYearMonth; + break; + default: fnGetGroup = _fnGetGroupByName; + break; + } + + + if (properties.asExpandedGroups != null) { + if (properties.asExpandedGroups == "NONE") { + properties.asExpandedGroups = []; + asExpandedGroups = properties.asExpandedGroups; + bInitialGrouping = false; + } else if (properties.asExpandedGroups == "ALL") { + properties.bAddAllGroupsAsExpanded = true; + } else if (properties.asExpandedGroups.constructor == String) { + var currentGroup = properties.asExpandedGroups; + properties.asExpandedGroups = new Array(); + properties.asExpandedGroups.push(_fnGetCleanedGroup(currentGroup)); + asExpandedGroups = properties.asExpandedGroups; + bInitialGrouping = false; + } else if (properties.asExpandedGroups.constructor == Array) { + for (var i = 0; i < properties.asExpandedGroups.length; i++) { + asExpandedGroups.push(_fnGetCleanedGroup(properties.asExpandedGroups[i])); + if (properties.bExpandSingleGroup) + break; + } + bInitialGrouping = false; + } + }else{ + properties.asExpandedGroups = new Array(); + properties.bAddAllGroupsAsExpanded = true; + } + if(properties.bExpandSingleGroup){ + var nTrs = $('tbody tr', oTable); + var sGroupData = oTable.fnGetData(nTrs[0], properties.iGroupingColumnIndex); + + var sGroup = sGroupData; + if (properties.sGroupBy != "year") + sGroup = fnGetGroup(sGroupData); + + var sGroupCleaned = _fnGetCleanedGroup(sGroup); + properties.asExpandedGroups = new Array(); + properties.asExpandedGroups.push(sGroupCleaned); + + } + + oTable.fnSetColumnVis(properties.iGroupingColumnIndex, !properties.bHideGroupingColumn); + if (properties.bCustomColumnOrdering) { + oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex, !properties.bHideGroupingOrderByColumn); + } + if (properties.iGroupingColumnIndex2 != -1) { + oTable.fnSetColumnVis(properties.iGroupingColumnIndex2, !properties.bHideGroupingColumn2); + } + if (properties.bCustomColumnOrdering2) { + oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex2, !properties.bHideGroupingOrderByColumn2); + } + oTable.fnSettings().aoDrawCallback.push({ + "fn": _fnDrawCallBackWithGrouping, + "sName": "fnRowGrouping" + }); + + var aaSortingFixed = new Array(); + aaSortingFixed.push([properties.iGroupingOrderByColumnIndex, properties.sGroupingColumnSortDirection]); + if (properties.iGroupingColumnIndex2 != -1) { + aaSortingFixed.push([properties.iGroupingOrderByColumnIndex2, properties.sGroupingColumnSortDirection2]); + } // end of if (properties.iGroupingColumnIndex2 != -1) + + oTable.fnSettings().aaSortingFixed = aaSortingFixed; + //Old way + //oTable.fnSettings().aaSortingFixed = [[properties.iGroupingOrderByColumnIndex, properties.sGroupingColumnSortDirection]]; + + switch (properties.sGroupBy) { + case "name": + break; + + + case "letter": + + /* Create an array with the values of all the input boxes in a column */ + oTable.fnSettings().aoColumns[properties.iGroupingOrderByColumnIndex].sSortDataType = "rg-letter"; + $.fn.dataTableExt.afnSortData['rg-letter'] = function (oSettings, iColumn) { + var aData = []; + $('td:eq(' + iColumn + ')', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () { + aData.push(_fnGetGroupByLetter(this.innerHTML)); + }); + return aData; + } + + + break; + + + case "year": + /* Create an array with the values of all the input boxes in a column */ + oTable.fnSettings().aoColumns[properties.iGroupingOrderByColumnIndex].sSortDataType = "rg-date"; + $.fn.dataTableExt.afnSortData['rg-date'] = function (oSettings, iColumn) { + var aData = []; + var nTrs = oSettings.oApi._fnGetTrNodes(oSettings); + for(i = 0; i< nTrs.length; i++) + { + aData.push(_fnGetYear( oTable.fnGetData( nTrs[i], iColumn) )); + } + +/* + $('td:eq(' + iColumn + ')', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () { + aData.push(_fnGetYear(this.innerHTML)); + }); +*/ + return aData; + } + break; + default: + break; + + } // end of switch (properties.sGroupBy) + + if(properties.bUseFilteringForGrouping) + $.fn.dataTableExt.afnFiltering.push(_rowGroupingRowFilter); + + oTable.fnDraw(); + + + + }); + }; +})(jQuery); \ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css index 685ebef..1edc850 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css +++ b/koha-tmpl/intranet-tmpl/prog/en/css/staff-global.css @@ -270,7 +270,7 @@ tr.even td, tr.even.highlight td { border-right : 1px solid #BCBCBC; } -td.od { +.overdue td.od { color : #cc0000; font-weight : bold; } diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc index 90c4cb2..9934201 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc @@ -1,6 +1,6 @@- Totals: +Totals: [% totaldue %] [% totalprice %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc new file mode 100644 index 0000000..e22810a --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc @@ -0,0 +1,30 @@ + diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js b/koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js new file mode 100644 index 0000000..2b7b991 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js @@ -0,0 +1,435 @@ +$(document).ready(function() { + // Handle the select all/none links for checkouts table columns + $("#CheckAllRenewals").on("click",function(){ + $("#UncheckAllCheckins").click(); + $(".renew:visible").attr("checked", "checked" ); + return false; + }); + $("#UncheckAllRenewals").on("click",function(){ + $(".renew:visible").removeAttr("checked"); + return false; + }); + + $("#CheckAllCheckins").on("click",function(){ + $("#UncheckAllRenewals").click(); + $(".checkin:visible").attr("checked", "checked" ); + return false; + }); + $("#UncheckAllCheckins").on("click",function(){ + $(".checkin:visible").removeAttr("checked"); + return false; + }); + + // Don't allow both return and renew checkboxes to be checked + $(document).on("change", '.renew', function(){ + if ( $(this).is(":checked") ) { + $( "#checkin_" + $(this).val() ).removeAttr("checked"); + } + }); + $(document).on("change", '.checkin', function(){ + if ( $(this).is(":checked") ) { + $( "#renew_" + $(this).val() ).removeAttr("checked"); + } + }); + + // Clicking the table cell checks the checkbox inside it + $(document).on("click", 'td', function(e){ + if(e.target.tagName.toLowerCase() == 'td'){ + $(this).find("input:checkbox:visible").each( function() { + $(this).click(); + }); + } + }); + + // Handle renewals and returns + $("#RenewCheckinChecked").on("click",function(){ + $(".checkin:checked:visible").each(function() { + itemnumber = $(this).val(); + + $(this).replaceWith(""); + + params = { + itemnumber: itemnumber, + borrowernumber: borrowernumber, + branchcode: branchcode, + exempt_fine: $("#exemptfine").is(':checked') + }; + + $.post( "/cgi-bin/koha/svc/checkin.pl", params, function( data ) { + id = "#checkin_" + data.itemnumber; + + content = ""; + if ( data.returned ) { + content = CIRCULATION_RETURNED; + } else { + content = CIRCULATION_NOT_RETURNED; + } + + $(id).replaceWith( content ); + }, "json") + }); + + $(".renew:checked:visible").each(function() { + var override_limit = $("#override_limit").is(':checked') ? 1 : 0; + + var itemnumber = $(this).val(); + + $(this).parent().parent().replaceWith(""); + + var params = { + itemnumber: itemnumber, + borrowernumber: borrowernumber, + branchcode: branchcode, + override_limit: override_limit, + date_due: $("#newduedate").val() + }; + + $.post( "/cgi-bin/koha/svc/renew.pl", params, function( data ) { + var id = "#renew_" + data.itemnumber; + + var content = ""; + if ( data.renew_okay ) { + content = CIRCULATION_RENEWED_DUE + " " + data.date_due; + } else { + content = CIRCULATION_RENEW_FAILED + " "; + if ( data.error == "no_checkout" ) { + content += NOT_CHECKED_OUT; + } else if ( data.error == "too_many" ) { + content += TOO_MANY_RENEWALS; + } else if ( data.error == "on_reserve" ) { + content += ON_RESERVE; + } else if ( data.error ) { + content += data.error; + } else { + content += REASON_UNKNOWN; + } + } + + $(id).replaceWith( content ); + }, "json") + }); + + // Prevent form submit + return false; + }); + + $("#RenewAll").on("click",function(){ + $("#CheckAllRenewals").click(); + $("#UncheckAllCheckins").click(); + $("#RenewCheckinChecked").click(); + + // Prevent form submit + return false; + }); + + var ymd = $.datepicker.formatDate('yy-mm-dd', new Date()); + + var issuesTable; + var drawn = 0; + issuesTable = $("#issues-table").dataTable({ + "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t", + "aaSorting": [[ 0, "desc" ]], + "aoColumns": [ + { + "mDataProp": function( oObj ) { + if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { + return "" + TODAYS_CHECKOUTS + ""; + } else { + return "" + PREVIOUS_CHECKOUTS + ""; + } + } + }, + { + "mDataProp": "date_due", + "bVisible": false, + }, + { + "iDataSort": 1, // Sort on hidden unformatted date due column + "mDataProp": function( oObj ) { + var today = new Date(); + var due = new Date( oObj.date_due ); + if ( today > due ) { + return "" + oObj.date_due_formatted + ""; + } else { + return oObj.date_due_formatted; + } + } + }, + { + "mDataProp": function ( oObj ) { + title = "" + + oObj.title; + + $.each(oObj.subtitle, function( index, value ) { + title += " " + value.subfield; + }); + + title += ""; + + if ( oObj.author ) { + title += " " + BY + " " + oObj.author; + } + + if ( oObj.itemnotes ) { + var span_class = ""; + if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { + span_class = "circ-hlt"; + } + title += " - " + oObj.itemnotes + "" + } + + title += " " + + "" + + oObj.barcode + + ""; + + return title; + } + }, + { "mDataProp": "itemtype" }, + { "mDataProp": "issuedate" }, + { "mDataProp": "branchname" }, + { "mDataProp": "itemcallnumber" }, + { + "bSortable": false, + "mDataProp": function ( oObj ) { + return parseFloat(oObj.charge).toFixed(2); + } + }, + { + "bSortable": false, + "mDataProp": "price" }, + { + "bSortable": false, + "mDataProp": function ( oObj ) { + var content = ""; + var span_style = ""; + var span_class = ""; + + content += ""; + content += "" + oObj.renewals_count + ""; + + if ( oObj.can_renew ) { + // Do nothing + } else if ( oObj.can_renew_error == "on_reserve" ) { + content += "" + + "" + ON_HOLD + "" + + ""; + + span_style = "display: none"; + span_class = "renewals-allowed"; + } else if ( oObj.can_renew_error == "too_many" ) { + content += "" + + NOT_RENEWABLE + + ""; + + span_style = "display: none"; + span_class = "renewals-allowed"; + } else { + content += "" + + oObj.can_renew_error + + ""; + + span_style = "display: none"; + span_class = "renewals-allowed"; + } + + content += "" + + "" + + ""; + + if ( oObj.renewals_remaining ) { + content += "(" + + oObj.renewals_remaining + + " " + OF + " " + + oObj.renewals_allowed + " " + + RENEWALS_REMAINING + ")"; + } + + content += ""; + + + return content; + } + }, + { + "bSortable": false, + "mDataProp": function ( oObj ) { + if ( oObj.can_renew_error == "on_reserve" ) { + return "" + ON_HOLD + ""; + } else { + return ""; + } + } + }, + { + "bVisible": exports_enabled ? true : false, + "bSortable": false, + "mDataProp": function ( oObj ) { + return ""; + } + } + ], + "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) { + var total_charge = 0; + var total_price = 0; + for ( var i=0; i < aaData.length; i++ ) { + total_charge += aaData[i]['charge'] * 1; + total_price += aaData[i]['price'] * 1; + } + var nCells = nRow.getElementsByTagName('td'); + nCells[1].innerHTML = total_charge.toFixed(2); + nCells[2].innerHTML = total_price.toFixed(2); + }, + "bPaginate": false, + "bProcessing": true, + "bServerSide": false, + "sAjaxSource": '/cgi-bin/koha/svc/checkouts.pl', + "fnServerData": function ( sSource, aoData, fnCallback ) { + aoData.push( { "name": "borrowernumber", "value": borrowernumber } ); + + $.getJSON( sSource, aoData, function (json) { + fnCallback(json) + } ); + }, + "fnInitComplete": function(oSettings) { + // Disable rowGrouping plugin after first use + // so any sorting on the table doesn't use it + var oSettings = issuesTable.fnSettings(); + + for (f = 0; f < oSettings.aoDrawCallback.length; f++) { + if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') { + oSettings.aoDrawCallback.splice(f, 1); + break; + } + } + + oSettings.aaSortingFixed = null; + }, + }).rowGrouping( + { + iGroupingOrderByColumnIndex: 0, + sGroupingColumnSortDirection: "desc" + } + ); + + if ( $("#issues-table").length ) { + $("#issues-table_processing").position({ + of: $( "#issues-table" ), + collision: "none" + }); + } + + // Don't load relatives' issues table unless it is clicked on + var relativesIssuesTable; + $("#relatives-issues-tab").click( function() { + if ( ! relativesIssuesTable ) { + relativesIssuesTable = $("#relatives-issues-table").dataTable({ + "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t", + "aaSorting": [], + "aoColumns": [ + { + "mDataProp": function( oObj ) { + var today = new Date(); + var due = new Date( oObj.date_due ); + if ( today > due ) { + return "" + oObj.date_due_formatted + ""; + } else { + return oObj.date_due_formatted; + } + } + }, + { + "mDataProp": function ( oObj ) { + title = "" + + oObj.title; + + $.each(oObj.subtitle, function( index, value ) { + title += " " + value.subfield; + }); + + title += ""; + + if ( oObj.author ) { + title += " " + BY + " " + oObj.author; + } + + if ( oObj.itemnotes ) { + var span_class = ""; + if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { + span_class = "circ-hlt"; + } + title += " - " + oObj.itemnotes + "" + } + + title += " " + + "" + + oObj.barcode + + ""; + + return title; + } + }, + { "mDataProp": "itemtype" }, + { "mDataProp": "issuedate" }, + { "mDataProp": "branchname" }, + { "mDataProp": "itemcallnumber" }, + { "mDataProp": "charge" }, + { "mDataProp": "price" }, + { + "mDataProp": function( oObj ) { + return "" + + oObj.borrower.firstname + " " + oObj.borrower.surname + " (" + oObj.borrower.cardnumber + ")" + } + }, + ], + "bPaginate": false, + "bProcessing": true, + "bServerSide": true, + "sAjaxSource": '/cgi-bin/koha/svc/checkouts.pl', + "fnServerData": function ( sSource, aoData, fnCallback ) { + $.each(relatives_borrowernumbers, function( index, value ) { + aoData.push( { "name": "borrowernumber", "value": value } ); + }); + + $.getJSON( sSource, aoData, function (json) { + fnCallback(json) + } ); + }, + }); + } + }); + + if ( $("#relatives-issues-table").length ) { + $("#relatives-issues-table_processing").position({ + of: $( "#relatives-issues-table" ), + collision: "none" + }); + } + + if ( AllowRenewalLimitOverride ) { + $( '#override_limit' ).click( function () { + if ( this.checked ) { + $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide(); + } else { + $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show(); + } + } ).attr( 'checked', false ); + } + }); diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/holds.js b/koha-tmpl/intranet-tmpl/prog/en/js/holds.js new file mode 100644 index 0000000..76dfee5 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/js/holds.js @@ -0,0 +1,133 @@ +$(document).ready(function() { + // Don't load holds table unless it is clicked on + var holdsTable; + $("#holds-tab").click( function() { + if ( ! holdsTable ) { + holdsTable = $("#holds-table").dataTable({ + "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t", + "aoColumns": [ + { + "mDataProp": "reservedate_formatted" + }, + { + "mDataProp": function ( oObj ) { + title = "" + + oObj.title; + + $.each(oObj.subtitle, function( index, value ) { + title += " " + value.subfield; + }); + + title += ""; + + if ( oObj.author ) { + title += " " + BY + " " + oObj.author; + } + + if ( oObj.itemnotes ) { + var span_class = ""; + if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { + span_class = "circ-hlt"; + } + title += " - " + oObj.itemnotes + "" + } + + title += " " + + "" + + oObj.barcode + + ""; + + return title; + } + }, + { + "mDataProp": function( oObj ) { + return oObj.itemcallnumber || ""; + } + }, + { + "mDataProp": function( oObj ) { + var data = ""; + + if ( oObj.suspend == 1 ) { + data += "" + HOLD_IS + " " + SUSPENDED + " "; + if ( oObj.suspend_until ) { + data += " " + UNTIL + " " + oObj.suspend_until_formatted; + } + data += "
"; + } + + if ( oObj.barcode ) { + data += ""; + if ( oObj.found == "W" ) { + data += ITEM_IS + " " + WAITING + " "; + + if ( ! oObj.waiting_here ) { + data += " " + AT + " " + oObj.waiting_at; + } + } else if ( oObj.transferred ) { + data += ITEM_IS + " " + IN_TRANSIT + " " + FROM + oObj.from_branch; + } else if ( oObj.not_transferred ) { + data += NOT_TRANSFERRED_YET + " " + oObj.not_transferred_by; + } data += ""; + + data += " " + oObj.barcode + ""; + } + + return data; + } + }, + { "mDataProp": "expirationdate_formatted" }, + { + "mDataProp": function( oObj ) { + if ( oObj.priority && parseInt( oObj.priority ) && parseInt( oObj.priority ) > 0 ) { + return oObj.priority; + } else { + return ""; + } + } + }, + { + "mDataProp": function( oObj ) { + return "" + + "" + + "" + + ""; + } + } + ], + "bPaginate": false, + "bProcessing": true, + "bServerSide": true, + "sAjaxSource": '/cgi-bin/koha/svc/holds.pl', + "fnServerData": function ( sSource, aoData, fnCallback ) { + aoData.push( { "name": "borrowernumber", "value": borrowernumber } ); + + $.getJSON( sSource, aoData, function (json) { + fnCallback(json) + } ); + }, + }); + + if ( $("#holds-table").length ) { + $("#holds-table_processing").position({ + of: $( "#holds-table" ), + collision: "none" + }); + } + } + }); + +}); diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/pages/circulation.js b/koha-tmpl/intranet-tmpl/prog/en/js/pages/circulation.js index fe307bf..489403f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/js/pages/circulation.js +++ b/koha-tmpl/intranet-tmpl/prog/en/js/pages/circulation.js @@ -1,57 +1,22 @@ $(document).ready(function() { - $('#patronlists').tabs(); - var allcheckboxes = $(".checkboxed"); - $("#renew_all").on("click",function(){ - allcheckboxes.checkCheckboxes(":input[name*=items]"); - allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); - }); - $("#CheckAllitems").on("click",function(){ - allcheckboxes.checkCheckboxes(":input[name*=items]"); - allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); return false; - }); - $("#CheckNoitems").on("click",function(){ - allcheckboxes.unCheckCheckboxes(":input[name*=items]"); return false; - }); - $("#CheckAllreturns").on("click",function(){ - allcheckboxes.checkCheckboxes(":input[name*=barcodes]"); - allcheckboxes.unCheckCheckboxes(":input[name*=items]"); return false; - }); - $("#CheckNoreturns" ).on("click",function(){ - allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); return false; - }); - - $("#CheckAllexports").on("click",function(){ - allcheckboxes.checkCheckboxes(":input[name*=biblionumbers]"); + $("#CheckAllExports").on("click",function(){ + $(".export:visible").attr("checked", "checked" ); return false; }); - $("#CheckNoexports").on("click",function(){ - allcheckboxes.unCheckCheckboxes(":input[name*=biblionumbers]"); + $("#UncheckAllExports").on("click",function(){ + $(".export:visible").removeAttr("checked"); return false; }); - $("#relrenew_all").on("click",function(){ - allcheckboxes.checkCheckboxes(":input[name*=items]"); - allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); - }); - $("#relCheckAllitems").on("click",function(){ - allcheckboxes.checkCheckboxes(":input[name*=items]"); - allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); return false; - }); - $("#relCheckNoitems").on("click",function(){ - allcheckboxes.unCheckCheckboxes(":input[name*=items]"); return false; - }); - $("#relCheckAllreturns").on("click",function(){ - allcheckboxes.checkCheckboxes(":input[name*=barcodes]"); - allcheckboxes.unCheckCheckboxes(":input[name*=items]"); return false; - }); - $("#relCheckNoreturns").on("click",function(){ - allcheckboxes.unCheckCheckboxes(":input[name*=barcodes]"); return false; - }); + $('#patronlists').tabs(); + $("#messages ul").after(""+MSG_ADD_MESSAGE+""); + $("#borrower_messages .cancel").on("click",function(){ $("#add_message_form").hide(); $("#addmessage").show(); }); + $("#addmessage").on("click",function(){ $(this).hide(); $("#add_message_form").show(); @@ -76,14 +41,7 @@ $(document).ready(function() { export_checkouts(export_format); return false; }); - // Clicking the table cell checks the checkbox inside it - $("td").on("click",function(e){ - if(e.target.tagName.toLowerCase() == 'td'){ - $(this).find("input:checkbox:visible").each( function() { - $(this).click(); - }); - } - }); + }); function export_checkouts(format) { @@ -107,13 +65,9 @@ function export_checkouts(format) { } else if (format == 'iso2709') { $("#dont_export_item").val(1); } - document.issues.action="/cgi-bin/koha/tools/export.pl"; + document.getElementById("export_format").value = format; document.issues.submit(); - - /* Reset form action to its initial value */ - document.issues.action="/cgi-bin/koha/reserve/renewscript.pl"; - } function validate1(date) { @@ -124,10 +78,3 @@ function validate1(date) { return false; } } - -// prevent adjacent checkboxes from being checked simultaneously -function radioCheckBox(box){ - box.parents("td").siblings().find("input:checkbox.radio").each(function(){ - $(this).removeAttr("checked"); - }); - } diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 70ac352..6e83eea 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -40,12 +40,6 @@ Circulation: desc: latest to earliest - due date. - - - pref: UseTablesortForCirc - choices: - yes: "Enable" - no: "Don't enable" - - "the sorting of current patron checkouts on the circulation screen.
NOTE: Enabling this function may slow down circulation time for patrons with many checkouts." - - - pref: soundon choices: yes: "Enable" diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index e667bc3..dc0d6ea 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -13,88 +13,46 @@ [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'calendar.inc' %] -[% IF ( UseTablesortForCirc ) %] + -[% INCLUDE 'datatables-strings.inc' %] -[% END %] +[% INCLUDE 'strings.inc' %] + [% INCLUDE 'timepicker.inc' %] + + + @@ -516,7 +474,7 @@ No patron matched [% message %] [% ELSE %] [% END %] - + [% IF ( SpecifyDueDate ) %][% END %] @@ -687,395 +645,111 @@ No patron matched [% message %]Specify due date [% INCLUDE 'date-format.inc' %]:@@ -528,7 +486,7 @@ No patron matched [% message %] [% ELSE %] [% END %] - +-
- - -- [% IF ( issuecount ) %] +
- + [% IF ( issuecount ) %] [% issuecount %] Checkout(s) - [% ELSE %] + [% ELSE %] 0 Checkouts - [% END %]
-[% IF ( displayrelissues ) %] -- Relatives' checkouts
-[% END %] -- [% IF ( countreserv ) %] - [% countreserv %] Hold(s) - [% ELSE %] - 0 Holds - [% END %]
-- [% debarments.size %] Restrictions
- --[% IF ( issuecount ) %] - -[% ELSE %] -- + -[% IF ( displayrelissues ) %] -Patron has nothing checked out.
-[% END %] - ---[% END %] + +[% IF ( relatives_issues_count ) %] +- -
-- - -[% IF ( relissues ) %] - - [% FOREACH relissue IN relissues %] - [% IF ( loop.odd ) %] -Due date -Title -Item type -Checked out on -Checked out from -Call no -Charge -Price -Patron -- [% ELSE %] - - [% END %] - [% IF ( relissue.overdue ) %] - [% END %] - [% END %] -[% IF ( relprevissues ) %] - [% IF ( UseTablesortForCirc ) %][% ELSE %] [% END %] - [% relissue.dd %] +- [% debarments.size %] Restrictions
+ - [% IF ( relissue.itemlost ) %] - [% AuthorisedValues.GetByCode( 'LOST', relissue.itemlost ) %] - [% END %] - [% IF ( relissue.damaged ) %] - [% AuthorisedValues.GetByCode( 'DAMAGED', relissue.damaged ) %] + ++ [% IF ( issuecount ) %] ++ +
+ ++ + + [% INCLUDE 'checkouts-table-footer.inc' %] ++ Due date +Due date +Title +Item type +Checked out on +Checked out from +Call no +Charge +Price +Renew +Check in +Export +[% ELSE %] Previous checkouts [% END %] - [% FOREACH relprevissue IN relprevissues %] - [% IF ( loop.odd ) %] - Previous checkouts + + + [% ELSE %] - + - [% END %] -[% END %] - -Patron has nothing checked out.
[% END %] - [% IF ( relprevissue.overdue ) %][% ELSE %] [% END %] - [% relprevissue.dd %] - -[% relprevissue.title |html %][% FOREACH subtitl IN relprevissue.subtitle %] [% subtitl.subfield %][% END %][% IF ( relprevissue.author ) %], by [% relprevissue.author %][% END %] [% IF ( relprevissue.itemnotes ) %]- [% relprevissue.itemnotes %][% END %] [% relprevissue.barcode %] -[% UNLESS noItemTypeImages %][% IF relprevissue.itemtype_image %][% END %][% END %][% relprevissue.itemtype %] -[% relprevissue.displaydate %] -[% relprevissue.issuingbranchname %] -[% relprevissue.itemcallnumber %] - [% IF ( relprevissue.multiple_borrowers ) %][% relprevissue.firstname %] [% relprevissue.surname %] [% END %] -[% relprevissue.charge %] -[% relprevissue.replacementprice %] -[% relprevissue.firstname %] [% relprevissue.surname %] ([% relprevissue.cardnumber %]) - -++[% END %] [% INCLUDE borrower_debarments.inc %]+ +
++ + +Due date +Title +Item type +Checked out on +Checked out from +Call no +Charge +Price +Patron +-[% IF ( reservloop ) %] +[% IF ( holds_count ) %] [% IF SuspendHoldsIntranet %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt index c4705d1..3c9b678 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt @@ -9,13 +9,29 @@ [% INCLUDE 'doc-head-close.inc' %] [% INCLUDE 'calendar.inc' %] - + [% INCLUDE 'datatables.inc' %] +[% INCLUDE 'strings.inc' %] [% INCLUDE 'timepicker.inc' %] + + +