From 708241c4c6011a30046be68cc131fd8d04b6b23d Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Sun, 8 Mar 2009 23:19:38 +0000 Subject: [PATCH 0001/1043] Initial checkin. --- .project | 11 + example1-simple.html | 84 + example2-formatters.html | 93 + example3-editing.html | 102 + examples.css | 33 + grid.html | 360 + images/ListView.gif | Bin 0 -> 2380 bytes images/Pencil.gif | Bin 0 -> 914 bytes images/ajax-loader-small.gif | Bin 0 -> 1849 bytes images/arrow_right_peppermint.png | Bin 0 -> 240 bytes images/arrow_right_spearmint.png | Bin 0 -> 240 bytes images/bullet_blue.png | Bin 0 -> 289 bytes images/bullet_star.png | Bin 0 -> 347 bytes images/bullet_toggle_minus.png | Bin 0 -> 207 bytes images/bullet_toggle_plus.png | Bin 0 -> 209 bytes images/calendar.gif | Bin 0 -> 1035 bytes images/collapse.gif | Bin 0 -> 846 bytes images/comment_yellow.gif | Bin 0 -> 257 bytes images/down.gif | Bin 0 -> 59 bytes images/editor-helper-bg.gif | Bin 0 -> 1164 bytes images/expand.gif | Bin 0 -> 851 bytes images/help.png | Bin 0 -> 510 bytes images/info.gif | Bin 0 -> 80 bytes images/stripes.png | Bin 0 -> 1238 bytes images/tag_red.png | Bin 0 -> 592 bytes images/tick.png | Bin 0 -> 537 bytes images/user_identity.gif | Bin 0 -> 905 bytes images/user_identity_plus.gif | Bin 0 -> 546 bytes lib/firebug-lite.js | 2068 ++++ lib/firebugx.js | 10 + lib/jquery-1.3.2.js | 4376 ++++++++ lib/jquery-ui-1.7.custom.js | 9049 +++++++++++++++++ lib/jquery-ui-1.7.custom.min.js | 273 + lib/jquery.getScrollbarWidth.js | 31 + lib/jquery.rule-1.0.1-min.js | 9 + lib/jquery.rule-1.0.1.js | 263 + simpledropdown.css | 83 + slick.editors.js | 567 ++ slick.globaleditorstate.js | 58 + slick.grid.css | 251 + slick.grid.js | 1038 ++ .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_75_ffffff_1x400.png | Bin 0 -> 107 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../ui-bg_inset-soft_95_fef1ec_1x100.png | Bin 0 -> 123 bytes .../base/images/ui-icons_222222_256x240.png | Bin 0 -> 4379 bytes .../base/images/ui-icons_2e83ff_256x240.png | Bin 0 -> 5399 bytes .../base/images/ui-icons_454545_256x240.png | Bin 0 -> 4379 bytes .../base/images/ui-icons_888888_256x240.png | Bin 0 -> 4379 bytes .../base/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4379 bytes themes/base/ui.accordion.css | 9 + themes/base/ui.all.css | 2 + themes/base/ui.base.css | 8 + themes/base/ui.core.css | 37 + themes/base/ui.datepicker.css | 62 + themes/base/ui.dialog.css | 13 + themes/base/ui.progressbar.css | 4 + themes/base/ui.resizable.css | 13 + themes/base/ui.slider.css | 17 + themes/base/ui.tabs.css | 11 + themes/base/ui.theme.css | 243 + .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 4379 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4379 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 4379 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 4379 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4379 bytes themes/smoothness/jquery-ui-1.7.custom.css | 405 + themes/smoothness/ui.accordion.css | 9 + themes/smoothness/ui.all.css | 2 + themes/smoothness/ui.base.css | 8 + themes/smoothness/ui.core.css | 37 + themes/smoothness/ui.datepicker.css | 62 + themes/smoothness/ui.dialog.css | 13 + themes/smoothness/ui.progressbar.css | 4 + themes/smoothness/ui.resizable.css | 13 + themes/smoothness/ui.slider.css | 17 + themes/smoothness/ui.tabs.css | 11 + themes/smoothness/ui.theme.css | 245 + 90 files changed, 20004 insertions(+) create mode 100644 .project create mode 100644 example1-simple.html create mode 100644 example2-formatters.html create mode 100644 example3-editing.html create mode 100644 examples.css create mode 100644 grid.html create mode 100644 images/ListView.gif create mode 100644 images/Pencil.gif create mode 100644 images/ajax-loader-small.gif create mode 100644 images/arrow_right_peppermint.png create mode 100644 images/arrow_right_spearmint.png create mode 100644 images/bullet_blue.png create mode 100644 images/bullet_star.png create mode 100644 images/bullet_toggle_minus.png create mode 100644 images/bullet_toggle_plus.png create mode 100644 images/calendar.gif create mode 100644 images/collapse.gif create mode 100644 images/comment_yellow.gif create mode 100644 images/down.gif create mode 100644 images/editor-helper-bg.gif create mode 100644 images/expand.gif create mode 100644 images/help.png create mode 100644 images/info.gif create mode 100644 images/stripes.png create mode 100644 images/tag_red.png create mode 100644 images/tick.png create mode 100644 images/user_identity.gif create mode 100644 images/user_identity_plus.gif create mode 100644 lib/firebug-lite.js create mode 100644 lib/firebugx.js create mode 100644 lib/jquery-1.3.2.js create mode 100644 lib/jquery-ui-1.7.custom.js create mode 100644 lib/jquery-ui-1.7.custom.min.js create mode 100644 lib/jquery.getScrollbarWidth.js create mode 100644 lib/jquery.rule-1.0.1-min.js create mode 100644 lib/jquery.rule-1.0.1.js create mode 100644 simpledropdown.css create mode 100644 slick.editors.js create mode 100644 slick.globaleditorstate.js create mode 100644 slick.grid.css create mode 100644 slick.grid.js create mode 100644 themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 themes/base/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 themes/base/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 themes/base/images/ui-bg_glass_75_ffffff_1x400.png create mode 100644 themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 themes/base/images/ui-bg_inset-soft_95_fef1ec_1x100.png create mode 100644 themes/base/images/ui-icons_222222_256x240.png create mode 100644 themes/base/images/ui-icons_2e83ff_256x240.png create mode 100644 themes/base/images/ui-icons_454545_256x240.png create mode 100644 themes/base/images/ui-icons_888888_256x240.png create mode 100644 themes/base/images/ui-icons_cd0a0a_256x240.png create mode 100644 themes/base/ui.accordion.css create mode 100644 themes/base/ui.all.css create mode 100644 themes/base/ui.base.css create mode 100644 themes/base/ui.core.css create mode 100644 themes/base/ui.datepicker.css create mode 100644 themes/base/ui.dialog.css create mode 100644 themes/base/ui.progressbar.css create mode 100644 themes/base/ui.resizable.css create mode 100644 themes/base/ui.slider.css create mode 100644 themes/base/ui.tabs.css create mode 100644 themes/base/ui.theme.css create mode 100644 themes/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 themes/smoothness/images/ui-icons_222222_256x240.png create mode 100644 themes/smoothness/images/ui-icons_2e83ff_256x240.png create mode 100644 themes/smoothness/images/ui-icons_454545_256x240.png create mode 100644 themes/smoothness/images/ui-icons_888888_256x240.png create mode 100644 themes/smoothness/images/ui-icons_cd0a0a_256x240.png create mode 100644 themes/smoothness/jquery-ui-1.7.custom.css create mode 100644 themes/smoothness/ui.accordion.css create mode 100644 themes/smoothness/ui.all.css create mode 100644 themes/smoothness/ui.base.css create mode 100644 themes/smoothness/ui.core.css create mode 100644 themes/smoothness/ui.datepicker.css create mode 100644 themes/smoothness/ui.dialog.css create mode 100644 themes/smoothness/ui.progressbar.css create mode 100644 themes/smoothness/ui.resizable.css create mode 100644 themes/smoothness/ui.slider.css create mode 100644 themes/smoothness/ui.tabs.css create mode 100644 themes/smoothness/ui.theme.css diff --git a/.project b/.project new file mode 100644 index 0000000..1af681d --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + SlickGrid + + + + + + + + diff --git a/example1-simple.html b/example1-simple.html new file mode 100644 index 0000000..3a8a1b1 --- /dev/null +++ b/example1-simple.html @@ -0,0 +1,84 @@ + + + + + SlickGrid example + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

Demonstrates:

+ +
    +
  • basic grid with minimal configuration
  • +
+ +
+ + + + + + diff --git a/example2-formatters.html b/example2-formatters.html new file mode 100644 index 0000000..96cf7a9 --- /dev/null +++ b/example2-formatters.html @@ -0,0 +1,93 @@ + + + + + SlickGrid example + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

Demonstrates:

+ +
    +
  • width, minWidth, maxWidth, resizable, cssClass column attributes
  • +
  • custom column formatters
  • + +
+ +
+ + + + + + + diff --git a/example3-editing.html b/example3-editing.html new file mode 100644 index 0000000..cbd01ba --- /dev/null +++ b/example3-editing.html @@ -0,0 +1,102 @@ + + + + + SlickGrid example + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

Demonstrates:

+ +
    +
  • adding basic keyboard navigation and editing
  • +
  • custom editors and validators
  • +
+ +
+ + + + + + + diff --git a/examples.css b/examples.css new file mode 100644 index 0000000..53af505 --- /dev/null +++ b/examples.css @@ -0,0 +1,33 @@ + * { + font-family: arial; + font-size: 8pt; +} + +body { + background: beige; +} + +h2 { + font-size: 10pt; + border-bottom: 1px dotted gray; +} + +ul { + margin-left: 0px; + padding: 0px; + cursor: default; +} + +li { + background: url("images/arrow_right_spearmint.png") no-repeat center left; + padding: 0px; + padding-left: 14px; + list-style: none; + margin: 0px; +} + +#myGrid { + background: white; + outline: 0px; + border: 1px solid gray; +} diff --git a/grid.html b/grid.html new file mode 100644 index 0000000..5098216 --- /dev/null +++ b/grid.html @@ -0,0 +1,360 @@ + + + + + Spreadsheet prototype + + + + + + + + + + + + + + + + + +
+
+ + + Reload grid +
+ Load 10 rows + Load 100 rows + Load 500 rows + Load 1'000 rows + Load 5'000 rows + Load 50'000 rows +
+
+ + + Change column styles +
+ Render % Complete as text + Render % Complete as graph +
+
+ + + Select rows +
+ 0 - 5 +
+
+ + + Options +
+ enableAddRow = true + enableAddRow = false +
+ editable = true + editable = false +
+ editOnDoubleClick = true + editOnDoubleClick = false +
+ enableCellNavigation = true + enableCellNavigation = false +
+ asyncEditorLoading = true + asyncEditorLoading = false +
+
+ + + Debug +
+ benchmark removeAllRows + benchmark render + benchmark render 200 +
+ stress test (infinite render/clear cycle) +
+ internal state +
+
+ + + Quick info +
+ + This page demonstrate the use of a SlickGrid control. +

+ Key features: +
    +
  • Virtual rendering/scrolling (hundreds of thousands of rows)
  • +
  • Extremely fast rendering speed
  • +
  • Support for a Model data source
  • +
  • Support for Ajax-loaded data
  • +
  • Multiple row selection
  • +
  • Edit and add new rows
  • +
  • Keyboard navigation for cell selection
  • +
  • Custom renderers for cells with conditional formatting
  • +
  • Formatters adaptive to column width
  • +
  • Custom editors for cells
  • +
  • Resizable and reorderable columns
  • +
  • Highly customizable & configurable
  • +
  • Built-in validators
  • +
  • Callbacks for events
  • +
  • Much much more...
  • +
+ +
+
+ +
+ +
+
+ +   +
+
+
+
+ + +
+ + + + + + + diff --git a/images/ListView.gif b/images/ListView.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ec25ca71979f1e2f0632060d8a295b5c668cb4b GIT binary patch literal 2380 zcmZ{i`BRz)0*2WnD~?ge>7lNssco}rj5ThWQEM{YY!5{Q>SQ|VnAEyyN39y;q#3m) z+qF5=D56QMST%|#2nZ+&h!=Fk=Dh+6hOiQYPg;Ed3mv|v$zM)-Zb(Gu~48X8JAIPvHsN_WdkL`{NYU<;}L?q zs$0sXqq^oP|8=JDN z?Va7d{jHC{N|jo3sMYBWMw8iMwb>ocqvI17=(NW<2n93o#Qp8C+gwW9RJqSb&}K+q z`%IPpCpl}}z79@J&=-~G68bxNFE04FaJPB=T>^CE_x$DrYPYZ{<|pMEkBSwy-gx5i z9&`XV*8zDI_AP&)X91hk0euY}#4iz2sX6QXL4t&wF;)3qB8~W_&n*=9t$^0MN-x;q zzfPo+)`yFY%5?#qyg6Qa`s{fagR(VM@%E*3fYGbCusO2cLNxr%Eg#3 zs?Nii0|)bGZxYgl%t4ie^1Yx1K1|cBGJaBR2#4v~P1cjM?;}PS`W^18OW%n`hK%yr zj>J~PDATN3q2_LiMu)9h*;Lj0Uyoh4yDJt5--*XYomSnBp!MtVv16yrsM-{dkN?q! zTd1t`jBmE=SNC9?%=OqaN+EmV6BoMm^qu7Ft!Mt3xUI5tg^I26pt8{IiVGuk{!B(yt{nGcx-4~GHp52$QsDs^CNpTnV z>b^<-aqqX(%$~ja+l2>v=!~+9`we%3GxmSa?(W%d%%dIbHx;li%9|f7|0sW5yx${l zd1N_|x0bqvDKJlca};eA!FWYGGD@lFsErFd=&Vc5Ip}K0#2<7w7b*|1n6j`OoM&B* zvIp0VSK^5@rIJ8lhpC7I%Q>oE#y(y}8nGx5L&`;vCVw4AFQwe1tMV@DR1 zb{qr_*Rjs{<>@BeLx{Rb&uF!7$|pWtKmATho_@wZi>POxD^lw@LH`Y(;9fxI8F-;s zqJbYyR~rP8oNyy>Rgz~E#>k0A(RHiZD82#y*fjg4-(AxjB&63g4~y2A7LwvWHZOjY za@V|+n$>GwzFnj-OVa-tWLfzEeb@3P8{2D<=Fv5l)dJ4P*0l$cyVmt$d9QWjkyT^e zECol{WKaF_ZCe!~B-=JJ`p~vh8y{ictxL(b?=@tR?EB3{hd;}`pGG)bicWOC;{b;x zIg~{Dp+iOCL^#z0l6Yj$e z+B{OYlfF#dvq)r{XBK2CK&mT?0ouHaxKrmHy7C*I?LOs@=???+6%bhaTWIcdaIF4$ z60-drEMz7uO<$P`wENO=GakkIstnH#e-4E0y3(jeX2UuHBwThBQ(s+x>^LWfaAKu; zR58$T-pb{C=Fr!adUghZ6S$uT7-}nEogez~xN)(D7q!UF3n2+SXqw?=1JD^9&Ep|T z46iVrU7_&_{F{x2IvlJkEQQBUW*UB@AiKh|5(H^dLp=lNiYVd<(j5jg%dW0TAi8^cKu-ETBDD`41I2~SkW zG``j$vDf7Z;u5K`#RgzMv+~5hIE<|zFWe1q82=ysCX72A_qiW`wk+1v=2MOPG6XtT znPzJD7vkcg`E#fem&v2sy$2ExoqySA>I{YVKvVeh^-NP&WOWZL3%bxKHFd`bdxAw1 z3oQ;4_J$WesT{i49$>~n;P{(p{$h8mxhJU_{|y$pbhmjIpDM&B)A>uJ5;Gygi;&8J zF84Q@iP>;MnuNbhW14#dKdrhghf0`IGpSfeNVoDOV-7R9)Qgw_PF$G`uuv-C#5?r+ zjqF%UUu`wg0&OgJ1m&?GAalEBoA5#Dx~9L{^0;N2^cPXeqJb^%hqkF8@4kw7*!EjZw&_qr zUu6n#C-<3pCKA<$%!2I%tlHQyqCQj+uyfvNuPuk|ei&%yzI(dqB^uZbzGmko zq5A8vu)VNbc7Cd;zn%{4MLe_%GQ6n`J(i&>O?Ds~L2Z-(`%%MoVF8NTEQiTsSM8!= z5w*n%$Upm9^sv->00V|AJ`Z%vRv-r2{e+6RYmT{E6mOt21bzU$<(O}%PX|W}4-gL> z3mES~Ts&NPv&pfDLk!|mgv#V$#}WlKNX&ZgUlCHrGD9>-DiW&Foel}hn?@;ztM3Fl zSGWjTKU%2HycSq_rkXZ@g==zdIi)Ki8jUX0pGM*FxndmMNqbLVvZZT7XU?Ap&N*bUuz`Z)T=HlYuZ}Y zeygzWRpG1!El$hZvwt_r|DUA)f2P^*T~hxSS{;~Hd~tr+?PVcn7nJ|s>;C_U{Qs+x z|L@EFzbF6WpvwOv`u|U<{6DMo|De(TQ%3)-*Q=zkmP#{rBIW-~a#rXBY*eApi>j9S{SQ7Z^Co85VNLyhu55pgBO~OvC~f z#cpY{ECY**BaPhhCQ>pg29KJ!Bn{a9%_wkcX=G%c&GEuP=}@Brb9|1$N5+HAjczst z8j1@KOm5T;TJVE`@%RBbMU#dF2@eyvm28Yu5{d%cC(23`Dey2XaN<#PIHVNGq{?}y Jk&%(X8US2;)^z{? literal 0 HcmV?d00001 diff --git a/images/ajax-loader-small.gif b/images/ajax-loader-small.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b33f7e54f4e55b6b8774d86d96895db9af044b4 GIT binary patch literal 1849 zcma*odr(tX9tZI2z31lM+(&YVk%mZ}5P~KlG2s=WSbGzm0!x7^P##Mnh7t-jP!X0Q zk_SQ}Po-L1tlDK;6l?(>v)e5ZBQx4|Y-Q?nr@Px3?9h(3ZWr3^tj=`TP57gKr87N$ zp2wWee1GRRCwo_xahnw)5cxNPJbCg2L6DV|6`#+yw6v6!mDS$f9-JvFD^n;GQ&UrZ zzh5jCkByB101O60U0q#p_1BM>Cv-vP?&s4@g_((4_1L=L$(a91)0=J91Gas#R{McE znYG^9*0A5YZ>#;~+Wkn(W5B0^yELIYLP!K}mB~<)AM@1&nqekynuaEGqPrzoH|KodRXJy)%+w_fu3nE5>@Bd_b zqC$EQ;{c`T&?EsNO|igL9gC7Ygxv?aQUEXMq?~>wg{EyW;VcJ37CUF#HjrT=KQO_* zS>M9yydXk18D(+QDJ1>r);Lav_uYKp$T?4vr{Q$lTo&pKv^?(>L-)G2*lwH!Ah7k? z7oH<8h-(KTKt5V6$8gF)C7Io&P5=SjTh)=zV=E2EUhQZP##L8S{d%UK>>+y82>+FV+#^BzW7u3F)Bb>=lYQ%%j`F>ASe zo*cw@V#u6T`A2He;70mR(V&iV&-7{qP~=SRf&jm9-T{*ZeZ}$rd0#6c&fLG^xJcf5 z+p<`wJYgW+_s*V{uI$nMB;%8`S_3>PfGOj3Rq}@Cx^+j?rk92fANSFDBYnOqQ>Vdj z)(|$AhP4t&Lb=Gvo2#3Gl%9<=Gv`Mz?Po@P4iLF!x}GUWJICDlFk-hS^Whyh7x~VH z@0vD1>HYD4&e+~yzS*-sFR{9`{QEEZO1zg7>R&7cHts-6j!xHVdA8eI+ZlVzd%`es zJT@$#GX(gvCJ1oJN%yLBK}{V=V;seo;!w|Yte!W1%5qLNFWqvZW>h&IiH+oPT=b@E zPhGzv5=(Un*X>v`>%8h_nj^NdYcE6NHS_ifkCV$*D)Tqrbu`s;<=t<4 zAHNqNV?6(g<1PY-w@#I-WYFViz?9TrkMr)u0g`O`u|>T;k|2sV*YF^punvT;$SuTy{j3Gv)yqD!R_CF>yR)MzmmYS5v+~R zXAdD%ng9?df;wd8GxR#%3O+gz};Vo;)sK%Bj-q>Oq%R7JU-KD?vYu>#2UjaDo z&8$>5xW~?KPD_#XFToU1hIb*VOMidUr6iYiO0N|i-7s`T8!cFT`rN!^1Pt78J93i6 z5HI1wIM$94m{3SLDvISDe6$ZG1;eq_D9RTaaC>=cO{@Bs>$IlPCPJJ$h$)-3vzNUQ6OsN#_zWxey!_9%hxwH2_dEJi=yY|1c7nDm2_Lm!Cof8-R_+9UkS zcBE(o47yE)oMR(Q=dp1a2wTX5KvvGyLqlWTa7V&!A*|w|)ax~1_~aJ0=_Lilg*0iQk7#ZD EAHN$8j{pDw literal 0 HcmV?d00001 diff --git a/images/arrow_right_peppermint.png b/images/arrow_right_peppermint.png new file mode 100644 index 0000000000000000000000000000000000000000..1804fa9f900ff840cd4427a1e5dc7ac3e76127cc GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEa{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5iyiDNMRkPr-H-w^rC^iexUih-$vv%Pmt0PmX}J-i9Zx+c*5+ z-=yHc@G$5PV~1*#(6v9VVk{gAIbHG&qW_$xGjJ%d1z0FQe)aR9&Wj`ipjkajT(}$< g3=JnRFfj2j_#0ZN_H7mB0J?_3)78&qol`;+0B}f4I{*Lx literal 0 HcmV?d00001 diff --git a/images/arrow_right_spearmint.png b/images/arrow_right_spearmint.png new file mode 100644 index 0000000000000000000000000000000000000000..298515ab6c37321d55e17f105cb093d2d984df6b GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhEa{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i9&PM5rc=s&0F3>*q<0T#-SZTnwEUO1WnG)uy>Q>1|* gDM^8mfklF$^RJbu%hc1sK-VyMy85}Sb4q9e0BIOb6#xJL literal 0 HcmV?d00001 diff --git a/images/bullet_blue.png b/images/bullet_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..a7651ec8a0f395be021bac262783ec604abf8c47 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i=8_H=O!u{izqk}bDmq0G^bpRL|W zr%VbmS`g2vdN_5Xhn$gw?joL;=H(n;{ewDX@>Vt8IAj)#jg!+?Z23wnf7d! zNAH#A4i6V)y_WtvZQ1hT)TAWgjoY{t%BOsI;8VOzQvNniDZk5xCy$)UQWb1PRjRoz l1#moJy|?3|{zvx%+MCW^-+4b6gSOJTlY4hP&f-;|-P$*M_2JKlU;gITjZ` z{x5A_(;&5}v4T&aoM|I#fY0yx;$r5+^$jtG$!>-LljTB+Ehjuewo4_`|D~s5}!Bww5usZ rTv^L-ldIQlg2YSCt_73XV;C9C`_J;k2tHT_^f`m4tDnm{r-UW|`Z|OR literal 0 HcmV?d00001 diff --git a/images/bullet_toggle_minus.png b/images/bullet_toggle_minus.png new file mode 100644 index 0000000000000000000000000000000000000000..b47ce55f685dac56ee9d63f2c3d426bfc4c9e31a GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$h^mK6y(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz1H+_;eX)`ni0%X8XBDc-`=Ph(Uan2 zYsR{H!kvIN--9isvHznRsC#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz4q@v|B?28{s)#N@CGn3@%_y|zAV9T z66e<&B4?b6oF&azg|C(V&1ZbI_D}pL`}(^FT2yXwG1Ph~$Q@h8mJYOz!PC{xWt~$( F699+YQR)By literal 0 HcmV?d00001 diff --git a/images/calendar.gif b/images/calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..90fd2e17fe247d3252977a0fb5b9e15aa0a513fb GIT binary patch literal 1035 zcmZ?wbhEHb6krfw_|5)@S9f&o11MQ?xO!cw>Iaru@>)1r=M0E4P+ZZ7mII zIULeKgDU;7-PP>>t`%1~&E2Rss zmoK_ev+zRIlAE$=f(b?AOC-O$p6(*{}&|uUzqrRQPTg#DgT!MQR@E+qCNbq%HSb);wrm_poFAqn?eAdp14k-|}?A)@PHqKcBko;gs#qr|o(M^svF)$&Z_>+Z^f#E-c4#;{?o?zg3!SJ6`#$&^S1A0Mo zOd^|}cuZ7utZDF2x^QZKw}f%r8-))i=S!QW?1-3n$c0l#`Co>>jVJxRayDfzPBbdB z@d(x%aio0O$kr>VAGIN%@zD`^9;T^(W-@hfEzoLM$MA{iMIURU+pmy=lUPqr(`R8} zQ7}$#a!{(>!NA06dGg`n cVfH2m1!<$04Gs?(n;)OBm5A{(P++hI0EaJh%K!iX literal 0 HcmV?d00001 diff --git a/images/collapse.gif b/images/collapse.gif new file mode 100644 index 0000000000000000000000000000000000000000..01e691450c48632dc92a40a8c2b509bf99987225 GIT binary patch literal 846 zcmZ?wbhEHb$FyaIl$)g-gQVfI}k_i-?$k!^A~S3=)P?0Tm31hZvXy UI%HM~I5JIC=Ul}jAi!V^09i~Z*8l(j literal 0 HcmV?d00001 diff --git a/images/comment_yellow.gif b/images/comment_yellow.gif new file mode 100644 index 0000000000000000000000000000000000000000..df7158a47713eaba957b506048235a44ea204b7e GIT binary patch literal 257 zcmV+c0sj6+Nk%w1VGsZi0K@S*iEN$I#V?9xjA@}>Xoga7rz|MtxP@t*(f zd;jyT|Ma^5_}BT?cIUw`|L>9O(^dcLa{u(R|L~Uo`Rwb_Gym_4@6JNjmm=$!66@0} z+@UAy$58+O|NsC0A^8LW0018VEC2ui01yBW000Gk;3tk`NqT6imL3tk1c6!B=8c}C zdO&j^2-_#;K`YF9fS*UcPPtW$y zAC1e8&dfF|PCBwPc)8m=``RLrQxnq8EOwjBBztRfX25cv`Ch$VTVDjNcFA@+x-0Z` z$h!EwVWQk+I+s?bT%LD!*S7528}iR;rCMLljonfHbWv~gw)MC6)cyQ-m%G9s_D~1E z_O{tGJ|^wyRkXimZCQ|baE5+%pU=&W=_lt~H_Pen+LC&1xwbUl+*x0Syf|Ke-=FW_A3xmP?_a;~@8`E4XYbdGudo02^{2Q(!*@ZAgvM7- z(;qZ(zPtXQo}W)bvFVLvgkp=h*9^s0F29Ng?L2uLi`o^-G?F^SX01r-(n;F!s9yG{ Q#^WB7YZ;4s85tR@0d|1E6951J literal 0 HcmV?d00001 diff --git a/images/expand.gif b/images/expand.gif new file mode 100644 index 0000000000000000000000000000000000000000..1b24ef1248de55c6140895f6760758a1579f14cf GIT binary patch literal 851 zcmZ?wbhEHb$FyaIl$)g-gPK!J(0fMMMlpH!w1DF=kxpFl=aGX3~-h X>0od?I!Q%XL14k81*aJp85yhr3QsCm literal 0 HcmV?d00001 diff --git a/images/help.png b/images/help.png new file mode 100644 index 0000000000000000000000000000000000000000..0eff0a5cb58f8d3478a23ffc5a39abcc03763ae8 GIT binary patch literal 510 zcmV7!c@t%Q;hm#>P z*^NPxS3gKuS@{l7aT6mW<9C1nVgeH0pME?A+VGD-R#BWGDbJVT&C3s9K1iIOpWh9r zm>Xm|KmdUh8-Dx!mH`9|OjQ}`3+6BwnyZ2NAaO1(E|4=gfS3g!fS7>py}-pP%m4$a z1%3?HPI_QANF3mXBsm=Pd=n125Jxr2{Gnt_p#39R7Qfh%Ad#0QB#dGh2Ckoy;i z{{sXN)4O-?mazO4TnF?F0}q=RLqwu0myv6~YMg-b(ohdF0R#{uDExq)WQKZz8%i@ntp=I+6+{Eo z{RIdhuwsZC!HxzgVgYeMZiHI>_dh5cfdC-D04Px#07*qoM6N<$f)Ak8 AdjJ3c literal 0 HcmV?d00001 diff --git a/images/info.gif b/images/info.gif new file mode 100644 index 0000000000000000000000000000000000000000..5769434fb244628e2a7637ae9efe4bb041aa8971 GIT binary patch literal 80 zcmZ?wbhEHbOr{Nf?NJjGBFly85}Sb4q9e03B>MiU0rr literal 0 HcmV?d00001 diff --git a/images/tag_red.png b/images/tag_red.png new file mode 100644 index 0000000000000000000000000000000000000000..6ebb37d25f58c68246d8ad6a015295dfa5367870 GIT binary patch literal 592 zcmV-W0k7R5;6p zlgVxxK@f)LC45c9TOf_{d{!)DV#gQ9u^lTnR)N?B4hRsNK&)mFLI{BXaU6RP-Hd*B zb;Jb3l0#jp`v2;$?rNpgYN6R|qF%3~R;!^}t)fz?pj!?Xf$9L#$Jra zV+qOU^Cuw+btb`RG?JZ%!=VYGoN$3mCUX>`kYzed-6&Bk7R#EZfpaeN1kB}fNG6j9 zAqsWf92DY}usm8Wm*DdmSn7|g4F&_G(`h6Ui9Luyoi~=(>orKcUM#@A*}%S@gC$>N zt>5pH3q+&Q9f%@k)E7cPhZtkvGtt>@1HZome|iABzA_=bUXNTL7z~;arBEn*5i{!Z z`TQ^BwFP!@4*qZt{`(pH*W(VP+wGDI_d4WAzVcfivW|vfP^h0000Hs{AQG2a)rMyf zFQK~pm1x3+7!nu%-M`k}``c>^00{o_1pjWJUTfl8mg=3qGEl8H@}^@w`VUx0_$uy4 z2FhRqKX}xI*?Tv1DJd8z#F#0c%*~rM30HE1@2o5m~}ZyoWhqv>ql{V z1ZGE0lgcoK^lx+eqc*rAX1Ky;Xx3U%u#zG!m-;eD1Qsn@kf3|F9qz~|95=&g3(7!X zB}JAT>RU;a%vaNOGnJ%e1=K6eAh43c(QN8RQ6~GP%O}Jju$~Ld*%`mO1pphCpI>2{dBys(sIwpFWDz^b5`?95CI)&S&yhXMcq literal 0 HcmV?d00001 diff --git a/images/user_identity_plus.gif b/images/user_identity_plus.gif new file mode 100644 index 0000000000000000000000000000000000000000..b276a81c786561a82422555b598bbc07e63bf82b GIT binary patch literal 546 zcmZ?wbhEHb!lchi~8b7yvx zhlk4?-L>w+!;3T8%cr#zy}WUJPJ8K&IgO7`ZD`I3>n%>ZR_fBqWElN7JYt`JY zvd_2nAK0?|(~Z5KA6>k%Ywn`{iZiJ$v>W7x^ZI1k2m*@ZCy08t@!iZBj>ivKDus3QITpr{ordpS$wvCCZh^f8h0exu+Lk$Bh>jMgM zY_{C4H(guY@7{B9dwAQ^-Q(GF_Xm%jK7af2_1kx^T;F{3c<=V*+cWo;Mh0sD^HazS literal 0 HcmV?d00001 diff --git a/lib/firebug-lite.js b/lib/firebug-lite.js new file mode 100644 index 0000000..1fa0bb4 --- /dev/null +++ b/lib/firebug-lite.js @@ -0,0 +1,2068 @@ +var firebug = { + version:[1.23,20090122], + el:{}, + env:{ + "cache":{}, + "css":"http://getfirebug.com/releases/lite/1.2/firebug-lite.css", + "dIndex":"console", + "height":295, + "init":false, + "isPopup":false, + "minimized":false, + "ml":false, + "override":false, + "popupWin":null + }, + init:function(_css){ + with(firebug){ + if(env.init) + return; + document.getElementsByTagName("head")[0].appendChild( + new lib.element("link").attribute.set("rel","stylesheet").attribute.set("href",env.css).element + ); + + /* + * main interface + */ + el.content = {}; + el.main = new lib.element("DIV").attribute.set("id","Firebug").environment.addStyle({ "display":"none", "width":lib.util.GetViewport().width+"px" }).insert(document.body); + if(!env.isPopup){ + el.resizer = new lib.element("DIV").attribute.addClass("Resizer").event.addListener("mousedown",win.resizer.start).insert(el.main); + } + el.header = new lib.element("DIV").attribute.addClass("Header").insert(el.main); + el.left = {}; + el.left.container = new lib.element("DIV").attribute.addClass("Left").insert(el.main); + el.right = {}; + el.right.container = new lib.element("DIV").attribute.addClass("Right").insert(el.main); + el.main.child.add(new lib.element("DIV").attribute.addClass('Clear')); + + /* + * buttons + */ + el.button = {}; + el.button.container = new lib.element("DIV").attribute.addClass("ButtonContainer").insert(el.header); + el.button.logo = new lib.element("A").attribute.set("title","Firebug Lite").attribute.set("target","_blank").attribute.set("href","http://getfirebug.com/lite.html").update(" ").attribute.addClass("Button Logo").insert(el.button.container); + el.button.inspect = new lib.element("A").attribute.addClass("Button").event.addListener("click",(env.isPopup && window.opener || window).firebug.d.inspector.toggle).update("Inspect").insert(el.button.container); + el.button.dock = new lib.element("A").attribute.addClass("Button Dock").event.addListener("click", win.dock).insert(el.button.container); + el.button.newWindow = new lib.element("A").attribute.addClass("Button NewWindow").event.addListener("click", win.newWindow).insert(el.button.container); + + if(!env.isPopup){ + el.button.maximize = new lib.element("A").attribute.addClass("Button Maximize").event.addListener("click",win.maximize).insert(el.button.container); + el.button.minimize = new lib.element("A").attribute.addClass("Button Minimize").event.addListener("click",win.minimize).insert(el.button.container); + el.button.close = new lib.element("A").attribute.addClass("Button Close").event.addListener("click",win.close).insert(el.button.container); + } + + if(lib.env.ie||lib.env.webkit){ + el.button.container.environment.addStyle({ "paddingTop":"12px" }); + } + + /* + * navigation + */ + el.nav = {}; + el.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.left.container); + el.nav.console = new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.navigate,window,"console")).update("Console").insert(el.nav.container); + el.nav.html = new lib.element("A").attribute.addClass("Tab").update("HTML").event.addListener("click",lib.util.Curry(d.navigate,window,"html")).insert(el.nav.container); + el.nav.css = new lib.element("A").attribute.addClass("Tab").update("CSS").event.addListener("click",lib.util.Curry(d.navigate,window,"css")).insert(el.nav.container); + if(!env.isPopup){ + el.nav.scripts = new lib.element("A").attribute.addClass("Tab").update("Script").event.addListener("click",lib.util.Curry(d.navigate,window,"scripts")).insert(el.nav.container); + } + el.nav.dom = new lib.element("A").attribute.addClass("Tab").update("DOM").event.addListener("click",lib.util.Curry(d.navigate,env.isPopup && window.opener || window,"dom")).insert(el.nav.container); + if(!env.isPopup){ + el.nav.xhr = new lib.element("A").attribute.addClass("Tab").update("XHR").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).insert(el.nav.container); + } + /* + * inspector + */ + + el.borderInspector = new lib.element("DIV").attribute.set("id","FirebugBorderInspector").event.addListener("click",listen.inspector).insert(document.body); + el.bgInspector = new lib.element("DIV").attribute.set("id","FirebugBGInspector").insert(document.body); + + /* + * console + */ + el.left.console = {}; + el.left.console.container = new lib.element("DIV").attribute.addClass("Console").insert(el.left.container); + el.left.console.mlButton = new lib.element("A").attribute.addClass("MLButton").event.addListener("click",d.console.toggleML).insert(el.left.console.container); + el.left.console.monitor = new lib.element("DIV").insert( + new lib.element("DIV").attribute.addClass("Monitor").insert(el.left.console.container) + ); + el.left.console.container.child.add( + new lib.element("DIV").attribute.addClass("InputArrow").update(">>>") + ); + el.left.console.input = new lib.element("INPUT").attribute.set("type","text").attribute.addClass("Input").event.addListener("keydown",listen.consoleTextbox).insert( + new lib.element("DIV").attribute.addClass("InputContainer").insert(el.left.console.container) + ); + + el.right.console = {}; + el.right.console.container = new lib.element("DIV").attribute.addClass("Console Container").insert(el.right.container); + el.right.console.mlButton = new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.console.container); + el.right.console.input = new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.console.container); + el.right.console.input.event.addListener("keydown",lib.util.Curry(tab,window,el.right.console.input.element)); + el.right.console.run = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runMultiline).update("Run").insert(el.right.console.container); + el.right.console.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.console.input)).update("Clear").insert(el.right.console.container); + + el.button.console = {}; + el.button.console.container = new lib.element("DIV").attribute.addClass("ButtonSet").insert(el.button.container); + el.button.console.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",d.console.clear).update("Clear").insert(el.button.console.container); + + /* + * html + */ + + el.left.html = {}; + el.left.html.container = new lib.element("DIV").attribute.addClass("HTML").insert(el.left.container); + + el.right.html = {}; + el.right.html.container = new lib.element("DIV").attribute.addClass("HTML Container").insert(el.right.container); + + el.right.html.nav = {}; + el.right.html.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.right.html.container); + el.right.html.nav.computedStyle = new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"computedStyle")).update("Computed Style").insert(el.right.html.nav.container); + el.right.html.nav.dom = new lib.element("A").attribute.addClass("Tab").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"dom")).update("DOM").insert(el.right.html.nav.container); + + el.right.html.content = new lib.element("DIV").attribute.addClass("Content").insert(el.right.html.container); + + el.button.html = {}; + el.button.html.container = new lib.element("DIV").attribute.addClass("ButtonSet HTML").insert(el.button.container); + + /* + * css + */ + + el.left.css = {}; + el.left.css.container = new lib.element("DIV").attribute.addClass("CSS").insert(el.left.container); + + el.right.css = {}; + el.right.css.container = new lib.element("DIV").attribute.addClass("CSS Container").insert(el.right.container); + + el.right.css.nav = {}; + el.right.css.nav.container = new lib.element("DIV").attribute.addClass("Nav").insert(el.right.css.container); + el.right.css.nav.runCSS = new lib.element("A").attribute.addClass("Tab Selected").update("Run CSS").insert(el.right.css.nav.container); + + el.right.css.mlButton = new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.css.container); + el.right.css.input = new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.css.container); + el.right.css.input.event.addListener("keydown",lib.util.Curry(firebug.tab,window,el.right.css.input.element)); + el.right.css.run = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runCSS).update("Run").insert(el.right.css.container); + el.right.css.clear = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.css.input)).update("Clear").insert(el.right.css.container); + + el.button.css = {}; + el.button.css.container = new lib.element("DIV").attribute.addClass("ButtonSet CSS").insert(el.button.container); + el.button.css.selectbox = new lib.element("SELECT").event.addListener("change",listen.cssSelectbox).insert(el.button.css.container); + + /* + * scripts + */ + + el.left.scripts = {}; + el.left.scripts.container = new lib.element("DIV").attribute.addClass("Scripts").insert(el.left.container); + + el.right.scripts = {}; + el.right.scripts.container = new lib.element("DIV").attribute.addClass("Scripts Container").insert(el.right.container); + + el.button.scripts = {}; + el.button.scripts.container = new lib.element("DIV").attribute.addClass("ButtonSet Scripts").insert(el.button.container); + el.button.scripts.selectbox = new lib.element("SELECT").event.addListener("change",listen.scriptsSelectbox).insert(el.button.scripts.container); + el.button.scripts.lineNumbers = new lib.element("A").attribute.addClass("Button").event.addListener("click",d.scripts.toggleLineNumbers).update("Show Line Numbers").insert(el.button.scripts.container); + + /* + * dom + */ + + el.left.dom = {}; + el.left.dom.container = new lib.element("DIV").attribute.addClass("DOM").insert(el.left.container); + + el.right.dom = {}; + el.right.dom.container = new lib.element("DIV").attribute.addClass("DOM Container").insert(el.right.container); + + el.button.dom = {}; + el.button.dom.container = new lib.element("DIV").attribute.addClass("ButtonSet DOM").insert(el.button.container); + el.button.dom.label = new lib.element("LABEL").update("Object Path:").insert(el.button.dom.container); + el.button.dom.textbox = new lib.element("INPUT").event.addListener("keydown",listen.domTextbox).update(env.isPopup&&"window.opener"||"window").insert(el.button.dom.container); + + /* + * str + */ + el.left.str = {}; + el.left.str.container = new lib.element("DIV").attribute.addClass("STR").insert(el.left.container); + + el.right.str = {}; + el.right.str.container = new lib.element("DIV").attribute.addClass("STR").insert(el.left.container); + + el.button.str = {}; + el.button.str.container = new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container); + el.button.str.watch = new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).update("Back").insert(el.button.str.container); + + /* + * xhr + */ + el.left.xhr = {}; + el.left.xhr.container = new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container); + + el.right.xhr = {}; + el.right.xhr.container = new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container); + + + el.button.xhr = {}; + el.button.xhr.container = new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container); + el.button.xhr.label = new lib.element("LABEL").update("XHR Path:").insert(el.button.xhr.container); + el.button.xhr.textbox = new lib.element("INPUT").event.addListener("keydown",listen.xhrTextbox).insert(el.button.xhr.container); + el.button.xhr.watch = new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.addXhrObject).update("Watch").insert(el.button.xhr.container); + + if (env.isPopup) { + lib.util.AddEvent(window, "unload", win.dock); + lib.util.AddEvent(window, "load", win.fitToPopup); + lib.util.AddEvent(window, "resize", win.fitToPopup); + } else { + lib.util.AddEvent(window, "resize", win.refreshSize); + } + lib.util.AddEvent(document,"mousemove",listen.mouse)("mousemove",win.resizer.resize)("mouseup",win.resizer.stop)("keydown",listen.keyboard); + + env.init = true; + + for(var i=0, len=d.console.cache.length; i -1) { + var scriptPath = scripts[i].src; + break; + } + } + + var script = firebug.env.popupWin.document.createElement('script'), done = false; + script.type = 'text/javascript'; + script.src = scriptPath; + + script[firebug.lib.env.ie?"onreadystatechange":"onload"] = function(){ + if(!done && (!firebug.lib.env.ie || this.readyState == "complete" || this.readyState=="loaded")){ + done = true; + + with(firebug.env.popupWin.firebug) { + env.isPopup = true; + env.css = firebug.env.css; + init(); + el.button.dock.environment.addStyle({ "display": "block"}); + el.button.newWindow.environment.addStyle({ "display": "none"}); + } + } + }; + + firebug.env.popupWin.document.getElementsByTagName('head')[0].appendChild(script); + + firebug.el.main.environment.addStyle({ + "display": "none" + }); + } + } + }, + dock: function() { + with(opener.firebug) { + env.popupWin = null; + el.main.environment.addStyle({ + "display": "block" + }); + window.close(); + }; + }, + fitToPopup: function() { + with(firebug) { + var viewport = lib.util.GetViewport(window); + win.setHeight((window.innerHeight||viewport.height) - 38); + el.main.environment.addStyle({ + "width": (viewport.width) + "px" + }); + } + }, + resizer:{ + y:[], enabled:false, + start:function(_event){ + with(firebug){ + if(env.minimized)return; + win.resizer.y=[el.main.element.offsetHeight,_event.clientY]; + if(lib.env.ie6){ + win.resizer.y[3]=parseInt(el.main.environment.getPosition().top); + } + win.resizer.enabled=true; + } + }, + resize:function(_event){ + with(firebug){ + if(!win.resizer.enabled)return; + win.resizer.y[2]=(win.resizer.y[0]+(win.resizer.y[1]-_event.clientY)); + el.main.environment.addStyle({ "height":win.resizer.y[2]+"px" }); + if(lib.env.ie6){ + el.main.environment.addStyle({ "top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px" }); + } + } + }, + stop:function(_event){ + with(firebug){ + if(win.resizer.enabled){ + win.resizer.enabled=false; + win.setHeight(win.resizer.y[2]-35); + } + } + } + }, + setHeight:function(_height){ + with(firebug){ + env.height=_height; + + el.left.container.environment.addStyle({ "height":_height+"px" }); + el.right.container.environment.addStyle({ "height":_height+"px" }); + el.main.environment.addStyle({ "height":_height+38+"px" }); + + win.refreshSize(); + + // console + el.left.console.monitor.element.parentNode.style.height=_height-47+"px"; + el.left.console.mlButton.environment.addStyle({ "top":_height+19+"px" }); + el.right.console.mlButton.environment.addStyle({ "top":_height+19+"px" }); + el.right.console.input.environment.addStyle({ "height":_height-29+"px" }); + + // html + el.left.html.container.environment.addStyle({"height":_height-23+"px"}); + el.right.html.content.environment.addStyle({"height":_height-23+"px"}); + + // css + el.left.css.container.environment.addStyle({"height":_height-33+"px"}); + el.right.css.input.environment.addStyle({ "height":_height-55+"px" }); + + // script + el.left.scripts.container.environment.addStyle({"height":_height-23+"px"}); + + // dom + el.left.dom.container.environment.addStyle({"height":_height-31+"px"}); + + // xhr + el.left.xhr.container.environment.addStyle({"height":_height-32+"px"}); + + // string + el.left.str.container.environment.addStyle({"height":_height-32+"px"}); + } + }, + refreshSize:function(){ + with(firebug){ + if(!env.init) + return; + + var dim = lib.util.GetViewport(); + el.main.environment.addStyle({ "width":dim.width+"px"}); + if(lib.env.ie6) + win.setVerticalPosition(dim); + } + }, + setVerticalPosition:function(_dim,_event){ + with(firebug){ + var dim = _dim||lib.util.GetViewport(); + el.main.environment.addStyle({ "top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px" }); + } + } + }, + d: { + clean:function(_element){ + with(firebug){ + _element.update(""); + } + }, + console:{ + addLine:function(){ + with (firebug) { + return new lib.element("DIV").attribute.addClass("Row").insert(el.left.console.monitor); + } + }, + cache:[], + clear:function(){ + with(firebug){ + d.clean(el.left.console.monitor); + d.console.cache = []; + } + }, + formatArgs:function(){ + with(firebug){ + var content = []; + for(var i=0, len=arguments.length; i>> "+_cmd); + d.console.addLine().update(d.highlight(_text,false,false,true)); + d.console.scroll(); + } + }, + printException: function(_exception){ + with(firebug){ + var message = _exception.description||_exception.message||_exception; + if(_exception.fileName){ + message+=' ('+(_exception.name&&(_exception.name+', ')||'')+getFileName(_exception.fileName)+', '+_exception.lineNumber+')'; + } + d.console.addLine().attribute.addClass("Error").update("Error: "+message,true); + } + }, + eval:function(_cmd){ + with(firebug){ + if(_cmd.length==0) + return; + + el.left.console.input.environment.getElement().value = ""; + d.console.historyIndex = d.console.history.push(_cmd); + + try { + var result = eval.call(window,_cmd); + d.console.print(_cmd,result); + } catch(e){ + d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd); + d.console.printException(e); + } + d.console.scroll(); + } + }, + scroll:function(){ + with(firebug){ + el.left.console.monitor.environment.getElement().parentNode.scrollTop = Math.abs(el.left.console.monitor.environment.getSize().offsetHeight-(el.left.console.monitor.element.parentNode.offsetHeight-11)); + } + }, + run:function(_command){ + with(firebug){ + if(!env.init){ + d.console.cache.push({ "command":_command, "arg":Array.prototype.slice.call(arguments,1) }); + } else { + d.console.cmd[_command].apply(window,Array.prototype.slice.call(arguments,1)); + } + } + }, + toggleML:function(){ + with(firebug){ + var open = !env.ml; + env.ml = !env.ml; + d.navigateRightColumn("console",open); + el[open?"left":"right"].console.mlButton.environment.addStyle({ display:"none" }); + el[!open?"left":"right"].console.mlButton.environment.addStyle({ display:"block" }); + el.left.console.mlButton.attribute[(open?"add":"remove")+"Class"]("CloseML"); + } + }, + countMap:{}, timeMap: {}, + cmd:{ + log: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Log").update(args); + d.console.scroll(); + } + }, + warn: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Warn").update(args); + d.console.scroll(); + } + }, + info: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Info").update(args); + d.console.scroll(); + } + }, + debug: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Debug").update(args); + d.console.scroll(); + } + }, + error: function(_value){ + with(firebug){ + var args = d.console.formatArgs.apply(window,arguments); + d.console.addLine().attribute.addClass("Error").update(args); + d.console.scroll(); + } + }, + trace: function(_value){ + with(firebug){ + var stackAmt = 3, f = arguments.caller, isArray = lib.util.IsArray(f); //function that called trace + + if((!isArray&&f)||(isArray&&f.length>0)){ + d.console.addLine().attribute.addClass("Arrow").update(">>> console.trace(stack)"); + for(var i=0;i>> console.dir("+_value+")"); + d.dom.open(_value,d.console.addLine()); + } + }, + dirxml: function(){ + with(firebug){ + d.console.cmd.log.apply(this, arguments); + } + }, + time: function(_name){ + with(firebug){ + d.console.timeMap[_name] = new Date().getTime(); + } + }, + timeEnd: function(_name){ + with(firebug){ + if(_name in d.console.timeMap){ + var delta = new Date().getTime() - d.console.timeMap[_name], + args = d.console.formatArgs.apply(window,[_name+":", delta+"ms"]); + d.console.addLine().attribute.addClass("log").update(args); + delete d.console.timeMap[_name]; + } + } + }, + count: function(_name){ + with(firebug){ + if(!d.console.countMap[_name]) + d.console.countMap[_name] = 0; + d.console.countMap[_name]++; + d.console.cmd.log.apply(window, [_name, d.console.countMap[_name]]); + } + }, + group:function(){ + with(firebug){ + d.console.cmd.log.apply(this, ["console.group is not supported"]); + } + }, + groupEnd:function(){ + with(firebug){ + d.console.cmd.log.apply(this, ["console.groupEnd is not supported"]); + } + }, + profile:function(){ + with(firebug){ + d.console.cmd.log.apply(this, ["console.profile is not supported"]); + } + }, + profileEnd:function(){ + with(firebug){ + d.console.cmd.log.apply(this, ["console.profileEnd is not supported"]); + } + } + } + }, + css:{ + index:-1, + open:function(_index){ + with (firebug) { + var item = (env.isPopup&&window.opener||window).document.styleSheets[_index], + uri = item.href, + dmn = getDomain(uri); + if(uri.indexOf("http:\/\/")>-1&&dmn!=document.domain&&'www.'+dmn!=document.domain){ + el.left.css.container.update("Access to restricted URI denied"); + return; + } + var rules = item[lib.env.ie ? "rules" : "cssRules"], str = ""; + for (var i=0; i"; + for(var i=0,len=_css.length; i$1$2;")+""; + } + str+="
}
"; + return str; + } + }, + refresh:function(){ + with(firebug){ + el.button.css.selectbox.update(""); + var collection = (env.isPopup&&window.opener||window).document.styleSheets; + for(var i=0,len=collection.length; inull"); + } else if (vtype=="boolean"||vtype=="number") { + result.push("" + _value + ""); + } else if(vtype=="function"){ + result.push("function()"); + } else { + result.push("\""+( !_inObject&&!_inArray?_value : _value.substring(0,35)+(_value.length>35?" ...":"") ).replace(/\n/g,"\\n").replace(/\s/g," ").replace(/>/g,">").replace(/"); + } + } + // element + else if(isElement){ + + if(_value.nodeType==3) + result.push(d.highlight(_value.nodeValue)); + else if(_inObject){ + result.push(""+_value.nodeName.toLowerCase()+""); + } else { + result.push(""); + + if(_inArray){ + result.push(_value.nodeName.toLowerCase()); + if(_value.getAttribute){ + if(_value.getAttribute&&_value.getAttribute("id")) + result.push("#"+_value.getAttribute("id")+""); + var elClass = _value.getAttribute(lib.env.ie?"className":"class")||""; + result.push(!elClass?"":"."+elClass.split(" ")[0]+""); + } + result.push(""); + } else { + result.push("<"+ _value.nodeName.toLowerCase()); + + if(_value.attributes){ + for(var i=0,len=_value.attributes.length; i"+item.nodeName+"=\""+item.nodeValue+"\""); + } + } + + result.push(">"); + } + } + } + // array, hash + else if(isArray||isHash){ + if(isArray){ + if(_inObject){ + result.push("["+_value.length+"]"); + } else { + result.push("[ "); + + for(var i=0,len=_value.length; i3){ + result.push(", "+(len-4)+" More..."); + break; + } + result.push( (i > 0 ? ", " : "") + d.highlight(_value[i], false, true, true) ); + } + + result.push(" ]"); + } + } else if(_inObject){ + result.push("Object"); + } else { + result.push("Object"); + var i=0; + for(var key in _value){ + var value = _value[key]; + if((_inObject||_inArray)&&i>3){ + result.push(" More..."); + break; + } + result.push(" "+key+"="+d.highlight(value,true)); + i++; + } + result.push(""); + } + } else { + result.push([""+_value+""]); + } + } catch(e){ + result.push(".."); + } + return result.join(""); + } + }, + html:{ + nIndex:"computedStyle", + current:null, + highlight:function(_element,_clear,_event){ + with(firebug){ + if(_element.firebugElement){ + return; + } + if(_clear){ + (env.isPopup&&window.opener||window).firebug.el.bgInspector.environment.addStyle({ "display":"none" }); + return; + } + d.inspector.inspect(_element,true); + } + }, + inspect:function(_element){ + var map = [], + parentLayer, + t, + tagName, + parent = _element; + while (parent) { + map.push(parent); + if (parent == (firebug.env.isPopup ? window.opener: window).document.body) break; + parent = parent.parentNode; + } + map = map.reverse(); + with(firebug) { + if (env.dIndex != "html") { + if (env.isPopup) { + window.opener.firebug.d.navigate("html"); + } else { + firebug.d.navigate("html"); + } + } + if (env.isPopup) { + window.opener.firebug.d.inspector.toggle(false); + } else { + firebug.d.inspector.toggle(false); + } + for (t = 0; t < el.left.html.container.child.get().length; t++) { + if (el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0]) { + if (el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].innerText) { + tagName = el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].innerText; + } else { + tagName = el.left.html.container.child.get()[t].childNodes[0].childNodes[1].childNodes[0].childNodes[0].textContent; + } + + if (/<html>").insert(parent); + }; + + for(var i=0; i<=len; i++){ + if(i==len){ + new lib.element("A").attribute.addClass("Block").update("</"+element.nodeName.toLowerCase()+">").insert(container); + break; + } + var item = element.childNodes[i]; + + if (item.nodeType != 3){ + var container = new lib.element().attribute.addClass("Block").insert(parent), + link = new lib.element("A").attribute.addClass("Link").insert(container), + spacer = new lib.element("SPAN").attribute.addClass("Spacer").update(" ").insert(link), + html = new lib.element("SPAN").attribute.addClass("Content").update(d.highlight(item)).insert(link), + subContainer = new lib.element("DIV").attribute.addClass("SubContainer").insert(container), + view = lib.util.Element.getView(item); + + link.event.addListener("click", lib.util.Curry(d.html.openHtmlTree, window, item, subContainer, false)); + link.event.addListener("mouseover", lib.util.Curry(d.html.highlight, window, item, false)); + link.event.addListener("mouseout", lib.util.Curry(d.html.highlight, window, item, true)); + + returnParentVal = returnParentEl == item ? subContainer : returnParentVal; + + if(d.html.current==null&&item==document.body){ + link.attribute.addClass("Selected"); + d.html.current = [item,link]; + d.html.openHtmlTree(item,subContainer); + } + + if(element.nodeName!="HEAD"&&element!=document.documentElement&&(view.visibility=="hidden"||view.display=="none")){ + container.attribute.addClass("Unvisible"); + }; + + if (item.childNodes){ + var childLen = item.childNodes.length; + if (childLen == 1 && item.childNodes[0].nodeType == 3) { + html.child.add(document.createTextNode(item.childNodes[0].nodeValue.substring(0, 50))); + html.child.add(document.createTextNode("")); + continue; + } + else + if (childLen > 0) { + link.attribute.addClass("Parent"); + } + } + } + }; + return returnParentVal; + } + }, + openProperties:function(){ + with(firebug){ + var index = d.html.nIndex; + var node = d.html.current[0]; + d.clean(el.right.html.content); + var str = ""; + switch(index){ + case "computedStyle": + var property = ["opacity","filter","azimuth","background","backgroundAttachment","backgroundColor","backgroundImage","backgroundPosition","backgroundRepeat","border","borderCollapse","borderColor","borderSpacing","borderStyle","borderTop","borderRight","borderBottom","borderLeft","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderWidth","bottom","captionSide","clear","clip","color","content","counterIncrement","counterReset","cue","cueAfter","cueBefore","cursor","direction","display","elevation","emptyCells","cssFloat","font","fontFamily","fontSize","fontSizeAdjust","fontStretch","fontStyle","fontVariant","fontWeight","height","left","letterSpacing","lineHeight","listStyle","listStyleImage","listStylePosition","listStyleType","margin","marginTop","marginRight","marginBottom","marginLeft","markerOffset","marks","maxHeight","maxWidth","minHeight","minWidth","orphans","outline","outlineColor","outlineStyle","outlineWidth","overflow","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","page","pageBreakAfter","pageBreakBefore","pageBreakInside","pause","pauseAfter","pauseBefore","pitch","pitchRange","playDuring","position","quotes","richness","right","size","speak","speakHeader","speakNumeral","speakPunctuation","speechRate","stress","tableLayout","textAlign","textDecoration","textIndent","textShadow","textTransform","top","unicodeBidi","verticalAlign","visibility","voiceFamily","volume","whiteSpace","widows","width","wordSpacing","zIndex"].sort(); + var view = document.defaultView?document.defaultView.getComputedStyle(node,null):node.currentStyle; + for(var i=0,len=property.length; i
"+d.highlight(view[item])+"
"; + } + el.right.html.content.update(str); + break; + case "dom": + d.dom.open(node,el.right.html.content,lib.env.ie); + break; + } + } + } + }, + inspector:{ + enabled:false, + el:null, + inspect:function(_element,_bgInspector){ + with(firebug){ + var pos = (env.isPopup && window.opener.firebug || window.firebug).lib.util.Element.getPosition(_element); + + (env.isPopup && window.opener.firebug || window.firebug).el[_bgInspector&&"bgInspector"||"borderInspector"].environment.addStyle({ + "width":_element.offsetWidth+"px", "height":_element.offsetHeight+"px", + "top":pos.offsetTop-(_bgInspector?0:2)+"px", "left":pos.offsetLeft-(_bgInspector?0:2)+"px", + "display":"block" + }); + + if(!_bgInspector){ + d.inspector.el = _element; + } + }; + }, + toggle:function(_absoluteValue,_event){ + with (firebug) { + if(_absoluteValue==d.inspector.enabled) + return; + d.inspector.enabled = _absoluteValue!=undefined&&!_absoluteValue.clientX?_absoluteValue:!d.inspector.enabled; + el.button.inspect.attribute[(d.inspector.enabled ? "add" : "remove") + "Class"]("Enabled"); + if(d.inspector.enabled==false){ + el.borderInspector.environment.addStyle({ "display":"none" }); + d.inspector.el = null; + } else if(lib.env.dIndex!="html") { + if (env.popupWin) { + env.popupWin.firebug.d.navigate("html"); + } else { + d.navigate("html"); + } + } + } + } + }, + scripts:{ + index:-1, + lineNumbers:false, + open:function(_index){ + with(firebug){ + d.scripts.index = _index; + el.left.scripts.container.update(""); + var script = document.getElementsByTagName("script")[_index],uri = script.src||document.location.href,source,dmn=getDomain(uri); + + if(uri.indexOf("http:\/\/")>-1&&dmn!=document.domain&&"www."+dmn!=document.domain){ + el.left.scripts.container.update("Access to restricted URI denied"); + return; + } + + if(uri!=document.location.href){ + source = env.cache[uri]||lib.xhr.get(uri).responseText; + env.cache[uri] = source; + } else + source = script.innerHTML; + source = source.replace(/\n|\t|<|>/g,function(_ch){ + return ({"<":"<",">":">","\t":"        ","\n":"
"})[_ch]; + }); + + if (!d.scripts.lineNumbers) + el.left.scripts.container.child.add( + new lib.element("DIV").attribute.addClass("CodeContainer").update(source) + ); + else { + source = source.split("
"); + for (var i = 0; i < source.length; i++) { + el.left.scripts.container.child.add(new lib.element("DIV").child.add(new lib.element("DIV").attribute.addClass("LineNumber").update(i + 1), new lib.element("DIV").attribute.addClass("Code").update(" " + source[i]), new lib.element("DIV").attribute.addClass('Clear'))); + }; + }; + } + }, + toggleLineNumbers:function(){ + with(firebug){ + d.scripts.lineNumbers = !d.scripts.lineNumbers; + el.button.scripts.lineNumbers.attribute[(d.scripts.lineNumbers ? "add" : "remove") + "Class"]("Enabled"); + d.scripts.open( d.scripts.index ); + } + }, + refresh:function(){ + with(firebug){ + el.button.scripts.selectbox.clean(); + var collection = (env.isPopup&&window.parent||window).document.getElementsByTagName("script"); + for(var i=0,len=collection.length; i")) + } + } + }, + xhr:{ + objects:[], + addObject:function(){ + with(firebug){ + for(var i=0,len=arguments.length; i0&&_object[0]!=undefined&&_object[len-1]!=undefined){ + return true; + } else { + for(var key in _object){ + if(key!="item"&&key!="length"&&key!="setNamedItemNS"&&key!="setNamedItem"&&key!="getNamedItem"&&key!="removeNamedItem"&&key!="getNamedItemNS"&&key!="removeNamedItemNS"&&key!="tags"){ + return false; + } + } + return true + }; + }, + IsHash:function(_object){ + return _object && typeof _object=="object"&&(_object==window||_object instanceof Object)&&!_object.nodeName&&!pi.util.IsArray(_object) + }, + Init:[], + AddEvent: function(_element,_eventName,_fn,_useCapture){ + _element[pi.env.ie?"attachEvent":"addEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false); + return pi.util.Curry(pi.util.AddEvent,this,_element); + }, + RemoveEvent: function(_element,_eventName,_fn,_useCapture){ + _element[pi.env.ie?"detachEvent":"removeEventListener"]((pi.env.ie?"on":"")+_eventName,_fn,_useCapture||false); + return pi.util.Curry(pi.util.RemoveEvent,this,_element); + }, + Element:{ + addClass:function(_element,_class){ + if( !pi.util.Element.hasClass(_element,_class) ) + pi.util.Element.setClass(_element, pi.util.Element.getClass(_element) + " " + _class ); + }, + getClass:function(_element){ + return _element.getAttribute(pi.env.ie?"className":"class")||""; + }, + hasClass:function(_element,_class){ + return pi.util.Array.indexOf(pi.util.Element.getClass(_element).split(" "),_class)>-1; + }, + removeClass:function(_element,_class){ + if( pi.util.Element.hasClass(_element,_class) ){ + var names = pi.util.Element.getClass(_element,_class).split(" "); + pi.util.Element.setClass( + _element, + pi.util.Array.remove(names,pi.util.Array.indexOf(names,_class)).join(" ") + ); + } + }, + setClass:function(_element,_value){ + _element.setAttribute(pi.env.ie?"className":"class", _value ); + }, + toggleClass:function(){ + if(pi.util.Element.hasClass.apply(this,arguments)) + pi.util.Element.removeClass.apply(this,arguments); + else + pi.util.Element.addClass.apply(this,arguments); + }, + getOpacity:function(_styleObject){ + var styleObject = _styleObject; + if(!pi.env.ie) + return styleObject["opacity"]; + + var alpha = styleObject["filter"].match(/opacity\=(\d+)/i); + return alpha?alpha[1]/100:1; + }, + setOpacity:function(_element,_value){ + if(!pi.env.ie) + return pi.util.Element.addStyle(_element,{ "opacity":_value }); + _value*=100; + pi.util.Element.addStyle(_element,{ "filter":"alpha(opacity="+_value+")" }); + return this._parent_; + }, + getPosition:function(_element){ + var parent = _element,offsetLeft = document.body.offsetLeft, offsetTop = document.body.offsetTop, view = pi.util.Element.getView(_element); + while(parent&&parent!=document.body&&parent!=document.firstChild){ + offsetLeft +=parseInt(parent.offsetLeft); + offsetTop += parseInt(parent.offsetTop); + parent = parent.offsetParent; + }; + return { + "bottom":view["bottom"], + "clientLeft":_element.clientLeft, + "clientTop":_element.clientTop, + "left":view["left"], + "marginTop":view["marginTop"], + "marginLeft":view["marginLeft"], + "offsetLeft":offsetLeft, + "offsetTop":offsetTop, + "position":view["position"], + "right":view["right"], + "top":view["top"], + "zIndex":view["zIndex"] + }; + }, + getSize:function(_element){ + var view = pi.util.Element.getView(_element); + return { + "height":view["height"], + "clientHeight":_element.clientHeight, + "clientWidth":_element.clientWidth, + "offsetHeight":_element.offsetHeight, + "offsetWidth":_element.offsetWidth, + "width":view["width"] + } + }, + addStyle:function(_element,_style){ + for(var key in _style){ + key = key=="float"?pi.env.ie?"styleFloat":"cssFloat":key; + if (key == "opacity" && pi.env.ie) { + pi.util.Element.setOpacity(_element,_style[key]); + continue; + } + try { + _element.style[key] = _style[key]; + }catch(e){} + } + }, + getStyle:function(_element,_property){ + _property = _property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property; + if(_property=="opacity"&&pi.env.ie) + return pi.util.Element.getOpacity(_element.style); + return typeof _property=="string"?_element.style[_property]:_element.style; + }, + getValue:function(_element){ + switch(_element.nodeName.toLowerCase()){ + case "input": + case "textarea": + return _element.value; + case "select": + return _element.options[_element.selectedIndex].value; + default: + return _element.innerHTML; + break; + } + }, + getView:function(_element,_property){ + var view = document.defaultView?document.defaultView.getComputedStyle(_element,null):_element.currentStyle; + _property = _property=="float"?pi.env.ie?"styleFloat":"cssFloat":_property; + if(_property=="opacity"&&pi.env.ie) + return pi.util.Element.getOpacity(_element,view); + return typeof _property=="string"?view[_property]:view; + } + }, + Hash: { + clone:function(_hash,_undeep){ + var tmp = {}; + for(var key in _hash){ + if( !_undeep&&pi.util.IsArray( _hash[key] ) ){ + tmp[key] = pi.util.Array.clone( _hash[key] ); + } else if( !_undeep&&pi.util.IsHash( _hash[key] ) ){ + tmp[ key ] = pi.util.Hash.clone(_hash[key]); + } else { + tmp[key] = _hash[key]; + } + } + return tmp; + }, + merge:function(_hash,_source,_undeep){ + for(var key in _source){ + var value = _source[key]; + if (!_undeep&&pi.util.IsArray(_source[key])) { + if(pi.util.IsArray( _hash[key] )){ + Array.prototype.push.apply( _source[key], _hash[key] ) + } + else + value = pi.util.Array.clone(_source[key]); + } + else if (!_undeep&&pi.util.IsHash(_source[key])) { + if (pi.util.IsHash(_hash[key])) { + value = pi.util.Hash.merge(_hash[key], _source[key]); + } else { + value = pi.util.Hash.clone( _source[key] ); + } + } else if( _hash[key] ) + value = _hash[ key ]; + _hash[key] = value; + }; + return _hash; + } + }, + String:{ + format:function(_str){ + var values = Array.prototype.slice.call(arguments,1); + return _str.replace(/\{(\d)\}/g,function(){ + return values[arguments[1]]; + }) + } + }, + GetViewport:function(){ + return { + height:document.documentElement.clientHeight||document.body.clientHeight, + width:document.documentElement.clientWidth||document.body.clientWidth + } + } + }; + + pi.base = function(){ + this.body = {}; + this.init = null; + + this.build = function(_skipClonning){ + var base = this, skipClonning = _skipClonning||false, _private = {}, + fn = function(){ + var _p = pi.util.Hash.clone(_private); + if(!skipClonning){ + for(var key in this){ + if(pi.util.IsArray( this[ key ] ) ){ + this[key] = pi.util.Array.clone( this[key] ); + } else + if( pi.util.IsHash(this[key]) ){ + this[key] = pi.util.Hash.clone( + this[ key ], + function(_key,_object){ + this[ _key ]._parent_ = this; + } + ); + //this[key]._parent_ = this; + } + } + }; + base.createAccessors( _p, this ); + if(base.init) + return base.init.apply(this,arguments); + return this; + }; + this.movePrivateMembers(this.body,_private); + if(this.init){ + fn["$Init"] = this.init; + }; + fn.prototype = this.body; + return fn; + }; + + this.createAccessors = function(_p, _branch){ + var getter = function(_property){ return this[_property]; }, + setter = function(_property,_value){ this[_property] = _value; return _branch._parent_||_branch; }; + + for (var name in _p) { + var isPrivate = name.substring(0, 1) == "_", title = name.substring(1, 2).toUpperCase() + name.substring(2); + + if (isPrivate) { + _branch[(_branch["get" + title]?"_":"")+"get" + title] = pi.util.Curry(getter,_p,name); + _branch[(_branch["set" + title]?"_":"")+"set" + title] = pi.util.Curry(setter,_p,name); + } + else + if (pi.util.IsHash(_p[name])){ + _branch[name]._parent_ = _branch; + if(!_branch[name]) + _branch[name] = {}; + this.createAccessors(_p[name], _branch[name]); + } + }; + }; + + this.movePrivateMembers = function(_object, _branch){ + for (var name in _object) { + var isPrivate = name.substring(0, 1) == "_"; + + if (isPrivate) { + _branch[name] = _object[name]; + delete _object[name]; + } + else + if (pi.util.IsHash(_object[name])){ + _branch[name] = {}; + this.movePrivateMembers(_object[name], _branch[name]); + } + }; + }; + }; + + pi.element = new pi.base; + pi.element.init = function(_val){ + this.environment.setElement( + typeof _val=="string"||!_val? + document.createElement(_val||"DIV"): + _val + ); + return this; + }; + + pi.element.body = { + "addStyle":function(){ + return this.environment.addStyle.apply(this.environment,arguments); + }, + "clean":function(){ + var childs = this.child.get(); + while(childs.length){ + childs[0].parentNode.removeChild(childs[0]); + } + }, + "clone":function(_deep){ + return this.environment.getElement().cloneNode(_deep); + }, + "insert":function(_element){ + _element = _element.environment?_element.environment.getElement():_element; + _element.appendChild(this.environment.getElement()); + return this; + }, + "insertAfter":function(_referenceElement){ _referenceElement = _referenceElement.environment?_referenceElement.environment.getElement():_referenceElement; + _referenceElement.nextSibling?this.insertBefore(_referenceElement.nextSibling):this.insert(_referenceElement.parentNode); + return this; + }, + "insertBefore":function(_referenceElement){ + _referenceElement = _referenceElement.environment?_referenceElement.environment.getElement():_referenceElement; + _referenceElement.parentNode.insertBefore(this.environment.getElement(),_referenceElement); + return this; + }, + "query":function(_expression,_resultType,namespaceResolver,_result){ + return pi.xpath(_expression,_resultType||"ORDERED_NODE_SNAPSHOT_TYPE",this.environment.getElement(),_namespaceResolver,_result); + }, + "remove":function(){ + if (this.environment.getParent()) { + this.environment.getParent().removeChild(this.environment.getElement()); + } + }, + "update":function(_value){ + this.element[this.element.nodeName.toLowerCase()=="textarea"||this.element.nodeName.toLowerCase()=="input"?"value":"innerHTML"]=_value; + return this; + }, + "attribute":{ + "getAll":function(){ + return this._parent_.environment.getElement().attributes; + }, + "clear":function(_name){ + this.set(_name,""); + return this._parent_; + }, + "get":function(_name){ + return this._parent_.environment.getElement().getAttribute(_name); + }, + "has":function(_name){ + return pi.env.ie?(this.get(_name)!=null):this._parent_.environment.getElement().hasAttribute(_name); + }, + "remove":function(_name){ + this._parent_.environment.getElement().removeAttribute(_name); + return this._parent_; + }, + "set":function(_name,_value){ + this._parent_.environment.getElement().setAttribute(_name,_value); + return this._parent_; + }, + "addClass":function(_classes){ + for(var i=0,len=arguments.length; i-1){ + callback[i].fn.apply(this); + } + } + } + }; + pi.xhr = pi.xhr.build(); + + /* + * xml.xhr.get + */ + + pi.xhr.get = function(_url,_returnPiObject){ + var request = new pi.xhr(); + request.environment.setAsync(false); + request.environment.setUrl(_url); + request.send(); + return _returnPiObject?request:request.environment.getApi(); + }; + + /* + * registering onload event for init functions + */ + pi.util.AddEvent( + pi.env.ie?window:document, + pi.env.ie?"load":"DOMContentLoaded", + function(){ + for(var i=0,len=pi.util.Init.length; i)[^>]*$|^#([\w-]+)$/, + // Is it a simple selector + isSimple = /^.[^:#\[\.,]*$/; + +jQuery.fn = jQuery.prototype = { + init: function( selector, context ) { + // Make sure that a selection was provided + selector = selector || document; + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this[0] = selector; + this.length = 1; + this.context = selector; + return this; + } + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + var match = quickExpr.exec( selector ); + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) + selector = jQuery.clean( [ match[1] ], context ); + + // HANDLE: $("#id") + else { + var elem = document.getElementById( match[3] ); + + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem && elem.id != match[3] ) + return jQuery().find( selector ); + + // Otherwise, we inject the element directly into the jQuery object + var ret = jQuery( elem || [] ); + ret.context = document; + ret.selector = selector; + return ret; + } + + // HANDLE: $(expr, [context]) + // (which is just equivalent to: $(content).find(expr) + } else + return jQuery( context ).find( selector ); + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) + return jQuery( document ).ready( selector ); + + // Make sure that old selector state is passed along + if ( selector.selector && selector.context ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return this.setArray(jQuery.isArray( selector ) ? + selector : + jQuery.makeArray(selector)); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.3.2", + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num === undefined ? + + // Return a 'clean' array + Array.prototype.slice.call( this ) : + + // Return just the object + this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = jQuery( elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) + ret.selector = this.selector + (this.selector ? " " : "") + selector; + else if ( name ) + ret.selector = this.selector + "." + name + "(" + selector + ")"; + + // Return the newly-formed element set + return ret; + }, + + // Force the current matched set of elements to become + // the specified array of elements (destroying the stack in the process) + // You should use pushStack() in order to do this, but maintain the stack + setArray: function( elems ) { + // Resetting the length to 0, then using the native Array push + // is a super-fast way to populate an object with array-like properties + this.length = 0; + Array.prototype.push.apply( this, elems ); + + return this; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem && elem.jquery ? elem[0] : elem + , this ); + }, + + attr: function( name, value, type ) { + var options = name; + + // Look for the case where we're accessing a style value + if ( typeof name === "string" ) + if ( value === undefined ) + return this[0] && jQuery[ type || "attr" ]( this[0], name ); + + else { + options = {}; + options[ name ] = value; + } + + // Check to see if we're setting style values + return this.each(function(i){ + // Set all the styles + for ( name in options ) + jQuery.attr( + type ? + this.style : + this, + name, jQuery.prop( this, options[ name ], type, i, name ) + ); + }); + }, + + css: function( key, value ) { + // ignore negative width and height values + if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) + value = undefined; + return this.attr( key, value, "curCSS" ); + }, + + text: function( text ) { + if ( typeof text !== "object" && text != null ) + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); + + var ret = ""; + + jQuery.each( text || this, function(){ + jQuery.each( this.childNodes, function(){ + if ( this.nodeType != 8 ) + ret += this.nodeType != 1 ? + this.nodeValue : + jQuery.fn.text( [ this ] ); + }); + }); + + return ret; + }, + + wrapAll: function( html ) { + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).clone(); + + if ( this[0].parentNode ) + wrap.insertBefore( this[0] ); + + wrap.map(function(){ + var elem = this; + + while ( elem.firstChild ) + elem = elem.firstChild; + + return elem; + }).append(this); + } + + return this; + }, + + wrapInner: function( html ) { + return this.each(function(){ + jQuery( this ).contents().wrapAll( html ); + }); + }, + + wrap: function( html ) { + return this.each(function(){ + jQuery( this ).wrapAll( html ); + }); + }, + + append: function() { + return this.domManip(arguments, true, function(elem){ + if (this.nodeType == 1) + this.appendChild( elem ); + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function(elem){ + if (this.nodeType == 1) + this.insertBefore( elem, this.firstChild ); + }); + }, + + before: function() { + return this.domManip(arguments, false, function(elem){ + this.parentNode.insertBefore( elem, this ); + }); + }, + + after: function() { + return this.domManip(arguments, false, function(elem){ + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + }, + + end: function() { + return this.prevObject || jQuery( [] ); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: [].push, + sort: [].sort, + splice: [].splice, + + find: function( selector ) { + if ( this.length === 1 ) { + var ret = this.pushStack( [], "find", selector ); + ret.length = 0; + jQuery.find( selector, this[0], ret ); + return ret; + } else { + return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){ + return jQuery.find( selector, elem ); + })), "find", selector ); + } + }, + + clone: function( events ) { + // Do the clone + var ret = this.map(function(){ + if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { + // IE copies events bound via attachEvent when + // using cloneNode. Calling detachEvent on the + // clone will also remove the events from the orignal + // In order to get around this, we use innerHTML. + // Unfortunately, this means some modifications to + // attributes in IE that are actually only stored + // as properties will not be copied (such as the + // the name attribute on an input). + var html = this.outerHTML; + if ( !html ) { + var div = this.ownerDocument.createElement("div"); + div.appendChild( this.cloneNode(true) ); + html = div.innerHTML; + } + + return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0]; + } else + return this.cloneNode(true); + }); + + // Copy the events from the original to the clone + if ( events === true ) { + var orig = this.find("*").andSelf(), i = 0; + + ret.find("*").andSelf().each(function(){ + if ( this.nodeName !== orig[i].nodeName ) + return; + + var events = jQuery.data( orig[i], "events" ); + + for ( var type in events ) { + for ( var handler in events[ type ] ) { + jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); + } + } + + i++; + }); + } + + // Return the cloned set + return ret; + }, + + filter: function( selector ) { + return this.pushStack( + jQuery.isFunction( selector ) && + jQuery.grep(this, function(elem, i){ + return selector.call( elem, i ); + }) || + + jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ + return elem.nodeType === 1; + }) ), "filter", selector ); + }, + + closest: function( selector ) { + var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null, + closer = 0; + + return this.map(function(){ + var cur = this; + while ( cur && cur.ownerDocument ) { + if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) { + jQuery.data(cur, "closest", closer); + return cur; + } + cur = cur.parentNode; + closer++; + } + }); + }, + + not: function( selector ) { + if ( typeof selector === "string" ) + // test special case where just one selector is passed in + if ( isSimple.test( selector ) ) + return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); + else + selector = jQuery.multiFilter( selector, this ); + + var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; + return this.filter(function() { + return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; + }); + }, + + add: function( selector ) { + return this.pushStack( jQuery.unique( jQuery.merge( + this.get(), + typeof selector === "string" ? + jQuery( selector ) : + jQuery.makeArray( selector ) + ))); + }, + + is: function( selector ) { + return !!selector && jQuery.multiFilter( selector, this ).length > 0; + }, + + hasClass: function( selector ) { + return !!selector && this.is( "." + selector ); + }, + + val: function( value ) { + if ( value === undefined ) { + var elem = this[0]; + + if ( elem ) { + if( jQuery.nodeName( elem, 'option' ) ) + return (elem.attributes.value || {}).specified ? elem.value : elem.text; + + // We need to handle select boxes special + if ( jQuery.nodeName( elem, "select" ) ) { + var index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type == "select-one"; + + // Nothing was selected + if ( index < 0 ) + return null; + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + if ( option.selected ) { + // Get the specifc value for the option + value = jQuery(option).val(); + + // We don't need an array for one selects + if ( one ) + return value; + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + } + + // Everything else, we just grab the value + return (elem.value || "").replace(/\r/g, ""); + + } + + return undefined; + } + + if ( typeof value === "number" ) + value += ''; + + return this.each(function(){ + if ( this.nodeType != 1 ) + return; + + if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) + this.checked = (jQuery.inArray(this.value, value) >= 0 || + jQuery.inArray(this.name, value) >= 0); + + else if ( jQuery.nodeName( this, "select" ) ) { + var values = jQuery.makeArray(value); + + jQuery( "option", this ).each(function(){ + this.selected = (jQuery.inArray( this.value, values ) >= 0 || + jQuery.inArray( this.text, values ) >= 0); + }); + + if ( !values.length ) + this.selectedIndex = -1; + + } else + this.value = value; + }); + }, + + html: function( value ) { + return value === undefined ? + (this[0] ? + this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : + null) : + this.empty().append( value ); + }, + + replaceWith: function( value ) { + return this.after( value ).remove(); + }, + + eq: function( i ) { + return this.slice( i, +i + 1 ); + }, + + slice: function() { + return this.pushStack( Array.prototype.slice.apply( this, arguments ), + "slice", Array.prototype.slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function(elem, i){ + return callback.call( elem, i, elem ); + })); + }, + + andSelf: function() { + return this.add( this.prevObject ); + }, + + domManip: function( args, table, callback ) { + if ( this[0] ) { + var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), + scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), + first = fragment.firstChild; + + if ( first ) + for ( var i = 0, l = this.length; i < l; i++ ) + callback.call( root(this[i], first), this.length > 1 || i > 0 ? + fragment.cloneNode(true) : fragment ); + + if ( scripts ) + jQuery.each( scripts, evalScript ); + } + + return this; + + function root( elem, cur ) { + return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? + (elem.getElementsByTagName("tbody")[0] || + elem.appendChild(elem.ownerDocument.createElement("tbody"))) : + elem; + } + } +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +function evalScript( i, elem ) { + if ( elem.src ) + jQuery.ajax({ + url: elem.src, + async: false, + dataType: "script" + }); + + else + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); + + if ( elem.parentNode ) + elem.parentNode.removeChild( elem ); +} + +function now(){ + return +new Date; +} + +jQuery.extend = jQuery.fn.extend = function() { + // copy reference to target object + var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) + target = {}; + + // extend jQuery itself if only one argument is passed + if ( length == i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) + // Extend the base object + for ( var name in options ) { + var src = target[ name ], copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) + continue; + + // Recurse if we're merging object values + if ( deep && copy && typeof copy === "object" && !copy.nodeType ) + target[ name ] = jQuery.extend( deep, + // Never move original objects, clone them + src || ( copy.length != null ? [ ] : { } ) + , copy ); + + // Don't bring in undefined values + else if ( copy !== undefined ) + target[ name ] = copy; + + } + + // Return the modified object + return target; +}; + +// exclude the following css properties to add px +var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, + // cache defaultView + defaultView = document.defaultView || {}, + toString = Object.prototype.toString; + +jQuery.extend({ + noConflict: function( deep ) { + window.$ = _$; + + if ( deep ) + window.jQuery = _jQuery; + + return jQuery; + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return toString.call(obj) === "[object Function]"; + }, + + isArray: function( obj ) { + return toString.call(obj) === "[object Array]"; + }, + + // check if an element is in a (or is an) XML document + isXMLDoc: function( elem ) { + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || + !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument ); + }, + + // Evalulates a script in a global context + globalEval: function( data ) { + if ( data && /\S/.test(data) ) { + // Inspired by code by Andrea Giammarchi + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html + var head = document.getElementsByTagName("head")[0] || document.documentElement, + script = document.createElement("script"); + + script.type = "text/javascript"; + if ( jQuery.support.scriptEval ) + script.appendChild( document.createTextNode( data ) ); + else + script.text = data; + + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709). + head.insertBefore( script, head.firstChild ); + head.removeChild( script ); + } + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, length = object.length; + + if ( args ) { + if ( length === undefined ) { + for ( name in object ) + if ( callback.apply( object[ name ], args ) === false ) + break; + } else + for ( ; i < length; ) + if ( callback.apply( object[ i++ ], args ) === false ) + break; + + // A special, fast, case for the most common use of each + } else { + if ( length === undefined ) { + for ( name in object ) + if ( callback.call( object[ name ], name, object[ name ] ) === false ) + break; + } else + for ( var value = object[0]; + i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} + } + + return object; + }, + + prop: function( elem, value, type, i, name ) { + // Handle executable functions + if ( jQuery.isFunction( value ) ) + value = value.call( elem, i ); + + // Handle passing in a number to a CSS property + return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ? + value + "px" : + value; + }, + + className: { + // internal only, use addClass("class") + add: function( elem, classNames ) { + jQuery.each((classNames || "").split(/\s+/), function(i, className){ + if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) + elem.className += (elem.className ? " " : "") + className; + }); + }, + + // internal only, use removeClass("class") + remove: function( elem, classNames ) { + if (elem.nodeType == 1) + elem.className = classNames !== undefined ? + jQuery.grep(elem.className.split(/\s+/), function(className){ + return !jQuery.className.has( classNames, className ); + }).join(" ") : + ""; + }, + + // internal only, use hasClass("class") + has: function( elem, className ) { + return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; + } + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var old = {}; + // Remember the old values, and insert the new ones + for ( var name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + callback.call( elem ); + + // Revert the old values + for ( var name in options ) + elem.style[ name ] = old[ name ]; + }, + + css: function( elem, name, force, extra ) { + if ( name == "width" || name == "height" ) { + var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; + + function getWH() { + val = name == "width" ? elem.offsetWidth : elem.offsetHeight; + + if ( extra === "border" ) + return; + + jQuery.each( which, function() { + if ( !extra ) + val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; + if ( extra === "margin" ) + val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; + else + val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; + }); + } + + if ( elem.offsetWidth !== 0 ) + getWH(); + else + jQuery.swap( elem, props, getWH ); + + return Math.max(0, Math.round(val)); + } + + return jQuery.curCSS( elem, name, force ); + }, + + curCSS: function( elem, name, force ) { + var ret, style = elem.style; + + // We need to handle opacity special in IE + if ( name == "opacity" && !jQuery.support.opacity ) { + ret = jQuery.attr( style, "opacity" ); + + return ret == "" ? + "1" : + ret; + } + + // Make sure we're using the right name for getting the float value + if ( name.match( /float/i ) ) + name = styleFloat; + + if ( !force && style && style[ name ] ) + ret = style[ name ]; + + else if ( defaultView.getComputedStyle ) { + + // Only "float" is needed here + if ( name.match( /float/i ) ) + name = "float"; + + name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); + + var computedStyle = defaultView.getComputedStyle( elem, null ); + + if ( computedStyle ) + ret = computedStyle.getPropertyValue( name ); + + // We should always get a number back from opacity + if ( name == "opacity" && ret == "" ) + ret = "1"; + + } else if ( elem.currentStyle ) { + var camelCase = name.replace(/\-(\w)/g, function(all, letter){ + return letter.toUpperCase(); + }); + + ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { + // Remember the original values + var left = style.left, rsLeft = elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + elem.runtimeStyle.left = elem.currentStyle.left; + style.left = ret || 0; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + elem.runtimeStyle.left = rsLeft; + } + } + + return ret; + }, + + clean: function( elems, context, fragment ) { + context = context || document; + + // !context.createElement fails in IE with an error but returns typeof 'object' + if ( typeof context.createElement === "undefined" ) + context = context.ownerDocument || context[0] && context[0].ownerDocument || document; + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { + var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); + if ( match ) + return [ context.createElement( match[1] ) ]; + } + + var ret = [], scripts = [], div = context.createElement("div"); + + jQuery.each(elems, function(i, elem){ + if ( typeof elem === "number" ) + elem += ''; + + if ( !elem ) + return; + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ + return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? + all : + front + ">"; + }); + + // Trim whitespace, otherwise indexOf won't work as expected + var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); + + var wrap = + // option or optgroup + !tags.indexOf("", "" ] || + + !tags.indexOf("", "" ] || + + tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && + [ 1, "", "
" ] || + + !tags.indexOf("", "" ] || + + // matched above + (!tags.indexOf("", "" ] || + + !tags.indexOf("", "" ] || + + // IE can't serialize and - - + + - + diff --git a/example2-formatters.html b/example2-formatters.html index 96cf7a9..b97512a 100644 --- a/example2-formatters.html +++ b/example2-formatters.html @@ -18,10 +18,10 @@ - - + + - + diff --git a/example3-editing.html b/example3-editing.html index cbd01ba..4a29d88 100644 --- a/example3-editing.html +++ b/example3-editing.html @@ -18,10 +18,10 @@ - - + + - + diff --git a/grid.html b/grid.html index 5098216..76af94e 100644 --- a/grid.html +++ b/grid.html @@ -78,10 +78,10 @@ - - + + - + diff --git a/images/listview.gif b/images/listview.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ec25ca71979f1e2f0632060d8a295b5c668cb4b GIT binary patch literal 2380 zcmZ{i`BRz)0*2WnD~?ge>7lNssco}rj5ThWQEM{YY!5{Q>SQ|VnAEyyN39y;q#3m) z+qF5=D56QMST%|#2nZ+&h!=Fk=Dh+6hOiQYPg;Ed3mv|v$zM)-Zb(Gu~48X8JAIPvHsN_WdkL`{NYU<;}L?q zs$0sXqq^oP|8=JDN z?Va7d{jHC{N|jo3sMYBWMw8iMwb>ocqvI17=(NW<2n93o#Qp8C+gwW9RJqSb&}K+q z`%IPpCpl}}z79@J&=-~G68bxNFE04FaJPB=T>^CE_x$DrYPYZ{<|pMEkBSwy-gx5i z9&`XV*8zDI_AP&)X91hk0euY}#4iz2sX6QXL4t&wF;)3qB8~W_&n*=9t$^0MN-x;q zzfPo+)`yFY%5?#qyg6Qa`s{fagR(VM@%E*3fYGbCusO2cLNxr%Eg#3 zs?Nii0|)bGZxYgl%t4ie^1Yx1K1|cBGJaBR2#4v~P1cjM?;}PS`W^18OW%n`hK%yr zj>J~PDATN3q2_LiMu)9h*;Lj0Uyoh4yDJt5--*XYomSnBp!MtVv16yrsM-{dkN?q! zTd1t`jBmE=SNC9?%=OqaN+EmV6BoMm^qu7Ft!Mt3xUI5tg^I26pt8{IiVGuk{!B(yt{nGcx-4~GHp52$QsDs^CNpTnV z>b^<-aqqX(%$~ja+l2>v=!~+9`we%3GxmSa?(W%d%%dIbHx;li%9|f7|0sW5yx${l zd1N_|x0bqvDKJlca};eA!FWYGGD@lFsErFd=&Vc5Ip}K0#2<7w7b*|1n6j`OoM&B* zvIp0VSK^5@rIJ8lhpC7I%Q>oE#y(y}8nGx5L&`;vCVw4AFQwe1tMV@DR1 zb{qr_*Rjs{<>@BeLx{Rb&uF!7$|pWtKmATho_@wZi>POxD^lw@LH`Y(;9fxI8F-;s zqJbYyR~rP8oNyy>Rgz~E#>k0A(RHiZD82#y*fjg4-(AxjB&63g4~y2A7LwvWHZOjY za@V|+n$>GwzFnj-OVa-tWLfzEeb@3P8{2D<=Fv5l)dJ4P*0l$cyVmt$d9QWjkyT^e zECol{WKaF_ZCe!~B-=JJ`p~vh8y{ictxL(b?=@tR?EB3{hd;}`pGG)bicWOC;{b;x zIg~{Dp+iOCL^#z0l6Yj$e z+B{OYlfF#dvq)r{XBK2CK&mT?0ouHaxKrmHy7C*I?LOs@=???+6%bhaTWIcdaIF4$ z60-drEMz7uO<$P`wENO=GakkIstnH#e-4E0y3(jeX2UuHBwThBQ(s+x>^LWfaAKu; zR58$T-pb{C=Fr!adUghZ6S$uT7-}nEogez~xN)(D7q!UF3n2+SXqw?=1JD^9&Ep|T z46iVrU7_&_{F{x2IvlJkEQQBUW*UB@AiKh|5(H^dLp=lNiYVd<(j5jg%dW0TAi8^cKu-ETBDD`41I2~SkW zG``j$vDf7Z;u5K`#RgzMv+~5hIE<|zFWe1q82=ysCX72A_qiW`wk+1v=2MOPG6XtT znPzJD7vkcg`E#fem&v2sy$2ExoqySA>I{YVKvVeh^-NP&WOWZL3%bxKHFd`bdxAw1 z3oQ;4_J$WesT{i49$>~n;P{(p{$h8mxhJU_{|y$pbhmjIpDM&B)A>uJ5;Gygi;&8J zF84Q@iP>;MnuNbhW14#dKdrhghf0`IGpSfeNVoDOV-7R9)Qgw_PF$G`uuv-C#5?r+ zjqF%UUu`wg0&OgJ1m&?GAalEBoA5#Dx~9L{^0;N2^cPXeqJb^%hqkF8@4kw7*!EjZw&_qr zUu6n#C-<3pCKA<$%!2I%tlHQyqCQj+uyfvNuPuk|ei&%yzI(dqB^uZbzGmko zq5A8vu)VNbc7Cd;zn%{4MLe_%GQ6n`J(i&>O?Ds~L2Z-(`%%MoVF8NTEQiTsSM8!= z5w*n%$Upm9^sv->00V|AJ`Z%vRv-r2{e+6RYmT{E6mOt21bzU$<(O}%PX|W}4-gL> z3mES~Ts&NPv&pfDLk!|mgv#V$#}WlKNX&ZgUlCHrGD9>-DiW&Foel}hn?@;ztM3Fl zSGWjTKU%2HycSq_rkXZ@g==zdIi)Ki8jUX0pGM*FxndmMNqbLVvZZT7XU?Ap)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); +/* + * Sizzle CSS Selector Engine - v0.9.3 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file From 3b0d7d975545d8e19d36acaa0fddca76c4b83521 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Sun, 8 Mar 2009 23:52:21 +0000 Subject: [PATCH 0006/1043] From 315794105aa9a6389344c7a094c5f00cea5d23df Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Sun, 8 Mar 2009 23:53:59 +0000 Subject: [PATCH 0007/1043] From 642d39bd7459fa01213c0d8facefbb9916063c29 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 9 Mar 2009 00:27:36 +0000 Subject: [PATCH 0008/1043] --- slick.grid.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index 55a3453..3f59454 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -2,8 +2,6 @@ * * (c) 2009 Michael Leibman (michael.leibman@gmail.com) * All rights reserved. - * You are not allowed to use this code in any way shape or form without the express written authorization by the author. - * * * * TODO: From 3e9757824c1b5b6bd770d17acf4bb0fd6ab03b63 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 9 Mar 2009 00:43:01 +0000 Subject: [PATCH 0009/1043] --- images/pencil.gif | Bin 0 -> 914 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/pencil.gif diff --git a/images/pencil.gif b/images/pencil.gif new file mode 100644 index 0000000000000000000000000000000000000000..29f78f433d0924b4ba58baf95a26403ee959388a GIT binary patch literal 914 zcmZ?wbhEHb&N*bUuz`Z)T=HlYuZ}Y zeygzWRpG1!El$hZvwt_r|DUA)f2P^*T~hxSS{;~Hd~tr+?PVcn7nJ|s>;C_U{Qs+x z|L@EFzbF6WpvwOv`u|U<{6DMo|De(TQ%3)-*Q=zkmP#{rBIW-~a#rXBY*eApi>j9S{SQ7Z^Co85VNLyhu55pgBO~OvC~f z#cpY{ECY**BaPhhCQ>pg29KJ!Bn{a9%_wkcX=G%c&GEuP=}@Brb9|1$N5+HAjczst z8j1@KOm5T;TJVE`@%RBbMU#dF2@eyvm28Yu5{d%cC(23`Dey2XaN<#PIHVNGq{?}y Jk&%(X8US2;)^z{? literal 0 HcmV?d00001 From 5fc53338e8d45b477d8a3edd43eea2fda100ca6b Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 9 Mar 2009 00:45:20 +0000 Subject: [PATCH 0010/1043] From b8b4543b998f93b9eb1d3dcd96a4f3e4326e4c8f Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 9 Mar 2009 00:46:52 +0000 Subject: [PATCH 0011/1043] From be899e2dcf339ee57a409ed0c6e1a31a54edae21 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 9 Mar 2009 02:25:11 +0000 Subject: [PATCH 0012/1043] --- example2-formatters.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example2-formatters.html b/example2-formatters.html index b97512a..5ce6350 100644 --- a/example2-formatters.html +++ b/example2-formatters.html @@ -19,7 +19,7 @@ - + From 62fe5fcacada8a699ad079b2ac10afbedcaae6f2 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Tue, 17 Mar 2009 02:56:33 +0000 Subject: [PATCH 0013/1043] --- example4-model.html | 198 ++++++++++++++++++++++++++++++++++++++++++++ slick.grid.js | 9 +- slick.model.js | 147 ++++++++++++++++++++++++++++++++ 3 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 example4-model.html create mode 100644 slick.model.js diff --git a/example4-model.html b/example4-model.html new file mode 100644 index 0000000..16bb318 --- /dev/null +++ b/example4-model.html @@ -0,0 +1,198 @@ + + + + + SlickGrid example + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+
+ +
+ + + + +
+ + +
+ +
+ +
+
+

Demonstrates:

+ +
    +
  • a filtered Model (DataView) as a data source instead of a simple array
  • +
  • grid reacting to model events (onRowCountChanged, onRowsChanged)
  • +
  • fast real-time grid updating in response to data changes
  • +
+ +
+ + + + + + + diff --git a/slick.grid.js b/slick.grid.js index 3f59454..437a22b 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -108,6 +108,8 @@ function SlickGrid($container,data,model,options) var counter_rows_rendered = 0; var counter_rows_removed = 0; + var fragment = document.createDocumentFragment(); + function init() { options = $.extend({},defaults,options); @@ -423,6 +425,8 @@ function SlickGrid($container,data,model,options) var rowsBefore = renderedRows; + var stringArray = []; + for (var i = from; i <= to; i++) { if (rowsCache[i]) continue; renderedRows++; @@ -432,9 +436,12 @@ function SlickGrid($container,data,model,options) var x = document.createElement("div"); x.innerHTML = getRowHtml(i); x = x.firstChild; - rowsCache[i] = $divMain[0].appendChild(x); + //rowsCache[i] = $divMain[0].appendChild(x); + rowsCache[i] = fragment.appendChild(x); } + $divMain[0].appendChild(fragment); + console.log("rendered " + (renderedRows - rowsBefore) + " rows"); console.timeEnd("renderRows"); } diff --git a/slick.model.js b/slick.model.js new file mode 100644 index 0000000..7838d78 --- /dev/null +++ b/slick.model.js @@ -0,0 +1,147 @@ +/*** + * A simple observer pattern implementation. + */ +function EventHelper() { + this.handlers = []; + + this.subscribe = function(fn) { + this.handlers.push(fn); + } + + this.notify = function(args) { + for (var i = 0; i < this.handlers.length; i++) { + this.handlers[i].call(this, args); + } + } + + return this; +} + + + +/*** + * A sample Model implementation. + * Provides a filtered view of the underlying data. + * + * Relies on the data item having an "id" property uniquely identifying it. + */ +function DataView() { + var self = this; + + // private + var items = []; // data by index + var rows = []; // data by row + var idxById = {}; // indexes by id + var rowsByIdx = {}; // rows by index + var filter = null; // filter function + var updated = []; // updated item ids + + // events + var onRowCountChanged = new EventHelper(); + var onRowsChanged = new EventHelper(); + + + + function setItems(data) { + items = data.concat(); + refresh(); + } + + function sort(comparer) { + items.sort(comparer); + refresh(); + } + + function setFilter(filterFn) { + filter = filterFn; + refresh(); + } + + function getItemById(id) { + return items[idxById[id]]; + } + + function getDiff(arrayA, arrayB) { + var diff = []; + + for (var i = 0; i < Math.min(arrayA.length, arrayB.length); i++) { + if (arrayA[i].id != arrayB[i].id) { + diff.push(i); + } + } + + if (arrayA.length > arrayB.length) { + for (var i = arrayB.length; i < arrayA.length; i++) { + diff.push(i); + } + } + + if (arrayB.length > arrayA.length) { + for (var i = arrayA.length; i < arrayB.length; i++) { + diff.push(i); + } + } + + return diff; + } + + function recalc() { + var tmp = []; + + for (var idx = 0; idx < items.length; idx++) { + var item = items[idx]; + if (!filter || filter(item)) tmp.push(item); + } + + // replace contents without changing the reference + rows.splice(0, rows.length); + for (var i=0; i 0) onRowsChanged.notify(diff); + + updated = []; + } + + + + return { + "rows": rows, + "setItems": setItems, + "setFilter": setFilter, + "sort": sort, + "getItemById": getItemById, + "refresh": refresh, + "onRowCountChanged": onRowCountChanged, + "onRowsChanged": onRowsChanged + }; +} From 6c2fe23e311fd3f1c25bf5d4ae6bab82d92847cb Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Tue, 17 Mar 2009 02:57:54 +0000 Subject: [PATCH 0014/1043] From b2cae29b1585a034a7140e62b3555c72f76b13cb Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Tue, 17 Mar 2009 07:15:11 +0000 Subject: [PATCH 0015/1043] --- example1-simple.html | 2 +- example2-formatters.html | 2 +- example3-editing.html | 2 +- example4-model.html | 49 +++++++--- grid.html | 12 +-- slick.editors.js | 1 + ...ditorstate.js => slick.globaleditorlock.js | 20 ++-- slick.grid.js | 96 ++++++++++--------- slick.model.js | 28 +++++- 9 files changed, 127 insertions(+), 85 deletions(-) rename slick.globaleditorstate.js => slick.globaleditorlock.js (60%) diff --git a/example1-simple.html b/example1-simple.html index 380e809..1327b77 100644 --- a/example1-simple.html +++ b/example1-simple.html @@ -18,7 +18,7 @@ - + diff --git a/example2-formatters.html b/example2-formatters.html index 5ce6350..bfe3b64 100644 --- a/example2-formatters.html +++ b/example2-formatters.html @@ -25,7 +25,7 @@ - +
diff --git a/example3-editing.html b/example3-editing.html index 4a29d88..1f4a963 100644 --- a/example3-editing.html +++ b/example3-editing.html @@ -25,7 +25,7 @@ - +
diff --git a/example4-model.html b/example4-model.html index 16bb318..73911ee 100644 --- a/example4-model.html +++ b/example4-model.html @@ -25,7 +25,7 @@ - + @@ -61,6 +61,8 @@

Demonstrates:

  • a filtered Model (DataView) as a data source instead of a simple array
  • grid reacting to model events (onRowCountChanged, onRowsChanged)
  • fast real-time grid updating in response to data changes
  • +
  • adding new rows
  • +
  • column options: setValueHandler, cannotTriggerInsert
  • @@ -84,17 +86,17 @@

    Demonstrates:

    var data = []; var columns = [ - {id:"title", name:"Title", field:"title", width:120, cssClass:"cell-title", editor:TextCellEditor, validator:requiredFieldValidator}, - {id:"duration", name:"Duration", field:"duration", editor:TextCellEditor}, - {id:"%", name:"% Complete", field:"percentComplete", width:80, resizable:false, formatter:GraphicalPercentCompleteCellFormatter, editor:PercentCompleteCellEditor}, - {id:"start", name:"Start", field:"start", minWidth:60, editor:DateCellEditor}, - {id:"finish", name:"Finish", field:"finish", minWidth:60, editor:DateCellEditor}, - {id:"effort-driven", name:"Effort Driven", width:80, minWidth:20, maxWidth:80, cssClass:"cell-effort-driven", field:"effortDriven", formatter:BoolCellFormatter, editor:YesNoCheckboxCellEditor} + {id:"title", name:"Title", field:"title", width:120, cssClass:"cell-title", editor:TextCellEditor, validator:requiredFieldValidator, setValueHandler:updateItem}, + {id:"duration", name:"Duration", field:"duration", editor:TextCellEditor, setValueHandler:updateItem}, + {id:"%", name:"% Complete", field:"percentComplete", width:80, resizable:false, formatter:GraphicalPercentCompleteCellFormatter, editor:PercentCompleteCellEditor, setValueHandler:updateItem}, + {id:"start", name:"Start", field:"start", minWidth:60, editor:DateCellEditor, setValueHandler:updateItem}, + {id:"finish", name:"Finish", field:"finish", minWidth:60, editor:DateCellEditor, setValueHandler:updateItem}, + {id:"effort-driven", name:"Effort Driven", width:80, minWidth:20, maxWidth:80, cssClass:"cell-effort-driven", field:"effortDriven", formatter:BoolCellFormatter, editor:YesNoCheckboxCellEditor, setValueHandler:updateItem, cannotTriggerInsert:true} ]; var options = { editable: true, - enableAddRow: false, + enableAddRow: true, enableCellNavigation: true, asyncEditorLoading: false }; @@ -118,6 +120,19 @@

    Demonstrates:

    } + + function updateItem(value,columnDef,item) { + item[columnDef.field] = value; + dataView.updateItem(item.id,item); + } + + function addItem(columnDef,value) { + var item = {"id": "new_" + (Math.round(Math.random()*10000)), "title":"New task", "duration":"1 day", "percentComplete":0, "start":"01/01/2009", "finish":"01/01/2009", "effortDriven":false}; + item[columnDef.field] = value; + dataView.addItem(item); + } + + $(function() { // prepare the data @@ -143,9 +158,13 @@

    Demonstrates:

    // initialize the grid grid = new SlickGrid($("#myGrid"), dataView.rows, columns, options); + grid.onAddNewRow = addItem; + // wire up model events to drive the grid - dataView.onRowCountChanged.subscribe(function() { + dataView.onRowCountChanged.subscribe(function(args) { + // remove the last "Add New" row + grid.removeRow(args.previous); grid.resizeCanvas(); }); @@ -162,8 +181,8 @@

    Demonstrates:

    $("#pcSlider").slider({ "range": "min", "slide": function(event,ui) { - if (GlobalEditorState.isEditing()) - GlobalEditorState.cancelCurrentEdit(); + if (GlobalEditorLock.isEditing()) + GlobalEditorLock.cancelCurrentEdit(); percentCompleteThreshold = ui.value; dataView.refresh(); @@ -173,8 +192,8 @@

    Demonstrates:

    // wire up the search textbox to apply the filter to the model $("#txtSearch").keyup(function(e) { - if (GlobalEditorState.isEditing()) - GlobalEditorState.cancelCurrentEdit(); + if (GlobalEditorLock.isEditing()) + GlobalEditorLock.cancelCurrentEdit(); // clear on Esc if (e.which == 27) @@ -185,8 +204,8 @@

    Demonstrates:

    }) $("#btnResort").click(function() { - if (GlobalEditorState.isEditing()) - GlobalEditorState.cancelCurrentEdit(); + if (GlobalEditorLock.isEditing()) + GlobalEditorLock.cancelCurrentEdit(); dataView.sort(percentCompleteSort); }); diff --git a/grid.html b/grid.html index 76af94e..ed7478b 100644 --- a/grid.html +++ b/grid.html @@ -243,7 +243,7 @@ function updateModel(id, args) { - if (GlobalEditorState.isEditing() && !GlobalEditorState.commitCurrentEdit()) return; + if (GlobalEditorLock.isEditing() && !GlobalEditorLock.commitCurrentEdit()) return; for (var i=0; i - + diff --git a/slick.editors.js b/slick.editors.js index c84a3a2..1c7d46c 100644 --- a/slick.editors.js +++ b/slick.editors.js @@ -312,6 +312,7 @@ var PercentCompleteCellEditor = function($container, columnDef, value, dataConte $picker.find(".editor-percentcomplete-slider").slider({ orientation: "vertical", + range: "min", value: defaultValue, slide: function(event, ui) { $input.val(ui.value) diff --git a/slick.globaleditorstate.js b/slick.globaleditorlock.js similarity index 60% rename from slick.globaleditorstate.js rename to slick.globaleditorlock.js index da68f41..222de48 100644 --- a/slick.globaleditorstate.js +++ b/slick.globaleditorlock.js @@ -1,8 +1,8 @@ - - -var GlobalEditorState = new function() +/*** + * A singleton for controlling access to the editing functionality for multiple components capable of editing the same data. + */ +var GlobalEditorLock = new function() { - var currentEditor = null; this.isEditing = function() @@ -10,7 +10,6 @@ var GlobalEditorState = new function() return (currentEditor != null); } - this.hasLock = function(editor) { return (currentEditor == editor); @@ -19,27 +18,25 @@ var GlobalEditorState = new function() this.enterEditMode = function(editor) { if (currentEditor != null) - throw "GlobalEditorState : enterEditMode : currentEditor == null"; + throw "GlobalEditorLock : enterEditMode : currentEditor == null"; if (!editor.commitCurrentEdit) - throw "GlobalEditorState : enterEditMode : editor must implement .commitCurrentEdit()"; + throw "GlobalEditorLock : enterEditMode : editor must implement .commitCurrentEdit()"; if (!editor.cancelCurrentEdit) - throw "GlobalEditorState : enterEditMode : editor must implement .cancelCurrentEdit()"; + throw "GlobalEditorLock : enterEditMode : editor must implement .cancelCurrentEdit()"; currentEditor = editor; } - this.leaveEditMode = function(editor) { if (currentEditor != editor) - throw "GlobalEditorState : leaveEditMode() : currentEditor != editor"; + throw "GlobalEditorLock : leaveEditMode() : currentEditor != editor"; currentEditor = null; } - this.commitCurrentEdit = function() { if (currentEditor) @@ -48,7 +45,6 @@ var GlobalEditorState = new function() return true; } - this.cancelCurrentEdit = function() { if (currentEditor) diff --git a/slick.grid.js b/slick.grid.js index 437a22b..9a20508 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -8,6 +8,7 @@ * - frozen columns * - built-in row reorder * - add custom editor options + * - consistent events (EventHelper? jQuery events?) * * KNOWN ISSUES: * - keyboard navigation doesn't "jump" over unselectable cells for now @@ -19,13 +20,13 @@ * editable - If false, no cells will be switched into edit mode. * editOnDoubleClick - Cell will not automatically go into edit mode without being double-clicked. * enableCellNavigation - If false, no cells will be selectable. - * defaultColumnWidth - Default column width in pixels (if model[cell].width is not specified). + * defaultColumnWidth - Default column width in pixels (if columns[cell].width is not specified). * enableColumnReorder - Allows the user to reorder columns. * asyncEditorLoading - Makes cell editors load asynchronously after a small delay. * This greatly increases keyboard navigation speed. * * - * COLUMN DEFINITION (MODEL) OPTIONS: + * COLUMN DEFINITION (columns) OPTIONS: * id - Column ID. * name - Column name to put in the header. * field - Property of the data context to bind to. @@ -53,11 +54,11 @@ * * @param {jQuery} $container Container object to create the grid in. * @param {Array} data An array of objects for databinding. - * @param {Array} model An array of column definitions. + * @param {Array} columns An array of column definitions. * @param {Object} options Grid options. * */ -function SlickGrid($container,data,model,options) +function SlickGrid($container,data,columns,options) { // settings var defaults = { @@ -132,9 +133,9 @@ function SlickGrid($container,data,model,options) viewportW = $divMainScroller.innerWidth(); viewportH = $divMainScroller.innerHeight(); - for (var i = 0; i < model.length; i++) + for (var i = 0; i < columns.length; i++) { - var m = model[i]; + var m = columns[i]; columnsById[m.id] = i; @@ -156,7 +157,7 @@ function SlickGrid($container,data,model,options) $divHeaders.find(".h").each(function() { var cell = parseInt($(this).attr("cell")); - var m = model[cell]; + var m = columns[cell]; if (m.resizable === false) return; @@ -167,12 +168,12 @@ function SlickGrid($container,data,model,options) stop: function(e, ui) { var cellId = $(this).attr("id"); var cell = columnsById[cellId]; - model[cell].width = $(this).width(); - $.rule("." + uid + " .grid-canvas .c" + cell, "style").css("width", model[cell].width + "px"); + columns[cell].width = $(this).width(); + $.rule("." + uid + " .grid-canvas .c" + cell, "style").css("width", columns[cell].width + "px"); resizeCanvas(); // todo: rerender single column instead of everything - if (model[cell].rerenderOnResize) { + if (columns[cell].rerenderOnResize) { removeAllRows(); renderViewport(); } @@ -193,15 +194,15 @@ function SlickGrid($container,data,model,options) var newOrder = $divHeaders.sortable("toArray"); var lookup = {}; - for (var i=0; i"); - for (var j=0; j"); @@ -364,7 +365,7 @@ function SlickGrid($container,data,model,options) var $cell = $(rowsCache[row]).find(".c[cell=" + cell + "]"); if ($cell.length == 0) return; - var m = model[cell]; + var m = columns[cell]; if (currentEditor && currentRow == row && currentCell == cell) currentEditor.setValue(data[currentRow][m.field]); @@ -379,7 +380,7 @@ function SlickGrid($container,data,model,options) // todo: perf: iterate over direct children? $(rowsCache[row]).find(".c").each(function(i) { - var m = model[i]; + var m = columns[i]; if (row == currentRow && i == currentCell && currentEditor) currentEditor.setValue(data[currentRow][m.field]); @@ -401,9 +402,9 @@ function SlickGrid($container,data,model,options) viewportH = $divMainScroller.innerHeight(); var totalWidth = 0; - for (var i=0; i= data.length) + if (columns[cell].cannotTriggerInsert && row >= data.length) return false; // does this cell have an editor? - if (!model[cell].editor) + if (!columns[cell].editor) return false; return true; @@ -752,7 +753,7 @@ function SlickGrid($container,data,model,options) if (data[currentRow]) - currentCellNode.innerHTML = model[currentCell].formatter(currentRow, currentCell, data[currentRow][model[currentCell].field], model[currentCell], data[currentRow]); + currentCellNode.innerHTML = columns[currentCell].formatter(currentRow, currentCell, data[currentRow][columns[currentCell].field], columns[currentCell], data[currentRow]); currentEditor = null; @@ -760,7 +761,7 @@ function SlickGrid($container,data,model,options) // IE can't set focus to anything else correctly if ($.browser.msie) clearTextSelection(); - GlobalEditorState.leaveEditMode(self); + GlobalEditorLock.leaveEditMode(self); } function makeSelectedCellEditable() @@ -776,7 +777,7 @@ function SlickGrid($container,data,model,options) if (!isCellPotentiallyEditable(currentRow,currentCell)) return; - GlobalEditorState.enterEditMode(self); + GlobalEditorLock.enterEditMode(self); $(currentCellNode).addClass("editable"); @@ -784,11 +785,11 @@ function SlickGrid($container,data,model,options) // if there is a corresponding row if (data[currentRow]) - value = data[currentRow][model[currentCell].field]; + value = data[currentRow][columns[currentCell].field]; currentCellNode.innerHTML = ""; - currentEditor = new model[currentCell].editor($(currentCellNode), model[currentCell], value, data[currentRow]); + currentEditor = new columns[currentCell].editor($(currentCellNode), columns[currentCell], value, data[currentRow]); } function scrollSelectedCellIntoView() { @@ -816,7 +817,7 @@ function SlickGrid($container,data,model,options) { if (!currentCellNode) return; if (!options.enableCellNavigation) return; - if (!GlobalEditorState.commitCurrentEdit()) return; + if (!GlobalEditorLock.commitCurrentEdit()) return; var nextRow = rowsCache[currentRow + dy]; var nextCell = nextRow ? $(nextRow).find(".c[cell=" + (currentCell + dx) + "][tabIndex=0]") : null; @@ -854,10 +855,10 @@ function SlickGrid($container,data,model,options) function gotoCell(row,cell) { - if (row > data.length || row < 0 || cell >= model.length || cell < 0) return; - if (!options.enableCellNavigation || model[cell].unselectable) return; + if (row > data.length || row < 0 || cell >= columns.length || cell < 0) return; + if (!options.enableCellNavigation || columns[cell].unselectable) return; - if (!GlobalEditorState.commitCurrentEdit()) return; + if (!GlobalEditorLock.commitCurrentEdit()) return; if (!rowsCache[row]) renderRows(row,row); @@ -873,7 +874,7 @@ function SlickGrid($container,data,model,options) ////////////////////////////////////////////////////////////////////////////////////////////// - // IEditor implementation for GlobalEditorState + // IEditor implementation for GlobalEditorLock this.commitCurrentEdit = function() { if (currentEditor) @@ -884,18 +885,19 @@ function SlickGrid($container,data,model,options) if (validationResults.valid) { + var value = currentEditor.getValue(); + + makeSelectedCellNormal(); + if (currentRow < data.length) { - if (model[currentCell].setValueHandler) - model[currentCell].setValueHandler(currentEditor.getValue(), model[currentCell], data[currentRow]); + if (columns[currentCell].setValueHandler) + columns[currentCell].setValueHandler(value, columns[currentCell], data[currentRow]); else - data[currentRow][model[currentCell].field] = currentEditor.getValue(); + data[currentRow][columns[currentCell].field] = value; } else if (self.onAddNewRow) - self.onAddNewRow(model[currentCell], currentEditor.getValue()); - - - makeSelectedCellNormal(); + self.onAddNewRow(columns[currentCell], value); return true; } @@ -905,7 +907,7 @@ function SlickGrid($container,data,model,options) $(currentCellNode).stop(true,true).effect("highlight", {color:"red"}, 300); if (self.onValidationError) - self.onValidationError(currentCellNode, validationResults, currentRow, currentCell, model[currentCell]); + self.onValidationError(currentCellNode, validationResults, currentRow, currentCell, columns[currentCell]); currentEditor.focus(); return false; diff --git a/slick.model.js b/slick.model.js index 7838d78..4dc54bb 100644 --- a/slick.model.js +++ b/slick.model.js @@ -61,6 +61,26 @@ function DataView() { return items[idxById[id]]; } + function updateItem(id,item) { + items[idxById[id]] = item; + refresh(); + } + + function insertItem(insertBefore,item) { + items.splice(insertBefore,0,item); + refresh(); + } + + function addItem(item) { + items.push(item); + refresh(); + } + + function deleteItem(id) { + items.splice(idxById[id],1); + refresh(); + } + function getDiff(arrayA, arrayB) { var diff = []; @@ -126,7 +146,7 @@ function DataView() { diff = $.unique(diff); - if (countBefore != rows.length) onRowCountChanged.notify(null); + if (countBefore != rows.length) onRowCountChanged.notify({previous:countBefore, current:rows.length}); if (diff.length > 0) onRowsChanged.notify(diff); updated = []; @@ -135,12 +155,16 @@ function DataView() { return { - "rows": rows, + "rows": rows, // note: neither the array or the data in it should really be modified directly "setItems": setItems, "setFilter": setFilter, "sort": sort, "getItemById": getItemById, "refresh": refresh, + "updateItem": updateItem, + "insertItem": insertItem, + "addItem": addItem, + "deleteItem": deleteItem, "onRowCountChanged": onRowCountChanged, "onRowsChanged": onRowsChanged }; From c97fcee1db39a0260a9015b15e50e393ddea12df Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Tue, 17 Mar 2009 07:17:09 +0000 Subject: [PATCH 0016/1043] --- example4-model.html | 1 + 1 file changed, 1 insertion(+) diff --git a/example4-model.html b/example4-model.html index 73911ee..1370eb3 100644 --- a/example4-model.html +++ b/example4-model.html @@ -63,6 +63,7 @@

    Demonstrates:

  • fast real-time grid updating in response to data changes
  • adding new rows
  • column options: setValueHandler, cannotTriggerInsert
  • +
  • NOTE: all filters are immediately applied to new/edited rows
  • From 5dde53dc7acbdedc71532ecc132a8a7501ae54dd Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Wed, 18 Mar 2009 21:23:22 +0000 Subject: [PATCH 0017/1043] --- example4-model.html | 32 ++++++- grid.html | 2 +- images/sort-asc.png | Bin 0 -> 163 bytes images/sort-desc.png | Bin 0 -> 161 bytes slick.grid.js | 208 +++++++++++++++++++++++-------------------- 5 files changed, 144 insertions(+), 98 deletions(-) create mode 100644 images/sort-asc.png create mode 100644 images/sort-desc.png diff --git a/example4-model.html b/example4-model.html index 1370eb3..c9dd40e 100644 --- a/example4-model.html +++ b/example4-model.html @@ -14,6 +14,14 @@ .cell-effort-driven { text-align: center; } + + .sort-asc { + background: silver url('images/sort-asc.png') no-repeat right center !important; + } + + .sort-desc { + background: silver url('images/sort-desc.png') no-repeat right center !important; + } @@ -120,7 +128,11 @@

    Demonstrates:

    return a["percentComplete"] - b["percentComplete"]; } - + var sortcol = "title"; + var sortdir = 1; + function comparer(a,b) { + return sortdir * ((a[sortcol] > b[sortcol]) ? 1 : -1); + } function updateItem(value,columnDef,item) { item[columnDef.field] = value; @@ -161,6 +173,24 @@

    Demonstrates:

    grid.onAddNewRow = addItem; + grid.onColumnHeaderClick = function(columnDef) { + if (GlobalEditorLock.isEditing() && !GlobalEditorLock.commitCurrentEdit()) + return; + + for (var i=0; i - +
    diff --git a/images/sort-asc.png b/images/sort-asc.png new file mode 100644 index 0000000000000000000000000000000000000000..e6b6264fccc153795c2a1281a9832efbd1995b87 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^96-#ra@ocD)4hB}!Z) zN`mv#O3D+9QW*jgGxJLH{9Hp6%8d1l%~n2tqzY7H=IP=XA`zaP=D_+U;9b2*p}}zopr0I3BsYybcN literal 0 HcmV?d00001 diff --git a/images/sort-desc.png b/images/sort-desc.png new file mode 100644 index 0000000000000000000000000000000000000000..74ad1540e35709bd2a5a35866899c40be9634d0d GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^96-#ra@ocD)4hB}!Z) zN`mv#O3D+9QW*jgGxJLH{9Hp6%8d1l%~n2tqzY7H;_2cTA`zaPpukkXc(sP<(f^De zb`#DsT|Up8Qq!#UgMG<;Mnmac4-H%+R1>>yHu9vU%w@3I!+n0@-}`@o`WZZ3{an^L HB{Ts5Wh^rm literal 0 HcmV?d00001 diff --git a/slick.grid.js b/slick.grid.js index 9a20508..72ba77f 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -12,6 +12,7 @@ * * KNOWN ISSUES: * - keyboard navigation doesn't "jump" over unselectable cells for now + * - main page must have at least one STYLE element * * * OPTIONS: @@ -44,6 +45,11 @@ * rerenderOnResize - Rerender the column when it is resized (useful for columns relying on cell width or adaptive formatters). * * + * EVENTS: + * + * ... + * + * * NOTES: * * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods. @@ -78,7 +84,7 @@ function SlickGrid($container,data,columns,options) var BUFFER = 5; // will be set to equal one page // private - var uid = "fastgrid_" + Math.round(1000000 * Math.random()); + var uid = "slickgrid_" + Math.round(1000000 * Math.random()); var self = this; var $divHeadersScroller; var $divHeaders; @@ -95,7 +101,7 @@ function SlickGrid($container,data,columns,options) var numVisibleRows; var lastRenderedScrollTop = 0; var currentScrollTop = 0; - var scrollingDown = true; + var scrollDir = 1; var selectedRows = []; var selectedRowsLookup = {}; @@ -188,7 +194,6 @@ function SlickGrid($container,data,columns,options) axis:"x", cancel:".ui-resizable-handle", update: function(e,ui) { - console.time("column reorder"); var newOrder = $divHeaders.sortable("toArray"); @@ -210,11 +215,25 @@ function SlickGrid($container,data,columns,options) createCssRules(); renderViewport(); + if (self.onColumnsReordered) + self.onColumnsReordered(); + + e.stopPropagation(); + console.timeEnd("column reorder"); } }); + $divHeaders.bind("click", function(e) { + if (!$(e.target).hasClass(".h")) return; + + var id = $(e.target).attr("id"); + + if (self.onColumnHeaderClick) + self.onColumnHeaderClick(columns[columnsById[id]]); + }); + createCssRules(); resizeCanvas(); @@ -223,13 +242,13 @@ function SlickGrid($container,data,columns,options) if (!options.manualScrolling) - $divMainScroller.bind("scroll", onScroll); + $divMainScroller.bind("scroll", handleScroll); - $divMainScroller.scroll(function() { $divHeadersScroller.scrollLeft(this.scrollLeft); }) + $divMainScroller.bind("scroll", function() { $divHeadersScroller.scrollLeft(this.scrollLeft); }) - $divMain.bind("keydown", onKeyDown); - $divMain.bind("click", onClick); - $divMain.bind("dblclick", onDblClick); + $divMain.bind("keydown", handleKeyDown); + $divMain.bind("click", handleClick); + $divMain.bind("dblclick", handleDblClick); if ($.browser.msie) $divMainScroller[0].onselectstart = function() { @@ -239,24 +258,21 @@ function SlickGrid($container,data,columns,options) } function createCssRules() { - for (var i = 0; i < columns.length; i++) - { + for (var i = 0; i < columns.length; i++) { $.rule("." + uid + " .grid-canvas .c" + i + " { width:" + columns[i].width + "px }").appendTo("style"); } - } - + } + function removeCssRules() { - for (var i = 0; i < columns.length; i++) - { + for (var i = 0; i < columns.length; i++) { $.rule("." + uid + " .grid-canvas .c" + i, "style").remove(); } } function destroy() { if (currentEditor) - self.cancelCurrentEdit(); + cancelCurrentEdit(); - $divMainScroller.unbind("scroll", onScroll); $divHeaders.sortable("destroy"); $divHeaders.find(".h").resizable("destroy"); @@ -268,6 +284,10 @@ function SlickGrid($container,data,columns,options) ////////////////////////////////////////////////////////////////////////////////////////////// // General + function setColumnHeaderCssClass(id,classesToAdd,classesToRemove) { + $divHeaders.find(".h[id=" + id + "]").removeClass(classesToRemove).addClass(classesToAdd); + } + function getColumnIndex(id) { return columnsById[id]; } @@ -304,7 +324,20 @@ function SlickGrid($container,data,columns,options) selectedRowsLookup = lookup; } - + function setOptions(args) { + if (currentEditor && !commitCurrentEdit()) + return; + + setSelectedCell(null); + + if (options.enableAddRow != args.enableAddRow) + removeRow(data.length); + + options = $.extend(options,args); + + renderViewport(); + } + ////////////////////////////////////////////////////////////////////////////////////////////// // Rendering / Scrolling @@ -350,6 +383,8 @@ function SlickGrid($container,data,columns,options) if (currentEditor && currentRow == row) throw "Grid : removeRow : Cannot remove a row that is currently in edit mode"; + // if we're removing rows, we're probably not scrolling + scrollDir = 0; node.parentNode.removeChild(node); node = null; @@ -449,9 +484,9 @@ function SlickGrid($container,data,columns,options) function renderViewport() { var vp = getViewport(); - var from = Math.max(0, vp.top - (scrollingDown ? 0 : BUFFER)); - var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollingDown ? BUFFER : 0)); - + var from = Math.max(0, vp.top - (scrollDir >= 0 ? 5 : BUFFER)); + var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollDir > 0 ? BUFFER : 5)); + renderRows(from,to); } @@ -473,7 +508,7 @@ function SlickGrid($container,data,columns,options) var from = vp.top - BUFFER, to = vp.bottom + BUFFER; // todo: bias based on the direction of scroll - // todo: remove rows in correct order (farthers first) + // todo: remove rows in correct order (farthest first) var parentNode = $divMain[0]; @@ -509,13 +544,19 @@ function SlickGrid($container,data,columns,options) h_render = null; } - function onScroll() { + function handleScroll() { currentScrollTop = parseInt($divMainScroller[0].scrollTop); var scrollDistance = Math.abs(lastRenderedScrollTop - currentScrollTop); if (scrollDistance < 5*ROW_HEIGHT) return; - scrollingDown = lastRenderedScrollTop < currentScrollTop; + if (lastRenderedScrollTop == currentScrollTop) + scrollDir = 0; + else if (lastRenderedScrollTop < currentScrollTop) + scrollDir = 1; + else + scrollDir = -1; + window.clearTimeout(h_render); @@ -534,11 +575,11 @@ function SlickGrid($container,data,columns,options) ////////////////////////////////////////////////////////////////////////////////////////////// // Interactivity - function onKeyDown(e) { + function handleKeyDown(e) { switch (e.which) { case 27: // esc if (GlobalEditorLock.isEditing() && GlobalEditorLock.hasLock(self)) - self.cancelCurrentEdit(self); + cancelCurrentEdit(self); if (currentCellNode) currentCellNode.focus(); @@ -597,7 +638,7 @@ function SlickGrid($container,data,columns,options) return false; } - function onClick(e) + function handleClick(e) { var $cell = $(e.target).closest(".c"); @@ -615,7 +656,7 @@ function SlickGrid($container,data,columns,options) if (data[row] && self.onClick) { // grid must not be in edit mode - if (!currentEditor || (validated = self.commitCurrentEdit())) + if (!currentEditor || (validated = commitCurrentEdit())) { // handler will return true if the event was handled if (self.onClick(e, row, cell)) @@ -631,12 +672,12 @@ function SlickGrid($container,data,columns,options) if (options.enableCellNavigation && !columns[cell].unselectable) { // commit current edit before proceeding - if (validated == true || (validated == null && self.commitCurrentEdit())) + if (validated == true || (validated == null && commitCurrentEdit())) setSelectedCellAndRow($cell[0]); } } - function onDblClick(e) + function handleDblClick(e) { var $cell = $(e.target).closest(".c"); @@ -802,14 +843,14 @@ function SlickGrid($container,data,columns,options) { $divMainScroller[0].scrollTop = (currentRow ) * ROW_HEIGHT; - onScroll(); + handleScroll(); } // or page up? else if (currentRow * ROW_HEIGHT < scrollTop) { $divMainScroller[0].scrollTop = (currentRow + 2) * ROW_HEIGHT - viewportH; - onScroll(); + handleScroll(); } } @@ -876,7 +917,7 @@ function SlickGrid($container,data,columns,options) ////////////////////////////////////////////////////////////////////////////////////////////// // IEditor implementation for GlobalEditorLock - this.commitCurrentEdit = function() { + function commitCurrentEdit() { if (currentEditor) { if (currentEditor.isValueChanged()) @@ -921,74 +962,11 @@ function SlickGrid($container,data,columns,options) return true; }; - this.cancelCurrentEdit = function() { + function cancelCurrentEdit() { makeSelectedCellNormal(); }; - - ////////////////////////////////////////////////////////////////////////////////////////////// - // Public methods - - this.getColumnIndex = getColumnIndex; - - this.setOptions = function(args) { - if (currentEditor && !self.commitCurrentEdit()) - return; - - setSelectedCell(null); - - if (options.enableAddRow != args.enableAddRow) - removeRow(data.length); - - options = $.extend(options,args); - - renderViewport(); - }; - - this.destroy = destroy; - - this.updateCell = updateCell; - - this.updateRow = updateRow; - - this.removeRow = removeRow; - - this.removeAllRows = removeAllRows; - - this.render = render; - - this.getViewport = getViewport; - - this.resizeCanvas = resizeCanvas; - - this.scroll = onScroll; - - this.scrollTo = function(top) { - $divMainScroller.scrollTop(top); - onScroll(); - }; - - this.getCellFromPoint = getCellFromPoint; - - this.gotoCell = gotoCell; - - this.editCurrentCell = makeSelectedCellEditable; - - this.getSelectedRows = getSelectedRows; - - this.setSelectedRows = setSelectedRows; - - ////////////////////////////////////////////////////////////////////////////////////////////// - // Events - - this.onClick = null; - this.onKeyDown = null; - this.onAddNewRow = null; - this.onValidationError = null; - this.onViewportChanged = null; - this.onSelectedRowsChanged = null; - ////////////////////////////////////////////////////////////////////////////////////////////// // Debug @@ -1042,4 +1020,42 @@ function SlickGrid($container,data,columns,options) init(); + + + ////////////////////////////////////////////////////////////////////////////////////////////// + // Public API + + $.extend(this, { + // Events + "onColumnHeaderClick": null, + "onClick": null, + "onKeyDown": null, + "onAddNewRow": null, + "onValidationError": null, + "onViewportChanged": null, + "onSelectedRowsChanged": null, + "onColumnsReordered": null, + + // Methods + "destroy": destroy, + "getColumnIndex": getColumnIndex, + "updateCell": updateCell, + "updateRow": updateRow, + "removeRow": removeRow, + "removeAllRows": removeAllRows, + "render": render, + "getViewport": getViewport, + "resizeCanvas": resizeCanvas, + "scroll": scroll, + "getCellFromPoint": getCellFromPoint, + "gotoCell": gotoCell, + "editCurrentCell": makeSelectedCellEditable, + "getSelectedRows": getSelectedRows, + "setSelectedRows": setSelectedRows, + "setColumnHeaderCssClass": setColumnHeaderCssClass, + + // IEditor implementation + "commitCurrentEdit": commitCurrentEdit, + "cancelCurrentEdit": cancelCurrentEdit + }); } From 39a0130075495e82816db4ba9f4c33300f0060c6 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 19 Mar 2009 08:07:41 +0000 Subject: [PATCH 0018/1043] --- example4-model.html | 5 ++- model benchmarks.html | 52 +++++++++++++++++++++++++ slick.grid.js | 1 + slick.model.js | 91 ++++++++++++++++--------------------------- 4 files changed, 90 insertions(+), 59 deletions(-) create mode 100644 model benchmarks.html diff --git a/example4-model.html b/example4-model.html index c9dd40e..71454ee 100644 --- a/example4-model.html +++ b/example4-model.html @@ -194,8 +194,9 @@

    Demonstrates:

    // wire up model events to drive the grid dataView.onRowCountChanged.subscribe(function(args) { - // remove the last "Add New" row - grid.removeRow(args.previous); + for (var i=args.current; i<=args.previous; i++) + grid.removeRow(i); + grid.resizeCanvas(); }); diff --git a/model benchmarks.html b/model benchmarks.html new file mode 100644 index 0000000..6c6ffd7 --- /dev/null +++ b/model benchmarks.html @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + diff --git a/slick.grid.js b/slick.grid.js index 72ba77f..4577a16 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -9,6 +9,7 @@ * - built-in row reorder * - add custom editor options * - consistent events (EventHelper? jQuery events?) + * - resizeCanvas() could take care of removing rows outside of data range * * KNOWN ISSUES: * - keyboard navigation doesn't "jump" over unselectable cells for now diff --git a/slick.model.js b/slick.model.js index 4dc54bb..4452439 100644 --- a/slick.model.js +++ b/slick.model.js @@ -34,7 +34,7 @@ function DataView() { var idxById = {}; // indexes by id var rowsByIdx = {}; // rows by index var filter = null; // filter function - var updated = []; // updated item ids + var updated = null; // updated item ids // events var onRowCountChanged = new EventHelper(); @@ -63,6 +63,8 @@ function DataView() { function updateItem(id,item) { items[idxById[id]] = item; + if (!updated) updated = {}; + updated[id] = true; refresh(); } @@ -80,76 +82,51 @@ function DataView() { items.splice(idxById[id],1); refresh(); } - - function getDiff(arrayA, arrayB) { + + function recalc() { var diff = []; + idxById = {}; + rowsByIdx = {}; - for (var i = 0; i < Math.min(arrayA.length, arrayB.length); i++) { - if (arrayA[i].id != arrayB[i].id) { - diff.push(i); - } - } - - if (arrayA.length > arrayB.length) { - for (var i = arrayB.length; i < arrayA.length; i++) { - diff.push(i); + // go over all items remapping them to rows on the fly while keeping track of the differences + var il = items.length; + var rl = rows.length; + var l = 0; + var i = 0; + while (i < il) { + var item = items[i]; + + idxById[item.id] = i; + + if (!filter || filter(item)) { + if (l >= rl || item.id != rows[l].id || (updated && updated[item.id])) { + diff.push(l); + rows[l] = item; + } + + rowsByIdx[i] = l; + + l++; } + + i++; } + + // remove unmapped portion + rows.splice(l,rows.length-l); - if (arrayB.length > arrayA.length) { - for (var i = arrayA.length; i < arrayB.length; i++) { - diff.push(i); - } - } + updated = null; return diff; } - function recalc() { - var tmp = []; - - for (var idx = 0; idx < items.length; idx++) { - var item = items[idx]; - if (!filter || filter(item)) tmp.push(item); - } - - // replace contents without changing the reference - rows.splice(0, rows.length); - for (var i=0; i 0) onRowsChanged.notify(diff); - - updated = []; + if (diff.length > 0 || countBefore != rows.length) onRowsChanged.notify(diff); } From 5b26bc93d5b5467d3fd4d6bc5cc90aabb76f84f1 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 19 Mar 2009 08:08:07 +0000 Subject: [PATCH 0019/1043] From 550505519dc16295e8067976cd21b7e5f804e051 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Fri, 20 Mar 2009 21:47:13 +0000 Subject: [PATCH 0020/1043] --- model benchmarks.html | 6 ++++-- slick.grid.js | 50 +++++++++++++++++++++++++++++-------------- slick.model.js | 45 ++++++++++++++++++++++++-------------- 3 files changed, 67 insertions(+), 34 deletions(-) diff --git a/model benchmarks.html b/model benchmarks.html index 6c6ffd7..39c1c06 100644 --- a/model benchmarks.html +++ b/model benchmarks.html @@ -18,7 +18,7 @@ var data = []; - for (var i=0; i<5000; i++) { + for (var i=0; i<50000; i++) { var d = (data[i] = {}); d["title"] = "Task " + i; @@ -27,15 +27,17 @@ var dv = new DataView(); + dv.beginUpdate(); dv.setItems(data); dv.setFilter(filter); + dv.endUpdate(); var b = new Date(); console.time("refresh"); - for (var i = 0; i < 100; i++) { + for (var i = 0; i <= 100; i+=10) { filterparam = i; dv.refresh(); } diff --git a/slick.grid.js b/slick.grid.js index 4577a16..c5dd9b2 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -9,11 +9,12 @@ * - built-in row reorder * - add custom editor options * - consistent events (EventHelper? jQuery events?) - * - resizeCanvas() could take care of removing rows outside of data range + * - break resizeCanvas() into two functions to handle container resize and data size changes + * - improve rendering speed by merging column extra cssClass into dynamically-generated .c{x} rules * * KNOWN ISSUES: * - keyboard navigation doesn't "jump" over unselectable cells for now - * - main page must have at least one STYLE element + * - main page must have at least one STYLE element for jQuery Rule to work * * * OPTIONS: @@ -348,7 +349,8 @@ function SlickGrid($container,data,columns,options) } function appendRowHtml(stringArray,row) { - var dataLoading = row < data.length && !data[row]; + var d = data[row]; + var dataLoading = row < data.length && !d; var css = "r" + (dataLoading ? " loading" : "") + (selectedRowsLookup[row] ? " selected" : ""); stringArray.push("
    "); @@ -360,8 +362,8 @@ function SlickGrid($container,data,columns,options) stringArray.push("
    "); // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet) - if (row < data.length && data[row]) - stringArray.push(m.formatter(row, j, data[row][m.field], m, data[row])); + if (row < data.length && d) + stringArray.push(m.formatter(row, j, d[m.field], m, d)); stringArray.push("
    "); } @@ -401,14 +403,13 @@ function SlickGrid($container,data,columns,options) var $cell = $(rowsCache[row]).find(".c[cell=" + cell + "]"); if ($cell.length == 0) return; - var m = columns[cell]; + var m = columns[cell]; + var d = data[row]; if (currentEditor && currentRow == row && currentCell == cell) - currentEditor.setValue(data[currentRow][m.field]); - else if (data[row]) - $cell[0].innerHTML = m.formatter(row, cell, data[row][m.field], m, data[row]); - else - $cell[0].innerHTML = ""; + currentEditor.setValue(d[m.field]); + else + $cell[0].innerHTML = d ? m.formatter(row, cell, d[m.field], m, d) : "" } function updateRow(row) { @@ -428,14 +429,14 @@ function SlickGrid($container,data,columns,options) } function resizeCanvas() { - BUFFER = numVisibleRows = Math.ceil(parseInt($divMainScroller.innerHeight()) / ROW_HEIGHT); - + viewportW = $divMainScroller.innerWidth(); + viewportH = $divMainScroller.innerHeight(); + + BUFFER = numVisibleRows = Math.ceil(viewportH / ROW_HEIGHT); CAPACITY = Math.max(CAPACITY, numVisibleRows + 2*BUFFER > CAPACITY); - $divMain.height(Math.max(ROW_HEIGHT * (data.length + numVisibleRows - 2), $divMainScroller.innerHeight() - $.getScrollbarWidth())); + $divMain.height(Math.max(ROW_HEIGHT * (data.length + numVisibleRows - 2), viewportH - $.getScrollbarWidth())); - viewportW = $divMainScroller.innerWidth(); - viewportH = $divMainScroller.innerHeight(); var totalWidth = 0; for (var i=0; i= l) + { + parentNode.removeChild(rowsCache[i]); + delete rowsCache[i]; + renderedRows--; + + counter_rows_removed++; + } + } + + // browsers sometimes do not adjust scrollTop/scrollHeight when the height of contained objects changes if ($divMainScroller.scrollTop() > $divMain.height() - $divMainScroller.height()) $divMainScroller.scrollTop($divMain.height() - $divMainScroller.height()); diff --git a/slick.model.js b/slick.model.js index 4452439..845bf4a 100644 --- a/slick.model.js +++ b/slick.model.js @@ -32,15 +32,24 @@ function DataView() { var items = []; // data by index var rows = []; // data by row var idxById = {}; // indexes by id - var rowsByIdx = {}; // rows by index + var rowsByIdx = []; // rows by index var filter = null; // filter function var updated = null; // updated item ids + var suspend = false; // suspends the recalculation // events var onRowCountChanged = new EventHelper(); var onRowsChanged = new EventHelper(); + function beginUpdate() { + suspend = true; + } + + function endUpdate() { + suspend = false; + refresh(); + } function setItems(data) { items = data.concat(); @@ -82,38 +91,39 @@ function DataView() { items.splice(idxById[id],1); refresh(); } - + function recalc() { var diff = []; idxById = {}; - rowsByIdx = {}; - // go over all items remapping them to rows on the fly while keeping track of the differences - var il = items.length; + // go over all items remapping them to rows on the fly + // while keeping track of the differences and updating indexes var rl = rows.length; var l = 0; - var i = 0; - while (i < il) { - var item = items[i]; + var item,id; + + for (var i=0, il=items.length; i= rl || item.id != rows[l].id || (updated && updated[item.id])) { + if (l >= rl || id != rows[l].id || (updated && updated[id])) { diff.push(l); rows[l] = item; + rowsByIdx[i] = l; } - rowsByIdx[i] = l; - l++; } - - i++; } // remove unmapped portion - rows.splice(l,rows.length-l); + if (rl > l) { + rows.splice(l, rl - l); + rowsByIdx.splice(l, rl - l); + } updated = null; @@ -121,8 +131,9 @@ function DataView() { } function refresh() { - var countBefore = rows.length; + if (suspend) return; + var countBefore = rows.length; var diff = recalc(); if (countBefore != rows.length) onRowCountChanged.notify({previous:countBefore, current:rows.length}); @@ -133,6 +144,8 @@ function DataView() { return { "rows": rows, // note: neither the array or the data in it should really be modified directly + "beginUpdate": beginUpdate, + "endUpdate": endUpdate, "setItems": setItems, "setFilter": setFilter, "sort": sort, From a7fafcdf3e5f8fd017ebfdb0a297f0b4b0448071 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Sat, 21 Mar 2009 01:25:07 +0000 Subject: [PATCH 0021/1043] --- example4-model.html | 20 ++++++++++++-------- model benchmarks.html | 6 +++--- slick.grid.js | 9 +++++---- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/example4-model.html b/example4-model.html index 71454ee..36006b8 100644 --- a/example4-model.html +++ b/example4-model.html @@ -68,8 +68,11 @@

    Demonstrates:

    • a filtered Model (DataView) as a data source instead of a simple array
    • grid reacting to model events (onRowCountChanged, onRowsChanged)
    • -
    • fast real-time grid updating in response to data changes
    • -
    • adding new rows
    • +
    • + FAST DataView recalculation and real-time grid updating in response to data changes.
      + The grid holds 1'000 rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows. +
    • +
    • adding new rows, bidirectional sorting
    • column options: setValueHandler, cannotTriggerInsert
    • NOTE: all filters are immediately applied to new/edited rows
    @@ -131,7 +134,9 @@

    Demonstrates:

    var sortcol = "title"; var sortdir = 1; function comparer(a,b) { - return sortdir * ((a[sortcol] > b[sortcol]) ? 1 : -1); + var x = a[sortcol], y = b[sortcol]; + + return sortdir * (x == y ? 0 : (x > y ? 1 : -1)); } function updateItem(value,columnDef,item) { @@ -149,7 +154,7 @@

    Demonstrates:

    $(function() { // prepare the data - for (var i=0; i<500; i++) { + for (var i=0; i<10000; i++) { var d = (data[i] = {}); d["id"] = "id_" + i; @@ -164,8 +169,10 @@

    Demonstrates:

    // initialize the model dataView = new DataView(); + dataView.beginUpdate(); dataView.setItems(data); dataView.setFilter(myFilter); + dataView.endUpdate(); // initialize the grid @@ -194,14 +201,11 @@

    Demonstrates:

    // wire up model events to drive the grid dataView.onRowCountChanged.subscribe(function(args) { - for (var i=args.current; i<=args.previous; i++) - grid.removeRow(i); - grid.resizeCanvas(); }); dataView.onRowsChanged.subscribe(function(rows) { - for (var i=0; i - + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + From d34a78d406b55abc72d5f00faf16b1ec2a5f5af1 Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Sun, 29 Mar 2009 23:22:23 +0000 Subject: [PATCH 0028/1043] Corrected MIME type on the scrolling benchmarks page. From ab64d8ada1cdaf0f4962ee615019691c1d9989bd Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Sun, 29 Mar 2009 23:49:19 +0000 Subject: [PATCH 0029/1043] Added the ability to adjust to the browser's rendering speed and not prematurely switch into async rendering mode if the browser can handle it. Other optimizations and minor code cleanup. --- example4-model.html | 2 +- scrolling benchmarks.html | 2 +- slick.grid.js | 130 ++++++++++++++++++-------------------- 3 files changed, 63 insertions(+), 71 deletions(-) diff --git a/example4-model.html b/example4-model.html index 36006b8..c16ee9c 100644 --- a/example4-model.html +++ b/example4-model.html @@ -70,7 +70,7 @@

    Demonstrates:

  • grid reacting to model events (onRowCountChanged, onRowsChanged)
  • FAST DataView recalculation and real-time grid updating in response to data changes.
    - The grid holds 1'000 rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows. + The grid holds 10'000 rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows.
  • adding new rows, bidirectional sorting
  • column options: setValueHandler, cannotTriggerInsert
  • diff --git a/scrolling benchmarks.html b/scrolling benchmarks.html index d7df111..3abd128 100644 --- a/scrolling benchmarks.html +++ b/scrolling benchmarks.html @@ -168,7 +168,7 @@ if ($grid.scrollTop() == lastScrollTop + scrollAmount) { lastScrollTop = $grid.scrollTop(); - window.setTimeout(bench, 0); + window.setTimeout(bench, 10); } else { alert((new Date() - startTime)); diff --git a/slick.grid.js b/slick.grid.js index 5c45ea9..b9b3cc1 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -106,6 +106,7 @@ function SlickGrid($container,data,columns,options) var currentScrollTop = 0; var currentScrollLeft = 0; var scrollDir = 1; + var avgRowRenderTime = 10; var selectedRows = []; var selectedRowsLookup = {}; @@ -121,6 +122,9 @@ function SlickGrid($container,data,columns,options) var fragment = document.createDocumentFragment(); + // internal + var _forceSyncScrolling = false; + function init() { options = $.extend({},defaults,options); @@ -182,7 +186,7 @@ function SlickGrid($container,data,columns,options) // todo: rerender single column instead of everything if (columns[cell].rerenderOnResize) { removeAllRows(); - renderViewport(); + render(); } } }); @@ -214,7 +218,7 @@ function SlickGrid($container,data,columns,options) removeAllRows(); removeCssRules(); createCssRules(); - renderViewport(); + render(); if (self.onColumnsReordered) self.onColumnsReordered(); @@ -334,7 +338,7 @@ function SlickGrid($container,data,columns,options) options = $.extend(options,args); - renderViewport(); + render(); } @@ -352,15 +356,15 @@ function SlickGrid($container,data,columns,options) stringArray.push("
    "); - for (var j=0; j"); + stringArray.push("
    "); // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet) if (row < data.length && d) - stringArray.push(m.formatter(row, j, d[m.field], m, d)); + stringArray.push(m.formatter(row, i, d[m.field], m, d)); stringArray.push("
    "); } @@ -430,7 +434,7 @@ function SlickGrid($container,data,columns,options) viewportH = $divMainScroller.innerHeight(); BUFFER = numVisibleRows = Math.ceil(viewportH / ROW_HEIGHT); - CAPACITY = Math.max(CAPACITY, numVisibleRows + 2*BUFFER > CAPACITY); + CAPACITY = Math.max(CAPACITY, numVisibleRows + 2*BUFFER); $divMain.height(Math.max(ROW_HEIGHT * (data.length + numVisibleRows - 2), viewportH - $.getScrollbarWidth())); @@ -471,41 +475,7 @@ function SlickGrid($container,data,columns,options) bottom: Math.floor((currentScrollTop + viewportH) / ROW_HEIGHT) }; } - - function renderRows(from,to) { - console.time("renderRows"); - - var rowsBefore = renderedRows; - - var stringArray = []; - - for (var i = from; i <= to; i++) { - if (rowsCache[i]) continue; - renderedRows++; - - counter_rows_rendered++; - - var x = document.createElement("div"); - x.innerHTML = getRowHtml(i); - x = x.firstChild; - //rowsCache[i] = $divMain[0].appendChild(x); - rowsCache[i] = fragment.appendChild(x); - } - - $divMain[0].appendChild(fragment); - - console.log("rendered " + (renderedRows - rowsBefore) + " rows"); - console.timeEnd("renderRows"); - } - - function renderViewport() { - var vp = getViewport(); - var from = Math.max(0, vp.top - (scrollDir >= 0 ? 5 : BUFFER)); - var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollDir > 0 ? BUFFER : 5)); - renderRows(from,to); - } - function removeAllRows() { console.time("removeAllRows"); @@ -516,23 +486,15 @@ function SlickGrid($container,data,columns,options) console.timeEnd("removeAllRows"); } - function cleanupRows() { + function cleanupRows(visibleFrom,visibleTo) { console.time("cleanupRows"); var rowsBefore = renderedRows; - var vp = getViewport(); - var from = vp.top - BUFFER, to = vp.bottom + BUFFER; - - // todo: bias based on the direction of scroll - // todo: remove rows in correct order (farthest first) - var parentNode = $divMain[0]; for (var i in rowsCache) { - if (renderedRows <= CAPACITY) break; - - if (i != currentRow && (i < from || i > to)) + if (i != currentRow && (i < visibleFrom || i > visibleTo)) { parentNode.removeChild(rowsCache[i]); @@ -547,16 +509,47 @@ function SlickGrid($container,data,columns,options) console.timeEnd("cleanupRows"); } - function render() { - if (renderedRows >= CAPACITY) - cleanupRows(); + function renderRows(from,to) { + console.time("renderRows"); + + var rowsBefore = renderedRows; + var stringArray = []; + var _start = new Date(); + + for (var i = from; i <= to; i++) { + if (rowsCache[i]) continue; + renderedRows++; + + counter_rows_rendered++; + + var x = document.createElement("div"); + x.innerHTML = getRowHtml(i); + x = x.firstChild; + rowsCache[i] = fragment.appendChild(x); + } + + $divMain[0].appendChild(fragment); + + if (renderedRows - rowsBefore > 5) + avgRowRenderTime = (new Date() - _start) / (renderedRows - rowsBefore); + + console.log("rendered " + (renderedRows - rowsBefore) + " rows"); + console.timeEnd("renderRows"); + } - renderViewport(); + function render() { + var vp = getViewport(); + var from = Math.max(0, vp.top - (scrollDir >= 0 ? 5 : BUFFER)); + var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollDir > 0 ? BUFFER : 5)); + + if (Math.abs(lastRenderedScrollTop - currentScrollTop) > ROW_HEIGHT*CAPACITY) + removeAllRows(); + else if (renderedRows >= CAPACITY) + cleanupRows(from,to); + + renderRows(from,to); - if (renderedRows >= CAPACITY) - cleanupRows(); - - lastRenderedScrollTop = parseInt(currentScrollTop); + lastRenderedScrollTop = currentScrollTop; h_render = null; } @@ -578,15 +571,13 @@ function SlickGrid($container,data,columns,options) else scrollDir = -1; - - window.clearTimeout(h_render); - - window.status = "async scroll = " + (scrollDistance > 2*numVisibleRows*ROW_HEIGHT); + if (h_render) + window.clearTimeout(h_render); - if (scrollDistance > 2*numVisibleRows*ROW_HEIGHT) - h_render = window.setTimeout(render, 50); - else + if (scrollDistance < 2*numVisibleRows*ROW_HEIGHT || avgRowRenderTime*CAPACITY < 30 || _forceSyncScrolling) render(); + else + h_render = window.setTimeout(render, 50); if (self.onViewportChanged) self.onViewportChanged(); @@ -997,7 +988,8 @@ function SlickGrid($container,data,columns,options) s += ("\n" + "renderedRows: " + renderedRows); s += ("\n" + "numVisibleRows: " + numVisibleRows); s += ("\n" + "CAPACITY: " + CAPACITY); - s += ("\n" + "BUFFER: " + BUFFER); + s += ("\n" + "BUFFER: " + BUFFER); + s += ("\n" + "avgRowRenderTime: " + avgRowRenderTime); alert(s); }; @@ -1064,7 +1056,7 @@ function SlickGrid($container,data,columns,options) "render": render, "getViewport": getViewport, "resizeCanvas": resizeCanvas, - "scroll": scroll, + "scroll": scroll, // TODO "getCellFromPoint": getCellFromPoint, "gotoCell": gotoCell, "editCurrentCell": makeSelectedCellEditable, From 9eab7afe5a216e35d217b016d1ecd5daba55506b Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Mon, 30 Mar 2009 00:10:31 +0000 Subject: [PATCH 0030/1043] --- slick.grid.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index b9b3cc1..2c58b9e 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -937,17 +937,20 @@ function SlickGrid($container,data,columns,options) { var value = currentEditor.getValue(); - if (currentRow < data.length) - { - if (columns[currentCell].setValueHandler) + if (currentRow < data.length) { + if (columns[currentCell].setValueHandler) { + makeSelectedCellNormal(); columns[currentCell].setValueHandler(value, columns[currentCell], data[currentRow]); - else + } + else { data[currentRow][columns[currentCell].field] = value; + makeSelectedCellNormal(); + } } - else if (self.onAddNewRow) - self.onAddNewRow(columns[currentCell], value); - - makeSelectedCellNormal(); + else if (self.onAddNewRow) { + makeSelectedCellNormal(); + self.onAddNewRow(columns[currentCell], value); + } return true; } From 36087a5769e70234654ebf4ecbaab5cee3a71367 Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Tue, 31 Mar 2009 17:58:59 +0000 Subject: [PATCH 0031/1043] Performance optimizations and code cleanup. --- example4-model.html | 5 +-- slick.grid.js | 103 ++++++++++++++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 37 deletions(-) diff --git a/example4-model.html b/example4-model.html index c16ee9c..63aec65 100644 --- a/example4-model.html +++ b/example4-model.html @@ -205,10 +205,7 @@

    Demonstrates:

    }); dataView.onRowsChanged.subscribe(function(rows) { - for (var i=0, rl=rows.length; i visibleTo)) + { + parentNode.removeChild(rowsCache[i]); + + delete rowsCache[i]; + renderedRows--; + + counter_rows_removed++; + } + } + + console.log("removed " + (rowsBefore - renderedRows) + " rows"); + console.timeEnd("cleanupRows"); + } + + function removeAllRows() { + console.time("removeAllRows"); + + $divMain[0].innerHTML = ""; + rowsCache= {}; + counter_rows_removed += renderedRows; + renderedRows = 0; + console.timeEnd("removeAllRows"); + } function removeRow(row) { var node = rowsCache[row]; @@ -399,6 +432,42 @@ function SlickGrid($container,data,columns,options) counter_rows_removed++; } + function removeRows(rows) { + console.time("removeRows"); + + if (!rows || !rows.length) return; + + scrollDir = 0; + var nodes = []; + + for (var i=0, rl=rows.length; i visibleTo)) - { - parentNode.removeChild(rowsCache[i]); - - delete rowsCache[i]; - renderedRows--; - - counter_rows_removed++; - } - } - - console.log("removed " + (rowsBefore - renderedRows) + " rows"); - console.timeEnd("cleanupRows"); - } function renderRows(from,to) { console.time("renderRows"); @@ -1055,6 +1091,7 @@ function SlickGrid($container,data,columns,options) "updateCell": updateCell, "updateRow": updateRow, "removeRow": removeRow, + "removeRows": removeRows, "removeAllRows": removeAllRows, "render": render, "getViewport": getViewport, From a0711355f4ae2e5140bfd6adcb6ef087f26e65e0 Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Thu, 2 Apr 2009 22:34:59 +0000 Subject: [PATCH 0032/1043] --- example5-collapsing.html | 287 +++++++++++++++++++++++++++++++++++++++ slick.grid.js | 39 +++--- slick.model.js | 5 + 3 files changed, 315 insertions(+), 16 deletions(-) create mode 100644 example5-collapsing.html diff --git a/example5-collapsing.html b/example5-collapsing.html new file mode 100644 index 0000000..7a76e58 --- /dev/null +++ b/example5-collapsing.html @@ -0,0 +1,287 @@ + + + + + SlickGrid example + + + + + + + + + + + + + + + + + + +
    + + + + +
    + +
    + + +
    +
    +
    + +
    + + + +
    + +
    + +
    +
    +

    Demonstrates:

    + +
      +
    • implementing expand/collapse as a filter for DataView
    • +
    + +
    + + + + + + + diff --git a/slick.grid.js b/slick.grid.js index f947a74..0d68955 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -12,6 +12,7 @@ * - break resizeCanvas() into two functions to handle container resize and data size changes * - improve rendering speed by merging column extra cssClass into dynamically-generated .c{x} rules * - expose row height in the API + * - improve rendering speed by reusing removed row nodes and doing one .replaceChild() instead of two .removeChild() and .appendChild() * * KNOWN ISSUES: * - keyboard navigation doesn't "jump" over unselectable cells for now @@ -434,7 +435,7 @@ function SlickGrid($container,data,columns,options) function removeRows(rows) { console.time("removeRows"); - + if (!rows || !rows.length) return; scrollDir = 0; @@ -444,10 +445,10 @@ function SlickGrid($container,data,columns,options) if (currentEditor && currentRow == i) throw "Grid : removeRow : Cannot remove a row that is currently in edit mode"; - var node = rowsCache[i]; + var node = rowsCache[rows[i]]; if (!node) continue; - nodes.push(i); + nodes.push(rows[i]); } if (nodes.length == renderedRows) { @@ -456,7 +457,7 @@ function SlickGrid($container,data,columns,options) counter_rows_removed += renderedRows; renderedRows = 0; } else { - for (var i=0, nl=nodes.length; i 5) avgRowRenderTime = (new Date() - _start) / (renderedRows - rowsBefore); @@ -590,14 +596,15 @@ function SlickGrid($container,data,columns,options) } function handleScroll() { - var scrollLeft = parseInt($divMainScroller[0].scrollLeft); + currentScrollTop = $divMainScroller[0].scrollTop; + var scrollDistance = Math.abs(lastRenderedScrollTop - currentScrollTop); + var scrollLeft = $divMainScroller[0].scrollLeft; if (scrollLeft != currentScrollLeft) - $divMainScroller[0].scrollLeft = currentScrollLeft = scrollLeft; + $divHeadersScroller[0].scrollLeft = currentScrollLeft = scrollLeft; + + window.status = currentScrollLeft; - currentScrollTop = parseInt($divMainScroller[0].scrollTop); - var scrollDistance = Math.abs(lastRenderedScrollTop - currentScrollTop); - if (scrollDistance < 5*ROW_HEIGHT) return; if (lastRenderedScrollTop == currentScrollTop) diff --git a/slick.model.js b/slick.model.js index 845bf4a..703d904 100644 --- a/slick.model.js +++ b/slick.model.js @@ -66,6 +66,10 @@ function DataView() { refresh(); } + function getIdxById(id) { + return idxById[id]; + } + function getItemById(id) { return items[idxById[id]]; } @@ -149,6 +153,7 @@ function DataView() { "setItems": setItems, "setFilter": setFilter, "sort": sort, + "getIdxById": getIdxById, "getItemById": getItemById, "refresh": refresh, "updateItem": updateItem, From 308ddaa56422b4884a45d84766e356158dee262c Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Thu, 2 Apr 2009 22:35:24 +0000 Subject: [PATCH 0033/1043] From 32d06faf90e087803aae2bcfa6883af24fdbab6d Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Fri, 10 Apr 2009 18:45:57 +0000 Subject: [PATCH 0034/1043] Moved examples and tests into separate folders. Some performance optimizations in the rendering function; needs more work. --- .../example1-simple.html | 20 +++++------ .../example2-formatters.html | 20 +++++------ .../example3-editing.html | 20 +++++------ .../example4-model.html | 28 +++++++-------- .../example5-collapsing.html | 30 ++++++++-------- examples.css => examples/examples.css | 0 grid.html => examples/grid.html | 0 .../simpledropdown.css | 0 slick.editors.js | 16 ++++----- slick.grid.js | 34 ++++++++----------- .../model benchmarks.html | 6 ++-- .../scrolling benchmarks.html | 31 +++++++++-------- 12 files changed, 99 insertions(+), 106 deletions(-) rename example1-simple.html => examples/example1-simple.html (64%) rename example2-formatters.html => examples/example2-formatters.html (69%) rename example3-editing.html => examples/example3-editing.html (73%) rename example4-model.html => examples/example4-model.html (83%) rename example5-collapsing.html => examples/example5-collapsing.html (82%) rename examples.css => examples/examples.css (100%) rename grid.html => examples/grid.html (100%) rename simpledropdown.css => examples/simpledropdown.css (100%) rename model benchmarks.html => tests/model benchmarks.html (76%) rename scrolling benchmarks.html => tests/scrolling benchmarks.html (76%) diff --git a/example1-simple.html b/examples/example1-simple.html similarity index 64% rename from example1-simple.html rename to examples/example1-simple.html index 1327b77..0bee461 100644 --- a/example1-simple.html +++ b/examples/example1-simple.html @@ -3,22 +3,22 @@ SlickGrid example - - + + - - - - - + + + + + - - - + + + diff --git a/example2-formatters.html b/examples/example2-formatters.html similarity index 69% rename from example2-formatters.html rename to examples/example2-formatters.html index bfe3b64..df63935 100644 --- a/example2-formatters.html +++ b/examples/example2-formatters.html @@ -3,8 +3,8 @@ SlickGrid example - - + + - - - - - + + + + + - - - + + +
    diff --git a/example3-editing.html b/examples/example3-editing.html similarity index 73% rename from example3-editing.html rename to examples/example3-editing.html index 1f4a963..9b724f5 100644 --- a/example3-editing.html +++ b/examples/example3-editing.html @@ -3,8 +3,8 @@ SlickGrid example - - + + - - - - - + + + + + - - - + + +
    diff --git a/example4-model.html b/examples/example4-model.html similarity index 83% rename from example4-model.html rename to examples/example4-model.html index 63aec65..d0934a7 100644 --- a/example4-model.html +++ b/examples/example4-model.html @@ -3,8 +3,8 @@ SlickGrid example - - + + - - - - - - - - - - + + + + + + + + + +
    diff --git a/example5-collapsing.html b/examples/example5-collapsing.html similarity index 82% rename from example5-collapsing.html rename to examples/example5-collapsing.html index 7a76e58..b6b8310 100644 --- a/example5-collapsing.html +++ b/examples/example5-collapsing.html @@ -3,8 +3,8 @@ SlickGrid example - - + + - - - - - + + + + + - - - - + + + +
    diff --git a/examples.css b/examples/examples.css similarity index 100% rename from examples.css rename to examples/examples.css diff --git a/grid.html b/examples/grid.html similarity index 100% rename from grid.html rename to examples/grid.html diff --git a/simpledropdown.css b/examples/simpledropdown.css similarity index 100% rename from simpledropdown.css rename to examples/simpledropdown.css diff --git a/slick.editors.js b/slick.editors.js index 1c7d46c..6d2a4a7 100644 --- a/slick.editors.js +++ b/slick.editors.js @@ -32,13 +32,13 @@ var YesNoCellFormatter = function(row, cell, value, columnDef, dataContext) { }; var BoolCellFormatter = function(row, cell, value, columnDef, dataContext) { - return value ? "" : ""; + return value ? "" : ""; }; var TaskNameFormatter = function(row, cell, value, columnDef, dataContext) { // todo: html encode var spacer = ""; - return spacer + "  " + value; + return spacer + "  " + value; }; var ResourcesFormatter = function(row, cell, value, columnDef, dataContext) { @@ -48,18 +48,14 @@ var ResourcesFormatter = function(row, cell, value, columnDef, dataContext) { return ""; if (columnDef.width < 50) - return (resources.length > 1 ? "
    1 ? "
    "; else return resources.join(", "); - - // todo: html encode - - //return "  " + resources.join(", "); }; var StarFormatter = function(row, cell, value, columnDef, dataContext) { - return (value) ? "" : ""; + return (value) ? "" : ""; }; @@ -142,7 +138,7 @@ var DateCellEditor = function($container, columnDef, value, dataContext) { $input.datepicker({ showOn: "button", buttonImageOnly: true, - buttonImage: "images/calendar.gif" + buttonImage: "../images/calendar.gif" }); $input.width($input.width() - $container.find("img").width()); } @@ -518,7 +514,7 @@ var StarCellEditor = function($container, columnDef, value, dataContext) { } this.init = function() { - $input = $(""); + $input = $(""); if (defaultValue) $input.css("opacity", 1); diff --git a/slick.grid.js b/slick.grid.js index 0d68955..3f1617a 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -136,6 +136,7 @@ function SlickGrid($container,data,columns,options) .attr("hideFocus",true) .css("overflow","hidden") .css("outline",0) + .css("position","relative") .addClass(uid); $divHeadersScroller = $("
    ").appendTo($container); @@ -185,10 +186,10 @@ function SlickGrid($container,data,columns,options) resizeCanvas(); // todo: rerender single column instead of everything - if (columns[cell].rerenderOnResize) { + if (columns[cell].rerenderOnResize) removeAllRows(); - render(); - } + + render(); } }); }); @@ -364,7 +365,7 @@ function SlickGrid($container,data,columns,options) stringArray.push("
    "); // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet) - if (row < data.length && d) + if (d && row < data.length) stringArray.push(m.formatter(row, i, d[m.field], m, d)); stringArray.push("
    "); @@ -389,7 +390,7 @@ function SlickGrid($container,data,columns,options) for (var i in rowsCache) { - if (i != currentRow && (i < visibleFrom || i > visibleTo)) + if ((i < visibleFrom || i > visibleTo) && i != currentRow) { parentNode.removeChild(rowsCache[i]); @@ -405,13 +406,10 @@ function SlickGrid($container,data,columns,options) } function removeAllRows() { - console.time("removeAllRows"); - $divMain[0].innerHTML = ""; rowsCache= {}; counter_rows_removed += renderedRows; renderedRows = 0; - console.timeEnd("removeAllRows"); } function removeRow(row) { @@ -532,6 +530,7 @@ function SlickGrid($container,data,columns,options) } } + // TODO: this sometimes results in scroll position jumping // browsers sometimes do not adjust scrollTop/scrollHeight when the height of contained objects changes if ($divMainScroller.scrollTop() > $divMain.height() - $divMainScroller.height()) @@ -549,12 +548,11 @@ function SlickGrid($container,data,columns,options) function renderRows(from,to) { console.time("renderRows"); + var parentNode = $divMain[0]; var rowsBefore = renderedRows; var stringArray = []; - var _start = new Date(); - var x = document.createElement("div"); - var rows =[]; + var _start = new Date(); for (var i = from; i <= to; i++) { if (rowsCache[i]) continue; @@ -566,11 +564,11 @@ function SlickGrid($container,data,columns,options) counter_rows_rendered++; } + var x = document.createElement("div"); x.innerHTML = stringArray.join(""); - - for (var i = 0, nodes = x.childNodes, l = nodes.length; i < l; i++) { - rowsCache[rows[i]] = $divMain[0].appendChild(x.firstChild); - } + + for (var i = 0, l = x.childNodes.length; i < l; i++) + rowsCache[rows[i]] = parentNode.appendChild(x.firstChild); if (renderedRows - rowsBefore > 5) avgRowRenderTime = (new Date() - _start) / (renderedRows - rowsBefore); @@ -583,10 +581,10 @@ function SlickGrid($container,data,columns,options) var vp = getViewport(); var from = Math.max(0, vp.top - (scrollDir >= 0 ? 5 : BUFFER)); var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollDir > 0 ? BUFFER : 5)); - + if (Math.abs(lastRenderedScrollTop - currentScrollTop) > ROW_HEIGHT*CAPACITY) removeAllRows(); - else if (renderedRows >= CAPACITY) + else cleanupRows(from,to); renderRows(from,to); @@ -603,8 +601,6 @@ function SlickGrid($container,data,columns,options) if (scrollLeft != currentScrollLeft) $divHeadersScroller[0].scrollLeft = currentScrollLeft = scrollLeft; - window.status = currentScrollLeft; - if (scrollDistance < 5*ROW_HEIGHT) return; if (lastRenderedScrollTop == currentScrollTop) diff --git a/model benchmarks.html b/tests/model benchmarks.html similarity index 76% rename from model benchmarks.html rename to tests/model benchmarks.html index a9423df..7968897 100644 --- a/model benchmarks.html +++ b/tests/model benchmarks.html @@ -5,9 +5,9 @@ - - - + + + - - - - + + + + + - - - - + + + + @@ -163,11 +164,11 @@ }, 500); } - function bench(){ - $grid.scrollTop(lastScrollTop + scrollAmount); + function bench() { + var scrollTop = $grid[0].scrollTop = lastScrollTop + scrollAmount; - if ($grid.scrollTop() == lastScrollTop + scrollAmount) { - lastScrollTop = $grid.scrollTop(); + if ($grid[0].scrollTop == lastScrollTop + scrollAmount) { + lastScrollTop = scrollTop; window.setTimeout(bench, 10); } else { From 396576788bf018313771478f7c4347892b529b62 Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Fri, 10 Apr 2009 22:09:12 +0000 Subject: [PATCH 0035/1043] --- examples/grid.html | 36 ++++++++++++++++++------------------ slick.grid.js | 13 ++++++------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/examples/grid.html b/examples/grid.html index 950c87a..ccff916 100644 --- a/examples/grid.html +++ b/examples/grid.html @@ -4,8 +4,8 @@ Spreadsheet prototype - - + + - - - - - + + + + + - - - + + +
    @@ -152,7 +152,7 @@ - Quick info + Quick info
    This page demonstrate the use of a SlickGrid control. @@ -337,7 +337,7 @@ // toggle expand/collapse icon if (model[cell].id == "title" && $(e.target).is("img")) { - $(e.target).attr("src", $(e.target).attr("src") != "images/collapse.gif" ? "images/collapse.gif" : "images/expand.gif"); + $(e.target).attr("src", $(e.target).attr("src") != "../images/collapse.gif" ? "../images/collapse.gif" : "../images/expand.gif"); return true; } diff --git a/slick.grid.js b/slick.grid.js index 3f1617a..6c1d06e 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -504,9 +504,6 @@ function SlickGrid($container,data,columns,options) BUFFER = numVisibleRows = Math.ceil(viewportH / ROW_HEIGHT); CAPACITY = Math.max(CAPACITY, numVisibleRows + 2*BUFFER); - $divMain.height(Math.max(ROW_HEIGHT * (data.length + numVisibleRows - 2), viewportH - $.getScrollbarWidth())); - - var totalWidth = 0; for (var i=0; i $divMain.height() - $divMainScroller.height()) - $divMainScroller.scrollTop($divMain.height() - $divMainScroller.height()); + if ($divMainScroller.scrollTop() > newHeight - $divMainScroller.height() + $.getScrollbarWidth()) + $divMainScroller.scrollTop(newHeight - $divMainScroller.height() + $.getScrollbarWidth()); + + $divMain.height(newHeight); } function getViewport() From b181526f151d2a931cc2e0d711d91f4cc6074f79 Mon Sep 17 00:00:00 2001 From: "michael.leibman@gmail.com" Date: Sat, 11 Apr 2009 00:08:49 +0000 Subject: [PATCH 0036/1043] Fixed a reported issue. Tweaked the rendering logic to avoid flicker (a bit of a step back for faster browsers; needs some more work). Fixed URLs broken during the reorg. --- examples/examples.css | 2 +- slick.grid.js | 20 +++++++++++--------- tests/scrolling benchmarks.html | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/examples/examples.css b/examples/examples.css index 53af505..7ec5f7a 100644 --- a/examples/examples.css +++ b/examples/examples.css @@ -19,7 +19,7 @@ ul { } li { - background: url("images/arrow_right_spearmint.png") no-repeat center left; + background: url("../images/arrow_right_spearmint.png") no-repeat center left; padding: 0px; padding-left: 14px; list-style: none; diff --git a/slick.grid.js b/slick.grid.js index 6c1d06e..468ee3e 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -406,6 +406,7 @@ function SlickGrid($container,data,columns,options) } function removeAllRows() { + console.log("removeAllRows") $divMain[0].innerHTML = ""; rowsCache= {}; counter_rows_removed += renderedRows; @@ -449,7 +450,7 @@ function SlickGrid($container,data,columns,options) nodes.push(rows[i]); } - if (nodes.length == renderedRows) { + if (renderedRows > 10 && nodes.length == renderedRows) { $divMain[0].innerHTML = ""; rowsCache= {}; counter_rows_removed += renderedRows; @@ -500,8 +501,8 @@ function SlickGrid($container,data,columns,options) function resizeCanvas() { viewportW = $divMainScroller.innerWidth(); viewportH = $divMainScroller.innerHeight(); - - BUFFER = numVisibleRows = Math.ceil(viewportH / ROW_HEIGHT); + + BUFFER = numVisibleRows = Math.ceil(viewportH / ROW_HEIGHT); CAPACITY = Math.max(CAPACITY, numVisibleRows + 2*BUFFER); var totalWidth = 0; @@ -530,10 +531,11 @@ function SlickGrid($container,data,columns,options) var newHeight = Math.max(ROW_HEIGHT * (data.length + numVisibleRows - 2), viewportH - $.getScrollbarWidth()); // browsers sometimes do not adjust scrollTop/scrollHeight when the height of contained objects changes - if ($divMainScroller.scrollTop() > newHeight - $divMainScroller.height() + $.getScrollbarWidth()) + if ($divMainScroller.scrollTop() > newHeight - $divMainScroller.height() + $.getScrollbarWidth()) { $divMainScroller.scrollTop(newHeight - $divMainScroller.height() + $.getScrollbarWidth()); + } + $divMain.height(newHeight); - $divMain.height(newHeight); } function getViewport() @@ -581,9 +583,9 @@ function SlickGrid($container,data,columns,options) var from = Math.max(0, vp.top - (scrollDir >= 0 ? 5 : BUFFER)); var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollDir > 0 ? BUFFER : 5)); - if (Math.abs(lastRenderedScrollTop - currentScrollTop) > ROW_HEIGHT*CAPACITY) + if (renderedRows > 10 && Math.abs(lastRenderedScrollTop - currentScrollTop) > ROW_HEIGHT*CAPACITY) removeAllRows(); - else + else //if (renderedRows >= CAPACITY) cleanupRows(from,to); renderRows(from,to); @@ -611,8 +613,8 @@ function SlickGrid($container,data,columns,options) if (h_render) window.clearTimeout(h_render); - - if (scrollDistance < 2*numVisibleRows*ROW_HEIGHT || avgRowRenderTime*CAPACITY < 30 || _forceSyncScrolling) + + if (scrollDistance < numVisibleRows*ROW_HEIGHT) // || avgRowRenderTime*CAPACITY < 30 || _forceSyncScrolling) render(); else h_render = window.setTimeout(render, 50); diff --git a/tests/scrolling benchmarks.html b/tests/scrolling benchmarks.html index a50ca6e..7ee48e6 100644 --- a/tests/scrolling benchmarks.html +++ b/tests/scrolling benchmarks.html @@ -31,7 +31,7 @@ - +
    From e6ff93ccaca1b1c6591c063014399eab4bf01a22 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Fri, 18 Sep 2009 20:22:41 +0000 Subject: [PATCH 0037/1043] --- examples/grid.html | 4 ++-- slick.grid.js | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/grid.html b/examples/grid.html index ccff916..27330b9 100644 --- a/examples/grid.html +++ b/examples/grid.html @@ -228,12 +228,12 @@ var model = [ {id:"#", name:"#", cssClass:"cell-move-handle", width:60, resizable:false, unselectable:true, formatter:SelectorCellFormatter}, {id:"title", name:"Title", field:"title", formatter:TaskNameFormatter, width:300, editor:TextCellEditor, validator:nonEmptyValidator}, - {id:"star", name:"", field:"starred", formatter:StarFormatter, editor:StarCellEditor, width:16, resizable:false, cannotTriggerInsert:true}, + {id:"star", name:"", field:"starred", formatter:StarFormatter, editor:StarCellEditor, width:16, resizable:false, cannotTriggerInsert:true}, {id:"duration", name:"Duration", field:"duration", width:80, editor:TextCellEditor}, {id:"%", name:"% Complete", field:"percentComplete", formatter:GraphicalPercentCompleteCellFormatter, width:60, editor:PercentCompleteCellEditor}, {id:"start", name:"Start", field:"start", width:100, editor:DateCellEditor}, {id:"finish", name:"Finish", field:"finish", width:100, editor:DateCellEditor}, - {id:"resources", name:"Resources", formatter:ResourcesFormatter, rerenderOnResize:true, width:200, editor:ResourcesCellEditor, setValueHandler:setTaskResources, cannotTriggerInsert:true, minWidth:16, maxWidth:200}, + {id:"resources", name:"Resources ", formatter:ResourcesFormatter, rerenderOnResize:true, width:200, editor:ResourcesCellEditor, setValueHandler:setTaskResources, cannotTriggerInsert:true, minWidth:16, maxWidth:200}, {id:"preds", name:"Predecessors", width:100, editor:TextCellEditor, cannotTriggerInsert:true} , {id:"e", name:"Deliverable", field:4, formatter:YesNoCellFormatter, width:60, editor:YesNoSelectCellEditor, cannotTriggerInsert:true}, diff --git a/slick.grid.js b/slick.grid.js index 468ee3e..347944d 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -162,10 +162,6 @@ function SlickGrid($container,data,columns,options) .html(m.name) .width(m.width) .appendTo($divHeaders); - - // todo: this is for demo purposes only - if (m.rerenderOnResize) - header.append(" "); } $divHeaders.find(".h").each(function() { @@ -343,6 +339,12 @@ function SlickGrid($container,data,columns,options) render(); } + function setData(newData) + { + removeAllRows(); + data = newData; + $divMainScroller.scrollTop(0); + } ////////////////////////////////////////////////////////////////////////////////////////////// // Rendering / Scrolling @@ -1090,6 +1092,8 @@ function SlickGrid($container,data,columns,options) "onColumnsReordered": null, // Methods + "setOptions": setOptions, + "setData": setData, "destroy": destroy, "getColumnIndex": getColumnIndex, "updateCell": updateCell, From 346d7a2905e4f829d695221f888293aed649e647 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 5 Oct 2009 18:58:33 +0000 Subject: [PATCH 0038/1043] Added zebra striping CSS for supported browsers (CSS3). --- slick.grid.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/slick.grid.css b/slick.grid.css index 2295730..ef1a735 100644 --- a/slick.grid.css +++ b/slick.grid.css @@ -44,6 +44,10 @@ background: white; } +.grid-canvas .r[row$="1"], .grid-canvas .r[row$="3"], .grid-canvas .r[row$="5"], .grid-canvas .r[row$="7"], .grid-canvas .r[row$="9"]{ + background: #f5f5f5; +} + .grid-canvas .r.loading { background: url("images/stripes.png") repeat-x center center; } From 0f26208e3b692d3ae83adfbf22be37664cd82268 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 8 Oct 2009 21:20:53 +0000 Subject: [PATCH 0039/1043] --- slick.grid.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slick.grid.css b/slick.grid.css index ef1a735..15132f5 100644 --- a/slick.grid.css +++ b/slick.grid.css @@ -49,7 +49,9 @@ } .grid-canvas .r.loading { - background: url("images/stripes.png") repeat-x center center; + -background: url("images/stripes.png") repeat-x center center; + opacity: 0.5; + filter: alpha(opacity=50); } .grid-canvas .r:hover { From 2342657da65cd9d23e076bf3bb87d84730aabe06 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 8 Oct 2009 21:22:32 +0000 Subject: [PATCH 0040/1043] --- examples/example6-ajax-loading.html | 115 ++++++++++++++++++++++ slick.grid.js | 38 ++++---- slick.remotemodel.js | 144 ++++++++++++++++++++++++++++ 3 files changed, 277 insertions(+), 20 deletions(-) create mode 100644 examples/example6-ajax-loading.html create mode 100644 slick.remotemodel.js diff --git a/examples/example6-ajax-loading.html b/examples/example6-ajax-loading.html new file mode 100644 index 0000000..2345be8 --- /dev/null +++ b/examples/example6-ajax-loading.html @@ -0,0 +1,115 @@ + + + + + SlickGrid example + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +

    Demonstrates:

    + +
      +
    • loading data through AJAX
    • +
    • custom row height
    • +
    + +
    + + + + + + diff --git a/slick.grid.js b/slick.grid.js index 347944d..aa18f2a 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -11,7 +11,6 @@ * - consistent events (EventHelper? jQuery events?) * - break resizeCanvas() into two functions to handle container resize and data size changes * - improve rendering speed by merging column extra cssClass into dynamically-generated .c{x} rules - * - expose row height in the API * - improve rendering speed by reusing removed row nodes and doing one .replaceChild() instead of two .removeChild() and .appendChild() * * KNOWN ISSUES: @@ -20,6 +19,7 @@ * * * OPTIONS: + * rowHeight - Row height in pixels. * enableAddRow - If true, a blank row will be displayed at the bottom - typing values in that row will add a new one. * manualScrolling - Disable automatic rerender on scroll. Client will take care of calling Grid.onScroll(). * editable - If false, no cells will be switched into edit mode. @@ -72,6 +72,7 @@ function SlickGrid($container,data,columns,options) { // settings var defaults = { + rowHeight: 24, enableAddRow: true, manualScrolling: false, editable: true, @@ -83,7 +84,6 @@ function SlickGrid($container,data,columns,options) }; // consts - var ROW_HEIGHT = 24; var CAPACITY = 50; var BUFFER = 5; // will be set to equal one page @@ -259,6 +259,8 @@ function SlickGrid($container,data,columns,options) } function createCssRules() { + $.rule(".grid-canvas .r .c { height:" + (options.rowHeight-5) + "px;}").appendTo("style"); + for (var i = 0; i < columns.length; i++) { $.rule("." + uid + " .grid-canvas .c" + i + " { width:" + columns[i].width + "px }").appendTo("style"); } @@ -358,7 +360,7 @@ function SlickGrid($container,data,columns,options) var dataLoading = row < data.length && !d; var css = "r" + (dataLoading ? " loading" : "") + (selectedRowsLookup[row] ? " selected" : ""); - stringArray.push("
    "); + stringArray.push("
    "); for (var i=0, cols=columns.length; i newHeight - $divMainScroller.height() + $.getScrollbarWidth()) { @@ -543,8 +545,8 @@ function SlickGrid($container,data,columns,options) function getViewport() { return { - top: Math.floor(currentScrollTop / ROW_HEIGHT), - bottom: Math.floor((currentScrollTop + viewportH) / ROW_HEIGHT) + top: Math.floor(currentScrollTop / options.rowHeight), + bottom: Math.floor((currentScrollTop + viewportH) / options.rowHeight) }; } @@ -585,7 +587,7 @@ function SlickGrid($container,data,columns,options) var from = Math.max(0, vp.top - (scrollDir >= 0 ? 5 : BUFFER)); var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollDir > 0 ? BUFFER : 5)); - if (renderedRows > 10 && Math.abs(lastRenderedScrollTop - currentScrollTop) > ROW_HEIGHT*CAPACITY) + if (renderedRows > 10 && Math.abs(lastRenderedScrollTop - currentScrollTop) > options.rowHeight*CAPACITY) removeAllRows(); else //if (renderedRows >= CAPACITY) cleanupRows(from,to); @@ -604,7 +606,7 @@ function SlickGrid($container,data,columns,options) if (scrollLeft != currentScrollLeft) $divHeadersScroller[0].scrollLeft = currentScrollLeft = scrollLeft; - if (scrollDistance < 5*ROW_HEIGHT) return; + if (scrollDistance < 5*options.rowHeight) return; if (lastRenderedScrollTop == currentScrollTop) scrollDir = 0; @@ -616,7 +618,7 @@ function SlickGrid($container,data,columns,options) if (h_render) window.clearTimeout(h_render); - if (scrollDistance < numVisibleRows*ROW_HEIGHT) // || avgRowRenderTime*CAPACITY < 30 || _forceSyncScrolling) + if (scrollDistance < numVisibleRows*options.rowHeight) // || avgRowRenderTime*CAPACITY < 30 || _forceSyncScrolling) render(); else h_render = window.setTimeout(render, 50); @@ -641,11 +643,7 @@ function SlickGrid($container,data,columns,options) break; case 9: // tab - if (e.shiftKey) - gotoDir(0,-1,true); //gotoPrev(); - else - gotoDir(0,1,true); //gotoNext(); - + gotoDir(0, (e.shiftKey) ? -1 : 1, true); break; case 37: // left @@ -745,7 +743,7 @@ function SlickGrid($container,data,columns,options) } function getCellFromPoint(x,y) { - var row = Math.floor(y/ROW_HEIGHT); + var row = Math.floor(y/options.rowHeight); var cell = 0; var w = 0; @@ -891,16 +889,16 @@ function SlickGrid($container,data,columns,options) var scrollTop = $divMainScroller[0].scrollTop; // need to page down? - if ((currentRow + 2) * ROW_HEIGHT > scrollTop + viewportH) + if ((currentRow + 2) * options.rowHeight > scrollTop + viewportH) { - $divMainScroller[0].scrollTop = (currentRow ) * ROW_HEIGHT; + $divMainScroller[0].scrollTop = (currentRow ) * options.rowHeight; handleScroll(); } // or page up? - else if (currentRow * ROW_HEIGHT < scrollTop) + else if (currentRow * options.rowHeight < scrollTop) { - $divMainScroller[0].scrollTop = (currentRow + 2) * ROW_HEIGHT - viewportH; + $divMainScroller[0].scrollTop = (currentRow + 2) * options.rowHeight - viewportH; handleScroll(); } diff --git a/slick.remotemodel.js b/slick.remotemodel.js new file mode 100644 index 0000000..869b071 --- /dev/null +++ b/slick.remotemodel.js @@ -0,0 +1,144 @@ +/*** + * A simple observer pattern implementation. + */ +function EventHelper() { + this.handlers = []; + + this.subscribe = function(fn) { + this.handlers.push(fn); + } + + this.notify = function(args) { + for (var i = 0; i < this.handlers.length; i++) { + this.handlers[i].call(this, args); + } + } + + return this; +} + + + +/*** + * A sample AJAX data store implementation. + * Right now, it's hooked up to load all Apple-related Digg stories, but can + * easily be extended to support and JSONP-compatible backend that accepts paging parameters. + */ +function RemoteModel() { + // private + var data = {length:0}; + var sortcol = null; + var sortdir = 1; + var h_request = null; + + // events + var onDataLoading = new EventHelper(); + var onDataLoaded = new EventHelper(); + + + function init() { + } + + + function isDataLoaded(from,to) { + for (var i=from; i<=to; i++) { + if (data[i] == undefined || data[i] == null) + return false; + } + + return true; + } + + + function clear() { + data = {length:0}; + } + + + function ensureData(from,to) { + if (from < 0) + from = 0; + + while (data[from] != undefined && from < to) + from++; + + while (data[to] != undefined && from < to) + to--; + + if (from == to || isDataLoaded(from,to)) + return; + + var url = "http://services.digg.com/stories/topic/apple?offset=" + from + "&count=" + (to-from+1) + "&appkey=http://slickgrid.googlecode.com&type=javascript" + + //if (sortcol != null) + // url += ("&sort=" + sortcol + "&dir=" + ((sortdir>0)?"ASC":"DESC")); + + + // TODO: make the request abortable (not supported by jQuery for JSONP) + + if (h_request != null) + window.clearTimeout(h_request); + + h_request = window.setTimeout(function() { + console.warn("loading..."); + + onDataLoading.notify({from:from, to:to}); + + $.ajax({ + type: "GET", + url: url, + cache: true, // Digg doesn't accept the autogenerated cachebuster param + dataType: "jsonp", + success: _ajaxCallback + }); + }, 50); + } + + + function _ajaxCallback(resp) { + var from = resp.offset, to = resp.offset + resp.count; + data.length = parseInt(resp.total); + + for (var i = 0; i < resp.stories.length; i++) { + data[from + i] = resp.stories[i]; + data[from + i].index = from + i; + } + + onDataLoaded.notify({from:from, to:to}); + } + + + function reloadData(from,to) { + for (var i=from; i<=to; i++) + delete data[i]; + + ensureData(from,to); + } + + + function setSort(column,dir) { + sortcol = column; + sortdir = dir; + } + + + + + init(); + + return { + // properties + "data": data, + + // methods + "clear": clear, + "isDataLoaded": isDataLoaded, + "ensureData": ensureData, + "reloadData": reloadData, + "setSort": setSort, + + // events + "onDataLoading": onDataLoading, + "onDataLoaded": onDataLoaded + }; +} From d416f0d1224e5cb395a24d9790b7157b034edf58 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 8 Oct 2009 21:23:12 +0000 Subject: [PATCH 0041/1043] From 8bdde663646c7be422483b87ecbf56b8128f1b7d Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 8 Oct 2009 21:24:43 +0000 Subject: [PATCH 0042/1043] --- slick.grid.css | 1 - 1 file changed, 1 deletion(-) diff --git a/slick.grid.css b/slick.grid.css index 15132f5..27d0053 100644 --- a/slick.grid.css +++ b/slick.grid.css @@ -49,7 +49,6 @@ } .grid-canvas .r.loading { - -background: url("images/stripes.png") repeat-x center center; opacity: 0.5; filter: alpha(opacity=50); } From 51ac5981358695a76167a8b6d055c273ba600311 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 8 Oct 2009 21:25:07 +0000 Subject: [PATCH 0043/1043] From 3860c88d226163bc3e3602c834e64c1a173940b8 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 8 Oct 2009 21:31:25 +0000 Subject: [PATCH 0044/1043] --- slick.grid.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/slick.grid.js b/slick.grid.js index aa18f2a..0070095 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -267,6 +267,8 @@ function SlickGrid($container,data,columns,options) } function removeCssRules() { + $.rule(".grid-canvas .r .c").remove(); + for (var i = 0; i < columns.length; i++) { $.rule("." + uid + " .grid-canvas .c" + i, "style").remove(); } From eb55c2829e166c642530fc57b6140c32f204c329 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Thu, 8 Oct 2009 21:31:43 +0000 Subject: [PATCH 0045/1043] --- slick.grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slick.grid.js b/slick.grid.js index 0070095..6286651 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -267,7 +267,7 @@ function SlickGrid($container,data,columns,options) } function removeCssRules() { - $.rule(".grid-canvas .r .c").remove(); + $.rule(".grid-canvas .r .c", "style").remove(); for (var i = 0; i < columns.length; i++) { $.rule("." + uid + " .grid-canvas .c" + i, "style").remove(); From e43dbd2d22295a90123dfbcde7fe60be7d7aa6e8 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Fri, 9 Oct 2009 18:26:19 +0000 Subject: [PATCH 0046/1043] --- examples/example1-simple.html | 4 ++++ examples/example4-model.html | 2 +- examples/example5-collapsing.html | 2 +- examples/example6-ajax-loading.html | 12 +++++++++++- examples/grid.html | 2 +- slick.editors.js | 2 +- slick.grid.js | 24 ++++++++++++++++++++---- 7 files changed, 39 insertions(+), 9 deletions(-) diff --git a/examples/example1-simple.html b/examples/example1-simple.html index 0bee461..624558b 100644 --- a/examples/example1-simple.html +++ b/examples/example1-simple.html @@ -31,6 +31,7 @@

    Demonstrates:

    • basic grid with minimal configuration
    • +
    • grid handles container resizing
    @@ -74,8 +75,11 @@

    Demonstrates:

    d["effortDriven"] = (i % 5 == 0); } + grid = new SlickGrid($("#myGrid"), data, columns, options); + + $("#myGrid").resizable(); }) diff --git a/examples/example4-model.html b/examples/example4-model.html index d0934a7..b50e37d 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -201,7 +201,7 @@

    Demonstrates:

    // wire up model events to drive the grid dataView.onRowCountChanged.subscribe(function(args) { - grid.resizeCanvas(); + grid.updateRowCount(); }); dataView.onRowsChanged.subscribe(function(rows) { diff --git a/examples/example5-collapsing.html b/examples/example5-collapsing.html index b6b8310..5c01849 100644 --- a/examples/example5-collapsing.html +++ b/examples/example5-collapsing.html @@ -245,7 +245,7 @@

    Demonstrates:

    // wire up model events to drive the grid dataView.onRowCountChanged.subscribe(function(args) { - grid.resizeCanvas(); + grid.updateRowCount(); }); dataView.onRowsChanged.subscribe(function(rows) { diff --git a/examples/example6-ajax-loading.html b/examples/example6-ajax-loading.html index 2345be8..d179a29 100644 --- a/examples/example6-ajax-loading.html +++ b/examples/example6-ajax-loading.html @@ -36,6 +36,10 @@
    + +
    +
    + Status: 

    Demonstrates:

    @@ -93,13 +97,19 @@

    Demonstrates:

    } + loader.onDataLoading.subscribe(function() { + $("#status").text("Loading..."); + }); + loader.onDataLoaded.subscribe(function(args) { for (var i = args.from; i <= args.to; i++) { grid.removeRow(i); } - grid.resizeCanvas(); + grid.updateRowCount(); grid.render(); + + $("#status").text("Ready."); }); diff --git a/examples/grid.html b/examples/grid.html index 27330b9..d9d27d2 100644 --- a/examples/grid.html +++ b/examples/grid.html @@ -328,7 +328,7 @@ data[data.length] = item; - grid.resizeCanvas(); + grid.updateRowCount(); grid.render(); grid.updateRow(data.length-1); } diff --git a/slick.editors.js b/slick.editors.js index 6d2a4a7..4914f67 100644 --- a/slick.editors.js +++ b/slick.editors.js @@ -140,7 +140,7 @@ var DateCellEditor = function($container, columnDef, value, dataContext) { buttonImageOnly: true, buttonImage: "../images/calendar.gif" }); - $input.width($input.width() - $container.find("img").width()); + $input.width($input.width() - 18); } diff --git a/slick.grid.js b/slick.grid.js index 6286651..9d81572 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -9,7 +9,6 @@ * - built-in row reorder * - add custom editor options * - consistent events (EventHelper? jQuery events?) - * - break resizeCanvas() into two functions to handle container resize and data size changes * - improve rendering speed by merging column extra cssClass into dynamically-generated .c{x} rules * - improve rendering speed by reusing removed row nodes and doing one .replaceChild() instead of two .removeChild() and .appendChild() * @@ -247,6 +246,8 @@ function SlickGrid($container,data,columns,options) if (!options.manualScrolling) $divMainScroller.bind("scroll", handleScroll); + $container.bind("resize", resizeCanvas); + $divMain.bind("keydown", handleKeyDown); $divMain.bind("click", handleClick); $divMain.bind("dblclick", handleDblClick); @@ -280,7 +281,7 @@ function SlickGrid($container,data,columns,options) $divHeaders.sortable("destroy"); $divHeaders.find(".h").resizable("destroy"); - + $container.unbind("resize", resizeCanvas); removeCssRules(); $container.empty().removeClass(uid); @@ -518,6 +519,21 @@ function SlickGrid($container,data,columns,options) } $divMain.width(totalWidth); + var newHeight = Math.max(options.rowHeight * (data.length + numVisibleRows - 2), viewportH - $.getScrollbarWidth()); + + $divMainScroller.height( $container.innerHeight() - $divHeadersScroller.outerHeight() ); + + // browsers sometimes do not adjust scrollTop/scrollHeight when the height of contained objects changes + if ($divMainScroller.scrollTop() > newHeight - $divMainScroller.height() + $.getScrollbarWidth()) { + $divMainScroller.scrollTop(newHeight - $divMainScroller.height() + $.getScrollbarWidth()); + } + $divMain.height(newHeight); + + render(); + } + + + function updateRowCount() { // remove the rows that are now outside of the data range // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows var parentNode = $divMain[0]; @@ -540,8 +556,7 @@ function SlickGrid($container,data,columns,options) if ($divMainScroller.scrollTop() > newHeight - $divMainScroller.height() + $.getScrollbarWidth()) { $divMainScroller.scrollTop(newHeight - $divMainScroller.height() + $.getScrollbarWidth()); } - $divMain.height(newHeight); - + $divMain.height(newHeight); } function getViewport() @@ -1104,6 +1119,7 @@ function SlickGrid($container,data,columns,options) "render": render, "getViewport": getViewport, "resizeCanvas": resizeCanvas, + "updateRowCount": updateRowCount, "scroll": scroll, // TODO "getCellFromPoint": getCellFromPoint, "gotoCell": gotoCell, From b5aab349442d0b6e72514b4e1593bf76c5db52f3 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Tue, 3 Nov 2009 18:31:42 +0000 Subject: [PATCH 0047/1043] Added "onContextMenu" event to SlickGrid. --- slick.grid.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/slick.grid.js b/slick.grid.js index 9d81572..1a056fd 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -251,6 +251,7 @@ function SlickGrid($container,data,columns,options) $divMain.bind("keydown", handleKeyDown); $divMain.bind("click", handleClick); $divMain.bind("dblclick", handleDblClick); + $divMain.bind("contextmenu", handleContextMenu) if ($.browser.msie) $divMainScroller[0].onselectstart = function() { @@ -746,6 +747,37 @@ function SlickGrid($container,data,columns,options) } } + + function handleContextMenu(e) + { + var $cell = $(e.target).closest(".c"); + if ($cell.length == 0) return; + + // are we editing this cell? + if (currentCellNode == $cell[0] && currentEditor != null) return; + + var row = parseInt($cell.parent().attr("row")); + var cell = parseInt($cell.attr("cell")); + var validated = null; + + // do we have any registered handlers? + if (data[row] && self.onContextMenu) + { + // grid must not be in edit mode + if (!currentEditor || (validated = commitCurrentEdit())) + { + // handler will return true if the event was handled + if (self.onContextMenu(e, row, cell)) + { + e.stopPropagation(); + e.preventDefault(); + return false; + } + } + } + } + + function handleDblClick(e) { var $cell = $(e.target).closest(".c"); @@ -1099,6 +1131,7 @@ function SlickGrid($container,data,columns,options) // Events "onColumnHeaderClick": null, "onClick": null, + "onContextMenu": null, "onKeyDown": null, "onAddNewRow": null, "onValidationError": null, From 718ad1a5bbed1dda9ccbb749f2bc8162f0e416ce Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 16 Nov 2009 21:13:59 +0000 Subject: [PATCH 0048/1043] Updated the example to include setting selected rows and demonstrated how row selection gets preserved across model changes. --- examples/example4-model.html | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/examples/example4-model.html b/examples/example4-model.html index b50e37d..07fa024 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -53,9 +53,10 @@ -
    +

    +

    @@ -75,6 +76,7 @@

    Demonstrates:

  • adding new rows, bidirectional sorting
  • column options: setValueHandler, cannotTriggerInsert
  • NOTE: all filters are immediately applied to new/edited rows
  • +
  • Handling row selection against model changes.
  • @@ -96,6 +98,7 @@

    Demonstrates:

    var grid; var data = []; + var selectedRowIds = []; var columns = [ {id:"title", name:"Title", field:"title", width:120, cssClass:"cell-title", editor:TextCellEditor, validator:requiredFieldValidator, setValueHandler:updateItem}, @@ -207,6 +210,13 @@

    Demonstrates:

    dataView.onRowsChanged.subscribe(function(rows) { grid.removeRows(rows); grid.render(); + + // since how the original data maps onto rows has changed, + // the selected rows in the grid need to be updated + var rows = []; + for (var i=0; iDemonstrates: searchString = this.value; dataView.refresh(); - }) + }); $("#btnResort").click(function() { if (GlobalEditorLock.isEditing()) @@ -242,6 +252,18 @@

    Demonstrates:

    dataView.sort(percentCompleteSort); }); + + $("#btnSelectRows").click(function() { + var rows = []; + selectedRowIds = []; + + for (var i=0; i<10 && i From 3324569f155dcf71901e0f264addba7b39648b07 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 16 Nov 2009 22:02:15 +0000 Subject: [PATCH 0049/1043] - Fixed a defect in slick.model.js (lookup tables weren't getting updated correctly on a refresh). - Removed logging and profiling code from slick.grid.js. --- examples/example4-model.html | 9 +++++++-- slick.grid.js | 19 ------------------- slick.model.js | 19 +++++++++++-------- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/examples/example4-model.html b/examples/example4-model.html index 07fa024..0485a70 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -211,11 +211,16 @@

    Demonstrates:

    grid.removeRows(rows); grid.render(); + // since how the original data maps onto rows has changed, // the selected rows in the grid need to be updated var rows = []; - for (var i=0; i 5) avgRowRenderTime = (new Date() - _start) / (renderedRows - rowsBefore); - - console.log("rendered " + (renderedRows - rowsBefore) + " rows"); - console.timeEnd("renderRows"); } function render() { diff --git a/slick.model.js b/slick.model.js index 703d904..082a363 100644 --- a/slick.model.js +++ b/slick.model.js @@ -70,6 +70,10 @@ function DataView() { return idxById[id]; } + function getRowById(id) { + return rowsByIdx[idxById[id]]; + } + function getItemById(id) { return items[idxById[id]]; } @@ -99,6 +103,7 @@ function DataView() { function recalc() { var diff = []; idxById = {}; + rowsByIdx = []; // go over all items remapping them to rows on the fly // while keeping track of the differences and updating indexes @@ -112,22 +117,19 @@ function DataView() { idxById[id] = i; - if (!filter || filter(item)) { + if (!filter || filter(item)) { if (l >= rl || id != rows[l].id || (updated && updated[id])) { diff.push(l); - rows[l] = item; - rowsByIdx[i] = l; } - - l++; + + rows[l] = item; + rowsByIdx[i] = l++; } } // remove unmapped portion - if (rl > l) { + if (rl > l) rows.splice(l, rl - l); - rowsByIdx.splice(l, rl - l); - } updated = null; @@ -154,6 +156,7 @@ function DataView() { "setFilter": setFilter, "sort": sort, "getIdxById": getIdxById, + "getRowById": getRowById, "getItemById": getItemById, "refresh": refresh, "updateItem": updateItem, From 6d4d72a205d6e2800f9f0aaadba0da78387f4b19 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Tue, 17 Nov 2009 01:53:20 +0000 Subject: [PATCH 0050/1043] Added an example showing how to hook into grid events: - Right-click anywhere on the row to open a context menu to change task priorities. - Click on the Priority cell to cycle through priorities. --- examples/example7-events.html | 157 ++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 examples/example7-events.html diff --git a/examples/example7-events.html b/examples/example7-events.html new file mode 100644 index 0000000..5c48389 --- /dev/null +++ b/examples/example7-events.html @@ -0,0 +1,157 @@ + + + + + SlickGrid example + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +

    Demonstrates:

    + +
      +
    • handling events from the grid:
    • +
    • Right-click the row to open the context menu
    • +
    • Click the priority cell to toggle values
    • +
    + +
    + + + + + + + + + + + + From 4840b2c5415d3c1b8181b06c4ac1e55020093822 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Wed, 18 Nov 2009 23:34:48 +0000 Subject: [PATCH 0051/1043] Minor code cleanup. Fixed a broken dblclick handler (thanks chuenou!). --- slick.grid.js | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index 17c7ec0..cf92320 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -84,7 +84,8 @@ function SlickGrid($container,data,columns,options) // consts var CAPACITY = 50; - var BUFFER = 5; // will be set to equal one page + var MIN_BUFFER = 5; + var BUFFER = MIN_BUFFER; // will be set to equal one page // private var uid = "slickgrid_" + Math.round(1000000 * Math.random()); @@ -497,7 +498,7 @@ function SlickGrid($container,data,columns,options) viewportH = $divMainScroller.innerHeight(); BUFFER = numVisibleRows = Math.ceil(viewportH / options.rowHeight); - CAPACITY = Math.max(CAPACITY, numVisibleRows + 2*BUFFER); + CAPACITY = Math.max(50, numVisibleRows + 2*BUFFER); var totalWidth = 0; for (var i=0; i 5) + if (renderedRows - rowsBefore > MIN_BUFFER) avgRowRenderTime = (new Date() - _start) / (renderedRows - rowsBefore); } function render() { var vp = getViewport(); - var from = Math.max(0, vp.top - (scrollDir >= 0 ? 5 : BUFFER)); - var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollDir > 0 ? BUFFER : 5)); + var from = Math.max(0, vp.top - (scrollDir >= 0 ? MIN_BUFFER : BUFFER)); + var to = Math.min(options.enableAddRow ? data.length : data.length - 1, vp.bottom + (scrollDir > 0 ? BUFFER : MIN_BUFFER)); if (renderedRows > 10 && Math.abs(lastRenderedScrollTop - currentScrollTop) > options.rowHeight*CAPACITY) removeAllRows(); - else //if (renderedRows >= CAPACITY) + else cleanupRows(from,to); renderRows(from,to); @@ -605,7 +604,7 @@ function SlickGrid($container,data,columns,options) if (scrollLeft != currentScrollLeft) $divHeadersScroller[0].scrollLeft = currentScrollLeft = scrollLeft; - if (scrollDistance < 5*options.rowHeight) return; + if (scrollDistance < MIN_BUFFER*options.rowHeight) return; if (lastRenderedScrollTop == currentScrollTop) scrollDir = 0; @@ -617,7 +616,7 @@ function SlickGrid($container,data,columns,options) if (h_render) window.clearTimeout(h_render); - if (scrollDistance < numVisibleRows*options.rowHeight) // || avgRowRenderTime*CAPACITY < 30 || _forceSyncScrolling) + if (scrollDistance < numVisibleRows*options.rowHeight) render(); else h_render = window.setTimeout(render, 50); @@ -728,7 +727,6 @@ function SlickGrid($container,data,columns,options) } } - function handleContextMenu(e) { var $cell = $(e.target).closest(".c"); @@ -758,7 +756,6 @@ function SlickGrid($container,data,columns,options) } } - function handleDblClick(e) { var $cell = $(e.target).closest(".c"); @@ -768,6 +765,26 @@ function SlickGrid($container,data,columns,options) // are we editing this cell? if (currentCellNode == $cell[0] && currentEditor != null) return; + var row = parseInt($cell.parent().attr("row")); + var cell = parseInt($cell.attr("cell")); + var validated = null; + + // do we have any registered handlers? + if (data[row] && self.onDblClick) + { + // grid must not be in edit mode + if (!currentEditor || (validated = commitCurrentEdit())) + { + // handler will return true if the event was handled + if (self.onDblClick(e, row, cell)) + { + e.stopPropagation(); + e.preventDefault(); + return false; + } + } + } + if (options.editOnDoubleClick) makeSelectedCellEditable(); } From 51de9d375f97c51b61a83032cd9de1cd94b8847b Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Mon, 23 Nov 2009 08:42:42 +0000 Subject: [PATCH 0052/1043] Lots of changes in this one: - Updated jQueryUI to 1.7.2. - Updated jQueryUI theme. - Started putting preliminary support for jQueryUI themes CSS framework. - Removed unminified library files. - New option in SlickGrid: "leaveRoomForNewRows". False by default (a change from the previous version). If true and new rows can be added, the grid adds one page of whitespace at the end to make bulk data entry easy. - Implemented paging support in the DataView (slick.model.js). - Implemented pager control to work with DataView (slick.pager.js). - Updated example7-model.html to make use of the pager. --- .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_75_ffffff_1x400.png | Bin 0 -> 107 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../ui-bg_inset-soft_95_fef1ec_1x100.png | Bin 0 -> 123 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes css/custom-theme/jquery-ui-1.7.2.custom.css | 406 + examples/example1-simple.html | 4 +- examples/example2-formatters.html | 4 +- examples/example3-editing.html | 4 +- examples/example4-model.html | 116 +- examples/example5-collapsing.html | 4 +- examples/example6-ajax-loading.html | 4 +- examples/example7-events.html | 4 +- examples/grid.html | 4 +- lib/jquery-1.3.2.js | 4376 -------- lib/jquery-ui-1.7.2.custom.min.js | 298 + lib/jquery-ui-1.7.custom.js | 9049 ----------------- lib/jquery-ui-1.7.custom.min.js | 273 - lib/jquery.rule-1.0.1.js | 263 - slick.grid.css | 2 +- slick.grid.js | 9 +- slick.model.js | 69 +- slick.pager.css | 47 + slick.pager.js | 138 + tests/model benchmarks.html | 1 + tests/scrolling benchmarks.html | 6 +- 34 files changed, 1049 insertions(+), 14032 deletions(-) create mode 100644 css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 css/custom-theme/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 css/custom-theme/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 css/custom-theme/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 css/custom-theme/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 css/custom-theme/images/ui-bg_glass_75_ffffff_1x400.png create mode 100644 css/custom-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 css/custom-theme/images/ui-bg_inset-soft_95_fef1ec_1x100.png create mode 100644 css/custom-theme/images/ui-icons_222222_256x240.png create mode 100644 css/custom-theme/images/ui-icons_2e83ff_256x240.png create mode 100644 css/custom-theme/images/ui-icons_454545_256x240.png create mode 100644 css/custom-theme/images/ui-icons_888888_256x240.png create mode 100644 css/custom-theme/images/ui-icons_cd0a0a_256x240.png create mode 100644 css/custom-theme/jquery-ui-1.7.2.custom.css delete mode 100644 lib/jquery-1.3.2.js create mode 100644 lib/jquery-ui-1.7.2.custom.min.js delete mode 100644 lib/jquery-ui-1.7.custom.js delete mode 100644 lib/jquery-ui-1.7.custom.min.js delete mode 100644 lib/jquery.rule-1.0.1.js create mode 100644 slick.pager.css create mode 100644 slick.pager.js diff --git a/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png b/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..5b5dab2ab7b1c50dea9cfe73dc5a269a92d2d4b4 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FscKIb$B>N1x91EQ4=4yQ7#`R^ z$vje}bP0l+XkK DSH>_4 literal 0 HcmV?d00001 diff --git a/css/custom-theme/images/ui-bg_glass_55_fbf9ee_1x400.png b/css/custom-theme/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..ad3d6346e00f246102f72f2e026ed0491988b394 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour0hLi978O6-<~(*I$*%ybaDOn z{W;e!B}_MSUQoPXhYd^Y6RUoS1yepnPx`2Kz)7OXQG!!=-jY=F+d2OOy?#DnJ32>z UEim$g7SJdLPgg&ebxsLQ09~*s;{X5v literal 0 HcmV?d00001 diff --git a/css/custom-theme/images/ui-bg_glass_65_ffffff_1x400.png b/css/custom-theme/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..42ccba269b6e91bef12ad0fa18be651b5ef0ee68 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouqzpV=978O6-=0?FV^9z|eBtf= z|7WztIJ;WT>{+tN>ySr~=F{k$>;_x^_y?afmf9pRKH0)6?eSP?3s5hEr>mdKI;Vst E0O;M1& literal 0 HcmV?d00001 diff --git a/css/custom-theme/images/ui-bg_glass_75_dadada_1x400.png b/css/custom-theme/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..5a46b47cb16631068aee9e0bd61269fc4e95e5cd GIT binary patch literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouq|7{B978O6lPf+wIa#m9#>Unb zm^4K~wN3Zq+uPMaW978O6-<~?i$)F&>d~nX+ z>vO)oJQ&&FVaKefeOt$qOR>f~^ebnN_=~%qdHEaS{Ou}E*`%9 zKPdOkfrN+ZlHSt7(uY{3{#;wiJb&Ugx1>W4qtrSDm(4hFaaY-$3p3x|sIU3`%J?Qj YcLn#R=pC)AfTl5cy85}Sb4q9e0MP_2(*OVf literal 0 HcmV?d00001 diff --git a/css/custom-theme/images/ui-icons_222222_256x240.png b/css/custom-theme/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..ee039dc096a38a3753f92519546eee94bcfbeffa GIT binary patch literal 4369 zcmd^?`8yPD_s3^phOrG}UnfiUEn8(9QW1?MNkxXVDEpFin2{xWrLx5kBC;k~GmI3`<(O3xvulR&VAkQJHZBho(m=l0{{SA7UpJl008iB z3Rqvn`1P1SiomLXkg776;)RSXXXV1Iqu_@e2%8dEPZ*NvG6-d*$oWlBXKKg zV({l@ll0gM+F;pm#SBg*2mQ!Rn_HBhT&5w_d`jyG6+_vuxMHXoKj|Yh2EGJ-B`N+E z$pmy>sA-*C0S`BfHv`&Y>Z626r?uZY8?`zzbXj7u1}` z;TS<~e1eY(jD4j)wElgyeR*V7`qdhf3S5Vcdq_R*a&F^r|9|M*i>!yeL)xMH?-6M_ zJjl&7(M|RQJ2z;fI7;E!$?Pfq$usWpjLxzlazT~K6v`ft@@P32;&o$5@b}Yj#d~r) z9^2%vhdyIgOXOGiCNOR_sjx3j8*01pUqQBn7r}I@E53HUy&DusRETO9wG~Rdfx=Ta zwD>0smtXx6l#X>f`lTc3c!pmLbwTP$Zfe7s__87<&i+s33P`Udim99RAA$T_Y7T3^ z>vV9wL8Sc0x! z_eRl4cEFZ`EXPfL3omdIIY|MS@P4-79I_Af%(!ONP=msk&*mFs^(0gOj->4HEJ}Ca zL(HZSEXEQH#fbJDfQ^RQnvtlx$kD>NeLhPB+yUp!E5O$&?fP1}JdI;l4(=H(hEfAQ zNRU;>uU@{f`2)^*UI^NA8VHraDlXrE*?OWOs z7D#P(ftiy|@ab?=t923@#mR}=S6GNj1 z?mTR4hby}vE*2>Wg7-X!KAz3vwvJ)qVMtB~**$wrQ^&0>;8UR6E7imZV-)iH?Tt~> zX-EGVhMYWVxX}dU)MQaN+jv0*8;3JBy*az#1aW|^_4%i?mlU$yRTy>-wCJJVC==P> zEx=B7cZ&E7jJ@{Z{CG+0A-lAG;ovs3FALs8|JLq?o#M-to~~wx^JI)GhP%l=X?-mS zEbfx}Nj)D74<>(1{)gt2^%v7UAlLYp6gO$gsv=`$#2)3F9ed8@mcK6i!h@mGQqU}e zyItCAfl~4IqG~(AU2lV?`)nu#S5+1BrCJv>QmoI?LyuLj8e^o>li?U6OMey{r_T(* zY8RG<@x>cK$(nNMlhy)E`{;|c6$@%L*hZEYs{mUmt$8-u8m?YV3{83m{YAwB%6Y{L z6k9V^jd0tnd%q4+xwp&Yfr#>WqoooH9K5xYM|V_s8{16~N?TcuYd@6+y1_aS;c{q^(Kyv6DZcFd zd@RkCqyC{5yX5E=oHd-`WBQ0I>9_&^<}<7793`JA=$mRuSrr}iQyzxG9T)%=Xp2g4 zkFI*p1^XIjQQE0yQNGyZNn{h@1;N1>r@)!(21u5LGg2Ob1==Thh`ZXost~Y05y+XE zrc7k%zx|Fxe^LX9HhqjcV~P|W`3AXYj%WAaFNz@uZ-xRmf!NHrNh4zKSO1WrwFL6P zXM}G=*p9v_k=mUmpg-$Y6I7Mt4@y2D+ys?c;_C@aVePnKabqAS%y%AoFzKI#JaeQxo%Il=}>GqqqxhG8cPyu>P?R=}Ol7vhvDcW{Z8i0Zn zzm^YCS5qT4m#*SycTaxzIpnMMHwFrEO>lJzqr0i6lGn6M7x;$7B7Iy)6renY$OiZc zMEFF-;Ff)@RWrYEodz{P?avD?^RtUsN$GEP>xrgxlbtd22`L1q+Vm;zyBzLIj#2fp zQZS2sUF)*%MR5S(jid&TIT<2`Js!yUdi}%lzzxkuKjf|bHvGZz#1l5%O0plla6C28K&%)=R}0F6xRI>HvM|=4x#=-to|lSN^N9P6&xIP z2dq0{CX-Xc&YJNeXXD#dn;c9feR-*P_CfUEp8(wN{z!yEZrI*MPs**fh@b|xe*S&i zHc8i5C2XFuJ)xhg7K~%2H`zsX?JhZT+>};UB5HaE$E92V@>aXAPbP zjHGY7LH_&c+;-7yblDf5tKrky!+N>Vx>?)QZi1hm1Aea(92RyRiFczw&w7)GT*KddVhT(T~0Egdo9qyLRosyG6?!=QbqPzk^x9!b!;O zjEYZ(YM2+oYg-TrJTt9??(26|bMF?&#cgl&%SzC;-tOToW%SoAmvaoExO%bz%?xjk zc(|{^J<~z4;>Loltn&Q#cD-zLlA0oFa(P1*5{sdl$v0#75<`$?CT{uv?urEF5%l#% z1*lLBO|PYH2z}OUCDP!56T6(s<{oG|TOAmiP3Z95>EKzFu=~wRiHd}%-yn`p^?J6( zih27|xpMpU0(-^Ma=J7`xm^&DhSqXkjnQt=LQjM?m_ss!!0cIcfgCXk7TijCGz5At zUKx0OZ(Pc2owm3zR5RS0N)Y#iMfl$WQCVB&sa%OY<#3FtYF&H{`S5{&n#aQKe2Se9 zB?KD>qbcT%&$2w0lfgg>hoa-{bj}D!0GrB0(o9%dP6Pxsw8y%(rU7O|*#fSHYBm2h zyytq$C(2?`j}W=ORiP$Y;41*}G=Y$(2OhqHVfd_b2NmhSboLunMtOr5!~U=jF_g7g zx!U^R$M++HtM%nJWA0HW6A->{j|_B;D@i9waP$)>{6HyW zi?%Q-uGS3xs5_COdmgZjld7Pfo4dBxil@eQDw4^F*Vcb}d)bfW?|OD#N(nd^;T^jB zZea;L9}obXL9cH4o}9qQv(@ovFw_meU5D94g#m>tZ>F(pY-+sVc~p1lWWYncfsZBD zlLUulh#8ZKbJZaXx~7T%9*9kCI?ptUWNtB6zk6wB?Esa@U>adq3-GJsAap@@buxd8 zEh*0kH65g*0pwfcCE82`98Gls@jB5(U`@lWMLxq4sPDlmq!Rv*Vp(zSX$437XGBPqZRXNva3-1V4LK`FF19js@6mZK*48gf-Z-ZNB zLM=}?fKd18YCyN<3I%#wqeFjR9^PLn0C|nbyn1-&Ph!re@O0EEp`97_ouN^T>luaA zQbRd68s2B-M1Q}bL`59M`{jC(<_`P4m+_LOgr`2Gt(Rm4y+wDaGcvik0$;t-0c3C{ zKhx0TB~7CpakFn?r9>!&+;ccIO!hd{$-sX1k+O&#=VmV@?^gOz?c=kZ*8x}L)H)dP zYzhfqNU`(IVUtd)A!)GN@5UL@&OX&+@1C?lb`+!>)>=w1JnE$X>Lw#Yjk7&t)#5>X#Cjs|&jQ!X46aWn?QOjkKm*1G ztbhAifM)AKF=tIbp&vSIPqX&9FQ`BEN|??$UXR)85VQkj*P`!)ht-9)fQ|t&EI}c) zY_Dp0Km2C(q8potDF7er6kZ;VOs*dAVznYFU=Tj)$Gq2%pheYQJdTMt)xV?d0aA0f zf!9BB;E?X!!FWTWHx>8q_1{a`32+aVn2QqF4@>>wO;ea#m&96EhNkjIR(#vwq%yr` zfH0w))fHpM%M^W;nW$_)tb@EVVvhrYi*g_wUlF^|U`HFf<~&JOeBOMX&56=R~^VwL+|j!Ca?>Tx==&$#g^C#2+mS?tyG29g?7BC;5|* zhNhNJ?*-LgdlM)3Jx?L+w7;FK4mFXC;;XzQ429NM`AD>QNUJVX`T3s9}m~hbK7csE0P(!l|C~FWjU=g#?C}12ipKQAA~kz3%msO zg2N0*dRqd|SG=WcPVM-2UAcd>w1y8d%zsl=9Z^nq83TK_9xPH=!{}}AuqY7aaFPnP l;BjQ_^4`vQQuBMqxOYB4T*@HG=I>V@U~v|0R%wcf{y%IJ0Z9M= literal 0 HcmV?d00001 diff --git a/css/custom-theme/images/ui-icons_2e83ff_256x240.png b/css/custom-theme/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..45e8928e5284adacea3f9ec07b9b50667d2ac65f GIT binary patch literal 4369 zcmd^?`8O2)_s3^phOrG}UnfiUEn8(9QW1?MNkxXVDEpFin2{xWrLx5kBC;k~GmFhwsn)TR1w<4t)tA3_robX4CdCOHJC|7j+vW z%J-EMX&`87enIluaSc0_SnYUx$GzUc?vrNXt&I`o?~7C3RJ>C-Ajq!3AfU8Dx90^_ zp3}MKjJzYC+`T(&egFXQ#9Ek{*oVAaa!zrZtmlRFnwQPRJXH<%pkK2*eP`pT=lwD7 zifq+4BY_rUTa+U|2#&?i7>PVvD?7R4ZfOLPT{e9G~G!Ls3s8JtQE`jMM9wl2V9&Q+K2DHW0M+uQmEr%nYJ^7cK?uIpU-)=wn71ZZ-=@ar0;3^AY z5+TI{2b(e%t{2PZ^HKF*vu@+Xr&BAc@2BC4 z_vCgww#i=)ea5Vo$glEEVBBg_VPBj!)OO>)f@}#dg6ULOeC>LBHz<;*5Y;YfE0lNx zg{N+4@lO~ozxpF69qV@VOGnc248Iuag4C1T)P^(hWkpP!{h!JekX}m^Q#b2B4f1oT zIjsGz)4}-$rQ*-tSuc%qG>%<4xM#E& zN)7lRK~^2VdiloY4>;#}A!yHOAXEmEi^+eA#05pawGXs>!z)gSoDuI#>bRCq-qjJe zZ)r=A`*EMX6+)~er1kdv1L^)0-PsAEM7JF$O6G8>496$24lkOSR^RTfUuIz%iSfn5b-t!##cs7sQI);gdAvqmn_v|%I9k;fCPl0Z)R1+hNQONJN zH%3jT9sOq*a`LF*MiY=zlSSQZ;{_FL9M07A=In+O!~wR}=bzGEQpk2!Vc0p)qKAH? zOk{(%06W#)DdICQ_S%Q@<0Y+!?9%#$gWJ%)EO->^YZP{<`oB4~9xh zL9-0*c4@B#O2ylYs_g`Ky$zb~v!M`NRaMNFYF*Gsu|7)=JyyMHjFC=HhGUE@{aI|B zJ~ITXU052%7jFb5Ys#fhS_?4kqc7H0EU49B8(Chg0&JzU=Gka#xOz1)H0d4m7ZnRA z=M^tdY|U6T!fmte{W?_r8H~qdq|q{5AMU_2It1I4143n~xL?4&K#BOB48l9_Rdm!(c^C?JU;tF0 zEh@o1y6Qa_>}#AwX{VY+`C^kNkxhgb1P5cB0%xupAXyg9NO=SnXrJUE?rQg{Lcsn+ zAZKctGLfbK_B#^&Nev|0^fB&?DN=ak8|0!np524LD25=s84BP8Vl(3=jflNp{X>e@ z637Ri5xx;&JNl+XYImA|{;XR~P*svYDEWYJ6I5!6uO~2twFC1ZQevB7#3z~(apxn& z^J@>Mc`>PJair{yT`iuan-V+i%|Ho-pA<1?V-k^R2Q<5;Co%XxmL` z018t4T0TTwO^w)Gx{9OSJ^9_|kgwX`7%0Rw!PO~@?xvnfUehvN;2Rc;^l>3kfbtk3 z8{j7p;S&{uTlTe9&HTc38q@%_KQFk<&n{vmrN7y&Cz{etcE->rq!6HL)2F!aa=0%! zM%Bwo!7TQ5t;@a_#Q}sjk{UebWQZ8{cp&HN^$*JfH#8spkhk{R@CVBiPuP@yEhu{} zsQfuhTqV%rioATpEphMfhyRYbVfVW`YwLFXUWm-===J(byMf!5;W^CV1g~2194Xx) zFK|z{pm%n-)-DRe{Qhk(d!QaoI*y%Wn6h7<6A{i*Sob&B^y|Spg!&J$`kN>zwUJ3x zaB$ciu*0FJKg}T ztgnh)ASF8njz5>h6?f#{c=*Yr4W_34$GmVIo8OLWjcZK4a0`+Yv-!*}9 zBwKm;DAsA(nDI-`iH@;`=gP+m{lgFLHK3m$W@?)&dGhDA_Z2xOzI0$p(ZJtH$vCxE zj>+kYNBJzs-TlSx!tSH}%I9fQv)mc!C7X0bKlZv4f&}C3+O-4k7AmVO|KYZ9ydP%(N1^uisV8y;~p`x4qFXD?!_OyN9=w(Od6W; zGrT?G;l2v@Ob5k^8w<9w%Jbjb^|H}PYKo}I~bobd!XrTbzp2Zp~H8lgJ)I3?l&(bDiWf8gE&6b z>)9GB=Iu-6%I((+>=jGP>CzD8c0oWITFZGgM!Q7|JrUYq4#^Y(vuDu-a>OWDa4Y4} z5a_*lW#IL_aVf8L+Ty}c&2VojLEIA-;eQK6Wo?xAuK>i;1VWx3c=!s2;j_*iRHOsb*>6-CgcYP+Ho=L@XLd*j~2ln-;WHg)|cCixksH$K={5rGSD@yB%LI|(NCc8 z1Er8H+QO)~S~K{g?nH|2dB8SKs)BxQ?%G}}o*LV!NG2m*TmR|pWj~g`>)ClJCE#F$ zcj)fBg(dKOKmc$Cy}IRlasngIR>z~kP&WW~9cC951{AKmnZ~ZMsqup6QQf7J0T1;C zK9*Qd5*(HxW=tl|RfjO>nkoW#AU3t>JkuzWxy4-l?xmTv15_r1X@p@dz^{&j&;{Mq z$^0$0q&y?kbdZh)kZ+NfXfqLTG}Q^j>qHlUH4VEK`3y^-z6Y<6O88Hf4v^;}!{t-a zDWg;znYu%6zA1~A5~w?fxO~i8-Ib(^02{c4pXjhDI^2 zXB1LP4dvWuc%PXQ{r!d#6>${rm+M8EJM8yf#!H$Kp8AxwUXm5`7Tu-J$mHeCG>vw|&Ay415}_1w&*9K8+2d3v1N+@a$|820o4u60Tj@u&kI!~q2V9X; z>tMvQDI|O$#m+m2O**ZHq`_{#8)ry6`&5s~2k{O4Du16Fn0P;&_(0!e5%Bel){nU0 zJX~<8U6hoI%yx}qGY_1Tq7YKDJ)ETOCs&W)TiCrK*1%DE*vXdD-7hwE*LUgjeHRM` z&@pkhTi>m#Kc+QIK+2Ybn9-sFVKNHyIgfob4H_77yYh))Rq$7Pw|+aD6&yZ|ki9 z8Zb6s{oBt1G+PgfIcxd}{m@~1nzhe;LH)5;!gS8@ddyabpdBc?7JVl?tS+<#bPSMT z2@0uYdsWN(;Ww)n-PlA-0r+62@bYkEa`k{0s})fJgYZ#5=DmIdEvok7aZJRi{w-|} zkea&6X}ZA3b7&vbDb7)v8CuI(+zzSf3z&P2eOrPNP?D~ zf zn0@)0h;~5F&BG5vOFU!=woW&ZSl~nrs{?1w>nWfW_dnpTd z4qvLDYJ*ft>Sp%M(^_xCZpNBnc66JX}A|ZL9IENM`U>`ph7d<+RQiI}@E8Y)70s zMC*_&))}GlmR}@{v9*nm)29-=rn`Q$rc^4G)GVQHlTr6BpGxtHuU(8AF7Ffh54?5w zj+EYT9>x)PWL-iQ@RNmT?R+|c@=FOmj)5Za6_ z@DkVy4l^L>Z3#SI@s_eVwd3D)<^Ivq8a~J{|4mhOL^<7M4D8){ut;GIqqn`oqCk|x pNh;Wa$C0(mdpqYz&F>xK-uVD=DT5%Jzh8ZT#aXmjr70%*{{S|9XD$E$ literal 0 HcmV?d00001 diff --git a/css/custom-theme/images/ui-icons_454545_256x240.png b/css/custom-theme/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..7ec70d11bfb2f77374dfd00ef61ba0c3647b5a0c GIT binary patch literal 4369 zcmd^?`8yPD_s3^phOrG}UnfiUEn8(9QW1?MNkxXVDEpFin2{xWrLx5kBC;k~GmI3`<(O3xvulR&VAkQJHZBho(m=l0{{SA7UpJl008iB z3RqC-Ajq!3AfU8Dx90^_p3}MK zjJzYC+`T(&egFXQ#9Ek{*oVAaa!zrZtmlRFnwQPRJXH<%pkK2*eP`pT=lwD7ifq+4 zBY_rUTa+U|2#&?i7>PVvD?7R4ZfOLPT{e9G~G!Ls3s8JtQE`jMM9wl2V9&Q+K2DHW0M+uQmEr%nYJ^7cK?uIpU-)=wn71ZZ-=@ar0;3^AY5+TI{ z2b(e%t{2PZ^HKF*vu@+Xr&BAc@2BC4_vCgw zw#i=)ea5Vo$glEEVBBg_VPBj!)OO>)f@}#dg6ULOeC>LBHz<;*5Y;YfE0lNxg{N+4 z@lO~ozxpF69qV@VOGnc248Iuag4C1T)P^(hWkpP!{h!JekX}m^Q#b2B0{OYr9M*o< z>EL{WQt@Z+Ea-hxX0}nTSZxnpi^#Kn8Ox8FgIS|hc}KJQ4tm*HO16ui{(O9}1YN)G zjiQt6fGq`Cj+^`zUf?8hk^(T{{cOQGWFP98am}is28A!5%{R#ENv8fCN!j69lMEK(2z?|BY=Je$XD9mB-Kkem*(d-j^9j$2#6r$Dz?s)-TCDCGCs8>6Pv zj{Y+YIeFA@qY22V$)awy@q!9A4rgk5b9TcC;s9Ig^G|6nDP+5=Fzg&?(L=vcCbGd> zfSu~@6!94td+o#d@sid!EIX$rx7*cawe6`dScJ z+$HssdOjE)O#Ybs56vm-FQ$7yuJJD^Zqk%hMaIgAJ<2yb_MFQte_i;62ScT$pjifY zyR_E=rQ+>H)pmlr-Udzg*-!|ssw(D7wJvC+Sf8bb9;;q8#z?0p!!bsd{wy|5pBaMH zE-Ve>i#LLjHRaMLtp%9&(HCng7Sw96jVv!#0k%?F^K7&=T)mnYn)D9(i;4x5^NJTJ zwq~pv;kH@#ejTd*48~(J(r6j34|m`h9fEDj0im)~+%I5XphWymhT;_Zty|Q&zjPg# z-ufAHZ1M*Gccw?Kf|8Pnhtb0`!{N`Bqsa37J+>wC$!e00k+2 zEgzz;rbcWoUB%Jvp8W1}$XD%e3>4y;;OZ1ccT-O#uW6Ys@C}Pa`nZrNKzR(24e%3) z@QI4SE&E!lW`5y14QhbepBG%_XBV-O(%5tj)@9#|;sC-MNev!zGDHk}JdpGC`iJF#8=8-P$Xoku_=Dw%Cv3{U7L>gfRQ?<$ zt`cZ*MP5GQmbmx#!++P@u>0MewRO9GFGS{b^m_fJ-N0?j@EqoFf>$khj+E|@7r3We z&^tR^YZrxKe*d22agXqCO0l44&kqCv{u)T|(lv`~PK@DvE{QI_T zlCH5z*gR!>LO)k67{^R+vWx24U2^2ODXpwT;6y+6+$5m)_*w4WY&#do9dCeE)>p+Y zkdhq($DhmMiaYXey!_kiL26uz($aJ!QT{B^Wu}U$^9e#5)=c+XF9@Ill?ZmMlNgHi zz*9!vDc&uxOo;ZVxb`Q!Sk0*gnfxWzmbZh4(=%CD%qP?0=);n$&zaW_$UKV98axdc zN#AyZ{P)wj?V{P}vM)YY!>6@}^>U+iv$`9>nMTCPjN>z%yF&3yf%>+T@0vh4lC8Xa z6zeo?%=o3}M8{aebLHcO{^1Ar8qiM=Gquf?Jo)q5`-+?sUpg?QXyEUpWSm+n$K-Uy zqkIwHLquru~o(OF)hhz$Y*|X>ZIbswnxRvr~2=rdO zGVuD|xRlpAZE<0!X1F(%Anpl^@V^D3vbM}qxe|NI;TTiZy7(IM;R69RkA>a&6gwYE z2sREzQ_LHmWqB+ogMk(fMaSFeoDq-!HkFB_nXt5+2ncFuk9BQL1I&oB1zZi)YW{6_ z&-Ip1l*OVRA##1ILQS;5R{-K^0wGTiJbVSi@LA^$D$;@J>^G{6@&+%4{b3(sC~LEH ziTv(0b#zxt?YJ0r_~pUZM~mQ(??(n#>&tD%+@nq=Abj5*8R!~Ul1`G~=qFJ4fl|m8 zZDCYgtr`4LcOpgiJYX9qRY5;DcWti~PmS$VB$E-Zt^f4)vLDOe_3XTq5^ylWJ9PKm z!V-8sAOJXnUfuFNIf0R9tK-pNs2hO04zr620}5B(Ok>yB)Of-3sP59qfQNbmA4{w! z2@cB;GbR(~szVrbO%(w=5S!X`o@o@x++wbN_tMPT0Vc)*I;Fgsbf^*g02Di?H zTApwKq3+YwfNsqd3iP%{hyK1iyuVZc@*0tO_3+N0#GFsz>8MjeJ2UJ%L!%hiGYYAt zhH`E+ywA*u{(eJ=ia3h*%k?779rk-K<0VZAPkl;TFUbmei|$fqWO8!_zIvqt$ly$V zrlH46nnpX~X5Yk0iBJl;=WuA4>~X4-f&K0yWf42h&0b30t@NYX$7egQ1Fp!abui-D z6cWCWV&|R1CY@G8(qOmWjWeX3eX7UggZPGimA}soOuQdXe4uZ#2>5zN>qlI09xk}l zE=tNpX1m6*nFr2EQ3xs79!^sCldDJYE$m(qYv3q7>}1R7?iZW7>$~*%zKaC|=$N?M zE$>#+%T&MZC`dW1wUl6Z)JgxkeN920S>e@EK`q~>k| zuYcsgA>F%!@rFciD(>Iwzn8KT;2tb77bUPCmioh+rZBfIiM6f_P34cQ__o1GWqQp3 zVL~~pE5?qODf%iiQQ3f42YF@09tQ*$4v_EKUx;t1KCPCBtgqg@+Tn; zO)a0uky_%jm+WjNB?=~VyH>V#L!*=l*@OSMSVyt_UEH&NA=?V2stHPyKkVN!&jg<#cjros){#ji)dK%)We0 zL_478=HZ8-@xnwsKrWs8)x`MB;(Y`Cmu2c-&SH(vN-F(*e`l?c%+l$|y_AJJhcDGn zwLvN+bu;_sX|1AiePhx@u&%P$hf*xE+O=~D?_(_KGWQ!158YL-y9$*6mmPo;Rp*Dl5lm-mVM2i`h-M@nxv z590_tvMwPD_{l=b$iOm|+|S{D9&P%zeT$GgX6Akl-tfUF>tL@Ld!B&{pN39tH>3V> zqksMAYul+jb7UiouWVGPNsxX7Ueba+9|~dz?d*QM$ng0DZfO0`7fAy?2yMm|cnRzU zhZ&IcwgjH9cuU!w+VStYa{p*)4IgBf|E8)sqMYtB2KH_}SfsFq(c9i(Q6S3UBo%DI k*Kv;w;*%(i9W@fAqs5i2wiq literal 0 HcmV?d00001 diff --git a/css/custom-theme/images/ui-icons_888888_256x240.png b/css/custom-theme/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..5ba708c39172a69e069136bd1309c4322c61f571 GIT binary patch literal 4369 zcmd^?`8yPD_s3^phOrG}UnfiUEn8(9QW1?MNkxXVDEpFin2{xWrLx5kBC;k~GmI3`<(O3xvulR&VAkQJHZBho(m=l0{{SA7UpJl008iB z3RqU$@Wfh}nb?QCTyjovo2=)B^qQB=#XMCF_n=?1Jbh>5sptJM?}}{I zHzR=-V_TFXKM0P+&lrh3TPr)c<8EmLl3g~EY}W@od*0X6Ljv>L(67bjz58EDypsu&ddu2a@@x)`5aA^S^DxkW8rs_vKtu8N8(o0 z#Nf}*Ch4&iw866BiW!_r4*HRsHn%80xlBW<`IOcXDu%LQam7$Ge$q#1415XvN>cnS zk_qU%P}4fO0v>J{Zw9o*)JF-CPA!KcpFR1Pn(l@*bKh=1_!ZRWb?FoG5a22cVG<$5 z0|%Qj7p@n}=Hrkk`BkD99I57h7_+lQ-AZ-?fETz5E~q(= z!!d%~_yivn82d_pX#M+Y`|`-F^s6-{6}S!?_mFzr<=n>M{{PUq7g-N`hqOcY-y_m= zc#xZEqMPgqc5cu{ag@Tdli5@JlV{xH8J%TA}P<$=Qej`5Hq>_Gzk+NDFM{b*SA6Yydp9VOs1VgIYAcj@1BIt< zXz@=NF2DLCC>`r|^h-z5@eIEh>Vnjh+|-6M@nuC!oc*856_8#_6jL|rKLYu=)Ew4+ z*XiJVgHrKl?=0wjQ)aeNu2^jkUW>@Hei_S;nuA%RRe49V`VM;8SxUBxpZPe>l9ZA{YS(NU; zhnP(vSd1kYiV^KQ02>XpH6u}Xk)wrk`+SxNxC73cSAefm+V!<`c^b#A9NaTn45bEq zkRYp$U%h-|^9P*syb!eKG!QC-$;IS9MdE^@-`WRSzTp+8M9zqJCUsoPC-3Tr+qbkO z$o;ra-wGjC64H8m{(*FVitg+LQKH+96D4!FREFb|Scex)lw()`rHV$WMdUJNe3E}`->+?@(FDYcZt1#>wXwgHzQ6{p% zTY#PF?iBGE7<=u*`SFt0Lw0HX!oh85UlzQH{;k~&JH?kPJzdQX=gAmX40n@#()wBu zSllJ`lX^ZF9!&n2{1443>o2BzK(6sGDQ?n~RYk_ih&{?TJNBH*Eq`73g$F~WrJz{` zce}LL0;S^ZMb&nKyWR#(_t{VguBs~LOSLX&q*$M&haRh5HO5G%C&MvDmi{a@PM;Zq z)h;XzD;Cshu#GG)RsptBTJvnQHC(-#7@G7B`iqJMl=F%g zD7I#-8sWBC_kJC!{tU)rGSX-nt`B$M86ARc$^oIWRNOCMU!X+%PKM$X`mI~kxxaKB znBMvsb8nZ)0}JBmidn3FUeG@ZcdpwZy_4oi*b{&c?T^HaVC|`tnlo?1SjRKLNPk{gDWT+_1fio|Ic{5kU=X{rvm3 zZIZ6BO4vMQdqO`~Ef~j4Z?cQ(+Ff$wxGAlyMBqd}_S__(_xM@v-fTM;$Q^HhR@PU= zE|8KP1IM4s;)*-+Z@m25>p^N(PgHJsq+a!8`ezsTQ3Np0+k4Mtdkgu z^}tg`-YMQKuuO>dsJQkgyjabt1)2OM)|R(}hto4zSIj5V;^@PYtIwI&4#+%;&Kf)o z7)jrDgZ%f?x$UCa=&~<9SHq{ZhxKx!b+ft~!I?(H$&BMOox4KuOo95gl<%5AIg+is zd=%?6ZOr(k=S0U?!*k{1h5q3O_ZrYo5Hq#Sl|1?L+WU%}6JI(orD)*qq-300E63z? z#iM){^ff?RwehBsE3Uh)}m z74!C`a^?2x1@?-i<#cI?a=RcP4Xx$88l&B!g`Nm)Fo$Fcf!VX@0y$z7EVz~OXbALP zyfX0m-nf+4I&E=bsAjk~l_2g3i}1e%qO!KkQ@Ij*%HbGO)w=i^^5FvkHIIee`4l@J zN(eR%MpMiipJjP0Cxd|&4n@b?>6{Ue05+A0q?xd^oCpYNXpePmO#{q`vISfX)oT82 zc+d5gPn5-?9wBmlt3pk*z*hj`X#ycn4?KJY!|++>4l2@t>FhVEjPeFAhW%k5Vkm2~ zbcy`#HFb1XOYOKAcKGGN*GG%skMBnYSL@4d#@wS$CLny@9vSEwSCUSW;OHk%_<>T$ z7HwfvT&)@WQFkIm_dH-5Csjc|H+OBX6;F-rR3wuTudV;|_Oc(#-}UUgloD_-!aH>L z-NF)hJ|F-%gI?Y8Jvo7qXRG7UV5l2_yAHF93IhsP-b`cH*wlEz^Qi99$$*D?10PGQ zCkYPA5Hltd=c+>(bWIfjJP@1Obe?Gx$=qVDe)rPM+5sw)!8F3K7T{OMLFj_+>SX>F zTT-48YC1?q1IV|?OSG8?IGXAN;&q~nz?z0#i+qM9P~U@BNG1FyO9#kvk>T>G=#)_^ zj!fMlH{X;+ONmr!LsJx(j*b2&WMpJ+s&cN;7Tyu8gf>RT2kOR+DBzZr7=m-v-UheM zgj$|(0HN;F)qrlz6$FyVsy6e02`M!$<1L&Bz z+b!=_(#ur8?I=h&thJP2c+^S%)lEi*8fSaPs>Or&i1kF^p9QX&8C;)E+S__7fCh{W zSpW930L|8eV$Pa=LO*oao@VWHUr>MSl`x%iydJaFA!rB6u0`Jo5337p0UZNmSb{=o z*%W(>6W|^!F&8DUAC~&Vo2D?gE{V0S3{B;atoXLUNo9J? z0AWHot1HHimnr%xGf~-qSOO6>z*MtHe(EIN3<7@k-U&gFD+Xq}Ua*o~(!1kApC zO+-7O=jP#uq4B~*JwPs<`_;tw%;J3m{g-9xU(RBU&q^x&eSc@Ik<8NR$i0+>JBKgT zPqjfRC3Q3V=4q|BVK-yVuyUMByvXqR1a4^k&=*MqJ_v2b7I+El z1&0}s^tJ?^uXsz@oZ9j4x^n+$X$>D_nE$4#I-;EJG6wc;Jy@i$hSA&JVNoE;;UpDo l!Q;r<<-MKrq~`aIaqoP9xRgPV&EKy+z~U_0tkM({{ePlYU?u&Z`mr_kcwz5Nh&g=McJ3E!;CE1E0ryV5Ro;>nvty8 zA{omJnn+{p4952Let*87zvA;auXFF~{<`_uPA4&sV%P>LMpp1PTBEIL*yWZ2%{t3Pe;FXZ3XmxI8(D_g57_$Zil~sY6d4T}-hu9_Wqp4C0AMO{-e2$W~1A}=8 z?24)=?B)4HUDo_oXckN%okP)HFJjaB4*3_SNpKaf;yPT}KqfS{2x7`d{0xbPErH%h zh`mQJ03DaATP9aP!}a4$fY#``NI~M6&RljED)8z}hhWxrNbxIBlTxG^j z!X>$3AQQ&I%_5mRECOjaGwR-GHmde})^)t-3_~aFM1G_L#mpCNdcLqr(RKjv3R}(z zG2^yBftMYh;H3a#-slaj|5$BX9+{PTv&NtR*P-L?l21FGTG`$H9~##p%VE!uR>=NG zc&auxVl!1_lP%uX71AJvlz(wLYl?63oLd~dqjZRrU#UEWw8J6Yn-7L~T$$tjeAQiW z9$XG5Hu>rxFBnzgd6ho#^gE5pY>U$dTCRN85Y1tQQ0=Pn{?7OJ10x9Xk!>P2f(f^f zILd}5--N;Po4*25F|J3ywIv+R@rfcYNj}R-sXrH2TFAiK{jFGG(ru1p=w$wR;IXQwAX*S~oiEK{g;kZPW;YE|!QY|g^2`dMS{&1Fr zkf?!sj~m)xO3v`hh4KQRJ&&Q!=X1HNq8T_Sg2P^B&rZX{VQUNc9O(K+B_Z4hiTH7M zW7K5Y!Ec5xD~B9zFlKUWG_Rd)xTK7U#hRGhp51T++e6oS{gT^?3s~>V4?6{zchhc_ z3UBb_W2U+~guMsG-g=@#aWPSFypk)5jIUTxFiM zycGZzbxQuCTnvH*kv=E=LsRnltLbhgm$=ttS1IzU0)1t~4(XE>bHVwJpAPKOqoI-# zrdc{yo0R7Qx%~ZQl{UPa?gmxo#ZWM|vNHNxl@8NLksfn5Ek>C${w=x~pekl%gfwaLwWspL{af)?f zTOBmhTyU&3;}QeF&VLwhJ>Dezu>~P zc+$aFxKDWKj-CmD(v`}uH|ts*SefX@lyrc<%~WE6tHU#dv;y+LlA@cTgl8J!u@@u6 z@@fvJdC)1TvBa$QT@ck`rUxF**7w4Yh0!vZUsGu%Lm(cl(l#QPpmoOH3JC>FMe07G zq0kl#K+GLndyoOx8{t9g8JiLs#`pH8JWqR_ZM%J!Yr>cp>95<^#=FWQfzPm%q;5B+ z0>}ul8+l+gRaHV$$tsq5|MU;?AJ~m-XNxjW3U6JH2k`tOXAqi)yGI@^uA&dQ% zZCJIe7{qK>+p_F)Sqy-GC!x-5MgogsP6lwiUH`N^a7*LKPdO{!4L^_^;goe*e}3s( z0i~~@V#)#L*W~2F?}&N*IQ)0a4Z1$uTU)p7^Mq&IM6K6d*$vpX2+L*+$9vY0=7?$b zxdD4R`8~74HMWsx#*goNSp#(_;z`UT-GuGxoUl-){JNk1rf)aSKE!W`#m`t#v6V!u zgn>fufpkVprL(KqSkhl*Z+yRQosF)bEiV<#K8hOr>yQ1@7Xg>g3EjKwLB7)(9$3%X z$G30OD&Z2Nh{;v5!}oF4fUu0TM%&2F-6aS1+fqu3cn;K4k4-#kkB|BO?bZtcTygp+ zB|R0)0x`)UVEm;Fwx~Vt*6ZV3k5Xcj6_=(X2y*8M&NGz^?Jr>Jutu8idcHpesED^^ znM9MV2AcX%oppm45TS9yYBtteX?1liAe($}l8Mrk|YY*cFUp@Yl5_|Ih%+ z5^dz*^BpQ&l8;Le-Z+E?J1_|}dtK>`0HCSg@u z*e9pUpX4zkcJ~*%3c8N=D_*8f&2puu6>riMeA#MG3E+*kYt|0Dnl;U^u0x`IJLnY* zjELAyFaL6=ihd=uwgnc)F;a_ZKEBsA_UuVc$NS1$GwozcE)2-hGS_c!*V9@%u`#?lhbMR;p$MXpbUS7*AsAt5?3(xQtcatZ zK;B-KhX__vb(?F4Q0GloBJ>|QvdJoM?lDbgsR3iM@a;Z3?cA&4wtslYkr80ETZHkc z9*>q7Q7<0~XHK7PK#yo@cBi@smopq(-%`e-KH4Qx-~rbHu}dW58QqJ{;3Inef@=x4 zI)BgQYXff|j7xg1Qx_M8s)u`0@M0d&aKAfD6qe?B3THxh84PWrQX5xII()>h>b|f$ zpKR+*4#vbnsS3H{v&>IrrO}Xrp{O`p?Q{I%z{XPHRAc7mQ~rVVZ80t_sel;~R{!fE znoWNU9=P1`jx=A?#Ye1fm8**6`|yK3jKQSofyZy4XkM$FK?NExjqO&YVea7N(7$X$ zbR{k3PT@a2CJt_@Dead-55GO?f3gVr{BdM(wXV#1%q{YCJlyB~k-m;m1@SZyhI$5p z9ViBGQ5QzVRGUDbbtaN^E&{f(lI64ub2s){aFm!11riDV*6MFh58H{nU5}0{$^Hi; zJVW(-UYp)>>|Lx|%+y^DwKhz`tPS-85#6Rh0)ckL)U$^na{7 z@VVG(5^ui@Hf1odF537(mlR>ZBhjf%rT+ zPUdZ~CgvIZM_wUkJAw%w}x9jc8!TL)0!EfOi*AMUgP00QdmWDhdxHH4HGc<~J zIVYb|Vj$~E#d*)1>gzKQFOMaAy}BVVo}IK&7ZMB zx!9l*+ek@g>FsKVCTu!A+bt50<5zR%LvhtB47 zphLoLmz-;H4@2#)g8=!k#zLI#UMqFnH)&}~tj#&gW_Q99mQw+L7dU5Tu)W%;@9Qi9 z>QGi--TSZnR2z4)8B5wJy^vu$s+IRc0ll#|LNt!?I`me%fGty24eDN4Xl+O{(+NPj z1ygVh>zf*$Pk&fEX-3AP^1w$s1y_e7lBxzgSu6?iXt=l939t1dNMV&Hw?hI}<+!vx zKuXRw@aAWBEW)iT2xma>qG11B|GnfLf43m`S%SD z3d3^-2o=m;T`_XFO4d`JiOd4T*vl!w_t?SMNPGOr712xew$!m3PP4`3g2iVGiU!9* z&w=GY2O}!evGB%RQa5rA7s5%`YA&A$+(`a%B< z)4%^Wyf-xKA)KjJ=y>(k$Cki3nVk)wxAEYIGA3p>sG^i;f$cIw3$H&^I7dNHU=sw$d)j7 zh|(sSuhT>1EWU{wVQLz{XV1iYPIvxnNv=>Vu3kdkB_SVNJ(KJiSF;#9T-Gc6A9!kU z?a4i1-1H;R$hx=;;1@G7Jsm?|a=U>2b+qZz`aN9sgsIyFSp6r%%!9oq%tbmjY#K7P z-Gux{jUMaKw>DF`W{3tTZ|SIDqX6v)w4@1rITXmow6pv9GTr+NsJ`V>Zv++iD5MFK z@5#Rx6sk|u-Qs__;w5Q)X2-Ad+QXxzHC&)U-n+`G@G_e77|5&TV3EucN^AXqK{AmK pCn+FvZU>f5ukGw-)qi%3dglGbB=rNWkH7i=^YbXv3KMkH{{f&jC-?vW literal 0 HcmV?d00001 diff --git a/css/custom-theme/jquery-ui-1.7.2.custom.css b/css/custom-theme/jquery-ui-1.7.2.custom.css new file mode 100644 index 0000000..050c2a4 --- /dev/null +++ b/css/custom-theme/jquery-ui-1.7.2.custom.css @@ -0,0 +1,406 @@ +/* +* jQuery UI CSS Framework +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +*/ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + + +/* +* jQuery UI CSS Framework +* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller +*/ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_75_ffffff_1x400.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; outline: none; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; outline: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; outline: none; } +.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; outline: none; text-decoration: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_inset-soft_95_fef1ec_1x100.png) 50% bottom repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }/* Accordion +----------------------------------*/ +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; } +.ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker +----------------------------------*/ +.ui-datepicker { width: 17em; padding: .2em .2em 0; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; } +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* Dialog +----------------------------------*/ +.ui-dialog { position: relative; padding: .2em; width: 300px; } +.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* Progressbar +----------------------------------*/ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable +----------------------------------*/ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider +----------------------------------*/ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs +----------------------------------*/ +.ui-tabs { padding: .2em; zoom: 1; } +.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; } +.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } diff --git a/examples/example1-simple.html b/examples/example1-simple.html index 624558b..50c5748 100644 --- a/examples/example1-simple.html +++ b/examples/example1-simple.html @@ -4,7 +4,7 @@ SlickGrid example - + @@ -12,7 +12,7 @@ - + diff --git a/examples/example2-formatters.html b/examples/example2-formatters.html index df63935..2b103ce 100644 --- a/examples/example2-formatters.html +++ b/examples/example2-formatters.html @@ -4,7 +4,7 @@ SlickGrid example - + - + @@ -35,33 +56,39 @@ + @@ -86,17 +114,8 @@

    Demonstrates:

    diff --git a/examples/example5-collapsing.html b/examples/example5-collapsing.html index 5c01849..e27d4dd 100644 --- a/examples/example5-collapsing.html +++ b/examples/example5-collapsing.html @@ -4,7 +4,7 @@ SlickGrid example - + @@ -51,6 +48,7 @@ + @@ -165,7 +163,6 @@

    Demonstrates:

    function comparer(a,b) { var x = a[sortcol], y = b[sortcol]; - return sortdir * (x == y ? 0 : (x > y ? 1 : -1)); } @@ -205,25 +202,12 @@

    Demonstrates:

    grid.onAddNewRow = addItem; - grid.onColumnHeaderClick = function(columnDef) { - if (GlobalEditorLock.isEditing() && !GlobalEditorLock.commitCurrentEdit()) - return; - - for (var i=0; i + diff --git a/examples/example6-ajax-loading.html b/examples/example6-ajax-loading.html index ab97586..145c01d 100644 --- a/examples/example6-ajax-loading.html +++ b/examples/example6-ajax-loading.html @@ -26,6 +26,7 @@ + diff --git a/examples/example7-events.html b/examples/example7-events.html index e12b1dd..ceb7882 100644 --- a/examples/example7-events.html +++ b/examples/example7-events.html @@ -44,6 +44,7 @@ + diff --git a/examples/grid.html b/examples/grid.html index ce5c516..69ee48c 100644 --- a/examples/grid.html +++ b/examples/grid.html @@ -82,6 +82,7 @@ + diff --git a/images/actions.gif b/images/actions.gif new file mode 100644 index 0000000000000000000000000000000000000000..026dd108edb433b2592695258f5a26fead66a7bf GIT binary patch literal 170 zcmV;b09F4-Nk%w1VG{ro0HOx~|NsBFxw+Wb*vQDp?Ck8An3!f}X8-^HA^8LW000L7 zEC2ui022Tc000ATcq&u=F9=14Bp_=*L>SeujoScvWSU8mntBE1j)XI(_C4mS;s1uf zhSviMhXoE{2?+d-ON=ebbPB1`WJl1!Tm@h-z_A1mz|k1KkDxg* Yaq4(_7$y}LDRLkb2QUy25)=slJ8Q{ByZ`_I literal 0 HcmV?d00001 diff --git a/images/header-bg.gif b/images/header-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..fe7dd1c1ebedc02d4e1aabf91fe43e1bcae824e7 GIT binary patch literal 872 zcmZ?wbhEHbWMt4`Y-eC-S#V_a@i#lpzuR@;-JVPD_g;R#|H_AhS3exO_Tk8lkH>C) zJaOyO$=jb!-~D{{-ski8KVNw8<p u#Ky(P`xTtKWIQ)5IXPLwHYwudrlqH+8zi5a#gWNI1yM!7mYUVnf4WCKe8!85Rx=4Ga>@3=9GS G4Auam1ttan literal 0 HcmV?d00001 diff --git a/images/header-columns-over-bg.gif b/images/header-columns-over-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..f9c07af1347fc44dcabb1a9d22458deb195fd92b GIT binary patch literal 823 zcmZ?wbhEHbWMU9wXlGzpb>`d67r$SB{>v~5Mnhoag@EEu7NDp9Gw6W44$2b@93l*? Z95Nmo7Bnz$2y4ZhC{SczU}R*l1^^j55kLR{ literal 0 HcmV?d00001 diff --git a/images/sort-asc.gif b/images/sort-asc.gif new file mode 100644 index 0000000000000000000000000000000000000000..67a2a4c669fc5821a07fc486228d626e16d6ad9e GIT binary patch literal 830 zcmZ?wbhEHb0&&L.which!=M.which)||E(L.target).is(M.not)){return }}switch(L.type){case"mousedown":E.extend(M,E(K).offset(),{elem:K,target:L.target,pageX:L.pageX,pageY:L.pageY});A.add(document,"mousemove mouseup",H,M);G(K,false);F.dragging=null;return false;case !F.dragging&&"mousemove":if(I(L.pageX-M.pageX)+I(L.pageY-M.pageY)").appendTo($container); - $divHeaders = $("
    ").appendTo($divHeadersScroller); + $divHeadersScroller = $("
    ").appendTo($container); + $divHeaders = $("
    ").appendTo($divHeadersScroller); $divMainScroller = $("
    ").appendTo($container); $divMain = $("
    ").appendTo($divMainScroller); + + - $divMainScroller.height( $container.innerHeight() - $divHeadersScroller.outerHeight() ); + // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?) + // calculate the diff so we can set consistent sizes + measureCellPaddingAndBorder(); for (var i = 0; i < columns.length; i++) { - var m = columns[i]; - + var m = columns[i] = $.extend({},columnDefaults,columns[i]); columnsById[m.id] = i; - if (!m.width) - m.width = options.defaultColumnWidth; - - if (!m.formatter) - m.formatter = defaultFormatter; - - var header = $("
    ") + var header = $("
    ") .html(m.name) - .width(m.width) + .width(m.width - headerColumnWidthDiff) .appendTo($divHeaders); + + if (m.sortable) header.append("") + if (m.resizable) header.append("
    "); } - $divHeaders.find(".h").each(function() { - var cell = parseInt($(this).attr("cell")); - var m = columns[cell]; - - if (m.resizable === false) return; - - $(this).resizable({ - handles: "e", - minWidth: (m.minWidth) ? m.minWidth : null, - maxWidth: (m.maxWidth) ? m.maxWidth : null, - stop: function(e, ui) { - var cellId = $(this).attr("id"); - var cell = columnsById[cellId]; - columns[cell].width = $(this).width(); - $.rule("." + uid + " .grid-canvas .c" + cell, "style").css("width", columns[cell].width + "px"); - resizeCanvas(); - - // todo: rerender single column instead of everything - if (columns[cell].rerenderOnResize) - removeAllRows(); - - render(); - } - }); - }); + $divMainScroller.height( $container.innerHeight() - $divHeadersScroller.outerHeight() ); + $divHeaders.disableSelection(); + + $divHeaders + .find(".slick-resizable-handle") + .bind('dragstart', function(e) { + var $col = $(this).parent(); + var colId = $col.attr("id"); + if (!columns[columnsById[colId]].resizable) return false; + if (currentEditor && !commitCurrentEdit()) return false; + + $col + .data("colId", colId) + .data("width", $col.width()) + .data("pageX", e.pageX) + .addClass("slick-header-column-active"); + }) + .bind('drag', function(e) { + var $col = $(this).parent(), w = $col.data("width") - $col.data("pageX") + e.pageX; + var cell = columnsById[$col.data("colId")]; + var m = columns[cell]; + if (m.minWidth) w = Math.max(m.minWidth - headerColumnWidthDiff,w); + if (m.maxWidth) w = Math.min(m.maxWidth - headerColumnWidthDiff,w); + $col.css({ width: Math.max(0, w) }); + }) + .bind('dragend', function(e) { + var $col = $(this).parent(); + var cell = columnsById[$col.data("colId")]; + $col.removeClass("slick-header-column-active"); + columns[cell].width = $col.outerWidth(); + $.rule("." + uid + " .grid-canvas .c" + cell, "style").css("width", (columns[cell].width - cellWidthDiff) + "px"); + resizeCanvas(); + + if (columns[cell].rerenderOnResize) + removeAllRows(); + + render(); + }) - // ignore .ui-resizable-handle to prevent sortable interfering with resizable + $divHeaders.click(function(e) { + var $col = $(e.target); + if (!$col.hasClass("slick-header-column") || !columns[columnsById[$col.attr("id")]].sortable) + return; + + if (currentEditor && !commitCurrentEdit()) return; + + if ($col.is(".slick-header-column-sorted")) + { + $col.find(".slick-sort-indicator").toggleClass("slick-sort-indicator-asc").toggleClass("slick-sort-indicator-desc"); + } + else + { + $divHeaders.children().removeClass("slick-header-column-sorted"); + $divHeaders.find(".slick-sort-indicator").removeClass("slick-sort-indicator-asc slick-sort-indicator-desc"); + $col.addClass("slick-header-column-sorted"); + $col.find(".slick-sort-indicator").addClass("slick-sort-indicator-asc"); + } + + if (self.onSort) + self.onSort(columns[columnsById[$col.attr("id")]], $col.find(".slick-sort-indicator").hasClass("slick-sort-indicator-asc")); + }) + if (options.enableColumnReorder) - $divHeaders.sortable({ - axis:"x", - cancel:".ui-resizable-handle", - update: function(e,ui) { - var newOrder = $divHeaders.sortable("toArray"); - - var lookup = {}; - for (var i=0; i
    ").appendTo($divHeaders); + headerColumnWidthDiff = tmp.outerWidth() - tmp.width(); + headerColumnHeightDiff = tmp.outerHeight() - tmp.height(); + tmp.remove(); + + var r = $("
    ").appendTo($divMain); + tmp = $("").appendTo(r); + cellWidthDiff = tmp.outerWidth() - tmp.width(); + cellHeightDiff = tmp.outerHeight() - tmp.height(); + r.remove(); + } + function createCssRules() { - $.rule(".grid-canvas .r .c { height:" + (options.rowHeight-5) + "px;}").appendTo("style"); + $.rule(".grid-canvas .r .c { height:" + (options.rowHeight - cellHeightDiff) + "px;}").appendTo("style"); for (var i = 0; i < columns.length; i++) { - $.rule("." + uid + " .grid-canvas .c" + i + " { width:" + columns[i].width + "px }").appendTo("style"); + $.rule("." + uid + " .grid-canvas .c" + i + " { width:" + (columns[i].width - cellWidthDiff) + "px }").appendTo("style"); } } @@ -279,7 +337,6 @@ function SlickGrid($container,data,columns,options) cancelCurrentEdit(); $divHeaders.sortable("destroy"); - $divHeaders.find(".h").resizable("destroy"); $container.unbind("resize", resizeCanvas); removeCssRules(); @@ -289,10 +346,6 @@ function SlickGrid($container,data,columns,options) ////////////////////////////////////////////////////////////////////////////////////////////// // General - function setColumnHeaderCssClass(id,classesToAdd,classesToRemove) { - $divHeaders.find(".h[id=" + id + "]").removeClass(classesToRemove).addClass(classesToAdd); - } - function getColumnIndex(id) { return columnsById[id]; } @@ -497,14 +550,14 @@ function SlickGrid($container,data,columns,options) function resizeCanvas() { viewportW = $divMainScroller.innerWidth(); viewportH = $divMainScroller.innerHeight(); - + BUFFER = numVisibleRows = Math.ceil(viewportH / options.rowHeight); CAPACITY = Math.max(50, numVisibleRows + 2*BUFFER); var totalWidth = 0; for (var i=0; i + From 01e301094293441cb1e9fc4aed34b02d38f28701 Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Wed, 25 Nov 2009 04:39:07 +0000 Subject: [PATCH 0058/1043] Fixed a layout issue in the graphical percent complete editor. --- slick.editors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slick.editors.js b/slick.editors.js index 4914f67..1b63bf8 100644 --- a/slick.editors.js +++ b/slick.editors.js @@ -295,7 +295,7 @@ var PercentCompleteCellEditor = function($container, columnDef, value, dataConte $input.val(defaultValue); } - $input.width(columnDef.width - 20); + $input.width($container.innerWidth() - 20); $input.appendTo($container); $picker = $("
    ").appendTo($container); From e44594d111cbf04606f856acc309836132617dde Mon Sep 17 00:00:00 2001 From: "michael.leibman" Date: Wed, 25 Nov 2009 06:13:33 +0000 Subject: [PATCH 0059/1043] - Added a column picker context menu to the header. - Added setColumnVisibility() method to the grid. - Updated "example4-model.html" with the column picker enabled. --- examples/example4-model.html | 14 +++----- slick.columnpicker.css | 19 +++++++++++ slick.columnpicker.js | 63 ++++++++++++++++++++++++++++++++++++ slick.grid.js | 21 ++++++++++-- 4 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 slick.columnpicker.css create mode 100644 slick.columnpicker.js diff --git a/examples/example4-model.html b/examples/example4-model.html index 1e7bb8a..f9236fc 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -7,6 +7,7 @@ + @@ -49,59 +57,56 @@ + + +
    +
    + +
    +
    +
    +
    -
    -
    - - -
    -
    +
    +
    + +
    +
    +
    + +
    + + + + +

    + + +
    - -
    - - - - -

    - - -

    +
    + +
    +

    Demonstrates:

    @@ -77,6 +104,7 @@

    Demonstrates:

  • column options: setValueHandler, cannotTriggerInsert
  • NOTE: all filters are immediately applied to new/edited rows
  • Handling row selection against model changes.
  • +
  • Paging.
  • - - - - -
    +
    + + Search: +
    + +
    + -
    -
    - -
    -
    -
    - -
    - - - - -

    - - - -
    +
    +

    -
    - -
    -
    -
    -
    -

    Demonstrates:

    + + -
      -
    • a filtered Model (DataView) as a data source instead of a simple array
    • -
    • grid reacting to model events (onRowCountChanged, onRowsChanged)
    • -
    • - FAST DataView recalculation and real-time grid updating in response to data changes.
      - The grid holds 10'000 rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows. -
    • -
    • adding new rows, bidirectional sorting
    • -
    • column options: setValueHandler, cannotTriggerInsert
    • -
    • NOTE: all filters are immediately applied to new/edited rows
    • -
    • Handling row selection against model changes.
    • -
    • Paging.
    • -
    +

    -
    - + +
    +
    + +
    +

    Demonstrates:

    + +
      +
    • a filtered Model (DataView) as a data source instead of a simple array
    • +
    • grid reacting to model events (onRowCountChanged, onRowsChanged)
    • +
    • + FAST DataView recalculation and real-time grid updating in response to data changes.
      + The grid holds 10'000 rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows. +
    • +
    • adding new rows, bidirectional sorting
    • +
    • column options: setValueHandler, cannotTriggerInsert
    • +
    • NOTE: all filters are immediately applied to new/edited rows
    • +
    • Handling row selection against model changes.
    • +
    • Paging.
    • +
    +
    + @@ -37,19 +59,13 @@
    - -
    -
    - Status: 

    Demonstrates:

    -
    • loading data through AJAX
    • custom row height
    - @@ -65,14 +81,11 @@

    Demonstrates:

    return "
    " + dataContext["title"] + "
    " + dataContext["description"]; }; - var userIconFormatter = function(row, cell, value, columnDef, dataContext) { - return ""; - }; var columns = [ - {id:"num", name:"#", field:"index", width:40}, - {id:"author", name:"Author", width:40, formatter:userIconFormatter, width:50}, - {id:"story", name:"Story", width:670, formatter:storyTitleFormatter, cssClass:"cell-story"} + {id:"num", name:"#", field:"index", width:40, sortable:false}, + {id:"story", name:"Story", width:670, formatter:storyTitleFormatter, cssClass:"cell-story", sortable:false}, + {id:"diggs", name:"Diggs", field:"diggs", width:60} ]; var options = { @@ -82,7 +95,7 @@

    Demonstrates:

    enableCellNavigation: false }; - + var loadingIndicator = null; @@ -92,14 +105,28 @@

    Demonstrates:

    grid.onViewportChanged = function() { var vp = grid.getViewport(); - var pagesize = vp.bottom - vp.top; - - loader.ensureData(vp.top - 2*pagesize, vp.bottom + 2*pagesize); + loader.ensureData(vp.top, vp.bottom); } + grid.onSort = function(sortCol,sortAsc) { + loader.setSort(sortCol.field,sortAsc?1:-1); + var vp = grid.getViewport(); + loader.ensureData(vp.top, vp.bottom); + } loader.onDataLoading.subscribe(function() { - $("#status").text("Loading..."); + if (!loadingIndicator) + { + loadingIndicator = $("").appendTo(document.body); + var $g = $("#myGrid"); + + loadingIndicator + .css("position", "absolute") + .css("top", $g.position().top + $g.height()/2 - loadingIndicator.height()/2) + .css("left", $g.position().left + $g.width()/2 - loadingIndicator.width()/2) + } + + loadingIndicator.show(); }); loader.onDataLoaded.subscribe(function(args) { @@ -110,17 +137,14 @@

    Demonstrates:

    grid.updateRowCount(); grid.render(); - $("#status").text("Ready."); + loadingIndicator.fadeOut(); }); // load the first page grid.onViewportChanged(); - }) - - diff --git a/examples/examples.css b/examples/examples.css index 8163aae..50416e4 100644 --- a/examples/examples.css +++ b/examples/examples.css @@ -68,6 +68,13 @@ li { text-align: left; } +.percent-complete-bar { + display: inline-block; + height: 6px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} + /* TextCellEditor, DateCellEditor */ diff --git a/lib/jquery.jsonp-1.1.0.min.js b/lib/jquery.jsonp-1.1.0.min.js new file mode 100644 index 0000000..7c47fbd --- /dev/null +++ b/lib/jquery.jsonp-1.1.0.min.js @@ -0,0 +1,3 @@ +// jquery.jsonp 1.1.0 (c)2009 Julian Aubourg | MIT License +// http://code.google.com/p/jquery-jsonp/ +(function(d){var b=function(n){return n!==undefined&&n!==null},m=function(p,n,o){b(p)&&p.apply(n,o)},e=function(n){setTimeout(n,0)},f="",a="&",k="?",l="success",g="error",i=d("head"),h={},c={callback:"C",url:location.href},j=function(s){s=d.extend({},c,s);var r=s.beforeSend,A=0;s.abort=function(){A=1};if(b(r)&&(r(s,s)===false||A)){return s}var q=s.success,o=s.complete,v=s.error,C=s.dataFilter,G=s.callbackParameter,w=s.callback,D=s.cache,n=s.pageCache,t=s.url,I=s.data,x=s.timeout,z,H,F,E;t=b(t)?t:f;I=b(I)?((typeof I)=="string"?I:d.param(I)):f;b(G)&&(I+=(I==f?f:a)+escape(G)+"=?");!D&&!n&&(I+=(I==f?f:a)+"_"+(new Date()).getTime()+"=");z=t.split(k);if(I!=f){H=I.split(k);E=z.length-1;E&&(z[E]+=a+H.shift());z=z.concat(H)}F=z.length-2;F&&(z[F]+=w+z.pop());var p=z.join(k),B=function(J){b(C)&&(J=C.apply(s,[J]));m(q,s,[J,l]);m(o,s,[s,l])},y=function(J){m(v,s,[s,J]);m(o,s,[s,J])},u=h[p];if(n&&b(u)){e(function(){b(u.s)?B(u.s):y(g)});return s}e(function(){if(A){return}var J=d("':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,monthNames,monthNamesShort){minDate=(inst.rangeStart&&minDate&&selectedDate "}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='"}if(!showMonthAfterYear){html+=monthHtml+((secondary||changeMonth||changeYear)&&(!(changeMonth&&changeYear))?" ":"")}if(secondary||!changeYear){html+=''+drawYear+""}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=drawYear+parseInt(years[0],10);endYear=drawYear+parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='"}if(showMonthAfterYear){html+=(secondary||changeMonth||changeYear?" ":"")+monthHtml}html+="";return html},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._daylightSavingAdjust(new Date(year,month,day));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&datemaxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:this._daylightSavingAdjust(new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay)));newMinDate=(newMinDate&&inst.rangeStart=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}if(options=="option"&&arguments.length==2&&typeof arguments[1]=="string"){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.7.2";window.DP_jQuery=$})(jQuery);;/* - * jQuery UI Progressbar 1.7.2 - * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * http://docs.jquery.com/UI/Progressbar - * - * Depends: - * ui.core.js - */ -(function(a){a.widget("ui.progressbar",{_init:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=a('
    ').appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow").removeData("progressbar").unbind(".progressbar");this.valueDiv.remove();a.widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===undefined){return this._value()}this._setData("value",b);return this},_setData:function(b,c){switch(b){case"value":this.options.value=c;this._refreshValue();this._trigger("change",null,{});break}a.widget.prototype._setData.apply(this,arguments)},_value:function(){var b=this.options.value;if(bthis._valueMax()){b=this._valueMax()}return b},_valueMin:function(){var b=0;return b},_valueMax:function(){var b=100;return b},_refreshValue:function(){var b=this.value();this.valueDiv[b==this._valueMax()?"addClass":"removeClass"]("ui-corner-right");this.valueDiv.width(b+"%");this.element.attr("aria-valuenow",b)}});a.extend(a.ui.progressbar,{version:"1.7.2",defaults:{value:0}})})(jQuery);;/* - * jQuery UI Effects 1.7.2 - * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * http://docs.jquery.com/UI/Effects/ - */ -jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(var f=0;f');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}};function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:(i.duration?i.duration:g[2]);h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[1])&&g[1])||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(d.isFunction(arguments[0])||typeof arguments[0]=="boolean")){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h").css({position:"absolute",visibility:"visible",left:-d*(g/e),top:-f*(c/k)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/e,height:c/k,left:l.left+d*(g/e)+(b.options.mode=="show"?(d-Math.floor(e/2))*(g/e):0),top:l.top+f*(c/k)+(b.options.mode=="show"?(f-Math.floor(k/2))*(c/k):0),opacity:b.options.mode=="show"?0:1}).animate({left:l.left+d*(g/e)+(b.options.mode=="show"?0:(d-Math.floor(e/2))*(g/e)),top:l.top+f*(c/k)+(b.options.mode=="show"?0:(f-Math.floor(k/2))*(c/k)),opacity:b.options.mode=="show"?1:0},b.duration||500)}}setTimeout(function(){b.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();if(b.callback){b.callback.apply(h[0])}h.dequeue();a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);;/* - * jQuery UI Effects Fold 1.7.2 - * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * http://docs.jquery.com/UI/Effects/Fold - * - * Depends: - * effects.core.js - */ -(function(a){a.effects.fold=function(b){return this.queue(function(){var e=a(this),k=["position","top","left"];var h=a.effects.setMode(e,b.options.mode||"hide");var o=b.options.size||15;var n=!(!b.options.horizFirst);var g=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(e,k);e.show();var d=a.effects.createWrapper(e).css({overflow:"hidden"});var i=((h=="show")!=n);var f=i?["width","height"]:["height","width"];var c=i?[d.width(),d.height()]:[d.height(),d.width()];var j=/([0-9]+)%/.exec(o);if(j){o=parseInt(j[1],10)/100*c[h=="hide"?0:1]}if(h=="show"){d.css(n?{height:0,width:o}:{height:o,width:0})}var m={},l={};m[f[0]]=h=="show"?c[0]:o;l[f[1]]=h=="show"?c[1]:0;d.animate(m,g,b.options.easing).animate(l,g,b.options.easing,function(){if(h=="hide"){e.hide()}a.effects.restore(e,k);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(e[0],arguments)}e.dequeue()})})}})(jQuery);;/* - * jQuery UI Effects Highlight 1.7.2 - * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * http://docs.jquery.com/UI/Effects/Highlight - * - * Depends: - * effects.core.js - */ -(function(a){a.effects.highlight=function(b){return this.queue(function(){var e=a(this),d=["backgroundImage","backgroundColor","opacity"];var h=a.effects.setMode(e,b.options.mode||"show");var c=b.options.color||"#ffff99";var g=e.css("backgroundColor");a.effects.save(e,d);e.show();e.css({backgroundImage:"none",backgroundColor:c});var f={backgroundColor:g};if(h=="hide"){f.opacity=0}e.animate(f,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(h=="hide"){e.hide()}a.effects.restore(e,d);if(h=="show"&&a.browser.msie){this.style.removeAttribute("filter")}if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/* - * jQuery UI Effects Pulsate 1.7.2 - * - * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT (MIT-LICENSE.txt) - * and GPL (GPL-LICENSE.txt) licenses. - * - * http://docs.jquery.com/UI/Effects/Pulsate - * - * Depends: - * effects.core.js - */ -(function(a){a.effects.pulsate=function(b){return this.queue(function(){var d=a(this);var g=a.effects.setMode(d,b.options.mode||"show");var f=b.options.times||5;var e=b.duration?b.duration/2:a.fx.speeds._default/2;if(g=="hide"){f--}if(d.is(":hidden")){d.css("opacity",0);d.show();d.animate({opacity:1},e,b.options.easing);f=f-2}for(var c=0;c').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);; \ No newline at end of file diff --git a/lib/jquery-ui-1.8.2.custom.min.js b/lib/jquery-ui-1.8.2.custom.min.js new file mode 100644 index 0000000..c11e844 --- /dev/null +++ b/lib/jquery-ui-1.8.2.custom.min.js @@ -0,0 +1,1012 @@ +/*! + * jQuery UI 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI + */ +(function(c){c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.2",plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=0)&&c(a).is(":focusable")}})}})(jQuery); +;/*! + * jQuery UI Widget 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Widget + */ +(function(b){var j=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add(this).each(function(){b(this).triggerHandler("remove")});return j.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend({},c.options);b[e][a].prototype= +b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==undefined){h=i;return false}}):this.each(function(){var g= +b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){this.element=b(c).data(this.widgetName,this);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create(); +this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===undefined)return this.options[a];d={};d[a]=c}b.each(d,function(f, +h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a= +b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery); +;/*! + * jQuery UI Mouse 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&& +this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault(); +return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&& +this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX- +a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); +;/* + * jQuery UI Position 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Position + */ +(function(c){c.ui=c.ui||{};var m=/left|center|right/,n=/top|center|bottom/,p=c.fn.position,q=c.fn.offset;c.fn.position=function(a){if(!a||!a.of)return p.apply(this,arguments);a=c.extend({},a);var b=c(a.of),d=(a.collision||"flip").split(" "),e=a.offset?a.offset.split(" "):[0,0],g,h,i;if(a.of.nodeType===9){g=b.width();h=b.height();i={top:0,left:0}}else if(a.of.scrollTo&&a.of.document){g=b.width();h=b.height();i={top:b.scrollTop(),left:b.scrollLeft()}}else if(a.of.preventDefault){a.at="left top";g=h= +0;i={top:a.of.pageY,left:a.of.pageX}}else{g=b.outerWidth();h=b.outerHeight();i=b.offset()}c.each(["my","at"],function(){var f=(a[this]||"").split(" ");if(f.length===1)f=m.test(f[0])?f.concat(["center"]):n.test(f[0])?["center"].concat(f):["center","center"];f[0]=m.test(f[0])?f[0]:"center";f[1]=n.test(f[1])?f[1]:"center";a[this]=f});if(d.length===1)d[1]=d[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(a.at[0]==="right")i.left+=g;else if(a.at[0]==="center")i.left+= +g/2;if(a.at[1]==="bottom")i.top+=h;else if(a.at[1]==="center")i.top+=h/2;i.left+=e[0];i.top+=e[1];return this.each(function(){var f=c(this),k=f.outerWidth(),l=f.outerHeight(),j=c.extend({},i);if(a.my[0]==="right")j.left-=k;else if(a.my[0]==="center")j.left-=k/2;if(a.my[1]==="bottom")j.top-=l;else if(a.my[1]==="center")j.top-=l/2;j.left=parseInt(j.left);j.top=parseInt(j.top);c.each(["left","top"],function(o,r){c.ui.position[d[o]]&&c.ui.position[d[o]][r](j,{targetWidth:g,targetHeight:h,elemWidth:k, +elemHeight:l,offset:e,my:a.my,at:a.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(j,{using:a.using}))})};c.ui.position={fit:{left:function(a,b){var d=c(window);b=a.left+b.elemWidth-d.width()-d.scrollLeft();a.left=b>0?a.left-b:Math.max(0,a.left)},top:function(a,b){var d=c(window);b=a.top+b.elemHeight-d.height()-d.scrollTop();a.top=b>0?a.top-b:Math.max(0,a.top)}},flip:{left:function(a,b){if(b.at[0]!=="center"){var d=c(window);d=a.left+b.elemWidth-d.width()-d.scrollLeft();var e=b.my[0]==="left"? +-b.elemWidth:b.my[0]==="right"?b.elemWidth:0,g=-2*b.offset[0];a.left+=a.left<0?e+b.targetWidth+g:d>0?e-b.targetWidth+g:0}},top:function(a,b){if(b.at[1]!=="center"){var d=c(window);d=a.top+b.elemHeight-d.height()-d.scrollTop();var e=b.my[1]==="top"?-b.elemHeight:b.my[1]==="bottom"?b.elemHeight:0,g=b.at[1]==="top"?b.targetHeight:-b.targetHeight,h=-2*b.offset[1];a.top+=a.top<0?e+b.targetHeight+h:d>0?e+g+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(a,b){if(/static/.test(c.curCSS(a,"position")))a.style.position= +"relative";var d=c(a),e=d.offset(),g=parseInt(c.curCSS(a,"top",true),10)||0,h=parseInt(c.curCSS(a,"left",true),10)||0;e={top:b.top-e.top+g,left:b.left-e.left+h};"using"in b?b.using.call(a,e):d.css(e)};c.fn.offset=function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(){c.offset.setOffset(this,a)});return q.call(this)}}})(jQuery); +;/* + * jQuery UI Draggable 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Draggables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper== +"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b= +this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;return true},_mouseStart:function(a){var b=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top- +this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions(); +d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);return true},_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis|| +this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b=false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if(!this.element[0]||!this.element[0].parentNode)return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element, +b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle||!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this== +a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone():this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]|| +0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0], +this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top- +(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment== +"parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&& +a.containment.constructor!=Array){var b=d(a.containment)[0];if(b){a=d(a.containment).offset();var c=d(b).css("overflow")!="hidden";this.containment=[a.left+(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0)-this.margins.top,a.left+(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"), +10)||0)-this.helperProportions.width-this.margins.left,a.top+(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"),10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0], +this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft(): +f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,g=a.pageY;if(this.originalPosition){if(this.containment){if(a.pageX-this.offset.click.leftthis.containment[2])e=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.topthis.containment[3])?g:!(g-this.offset.click.topthis.containment[2])?e:!(e-this.offset.click.left').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")})},stop:function(){d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});d.ui.plugin.add("draggable","opacity",{start:function(a,b){a=d(b.helper);b=d(this).data("draggable").options; +if(a.css("opacity"))b._opacity=a.css("opacity");a.css("opacity",b.opacity)},stop:function(a,b){a=d(this).data("draggable").options;a._opacity&&d(b.helper).css("opacity",a._opacity)}});d.ui.plugin.add("draggable","scroll",{start:function(){var a=d(this).data("draggable");if(a.scrollParent[0]!=document&&a.scrollParent[0].tagName!="HTML")a.overflowOffset=a.scrollParent.offset()},drag:function(a){var b=d(this).data("draggable"),c=b.options,f=false;if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!= +"HTML"){if(!c.axis||c.axis!="x")if(b.overflowOffset.top+b.scrollParent[0].offsetHeight-a.pageY=0;h--){var i=c.snapElements[h].left,k=i+c.snapElements[h].width,j=c.snapElements[h].top,l=j+c.snapElements[h].height;if(i-e=j&&f<=l||h>=j&&h<=l||fl)&&(e>=i&& +e<=k||g>=i&&g<=k||ek);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), +top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= +this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!d(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", +nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var e=0;e');/sw|se|ne|nw/.test(g)&&f.css({zIndex:++a.zIndex});"se"==g&&f.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[g]=".ui-resizable-"+g;this.element.append(f)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor== +String)this.handles[i]=d(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=d(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}d(this.handles[i])}};this._renderAxis(this.element);this._handles=d(".ui-resizable-handle",this.element).disableSelection(); +this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();d(this.element).addClass("ui-resizable-autohide").hover(function(){d(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){d(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){d(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()}; +if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(d(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(), +e=this.element;this.resizing=true;this.documentScroll={top:d(document).scrollTop(),left:d(document).scrollLeft()};if(e.is(".ui-draggable")||/absolute/.test(e.css("position")))e.css({position:"absolute",top:c.top,left:c.left});d.browser.opera&&/relative/.test(e.css("position"))&&e.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var g=m(this.helper.css("top"));if(a.containment){c+=d(a.containment).scrollLeft()||0;g+=d(a.containment).scrollTop()||0}this.offset= +this.helper.offset();this.position={left:c,top:g};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:c,top:g};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio: +this.originalSize.width/this.originalSize.height||1;a=d(".ui-resizable-"+this.axis).css("cursor");d("body").css("cursor",a=="auto"?this.axis+"-resize":a);e.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,e=this._change[this.axis];if(!e)return false;c=e.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize", +b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var e=this._proportionallyResizeElements,g=e.length&&/textarea/i.test(e[0].nodeName);e=g&&d.ui.hasScroll(e[0],"left")?0:c.sizeDiff.height; +g={width:c.size.width-(g?0:c.sizeDiff.width),height:c.size.height-e};e=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var f=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(d.extend(g,{top:f,left:e}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}d("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop", +b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(k(b.left))this.position.left=b.left;if(k(b.top))this.position.top=b.top;if(k(b.height))this.size.height=b.height;if(k(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,e=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(e=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(e=="nw"){b.top= +a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,e=k(b.width)&&a.maxWidth&&a.maxWidthb.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(f)b.width=a.minWidth;if(h)b.height=a.minHeight;if(e)b.width=a.maxWidth;if(g)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height, +l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(f&&l)b.left=i-a.minWidth;if(e&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(g&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a');var a=d.browser.msie&&d.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+ +a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return d.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return d.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return d.extend(this._change.n.apply(this, +arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return d.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){d.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});d.extend(d.ui.resizable, +{version:"1.8.2"});d.ui.plugin.add("resizable","alsoResize",{start:function(){var b=d(this).data("resizable").options,a=function(c){d(c).each(function(){d(this).data("resizable-alsoresize",{width:parseInt(d(this).width(),10),height:parseInt(d(this).height(),10),left:parseInt(d(this).css("left"),10),top:parseInt(d(this).css("top"),10)})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else d.each(b.alsoResize,function(c){a(c)}); +else a(b.alsoResize)},resize:function(){var b=d(this).data("resizable"),a=b.options,c=b.originalSize,e=b.originalPosition,g={height:b.size.height-c.height||0,width:b.size.width-c.width||0,top:b.position.top-e.top||0,left:b.position.left-e.left||0},f=function(h,i){d(h).each(function(){var j=d(this),l=d(this).data("resizable-alsoresize"),p={};d.each((i&&i.length?i:["width","height","top","left"])||["width","height","top","left"],function(n,o){if((n=(l[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(/relative/.test(j.css("position"))&& +d.browser.opera){b._revertToRelativePosition=true;j.css({position:"absolute",top:"auto",left:"auto"})}j.css(p)})};typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?d.each(a.alsoResize,function(h,i){f(h,i)}):f(a.alsoResize)},stop:function(){var b=d(this).data("resizable");if(b._revertToRelativePosition&&d.browser.opera){b._revertToRelativePosition=false;el.css({position:"relative"})}d(this).removeData("resizable-alsoresize-start")}});d.ui.plugin.add("resizable","animate",{stop:function(b){var a= +d(this).data("resizable"),c=a.options,e=a._proportionallyResizeElements,g=e.length&&/textarea/i.test(e[0].nodeName),f=g&&d.ui.hasScroll(e[0],"left")?0:a.sizeDiff.height;g={width:a.size.width-(g?0:a.sizeDiff.width),height:a.size.height-f};f=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(d.extend(g,h&&f?{top:h,left:f}:{}),{duration:c.animateDuration,easing:c.animateEasing, +step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};e&&e.length&&d(e[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});d.ui.plugin.add("resizable","containment",{start:function(){var b=d(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof d?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement= +d(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:d(document),left:0,top:0,width:d(document).width(),height:d(document).height()||document.body.parentNode.scrollHeight}}else{var e=d(a),g=[];d(["Top","Right","Left","Bottom"]).each(function(i,j){g[i]=m(e.css("padding"+j))});b.containerOffset=e.offset();b.containerPosition=e.position();b.containerSize={height:e.innerHeight()-g[3],width:e.innerWidth()-g[1]};c=b.containerOffset; +var f=b.containerSize.height,h=b.containerSize.width;h=d.ui.hasScroll(a,"left")?a.scrollWidth:h;f=d.ui.hasScroll(a)?a.scrollHeight:f;b.parentData={element:a,left:c.left,top:c.top,width:h,height:f}}}},resize:function(b){var a=d(this).data("resizable"),c=a.options,e=a.containerOffset,g=a.position;b=a._aspectRatio||b.shiftKey;var f={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))f=e;if(g.left<(a._helper?e.left:0)){a.size.width+=a._helper?a.position.left-e.left: +a.position.left-f.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?e.left:0}if(g.top<(a._helper?e.top:0)){a.size.height+=a._helper?a.position.top-e.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?e.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-f.left:a.offset.left-f.left)+a.sizeDiff.width);e=Math.abs((a._helper?a.offset.top-f.top:a.offset.top- +e.top)+a.sizeDiff.height);g=a.containerElement.get(0)==a.element.parent().get(0);f=/relative|absolute/.test(a.containerElement.css("position"));if(g&&f)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(e+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-e;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=d(this).data("resizable"),a=b.options,c=b.containerOffset,e=b.containerPosition, +g=b.containerElement,f=d(b.helper),h=f.offset(),i=f.outerWidth()-b.sizeDiff.width;f=f.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(g.css("position"))&&d(this).css({left:h.left-e.left-c.left,width:i,height:f});b._helper&&!a.animate&&/static/.test(g.css("position"))&&d(this).css({left:h.left-e.left-c.left,width:i,height:f})}});d.ui.plugin.add("resizable","ghost",{start:function(){var b=d(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25, +display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=d(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=d(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});d.ui.plugin.add("resizable","grid",{resize:function(){var b= +d(this).data("resizable"),a=b.options,c=b.size,e=b.originalSize,g=b.originalPosition,f=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-e.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-e.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(f)){b.size.width=e.width+h;b.size.height=e.height+a}else if(/^(ne)$/.test(f)){b.size.width=e.width+h;b.size.height=e.height+a;b.position.top=g.top-a}else{if(/^(sw)$/.test(f)){b.size.width=e.width+h;b.size.height= +e.height+a}else{b.size.width=e.width+h;b.size.height=e.height+a;b.position.top=g.top-a}b.position.left=g.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery); +; +/* + * jQuery UI Selectable 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Selectables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function($) { + +$.widget("ui.selectable", $.ui.mouse, { + options: { + appendTo: 'body', + autoRefresh: true, + distance: 0, + filter: '*', + tolerance: 'touch' + }, + _create: function() { + var self = this; + + this.element.addClass("ui-selectable"); + + this.dragged = false; + + // cache selectee children based on filter + var selectees; + this.refresh = function() { + selectees = $(self.options.filter, self.element[0]); + selectees.each(function() { + var $this = $(this); + var pos = $this.offset(); + $.data(this, "selectable-item", { + element: this, + $element: $this, + left: pos.left, + top: pos.top, + right: pos.left + $this.outerWidth(), + bottom: pos.top + $this.outerHeight(), + startselected: false, + selected: $this.hasClass('ui-selected'), + selecting: $this.hasClass('ui-selecting'), + unselecting: $this.hasClass('ui-unselecting') + }); + }); + }; + this.refresh(); + + this.selectees = selectees.addClass("ui-selectee"); + + this._mouseInit(); + + this.helper = $("
    "); + }, + + destroy: function() { + this.selectees + .removeClass("ui-selectee") + .removeData("selectable-item"); + this.element + .removeClass("ui-selectable ui-selectable-disabled") + .removeData("selectable") + .unbind(".selectable"); + this._mouseDestroy(); + + return this; + }, + + _mouseStart: function(event) { + var self = this; + + this.opos = [event.pageX, event.pageY]; + + if (this.options.disabled) + return; + + var options = this.options; + + this.selectees = $(options.filter, this.element[0]); + + this._trigger("start", event); + + $(options.appendTo).append(this.helper); + // position helper (lasso) + this.helper.css({ + "z-index": 100, + "position": "absolute", + "left": event.clientX, + "top": event.clientY, + "width": 0, + "height": 0 + }); + + if (options.autoRefresh) { + this.refresh(); + } + + this.selectees.filter('.ui-selected').each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.startselected = true; + if (!event.metaKey) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + // selectable UNSELECTING callback + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + }); + + $(event.target).parents().andSelf().each(function() { + var selectee = $.data(this, "selectable-item"); + if (selectee) { + var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected'); + selectee.$element + .removeClass(doSelect ? "ui-unselecting" : "ui-selected") + .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); + selectee.unselecting = !doSelect; + selectee.selecting = doSelect; + selectee.selected = doSelect; + // selectable (UN)SELECTING callback + if (doSelect) { + self._trigger("selecting", event, { + selecting: selectee.element + }); + } else { + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + return false; + } + }); + + }, + + _mouseDrag: function(event) { + var self = this; + this.dragged = true; + + if (this.options.disabled) + return; + + var options = this.options; + + var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; + if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } + if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } + this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); + + this.selectees.each(function() { + var selectee = $.data(this, "selectable-item"); + //prevent helper from being selected if appendTo: selectable + if (!selectee || selectee.element == self.element[0]) + return; + var hit = false; + if (options.tolerance == 'touch') { + hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); + } else if (options.tolerance == 'fit') { + hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); + } + + if (hit) { + // SELECT + if (selectee.selected) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + } + if (selectee.unselecting) { + selectee.$element.removeClass('ui-unselecting'); + selectee.unselecting = false; + } + if (!selectee.selecting) { + selectee.$element.addClass('ui-selecting'); + selectee.selecting = true; + // selectable SELECTING callback + self._trigger("selecting", event, { + selecting: selectee.element + }); + } + } else { + // UNSELECT + if (selectee.selecting) { + if (event.metaKey && selectee.startselected) { + selectee.$element.removeClass('ui-selecting'); + selectee.selecting = false; + selectee.$element.addClass('ui-selected'); + selectee.selected = true; + } else { + selectee.$element.removeClass('ui-selecting'); + selectee.selecting = false; + if (selectee.startselected) { + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + } + // selectable UNSELECTING callback + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + if (selectee.selected) { + if (!event.metaKey && !selectee.startselected) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + // selectable UNSELECTING callback + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + } + }); + + return false; + }, + + _mouseStop: function(event) { + var self = this; + + this.dragged = false; + + var options = this.options; + + $('.ui-unselecting', this.element[0]).each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.$element.removeClass('ui-unselecting'); + selectee.unselecting = false; + selectee.startselected = false; + self._trigger("unselected", event, { + unselected: selectee.element + }); + }); + $('.ui-selecting', this.element[0]).each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); + selectee.selecting = false; + selectee.selected = true; + selectee.startselected = true; + self._trigger("selected", event, { + selected: selectee.element + }); + }); + this._trigger("stop", event); + + this.helper.remove(); + + return false; + } + +}); + +$.extend($.ui.selectable, { + version: "1.8.2" +}); + +})(jQuery); +(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"), +selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("
    ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, +c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({"z-index":100,position:"absolute",left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting"); +b.unselecting=true;f._trigger("unselecting",c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f= +this;this.dragged=true;if(!this.options.disabled){var d=this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.righti||a.bottomb&&a.rightg&&a.bottom *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){this.containerCache={};this.element.addClass("ui-sortable"); +this.refresh();this.floating=this.items.length?/left|right/.test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a==="disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this, +arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&&!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem= +c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset, +{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment(); +if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start", +a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute"); +if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0],e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a, +c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset();c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]== +document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp();this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate", +null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem): +d(this.domPosition.parent).prepend(this.currentItem);return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});return c.join("&")},toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c}, +_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+jg&&b+la[this.floating?"width":"height"]?j:g0?"down":"up")},_getDragHorizontalDirection:function(){var a= +this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith();if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)? +h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"), +b=0;b=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)? +i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h=0;b--){var c=this.items[b],e=this.options.toleranceElement?d(this.options.toleranceElement, +c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b=this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height= +this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()- +parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0], +this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b= +1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h-f)this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g-this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.topthis.containment[3])?g:!(g-this.offset.click.topthis.containment[2])?f:!(f-this.offset.click.left=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update", +g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity", +this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop",a,this._uiHash());for(e=0;e li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()}},_create:function(){var a=this.options,b=this;this.running=0;this.element.addClass("ui-accordion ui-widget ui-helper-reset"); +this.element.children("li").addClass("ui-accordion-li-fix");this.headers=this.element.find(a.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c(this).removeClass("ui-state-focus")});this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); +if(a.navigation){var d=this.element.find("a").filter(a.navigationFilter);if(d.length){var f=d.closest(".ui-accordion-header");this.active=f.length?f:d.closest(".ui-accordion-content").prev()}}this.active=this._findActive(this.active||a.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");this.active.next().addClass("ui-accordion-content-active");this._createIcons();this.resize();this.element.attr("role","tablist");this.headers.attr("role", +"tab").bind("keydown",function(g){return b._keydown(g)}).next().attr("role","tabpanel");this.headers.not(this.active||"").attr("aria-expanded","false").attr("tabIndex","-1").next().hide();this.active.length?this.active.attr("aria-expanded","true").attr("tabIndex","0"):this.headers.eq(0).attr("tabIndex","0");c.browser.safari||this.headers.find("a").attr("tabIndex","-1");a.event&&this.headers.bind(a.event+".accordion",function(g){b._clickHandler.call(b,g,this);g.preventDefault()})},_createIcons:function(){var a= +this.options;if(a.icons){c("").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.find(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role").unbind(".accordion").removeData("accordion"); +this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("tabIndex");this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active");if(a.autoHeight||a.fillHeight)b.css("height", +"");return this},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons();b&&this._createIcons()}},_keydown:function(a){var b=c.ui.keyCode;if(!(this.options.disabled||a.altKey||a.ctrlKey)){var d=this.headers.length,f=this.headers.index(a.target),g=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:g=this.headers[(f+1)%d];break;case b.LEFT:case b.UP:g=this.headers[(f-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target}, +a.target);a.preventDefault()}if(g){c(a.target).attr("tabIndex","-1");c(g).attr("tabIndex","0");g.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0, +b-c(this).innerHeight()+c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a=="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d= +this.options;if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]==this.active[0];d.active=d.collapsible&&b?false:c(".ui-accordion-header",this.element).index(a);if(!(this.running||!d.collapsible&&b)){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").find(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").find(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected); +a.next().addClass("ui-accordion-content-active")}e=a.next();f=this.active.next();g={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):e,oldContent:f};d=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(e,f,g,b,d)}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").find(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header); +this.active.next().addClass("ui-accordion-content-active");var f=this.active.next(),g={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:f},e=this.active=c([]);this._toggle(e,f,g)}},_toggle:function(a,b,d,f,g){var e=this.options,k=this;this.toShow=a;this.toHide=b;this.data=d;var i=function(){if(k)return k._completed.apply(k,arguments)};this._trigger("changestart",null,this.data);this.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&f?{toShow:c([]), +toHide:b,complete:i,down:g,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:i,down:g,autoHeight:e.autoHeight||e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;f=c.ui.accordion.animations;var h=e.duration,j=e.animated;if(j&&!f[j]&&!c.easing[j])j="slide";f[j]||(f[j]=function(l){this.slide(l,{easing:j, +duration:h||700})});f[j](d)}else{if(e.collapsible&&f)a.toggle();else{b.hide();a.show()}i(true)}b.prev().attr("aria-expanded","false").attr("tabIndex","-1").blur();a.prev().attr("aria-expanded","true").attr("tabIndex","0").focus()},_completed:function(a){var b=this.options;this.running=a?0:--this.running;if(!this.running){b.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion, +{version:"1.8.2",animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),f=0,g={},e={},k;b=a.toShow;k=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(i,h){e[h]="hide";i=(""+c.css(a.toShow[0], +h)).match(/^([\d+-.]+)(.*)$/);g[h]={value:i[1],unit:i[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(e,{step:function(i,h){if(h.prop=="height")f=h.end-h.start===0?0:(h.now-h.start)/(h.end-h.start);a.toShow[0].style[h.prop]=f*g[h.prop].value+g[h.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css("width",k);a.toShow.css({overflow:d});a.complete()}})}else a.toHide.animate({height:"hide"}, +a);else a.toShow.animate({height:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery); +;/* + * jQuery UI Autocomplete 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Autocomplete + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */ +(function(e){e.widget("ui.autocomplete",{options:{minLength:1,delay:300},_create:function(){var a=this,c=this.element[0].ownerDocument;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(d){var b=e.ui.keyCode;switch(d.keyCode){case b.PAGE_UP:a._move("previousPage",d);break;case b.PAGE_DOWN:a._move("nextPage",d);break;case b.UP:a._move("previous",d);d.preventDefault(); +break;case b.DOWN:a._move("next",d);d.preventDefault();break;case b.ENTER:case b.NUMPAD_ENTER:a.menu.active&&d.preventDefault();case b.TAB:if(!a.menu.active)return;a.menu.select(d);break;case b.ESCAPE:a.element.val(a.term);a.close(d);break;case b.LEFT:case b.RIGHT:case b.SHIFT:case b.CONTROL:case b.ALT:case b.COMMAND:case b.COMMAND_RIGHT:case b.INSERT:case b.CAPS_LOCK:case b.END:case b.HOME:break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){a.search(null,d)},a.options.delay); +break}}).bind("focus.autocomplete",function(){a.selectedItem=null;a.previous=a.element.val()}).bind("blur.autocomplete",function(d){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(d);a._change(d)},150)});this._initSource();this.response=function(){return a._response.apply(a,arguments)};this.menu=e("
      ").addClass("ui-autocomplete").appendTo("body",c).mousedown(function(){setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(d,b){b=b.item.data("item.autocomplete"); +false!==a._trigger("focus",null,{item:b})&&/^key/.test(d.originalEvent.type)&&a.element.val(b.value)},selected:function(d,b){b=b.item.data("item.autocomplete");false!==a._trigger("select",d,{item:b})&&a.element.val(b.value);a.close(d);d=a.previous;if(a.element[0]!==c.activeElement){a.element.focus();a.previous=d}a.selectedItem=b},blur:function(){a.menu.element.is(":visible")&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");e.fn.bgiframe&&this.menu.element.bgiframe()}, +destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();e.Widget.prototype.destroy.call(this)},_setOption:function(a){e.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource()},_initSource:function(){var a,c;if(e.isArray(this.options.source)){a=this.options.source;this.source=function(d,b){b(e.ui.autocomplete.filter(a,d.term))}}else if(typeof this.options.source=== +"string"){c=this.options.source;this.source=function(d,b){e.getJSON(c,d,b)}}else this.source=this.options.source},search:function(a,c){a=a!=null?a:this.element.val();if(a.length").data("item.autocomplete", +c).append(""+c.label+"").appendTo(a)},_move:function(a,c){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](c);else this.search(null,c)},widget:function(){return this.menu.element}});e.extend(e.ui.autocomplete,{escapeRegex:function(a){return a.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")},filter:function(a,c){var d=new RegExp(e.ui.autocomplete.escapeRegex(c), +"i");return e.grep(a,function(b){return d.test(b.label||b.value||b)})}})})(jQuery); +(function(e){e.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){if(e(c.target).closest(".ui-menu-item a").length){c.preventDefault();a.select(c)}});this.refresh()},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", +-1).mouseenter(function(c){a.activate(c,e(this).parent())}).mouseleave(function(){a.deactivate()})},activate:function(a,c){this.deactivate();if(this.hasScroll()){var d=c.offset().top-this.element.offset().top,b=this.element.attr("scrollTop"),f=this.element.height();if(d<0)this.element.attr("scrollTop",b+d);else d>f&&this.element.attr("scrollTop",b+d-f+c.height())}this.active=c.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",a,{item:c})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id"); +this._trigger("blur");this.active=null}},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prev().length},last:function(){return this.active&&!this.active.next().length},move:function(a,c,d){if(this.active){a=this.active[a+"All"](".ui-menu-item").eq(0);a.length?this.activate(d,a):this.activate(d,this.element.children(c))}else this.activate(d,this.element.children(c))},nextPage:function(a){if(this.hasScroll())if(!this.active|| +this.last())this.activate(a,this.element.children(":first"));else{var c=this.active.offset().top,d=this.element.height(),b=this.element.children("li").filter(function(){var f=e(this).offset().top-c-d+e(this).height();return f<10&&f>-10});b.length||(b=this.element.children(":last"));this.activate(a,b)}else this.activate(a,this.element.children(!this.active||this.last()?":first":":last"))},previousPage:function(a){if(this.hasScroll())if(!this.active||this.first())this.activate(a,this.element.children(":last")); +else{var c=this.active.offset().top,d=this.element.height();result=this.element.children("li").filter(function(){var b=e(this).offset().top-c+d-e(this).height();return b<10&&b>-10});result.length||(result=this.element.children(":first"));this.activate(a,result)}else this.activate(a,this.element.children(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()
      ").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary;if(d.primary||d.secondary){b.addClass("ui-button-text-icon"+(e?"s":""));d.primary&&b.prepend("");d.secondary&&b.append("");if(!this.options.text){b.addClass(e?"ui-button-icons-only":"ui-button-icon-only").removeClass("ui-button-text-icons ui-button-text-icon"); +this.hasTitle||b.attr("title",c)}}else b.addClass("ui-button-text-only")}}});a.widget("ui.buttonset",{_create:function(){this.element.addClass("ui-buttonset");this._init()},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){this.buttons=this.element.find(":button, :submit, :reset, :checkbox, :radio, a, :data(button)").filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass("ui-corner-left").end().filter(":last").addClass("ui-corner-right").end().end()}, +destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");a.Widget.prototype.destroy.call(this)}})})(jQuery); +;/* + * jQuery UI Dialog 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Dialog + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.draggable.js + * jquery.ui.mouse.js + * jquery.ui.position.js + * jquery.ui.resizable.js + */ +(function(c){c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");var a=this,b=a.options,d=b.title||a.originalTitle||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("
      ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ +b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g), +h=c('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("").addClass("ui-dialog-title").attr("id", +e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); +a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!== +b.uiDialog[0])d=Math.max(d,c(this).css("z-index"))});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index", +c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;d.next().length&&d.appendTo("body");a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target=== +f[0]&&e.shiftKey){g.focus(1);return false}}});c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();a._trigger("open");a._isOpen=true;return a}},_createButtons:function(a){var b=this,d=false,e=c("
      ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a, +function(g,f){g=c('').text(g).click(function(){f.apply(b.element[0],arguments)}).appendTo(e);c.fn.button&&g.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging"); +b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,originalSize:f.originalSize,position:f.position,size:f.size}}a=a===undefined?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position"); +a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop", +f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0];a=a||c.ui.dialog.prototype.options.position;if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(e,g){if(+b[e]===b[e]){d[e]=b[e];b[e]= +g}})}else if(typeof a==="object"){if("left"in a){b[0]="left";d[0]=a.left}else if("right"in a){b[0]="right";d[0]=-a.right}if("top"in a){b[1]="top";d[1]=a.top}else if("bottom"in a){b[1]="bottom";d[1]=-a.bottom}}(a=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position({my:b.join(" "),at:b.join(" "),offset:d.join(" "),of:window,collision:"fit",using:function(e){var g=c(this).css(e).offset().top;g<0&&c(this).css("top",e.top-g)}});a||this.uiDialog.hide()},_setOption:function(a, +b){var d=this,e=d.uiDialog,g=e.is(":data(resizable)"),f=false;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):e.removeClass("ui-dialog-disabled");break;case "draggable":b?d._makeDraggable():e.draggable("destroy");break; +case "height":f=true;break;case "maxHeight":g&&e.resizable("option","maxHeight",b);f=true;break;case "maxWidth":g&&e.resizable("option","maxWidth",b);f=true;break;case "minHeight":g&&e.resizable("option","minHeight",b);f=true;break;case "minWidth":g&&e.resizable("option","minWidth",b);f=true;break;case "position":d._position(b);break;case "resizable":g&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title", +d.uiDialogTitlebar).html(""+(b||" "));break;case "width":f=true;break}c.Widget.prototype._setOption.apply(d,arguments);f&&d._size()},_size:function(){var a=this.options,b;this.element.css({width:"auto",minHeight:0,height:0});b=this.uiDialog.css({height:"auto",width:a.width}).height();this.element.css(a.height==="auto"?{minHeight:Math.max(a.minHeight-b,0),height:"auto"}:{minHeight:0,height:Math.max(a.height-b,0)}).show();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight", +this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.2",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&& +c(document).bind(c.ui.dialog.overlay.events,function(d){return c(d.target).zIndex()>=c.ui.dialog.overlay.maxZ})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("
      ").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&& +b.bgiframe();this.instances.push(b);return b},destroy:function(a){this.oldInstances.push(this.instances.splice(c.inArray(a,this.instances),1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var b=0;c.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight, +document.body.offsetHeight);return a");if(!b.values)b.values=[this._valueMin(),this._valueMin()];if(b.values.length&&b.values.length!==2)b.values=[b.values[0],b.values[0]]}else this.range=d("
      ");this.range.appendTo(this.element).addClass("ui-slider-range");if(b.range==="min"||b.range==="max")this.range.addClass("ui-slider-range-"+b.range);this.range.addClass("ui-widget-header")}d(".ui-slider-handle",this.element).length===0&&d("").appendTo(this.element).addClass("ui-slider-handle"); +if(b.values&&b.values.length)for(;d(".ui-slider-handle",this.element).length").appendTo(this.element).addClass("ui-slider-handle");this.handles=d(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(c){c.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur(); +else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(c){d(this).data("index.ui-slider-handle",c)});this.handles.keydown(function(c){var e=true,f=d(this).data("index.ui-slider-handle"),g,h,i;if(!a.options.disabled){switch(c.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:e= +false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");g=a._start(c,f);if(g===false)return}break}i=a.options.step;g=a.options.values&&a.options.values.length?(h=a.values(f)):(h=a.value());switch(c.keyCode){case d.ui.keyCode.HOME:h=a._valueMin();break;case d.ui.keyCode.END:h=a._valueMax();break;case d.ui.keyCode.PAGE_UP:h=a._trimAlignValue(g+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(g-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(g=== +a._valueMax())return;h=a._trimAlignValue(g+i);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(g===a._valueMin())return;h=a._trimAlignValue(g-i);break}a._slide(c,f,h);return e}}).keyup(function(c){var e=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(c,e);a._change(c,e);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"); +this._mouseDestroy();return this},_mouseCapture:function(a){var b=this.options,c,e,f,g,h,i;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c={x:a.pageX,y:a.pageY};e=this._normValueFromMouse(c);f=this._valueMax()-this._valueMin()+1;h=this;this.handles.each(function(j){var k=Math.abs(e-h.values(j));if(f>k){f=k;g=d(this);i=j}});if(b.range===true&&this.values(1)===b.min){i+=1;g=d(this.handles[i])}if(this._start(a, +i)===false)return false;this._mouseSliding=true;h._handleIndex=i;g.addClass("ui-state-active").focus();b=g.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-g.width()/2,top:a.pageY-b.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)};e=this._normValueFromMouse(c);this._slide(a,i,e);return this._animateOff=true},_mouseStart:function(){return true}, +_mouseDrag:function(a){var b=this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b; +if(this.orientation==="horizontal"){b=this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value= +this.values(b);c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var e;if(this.options.values&&this.options.values.length){e=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>e||b===1&&c1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;e=arguments[0];for(f=0;fthis._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=a%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a= +this.options.range,b=this.options,c=this,e=!this._animateOff?b.animate:false,f,g={},h,i,j,k;if(this.options.values&&this.options.values.length)this.handles.each(function(l){f=(c.values(l)-c._valueMin())/(c._valueMax()-c._valueMin())*100;g[c.orientation==="horizontal"?"left":"bottom"]=f+"%";d(this).stop(1,1)[e?"animate":"css"](g,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(l===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},b.animate);if(l===1)c.range[e?"animate":"css"]({width:f- +h+"%"},{queue:false,duration:b.animate})}else{if(l===0)c.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},b.animate);if(l===1)c.range[e?"animate":"css"]({height:f-h+"%"},{queue:false,duration:b.animate})}h=f});else{i=this.value();j=this._valueMin();k=this._valueMax();f=k!==j?(i-j)/(k-j)*100:0;g[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](g,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"}, +b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[e?"animate":"css"]({width:100-f+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.2"})})(jQuery); +;/* + * jQuery UI Tabs 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Tabs + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(d){function s(){return++u}function v(){return++w}var u=0,w=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
      ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:'
    • #{label}
    • '},_create:function(){this._tabify(true)},_setOption:function(c,e){if(c=="selected")this.options.collapsible&& +e==this.options.selected||this.select(e);else{this.options[c]=e;this._tabify()}},_tabId:function(c){return c.title&&c.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+s()},_sanitizeSelector:function(c){return c.replace(/:/g,"\\:")},_cookie:function(){var c=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+v());return d.cookie.apply(null,[c].concat(d.makeArray(arguments)))},_ui:function(c,e){return{tab:c,panel:e,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var c= +d(this);c.html(c.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function e(g,f){g.css({display:""});!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}this.list=this.element.find("ol,ul").eq(0);this.lis=d("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);var a=this,b=this.options,h=/^#.+/;this.anchors.each(function(g,f){var j=d(f).attr("href"),l=j.split("#")[0],p;if(l&&(l===location.toString().split("#")[0]|| +(p=d("base")[0])&&l===p.href)){j=f.hash;f.href=j}if(h.test(j))a.panels=a.panels.add(a._sanitizeSelector(j));else if(j!="#"){d.data(f,"href.tabs",j);d.data(f,"load.tabs",j.replace(/#.*$/,""));j=a._tabId(f);f.href="#"+j;f=d("#"+j);if(!f.length){f=d(b.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else b.disabled.push(g)});if(c){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); +this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(b.selected===undefined){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){b.selected=g;return false}});if(typeof b.selected!="number"&&b.cookie)b.selected=parseInt(a._cookie(),10);if(typeof b.selected!="number"&&this.lis.filter(".ui-tabs-selected").length)b.selected= +this.lis.index(this.lis.filter(".ui-tabs-selected"));b.selected=b.selected||(this.lis.length?0:-1)}else if(b.selected===null)b.selected=-1;b.selected=b.selected>=0&&this.anchors[b.selected]||b.selected<0?b.selected:0;b.disabled=d.unique(b.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(b.selected,b.disabled)!=-1&&b.disabled.splice(d.inArray(b.selected,b.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); +if(b.selected>=0&&this.anchors.length){this.panels.eq(b.selected).removeClass("ui-tabs-hide");this.lis.eq(b.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[b.selected],a.panels[b.selected]))});this.load(b.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else b.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));this.element[b.collapsible?"addClass": +"removeClass"]("ui-tabs-collapsible");b.cookie&&this._cookie(b.selected,b.cookie);c=0;for(var i;i=this.lis[c];c++)d(i)[d.inArray(c,b.disabled)!=-1&&!d(i).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");b.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(b.event!="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+g)};this.lis.bind("mouseover.tabs", +function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(b.fx)if(d.isArray(b.fx)){m=b.fx[0];o=b.fx[1]}else m=o=b.fx;var q=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",function(){e(f,o);a._trigger("show", +null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},r=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};this.anchors.bind(b.event+".tabs", +function(){var g=this,f=d(this).closest("li"),j=a.panels.filter(":not(.ui-tabs-hide)"),l=d(a._sanitizeSelector(this.hash));if(f.hasClass("ui-tabs-selected")&&!b.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}b.selected=a.anchors.index(this);a.abort();if(b.collapsible)if(f.hasClass("ui-tabs-selected")){b.selected=-1;b.cookie&&a._cookie(b.selected,b.cookie);a.element.queue("tabs",function(){r(g, +j)}).dequeue("tabs");this.blur();return false}else if(!j.length){b.cookie&&a._cookie(b.selected,b.cookie);a.element.queue("tabs",function(){q(g,l)});a.load(a.anchors.index(this));this.blur();return false}b.cookie&&a._cookie(b.selected,b.cookie);if(l.length){j.length&&a.element.queue("tabs",function(){r(g,j)});a.element.queue("tabs",function(){q(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";d.browser.msie&&this.blur()});this.anchors.bind("click.tabs", +function(){return false})},destroy:function(){var c=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(b,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this, +"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});c.cookie&&this._cookie(null,c.cookie);return this},add:function(c,e,a){if(a===undefined)a=this.anchors.length;var b=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,e));c=!c.indexOf("#")?c.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs", +true);var i=d("#"+c);i.length||(i=d(h.panelTemplate).attr("id",c).data("destroy.tabs",true));i.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);i.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);i.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");i.removeClass("ui-tabs-hide"); +this.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[0],b.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(c){var e=this.options,a=this.lis.eq(c).remove(),b=this.panels.eq(c).remove();if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(c+(c+1=c?--h:h});this._tabify();this._trigger("remove", +null,this._ui(a.find("a")[0],b[0]));return this},enable:function(c){var e=this.options;if(d.inArray(c,e.disabled)!=-1){this.lis.eq(c).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=c});this._trigger("enable",null,this._ui(this.anchors[c],this.panels[c]));return this}},disable:function(c){var e=this.options;if(c!=e.selected){this.lis.eq(c).addClass("ui-state-disabled");e.disabled.push(c);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[c],this.panels[c]))}return this}, +select:function(c){if(typeof c=="string")c=this.anchors.index(this.anchors.filter("[href$="+c+"]"));else if(c===null)c=-1;if(c==-1&&this.options.collapsible)c=this.options.selected;this.anchors.eq(c).trigger(this.options.event+".tabs");return this},load:function(c){var e=this,a=this.options,b=this.anchors.eq(c)[0],h=d.data(b,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(b,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(c).addClass("ui-state-processing"); +if(a.spinner){var i=d("span",b);i.data("label.tabs",i.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){d(e._sanitizeSelector(b.hash)).html(k);e._cleanup();a.cache&&d.data(b,"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[c],e.panels[c]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[c],e.panels[c]));try{a.ajaxOptions.error(k,n,c,b)}catch(m){}}}));e.element.dequeue("tabs");return this}}, +abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},url:function(c,e){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.2"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(c,e){var a=this,b=this.options,h=a._rotate||(a._rotate= +function(i){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=b.selected;a.select(++k')}function E(a,b){d.extend(a, +b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.2"}});var y=(new Date).getTime();d.extend(J.prototype,{markerClassName:"hasDatepicker",log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){E(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]= +f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:d('
      ')}}, +_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&& +b.append.remove();if(c){b.append=d(''+c+"");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c=="focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('').addClass(this._triggerClass).html(f== +""?c:d("").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker():d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;gh){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a, +c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b), +true);this._updateDatepicker(b);this._updateAlternate(b)}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+=1;this._dialogInput=d('');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}E(a.settings,e||{});b=b&&b.constructor== +Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]); +d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}}, +_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().removeClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b= +d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span")b.children("."+this._inlineClass).children().addClass("ui-state-disabled");this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false; +for(var b=0;b-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target|| +a;if(a.nodeName.toLowerCase()!="input")a=d("input",a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);d.datepicker._curInst&&d.datepicker._curInst!=b&&d.datepicker._curInst.dpDiv.stop(true,true);var c=d.datepicker._get(b,"beforeShow");E(b.settings,c?c.apply(a,[a,b]):{});b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value="";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a); +d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b);c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&& +d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){d.datepicker._datepickerShowing=true;var i=d.datepicker._getBorders(b.dpDiv);b.dpDiv.find("iframe.ui-datepicker-cover").css({left:-i[0],top:-i[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})};b.dpDiv.zIndex(d(a).zIndex()+1);d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f, +h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this,c=d.datepicker._getBorders(a.dpDiv);a.dpDiv.empty().append(this._generateHTML(a)).find("iframe.ui-datepicker-cover").css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){d(this).removeClass("ui-state-hover"); +this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).removeClass("ui-datepicker-prev-hover");this.className.indexOf("ui-datepicker-next")!=-1&&d(this).removeClass("ui-datepicker-next-hover")}).bind("mouseover",function(){if(!b._isDisabledDatepicker(a.inline?a.dpDiv.parent()[0]:a.input[0])){d(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");d(this).addClass("ui-state-hover");this.className.indexOf("ui-datepicker-prev")!=-1&&d(this).addClass("ui-datepicker-prev-hover"); +this.className.indexOf("ui-datepicker-next")!=-1&&d(this).addClass("ui-datepicker-next-hover")}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();c=this._getNumberOfMonths(a);var e=c[1];e>1?a.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",17*e+"em"):a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");a.dpDiv[(c[0]!=1||c[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"); +a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input.focus()},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(),h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(), +k=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>k&&k>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b=this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1);)a=a[b?"previousSibling":"nextSibling"]; +a=d(a).offset();return[a.left,a.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b);this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();if(a=this._get(b,"onClose"))a.apply(b.input?b.input[0]:null,[b.input?b.input.val(): +"",b]);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&& +!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth; +b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e._selectingMonthYear=false;e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){a=this._getInst(d(a)[0]); +a.input&&a._selectingMonthYear&&!d.browser.msie&&a.input.focus();a._selectingMonthYear=!a._selectingMonthYear},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a);this._getInst(a[0]);this._selectDate(a, +"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")|| +this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null; +for(var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff,f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,k=c=-1,l=-1,u=-1,j=false,o=function(p){(p=z+1-1){k=1;l=u;do{e=this._getDaysInMonth(c,k-1);if(l<=e)break;k++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c, +k-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=k||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c? +c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames:null)||this._defaults.monthNames;var i=function(o){(o=j+112?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear|| +a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),k=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay? +new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),j=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=j&&nn;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-k,1)),this._getFormatConfig(a)); +n=this._canAdjustMonth(a,-1,m,g)?''+n+"":f?"":''+n+"";var r=this._get(a,"nextText");r=!h?r:this.formatDate(r,this._daylightSavingAdjust(new Date(m, +g+k,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?''+r+"":f?"":''+r+"";k=this._get(a,"currentText");r=this._get(a,"gotoCurrent")&& +a.currentDay?u:b;k=!h?k:this.formatDate(k,r,this._getFormatConfig(a));h=!a.inline?'":"";e=e?'
      '+(c?h:"")+(this._isInRange(a,r)?'":"")+(c?"":h)+"
      ":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;k=this._get(a,"showWeek");r=this._get(a,"dayNames");this._get(a,"dayNamesShort");var s=this._get(a,"dayNamesMin"),z=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),w=this._get(a,"showOtherMonths"),G=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var K=this._getDefaultDate(a),H="",C=0;C1)switch(D){case 0:x+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:x+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:x+=" ui-datepicker-group-middle";t="";break}x+='">'}x+='
      '+(/all|left/.test(t)&&C==0?c? +f:n:"")+(/all|right/.test(t)&&C==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,j,o,C>0||D>0,z,v)+'
      ';var A=k?'":"";for(t=0;t<7;t++){var q=(t+h)%7;A+="=5?' class="ui-datepicker-week-end"':"")+'>'+s[q]+""}x+=A+"";A=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay, +A);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;A=l?6:Math.ceil((t+A)/7);q=this._daylightSavingAdjust(new Date(m,g,1-t));for(var N=0;N";var O=!k?"":'";for(t=0;t<7;t++){var F=p?p.apply(a.input?a.input[0]:null,[q]):[true,""],B=q.getMonth()!=g,I=B&&!G||!F[0]||j&&qo;O+='";q.setDate(q.getDate()+1);q=this._daylightSavingAdjust(q)}x+=O+""}g++;if(g>11){g=0;m++}x+="
      '+this._get(a,"weekHeader")+"
      '+this._get(a,"calculateWeek")(q)+""+(B&&!w?" ":I?''+q.getDate()+ +"":''+q.getDate()+"")+"
      "+(l?""+(i[0]>0&&D==i[1]-1?'
      ':""):"");L+=x}H+=L}H+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'': +"");a._keyEvent=false;return H},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var k=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),j='
      ',o="";if(h||!k)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(j+=o+(h||!(k&&l)?" ":""));if(h||!l)j+=''+c+"";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b, +i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(j+='"}j+=this._get(a,"yearSuffix");if(u)j+=(h||!(k&&l)?" ":"")+o;j+="
      ";return j},_adjustInstDate:function(a,b,c){var e= +a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a, +"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a); +c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a, +"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker= +function(a){if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b)); +return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new J;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.2";window["DP_jQuery_"+y]=d})(jQuery); +;/* + * jQuery UI Progressbar 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(b){b.widget("ui.progressbar",{options:{value:0},_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=b("
      ").appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===undefined)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){switch(a){case "value":this.options.value=c;this._refreshValue();this._trigger("change");break}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;if(athis._valueMax())a=this._valueMax();return a}, +_valueMin:function(){return 0},_valueMax:function(){return 100},_refreshValue:function(){var a=this.value();this.valueDiv[a===this._valueMax()?"addClass":"removeClass"]("ui-corner-right").width(a+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.2"})})(jQuery); +;/* + * jQuery UI Effects 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f){function k(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return l.transparent;return l[f.trim(c).toLowerCase()]}function q(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return k(b)}function m(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, +a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function n(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in r||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function s(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function j(c,a,b,d){if(typeof c=="object"){d= +a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(f.isFunction(b)){d=b;b=null}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:f.fx.speeds[b]||f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=q(b.elem,a);b.end=k(b.end);b.colorInit= +true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var l={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189, +183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255, +165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},o=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b,d){if(f.isFunction(b)){d=b;b=null}return this.each(function(){var e=f(this),g=e.attr("style")||" ",h=n(m.call(this)),p,t=e.attr("className");f.each(o,function(u, +i){c[i]&&e[i+"Class"](c[i])});p=n(m.call(this));e.attr("className",t);e.animate(s(h,p),a,b,function(){f.each(o,function(u,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)})})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a? +f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===undefined?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.2",save:function(c,a){for(var b=0;b").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"}); +c.css({position:"relative",top:0,left:0})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=j.apply(this,arguments);a={options:a[1],duration:a[2],callback:a[3]};var b=f.effects[c];return b&&!f.fx.off?b.call(this,a):this},_show:f.fn.show,show:function(c){if(!c|| +typeof c=="number"||f.fx.speeds[c])return this._show.apply(this,arguments);else{var a=j.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(!c||typeof c=="number"||f.fx.speeds[c])return this._hide.apply(this,arguments);else{var a=j.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(!c||typeof c=="number"||f.fx.speeds[c]||typeof c=="boolean"||f.isFunction(c))return this.__toggle.apply(this, +arguments);else{var a=j.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c, +a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+ +b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2, +10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)* +a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ +e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +;/* + * jQuery UI Effects Fold 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","left"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1],10)/100* +f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); +;/* + * jQuery UI Effects Highlight 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Pulsate 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); +b.dequeue()})})}})(jQuery); +; \ No newline at end of file diff --git a/lib/jquery.rule-1.0.1.1-min.js b/lib/jquery.rule-1.0.1.1-min.js deleted file mode 100644 index 6e9b254..0000000 --- a/lib/jquery.rule-1.0.1.1-min.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - - jQuery.Rule - Css Rules manipulation, the jQuery way. - Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com - Dual licensed under MIT and GPL. - Date: 02/27/2008 - Compatible with jQuery 1.2.x, tested on FF 2, Opera 9, Safari 3, and IE 6, on Windows. - (version 1.0.1.1 adds support for jQuery 1.4.2 to version 1.0.1) - -*/ -(function(c){var i=c(' + + + + +
      +
      +
      + +
      +

      About

      + This example simulates a real-time display of CPU utilization in a web farm. + Data is updated in real-time, and cells with changed data are highlighted. + You can also click "Find current server" to scroll the row displaying data for the current + server into view and flash it. +

      Demonstrates

      +
        +
      • setHighlightedCells()
      • +
      • flashCell()
      • +
      +

      Controls

      + + +
      + + + + + + + + + + + + + + From 2ac42e643603f3af07b71fdcdaaf4b05e4fdb440 Mon Sep 17 00:00:00 2001 From: mleibman Date: Fri, 9 Jul 2010 12:26:36 -0700 Subject: [PATCH 0269/1043] - CHANGED: removed "overflow:hidden" on grid canvas to allow outline and box-shadow to work - ADDED: "eval(expr)" debug method to simplify development and debugging --- slick.grid.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/slick.grid.js b/slick.grid.js index 3cdefff..d873dfe 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -368,7 +368,7 @@ if (!jQuery.fn.drag) { } $viewport = $("
      ").appendTo($container); - $canvas = $("
      ").appendTo($viewport); + $canvas = $("
      ").appendTo($viewport); // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?) // calculate the diff so we can set consistent sizes @@ -2267,6 +2267,11 @@ if (!jQuery.fn.drag) { alert(s); }; + // a debug helper to be able to access private members + this.eval = function(expr) { + return eval(expr); + } + init(); From ef6d9280d59cf168e45c07befe8807a865ac39c6 Mon Sep 17 00:00:00 2001 From: mleibman Date: Fri, 9 Jul 2010 16:20:26 -0700 Subject: [PATCH 0270/1043] - ADDED: preliminary support for cell range selection ("enableCellRangeSelection" option, "onCellRangeSelected" event) --- slick.grid.css | 12 ++++ slick.grid.js | 174 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 144 insertions(+), 42 deletions(-) diff --git a/slick.grid.css b/slick.grid.css index c9333e2..73d37d9 100644 --- a/slick.grid.css +++ b/slick.grid.css @@ -139,3 +139,15 @@ classes should alter those! opacity: 0.7; filter: alpha(opacity=70); } + +.slick-selection { + z-index: 10; + position: absolute; + background: gray; + border: 1px solid black; + opacity: 0.3; + filter: alpha(opacity=30); + -webkit-box-shadow: 0px 0px 10px black; + -moz-box-shadow: 0px 0px 10px black; + box-shadow: 0px 0px 10px black; +} \ No newline at end of file diff --git a/slick.grid.js b/slick.grid.js index d873dfe..5942d12 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -19,6 +19,7 @@ * editable - (default false) If false, no cells will be switched into edit mode. * autoEdit - (default true) Cell will not automatically go into edit mode when selected. * enableCellNavigation - (default true) If false, no cells will be selectable. + * enableCellRangeSelection - (default false) If true, user will be able to select a cell range. onCellRangeSelected event will be fired. * defaultColumnWidth - (default 80px) Default column width in pixels (if columns[cell].width is not specified). * enableColumnReorder - (default true) Allows the user to reorder columns. * asyncEditorLoading - (default false) Makes cell editors load asynchronously after a small delay. @@ -81,6 +82,7 @@ * onBeforeCellEditorDestroy - Raised before a cell editor is destroyed. Args: current cell editor. * onBeforeDestroy - Raised just before the grid control is destroyed (part of the destroy() method). * onCurrentCellChanged - Raised when the selected (active) cell changed. Args: {row:currentRow, cell:currentCell}. + * onCellRangeSelected - Raised when a user selects a range of cells. Args: {from:{row,cell}, to:{row,cell}}. * * NOTES: * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods. @@ -221,6 +223,7 @@ if (!jQuery.fn.drag) { editable: false, autoEdit: true, enableCellNavigation: true, + enableCellRangeSelection: false, enableColumnReorder: true, asyncEditorLoading: false, asyncEditorLoadDelay: 100, @@ -255,7 +258,7 @@ if (!jQuery.fn.drag) { var cj; // "jumpiness" coefficient var page = 0; // current page - var offset=0; // current page offset + var offset = 0; // current page offset var scrollDir = 1; // private @@ -389,7 +392,7 @@ if (!jQuery.fn.drag) { createColumnHeaders(); setupColumnSort(); - setupRowReordering(); + setupDragEvents(); createCssRules(); resizeAndRender(); @@ -749,61 +752,123 @@ if (!jQuery.fn.drag) { }); } - function setupRowReordering() { + function setupDragEvents() { + var MOVE_ROWS = 1; + var SELECT_CELLS = 2; + + function fixUpRange(range) { + var r1 = Math.min(range.start.row,range.end.row); + var c1 = Math.min(range.start.cell,range.end.cell); + var r2 = Math.max(range.start.row,range.end.row); + var c2 = Math.max(range.start.cell,range.end.cell); + return { + start: {row:r1, cell:c1}, + end: {row:r2, cell:c2} + }; + } + $canvas .bind("draginit", function(e,dd) { var $cell = $(e.target).closest(".slick-cell"); if ($cell.length === 0) { return false; } - if (parseInt($cell.parent().attr("row"), 10) >= gridDataGetLength()) { return false; } + if (parseInt($cell.parent().attr("row"), 10) >= gridDataGetLength()) + return false; + var colDef = columns[getSiblingIndex($cell[0])]; - if (colDef.behavior !== "move" && colDef.behavior !== "selectAndMove") { return false; } + if (colDef.behavior == "move" || colDef.behavior == "selectAndMove") { + dd.mode = MOVE_ROWS; + } + else if (options.enableCellRangeSelection) { + dd.mode = SELECT_CELLS; + } + else + return false; }) .bind("dragstart", function(e,dd) { if (!options.editorLock.commitCurrentEdit()) { return false; } var row = parseInt($(e.target).closest(".slick-row").attr("row"), 10); - if (!selectedRowsLookup[row]) { - setSelectedRows([row]); + if (dd.mode == MOVE_ROWS) { + if (!selectedRowsLookup[row]) { + setSelectedRows([row]); + } + + dd.selectionProxy = $("
      ") + .css("position", "absolute") + .css("zIndex", "99999") + .css("width", $(this).innerWidth()) + .css("height", options.rowHeight*selectedRows.length) + .appendTo($viewport); + + dd.guide = $("
      ") + .css("position", "absolute") + .css("zIndex", "99998") + .css("width", $(this).innerWidth()) + .css("top", -1000) + .appendTo($viewport); + + dd.insertBefore = -1; } - dd.selectionProxy = $("
      ") - .css("position", "absolute") - .css("zIndex", "99999") - .css("width", $(this).innerWidth()) - .css("height", options.rowHeight*selectedRows.length) - .appendTo($viewport); - - dd.guide = $("
      ") - .css("position", "absolute") - .css("zIndex", "99998") - .css("width", $(this).innerWidth()) - .css("top", -1000) - .appendTo($viewport); - - dd.insertBefore = -1; + if (dd.mode == SELECT_CELLS) { + var start = getCellFromPoint(dd.startX - $canvas.offset().left, dd.startY - $canvas.offset().top); + if (!cellExists(start.row,start.cell)) + return false; + + dd.range = {start:start,end:{}}; + return $("
      ").appendTo($canvas); + } }) .bind("drag", function(e,dd) { - var top = e.clientY - $(this).offset().top; - dd.selectionProxy.css("top",top-5); - - var insertBefore = Math.max(0,Math.min(Math.round(top/options.rowHeight),gridDataGetLength())); - if (insertBefore !== dd.insertBefore) { - if (self.onBeforeMoveRows && self.onBeforeMoveRows(getSelectedRows(),insertBefore) === false) { - dd.guide.css("top", -1000); - dd.canMove = false; - } - else { - dd.guide.css("top",insertBefore*options.rowHeight); - dd.canMove = true; + if (dd.mode == MOVE_ROWS) { + var top = e.clientY - $(this).offset().top; + dd.selectionProxy.css("top",top-5); + + var insertBefore = Math.max(0,Math.min(Math.round(top/options.rowHeight),gridDataGetLength())); + if (insertBefore !== dd.insertBefore) { + if (self.onBeforeMoveRows && self.onBeforeMoveRows(getSelectedRows(),insertBefore) === false) { + dd.guide.css("top", -1000); + dd.canMove = false; + } + else { + dd.guide.css("top",insertBefore*options.rowHeight); + dd.canMove = true; + } + dd.insertBefore = insertBefore; } - dd.insertBefore = insertBefore; + } + + if (dd.mode == SELECT_CELLS) { + var end = getCellFromPoint(e.clientX - $canvas.offset().left, e.clientY - $canvas.offset().top); + if (!cellExists(end.row,end.cell)) + return; + + dd.range.end = end; + var r = fixUpRange(dd.range); + var from = getCellNodeBox(r.start.row,r.start.cell); + var to = getCellNodeBox(r.end.row,r.end.cell); + $(dd.proxy).css({ + top: from.top, + left: from.left, + height: to.bottom - from.top - 2, + width: to.right - from.left - 2 + }); } }) .bind("dragend", function(e,dd) { - dd.guide.remove(); - dd.selectionProxy.remove(); - if (self.onMoveRows && dd.canMove) { - self.onMoveRows(getSelectedRows(),dd.insertBefore); + if (dd.mode == MOVE_ROWS) { + dd.guide.remove(); + dd.selectionProxy.remove(); + if (self.onMoveRows && dd.canMove) { + self.onMoveRows(getSelectedRows(),dd.insertBefore); + } + } + + if (dd.mode == SELECT_CELLS) { + $(dd.proxy).remove(); + + if (self.onCellRangeSelected) + self.onCellRangeSelected(fixUpRange(dd.range)); } }); } @@ -1758,12 +1823,16 @@ if (!jQuery.fn.drag) { } } + function cellExists(row,cell) { + return !(row < 0 || row >= gridDataGetLength() || cell < 0 || cell >= columns.length); + } + function getCellFromPoint(x,y) { - var row = Math.floor(y/options.rowHeight); + var row = Math.floor((y+offset)/options.rowHeight); var cell = 0; var w = 0; - for (var i=0; i Date: Tue, 10 Aug 2010 21:48:46 +0800 Subject: [PATCH 0271/1043] Added onHeaderClick event --- slick.grid.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/slick.grid.js b/slick.grid.js index 5942d12..5fac968 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -65,6 +65,7 @@ * EVENTS: * onSort - * onHeaderContextMenu - + * onHeaderClick - Matt Baker: Added onHeaderClick for column headers * onClick - * onDblClick - * onContextMenu - @@ -406,6 +407,7 @@ if (!jQuery.fn.drag) { $canvas.bind("contextmenu", handleContextMenu); $canvas.bind("mouseover", handleHover); $headerScroller.bind("contextmenu", handleHeaderContextMenu); + $headerScroller.bind("click", handleHeaderClick); } function measureScrollbar() { @@ -1809,6 +1811,18 @@ if (!jQuery.fn.drag) { self.onHeaderContextMenu(e); } } + + function handleHeaderClick(e) { + + var $col = $(e.target).closest(".slick-header-column"); + if ($col.length ==0) { return; } + var column = columns[getSiblingIndex($col[0])]; + + if (self.onHeaderClick && options.editorLock.commitCurrentEdit()) { + e.preventDefault(); + self.onHeaderClick(e, column); + } + } function handleHover(e) { if (!options.enableAutoTooltips) return; From 40d9762d294cd6976f034b2f307d3a4c49e1d951 Mon Sep 17 00:00:00 2001 From: mleibman Date: Mon, 23 Aug 2010 14:26:32 -0700 Subject: [PATCH 0272/1043] Merged in Daptiv changes. - ADDED: "toolTipMaxLength" option. - FIXED: not all rows getting removed by updateRowCount(). - ADDED: onHeaderContextMenu event now passes in a column definition as a second parameter. - ADDED: "getGridPosition" method. --- slick.grid.js | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index 5fac968..b5c937c 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -237,6 +237,7 @@ if (!jQuery.fn.drag) { secondaryHeaderRowHeight: 25, syncColumnCellResize: false, enableAutoTooltips: true, + toolTipMaxLength: null, formatterFactory: null, editorFactory: null, cellHighlightCssClass: "highlighted", @@ -245,6 +246,7 @@ if (!jQuery.fn.drag) { gridData, gridDataGetLength, gridDataGetItem; var columnDefaults = { + name: "", resizable: true, sortable: false, minWidth: 30 @@ -510,6 +512,7 @@ if (!jQuery.fn.drag) { .html("" + m.name + "") .width(m.width - headerColumnWidthDiff) .attr("title", m.toolTip || m.name || "") + .data("fieldId", m.id) .appendTo($headers); if (options.enableColumnReorder || m.sortable) { @@ -951,6 +954,7 @@ if (!jQuery.fn.drag) { $container.unbind("resize", resizeCanvas); removeCssRules(); + $canvas.unbind("draginit dragstart dragend drag"); $container.empty().removeClass(uid); } @@ -1086,6 +1090,7 @@ if (!jQuery.fn.drag) { removeCssRules(); createCssRules(); resizeAndRender(); + handleScroll(); } function getOptions() { @@ -1344,7 +1349,14 @@ if (!jQuery.fn.drag) { function updateRowCount() { var newRowCount = gridDataGetLength() + (options.enableAddRow?1:0) + (options.leaveSpaceForNewRows?numVisibleRows-1:0); var oldH = h; - + // remove the rows that are now outside of the data range + // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows + var l = options.enableAddRow ? gridDataGetLength() : gridDataGetLength() - 1; + for (var i in rowsCache) { + if (i >= l) { + removeRowFromCache(i); + } + } th = Math.max(options.rowHeight * newRowCount, viewportH - scrollbarDimensions.height); if (th < maxSupportedCssHeight) { // just one page @@ -1669,7 +1681,7 @@ if (!jQuery.fn.drag) { } function handleClick(e) { - var $cell = $(e.target).closest(".slick-cell"); + var $cell = $(e.target).closest(".slick-cell", $canvas); if ($cell.length === 0) { return; } // are we editing this cell? @@ -1749,7 +1761,7 @@ if (!jQuery.fn.drag) { } function handleContextMenu(e) { - var $cell = $(e.target).closest(".slick-cell"); + var $cell = $(e.target).closest(".slick-cell", $canvas); if ($cell.length === 0) { return; } // are we editing this cell? @@ -1775,7 +1787,7 @@ if (!jQuery.fn.drag) { } function handleDblClick(e) { - var $cell = $(e.target).closest(".slick-cell"); + var $cell = $(e.target).closest(".slick-cell", $canvas); if ($cell.length === 0) { return; } // are we editing this cell? @@ -1807,8 +1819,8 @@ if (!jQuery.fn.drag) { function handleHeaderContextMenu(e) { if (self.onHeaderContextMenu && options.editorLock.commitCurrentEdit()) { e.preventDefault(); - // TODO: figure out which column was acted on and pass it as a param to the handler - self.onHeaderContextMenu(e); + var selectedElement = $(e.target).closest(".slick-header-column", ".slick-header-columns"); + self.onHeaderContextMenu(e, columns[self.getColumnIndex(selectedElement.data("fieldId"))]); } } @@ -1827,9 +1839,10 @@ if (!jQuery.fn.drag) { function handleHover(e) { if (!options.enableAutoTooltips) return; var $cell = $(e.target).closest(".slick-cell",$canvas); - if ($cell && $cell.length) { + if ($cell.length) { if ($cell.innerWidth() < $cell[0].scrollWidth) { - $cell.attr("title", $.trim($cell.text())); + var text = $.trim($cell.text()); + $cell.attr("title", (options.toolTipMaxLength && text.length > options.toolTipMaxLength) ? text.substr(0, options.toolTipMaxLength - 3) + "..." : text); } else { $cell.attr("title",""); @@ -1915,7 +1928,7 @@ if (!jQuery.fn.drag) { currentCellNode = newCell; - if (currentCellNode !== null) { + if (currentCellNode != null) { currentRow = parseInt($(currentCellNode).parent().attr("row"), 10); currentCell = getSiblingIndex(currentCellNode); @@ -2113,6 +2126,9 @@ if (!jQuery.fn.drag) { return absBox(currentCellNode); } + function getGridPosition(){ + return absBox($container[0]) + } function handleCurrentCellPositionChange() { if (!currentCellNode) return; var cellBox; @@ -2449,7 +2465,7 @@ if (!jQuery.fn.drag) { "hideSecondaryHeaderRow": hideSecondaryHeaderRow, "setSortColumn": setSortColumn, "getCurrentCellPosition" : getCurrentCellPosition, - + "getGridPosition": getGridPosition, // IEditor implementation "getEditController": getEditController }); From fe22711b5453ce97239583051b5fc6f9f2f8a512 Mon Sep 17 00:00:00 2001 From: Milan Gardian Date: Tue, 31 Aug 2010 21:06:14 +0800 Subject: [PATCH 0273/1043] Updated version in SlickGrid comments to 1.4.1 --- slick.grid.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index b5c937c..8be93c6 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -5,7 +5,7 @@ * Distributed under MIT license. * All rights reserved. * - * SlickGrid v1.4 + * SlickGrid v1.4.1 * * TODO: * - frozen columns @@ -394,7 +394,7 @@ if (!jQuery.fn.drag) { $viewport.bind("selectstart.ui", function (event) { return $(event.target).is("input,textarea"); }); // disable text selection in grid cells except in input and textarea elements (this is IE-specific, because selectstart event will only fire in IE) createColumnHeaders(); - setupColumnSort(); + setupColumnSort(); setupDragEvents(); createCssRules(); @@ -462,7 +462,7 @@ if (!jQuery.fn.drag) { var increment = 1000000; var supportedHeight = 0; // FF reports the height back but still renders blank after ~6M px - var testUpTo = ($.browser.mozilla) ? 5000000 : 1000000000; + var testUpTo = ($.browser.mozilla) ? 5000000 : 1000000000; var div = $("
      ").appendTo(document.body); while (supportedHeight <= testUpTo) { @@ -536,7 +536,7 @@ if (!jQuery.fn.drag) { if ($(e.target).hasClass("slick-resizable-handle")) { return; } - + if (self.onSort) { var $col = $(e.target).closest(".slick-header-column"); if (!$col.length) @@ -546,7 +546,7 @@ if (!jQuery.fn.drag) { if (column.sortable) { if (!options.editorLock.commitCurrentEdit()) return; - + if (column.id === sortColumnId) { sortAsc = !sortAsc; } @@ -778,7 +778,7 @@ if (!jQuery.fn.drag) { if ($cell.length === 0) { return false; } if (parseInt($cell.parent().attr("row"), 10) >= gridDataGetLength()) return false; - + var colDef = columns[getSiblingIndex($cell[0])]; if (colDef.behavior == "move" || colDef.behavior == "selectAndMove") { dd.mode = MOVE_ROWS; @@ -873,7 +873,7 @@ if (!jQuery.fn.drag) { $(dd.proxy).remove(); if (self.onCellRangeSelected) - self.onCellRangeSelected(fixUpRange(dd.range)); + self.onCellRangeSelected(fixUpRange(dd.range)); } }); } @@ -1159,7 +1159,7 @@ if (!jQuery.fn.drag) { if (self.onViewportChanged) { self.onViewportChanged(); - } + } } } @@ -1399,7 +1399,7 @@ if (!jQuery.fn.drag) { function getVisibleRange(viewportTop) { if (viewportTop == null) viewportTop = scrollTop; - + return { top: Math.floor((scrollTop+offset)/options.rowHeight), bottom: Math.ceil((scrollTop+offset+viewportH)/options.rowHeight) @@ -1530,7 +1530,7 @@ if (!jQuery.fn.drag) { if (oldOffset != offset) removeAllRows(); } - + if (h_render) clearTimeout(h_render); @@ -1823,13 +1823,13 @@ if (!jQuery.fn.drag) { self.onHeaderContextMenu(e, columns[self.getColumnIndex(selectedElement.data("fieldId"))]); } } - + function handleHeaderClick(e) { - + var $col = $(e.target).closest(".slick-header-column"); if ($col.length ==0) { return; } var column = columns[getSiblingIndex($col[0])]; - + if (self.onHeaderClick && options.editorLock.commitCurrentEdit()) { e.preventDefault(); self.onHeaderClick(e, column); @@ -1886,7 +1886,7 @@ if (!jQuery.fn.drag) { right: x2 }; } - + ////////////////////////////////////////////////////////////////////////////////////////////// // Cell switching @@ -2398,7 +2398,7 @@ if (!jQuery.fn.drag) { // Public API $.extend(this, { - "slickGridVersion": "1.4", + "slickGridVersion": "1.4.1", // Events "onSort": null, From 16e25ebcf55a66e9f88825dcae71aa2308b271cd Mon Sep 17 00:00:00 2001 From: mleibman Date: Wed, 1 Sep 2010 13:51:29 -0700 Subject: [PATCH 0274/1043] =?UTF-8?q?-=20ADDED:=20=20=E2=80=9CmultiSelect?= =?UTF-8?q?=E2=80=9D=20options=20to=20control=20row=20selection.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- slick.grid.js | 63 +++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index 8be93c6..20114fe 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -5,7 +5,7 @@ * Distributed under MIT license. * All rights reserved. * - * SlickGrid v1.4.1 + * SlickGrid v1.4.2 * * TODO: * - frozen columns @@ -40,6 +40,7 @@ * Must implement getFormatter(column). * editorFactory - (default null) A factory object responsible to creating an editor for a given cell. * Must implement getEditor(column). + * multiSelect - (default true) Enable multiple row selection. * * COLUMN DEFINITION (columns) OPTIONS: * id - Column ID. @@ -241,7 +242,8 @@ if (!jQuery.fn.drag) { formatterFactory: null, editorFactory: null, cellHighlightCssClass: "highlighted", - cellFlashingCssClass: "flashing" + cellFlashingCssClass: "flashing", + multiSelect: true }, gridData, gridDataGetLength, gridDataGetItem; @@ -1090,7 +1092,7 @@ if (!jQuery.fn.drag) { removeCssRules(); createCssRules(); resizeAndRender(); - handleScroll(); + handleScroll(); } function getOptions() { @@ -1349,14 +1351,15 @@ if (!jQuery.fn.drag) { function updateRowCount() { var newRowCount = gridDataGetLength() + (options.enableAddRow?1:0) + (options.leaveSpaceForNewRows?numVisibleRows-1:0); var oldH = h; - // remove the rows that are now outside of the data range - // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows - var l = options.enableAddRow ? gridDataGetLength() : gridDataGetLength() - 1; - for (var i in rowsCache) { - if (i >= l) { - removeRowFromCache(i); - } - } + + // remove the rows that are now outside of the data range + // this helps avoid redundant calls to .removeRow() when the size of the data decreased by thousands of rows + var l = options.enableAddRow ? gridDataGetLength() : gridDataGetLength() - 1; + for (var i in rowsCache) { + if (i >= l) { + removeRowFromCache(i); + } + } th = Math.max(options.rowHeight * newRowCount, viewportH - scrollbarDimensions.height); if (th < maxSupportedCssHeight) { // just one page @@ -1704,25 +1707,26 @@ if (!jQuery.fn.drag) { if (!e.ctrlKey && !e.shiftKey) { selection = [row]; } - else if (idx === -1 && e.ctrlKey) { - selection.push(row); - } - else if (idx !== -1 && e.ctrlKey) { - selection = $.grep(selection, function(o, i) { return (o !== row); }); - } - else if (selection.length && e.shiftKey) { - var last = selection.pop(); - var from = Math.min(row, last); - var to = Math.max(row, last); - selection = []; - for (var i = from; i <= to; i++) { - if (i !== last) { - selection.push(i); + else if (options.multiSelect) { + if (idx === -1 && e.ctrlKey) { + selection.push(row); + } + else if (idx !== -1 && e.ctrlKey) { + selection = $.grep(selection, function(o, i) { return (o !== row); }); + } + else if (selection.length && e.shiftKey) { + var last = selection.pop(); + var from = Math.min(row, last); + var to = Math.max(row, last); + selection = []; + for (var i = from; i <= to; i++) { + if (i !== last) { + selection.push(i); + } } + selection.push(last); } - selection.push(last); } - resetCurrentCell(); setSelectedRows(selection); if (self.onSelectedRowsChanged) { @@ -1819,7 +1823,7 @@ if (!jQuery.fn.drag) { function handleHeaderContextMenu(e) { if (self.onHeaderContextMenu && options.editorLock.commitCurrentEdit()) { e.preventDefault(); - var selectedElement = $(e.target).closest(".slick-header-column", ".slick-header-columns"); + var selectedElement = $(e.target).closest(".slick-header-column", ".slick-header-columns"); self.onHeaderContextMenu(e, columns[self.getColumnIndex(selectedElement.data("fieldId"))]); } } @@ -2398,7 +2402,7 @@ if (!jQuery.fn.drag) { // Public API $.extend(this, { - "slickGridVersion": "1.4.1", + "slickGridVersion": "1.4.2", // Events "onSort": null, @@ -2466,6 +2470,7 @@ if (!jQuery.fn.drag) { "setSortColumn": setSortColumn, "getCurrentCellPosition" : getCurrentCellPosition, "getGridPosition": getGridPosition, + // IEditor implementation "getEditController": getEditController }); From 5f1303d8402e730cd6bce3720d6761925a877d47 Mon Sep 17 00:00:00 2001 From: mleibman Date: Wed, 1 Sep 2010 14:13:48 -0700 Subject: [PATCH 0275/1043] - CHANGED: Switched the constructor to use a DOM node instead of a jQuery object (passing a jQuery object still works though). This removes the need for the user to know or use jQuery. --- slick.grid.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index 20114fe..c01c0e4 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -93,7 +93,7 @@ * and do proper cleanup. * * - * @param {jQuery} $container Container object to create the grid in. + * @param {NOde} container Container node to create the grid in. * @param {Array} or {Object} data An array of objects for databinding. * @param {Array} columns An array of column definitions. * @param {Object} options Grid options. @@ -208,7 +208,7 @@ if (!jQuery.fn.drag) { // SlickGrid class implementation (available as Slick.Grid) /** @constructor */ - function SlickGrid($container,data,columns,options) { + function SlickGrid(container,data,columns,options) { /// /// Create and manage virtual grid in the specified $container, /// connecting it to the specified data source. Data is presented @@ -267,6 +267,7 @@ if (!jQuery.fn.drag) { var scrollDir = 1; // private + var $container; var uid = "slickgrid_" + Math.round(1000000 * Math.random()); var self = this; var $headerScroller; @@ -326,6 +327,8 @@ if (!jQuery.fn.drag) { /// This function is called by the constructor. /// + $container = $(container) + gridData = data; gridDataGetLength = gridData.getLength || defaultGetLength; gridDataGetItem = gridData.getItem || defaultGetItem; @@ -355,15 +358,9 @@ if (!jQuery.fn.drag) { .addClass(uid) .addClass("ui-widget"); - switch ($container.css("position")) { - case "absolute": // if the container is already positioning origin, keep it as it is - case "relative": - case "fixed": - break; - default: // container is not a positioning origin, convert it to one - $container.css("position","relative"); - break; - } + // set up a positioning container if needed + if (!/relative|absolute|fixed/.test($container.css("position"))) + $container.css("position","relative"); $headerScroller = $("
      ").appendTo($container); $headers = $("
      ").appendTo($headerScroller); From df118dfaa2b3e8d5d216ddccfa10d13386a92d67 Mon Sep 17 00:00:00 2001 From: mleibman Date: Wed, 1 Sep 2010 14:23:08 -0700 Subject: [PATCH 0276/1043] =?UTF-8?q?-=20FIXED:=20=20row=20reordering=20di?= =?UTF-8?q?dn=E2=80=99t=20work=20when=20the=20page=20was=20scrolled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- slick.grid.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index c01c0e4..fe95989 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -327,7 +327,7 @@ if (!jQuery.fn.drag) { /// This function is called by the constructor. /// - $container = $(container) + $container = $(container); gridData = data; gridDataGetLength = gridData.getLength || defaultGetLength; @@ -825,7 +825,7 @@ if (!jQuery.fn.drag) { }) .bind("drag", function(e,dd) { if (dd.mode == MOVE_ROWS) { - var top = e.clientY - $(this).offset().top; + var top = e.pageY - $(this).offset().top; dd.selectionProxy.css("top",top-5); var insertBefore = Math.max(0,Math.min(Math.round(top/options.rowHeight),gridDataGetLength())); From 978441963e9748050e55920767051911925ffc1f Mon Sep 17 00:00:00 2001 From: mleibman Date: Wed, 1 Sep 2010 15:55:45 -0700 Subject: [PATCH 0277/1043] - CHANGED: Moved line-height out into the default theme CSS file. This makes it possible to have multiline text in cells (wrapping), but leaves the responsibility of vertically centering cell contents on the user (if that's what they want). --- examples/slick-default-theme.css | 1 + slick.grid.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/slick-default-theme.css b/examples/slick-default-theme.css index 428f356..46e837e 100644 --- a/examples/slick-default-theme.css +++ b/examples/slick-default-theme.css @@ -27,6 +27,7 @@ classes should alter those! position: absolute; background: white; border: 0px; + line-height: 20px; } .slick-row.selected { diff --git a/slick.grid.js b/slick.grid.js index fe95989..a1535d4 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -899,7 +899,7 @@ if (!jQuery.fn.drag) { var rules = [ "." + uid + " .slick-header-column { left: 10000px; }", "." + uid + " .slick-header-columns-secondary { height:" + options.secondaryHeaderRowHeight + "px; }", - "." + uid + " .slick-cell { height:" + rowHeight + "px; line-height:" + rowHeight + "px; }" + "." + uid + " .slick-cell { height:" + rowHeight + "px; }" ]; for (var i=0; i Date: Thu, 9 Sep 2010 12:49:38 -0700 Subject: [PATCH 0278/1043] - CHANGED: removed unused files and added jquery.event.drop-2.9.min.js - ADDED: new grid method "getCellFromEvent" - ADDED: drag'n'drop example to "example9-row-reordering.html" --- examples/example9-row-reordering.html | 150 +++++++++++++++++++++----- lib/jquery.event.drag.custom.js | 142 ------------------------ lib/jquery.event.drop-2.0.min.js | 6 ++ slick.grid.js | 12 +++ 4 files changed, 140 insertions(+), 170 deletions(-) delete mode 100644 lib/jquery.event.drag.custom.js create mode 100644 lib/jquery.event.drop-2.0.min.js diff --git a/examples/example9-row-reordering.html b/examples/example9-row-reordering.html index b2e3ac4..827015d 100644 --- a/examples/example9-row-reordering.html +++ b/examples/example9-row-reordering.html @@ -17,6 +17,18 @@ cursor: move; background: url("../images/drag-handle.png") no-repeat center center; } + + .recycle-bin { + width: 120px; + border: 1px solid gray; + background: beige; + padding: 4px; + font-size: 12pt; + font-weight: bold; + color: black; + text-align: center; + -moz-border-radius: 10px; + } @@ -31,7 +43,14 @@
      Click to select, Ctrl-click to toggle selection, Shift-click to select a range.
      - Drag one or more rows to reorder. + Drag one or more rows by the handle to reorder.
      + Drag one or more rows to the recycle bin to delete. + +
      +
      +
      + Recycle Bin +
      @@ -40,6 +59,7 @@ + @@ -48,32 +68,36 @@ var grid; var data = []; - var columns = [{ - id: "#", - name: "", - width: 40, - behavior: "selectAndMove", - unselectable: true, - resizable: false, - cssClass: "cell-reorder" - }, { - id: "name", - name: "Name", - field: "name", - width: 500, - cssClass: "cell-title", - editor: TextCellEditor, - validator: requiredFieldValidator - }, { - id: "complete", - name: "Complete", - width: 60, - cssClass: "cell-effort-driven", - field: "complete", - cannotTriggerInsert: true, - formatter: BoolCellFormatter, - editor: YesNoCheckboxCellEditor - }]; + var columns = [ + { + id: "#", + name: "", + width: 40, + behavior: "selectAndMove", + unselectable: true, + resizable: false, + cssClass: "cell-reorder dnd" + }, + { + id: "name", + name: "Name", + field: "name", + width: 500, + cssClass: "cell-title", + editor: TextCellEditor, + validator: requiredFieldValidator + }, + { + id: "complete", + name: "Complete", + width: 60, + cssClass: "cell-effort-driven", + field: "complete", + cannotTriggerInsert: true, + formatter: BoolCellFormatter, + editor: YesNoCheckboxCellEditor + } + ]; var options = { editable: true, @@ -107,7 +131,77 @@ grid = new Slick.Grid($("#myGrid"), data, columns, options); - grid.onAddNewRow = function addItem(newItem,columnDef) { + $("#myGrid") + .bind("draginit", function(e,dd) { + var cell = grid.getCellFromEvent(e); + if (!cell) + return false; + + dd.row = cell.row; + if (!data[dd.row]) + return false; + + if (Slick.GlobalEditorLock.isActive() && !Slick.GlobalEditorLock.cancelCurrentEdit()) + return false; + }) + .bind("dragstart", function(e,dd) { + var selectedRows = grid.getSelectedRows(); + + if (!selectedRows.length || $.inArray(dd.row,selectedRows) == -1) { + selectedRows = [dd.row]; + grid.setSelectedRows(selectedRows); + } + + dd.rows = selectedRows; + dd.count = selectedRows.length; + + var proxy = $("") + .css({ + position: "absolute", + display: "inline-block", + padding: "4px 10px", + background: "#e0e0e0", + border: "1px solid gray", + "z-index": 99999, + "-moz-border-radius": "8px", + "-moz-box-shadow": "2px 2px 6px silver" + }) + .text("Drag to Recycle Bin to delete " + dd.count + " selected row(s)") + .appendTo("body"); + + dd.helper = proxy; + + $(dd.available).css("background","pink"); + + return proxy; + }) + .bind("drag", function(e,dd) { + dd.helper.css({top: e.pageY + 5, left: e.pageX + 5}); + }) + .bind("dragend", function(e,dd) { + dd.helper.remove(); + $(dd.available).css("background","beige"); + }); + + + $("#dropzone") + .bind("dropstart", function(e,dd) { + $(this).css("background","yellow"); + }) + .bind("dropend", function(e,dd) { + $(dd.available).css("background","pink"); + }) + .bind("drop", function(e,dd) { + var rowsToDelete = dd.rows.sort().reverse(); + for (var i=0; i0 && event.which!=data.which ) || - $( event.target ).is( data.not ) ) return; - // handle various events - switch ( event.type ){ - // mousedown, left click, event.target is not restricted, init dragging - case 'mousedown': - returned = hijack(event, "beforedragstart", elem); - if (returned === false) - return true; - $.extend( data, $( elem ).offset(), { - elem: elem, target: event.target, - pageX: event.pageX, pageY: event.pageY - }); // store some initial attributes - $event.add( document, "mousemove mouseup", handler, data ); - selectable( elem, false ); // disable text selection - drag.dragging = null; // pending state - return false; // prevents text selection in safari - // mousemove, check distance, start dragging - case !drag.dragging && 'mousemove': - if ( squared( event.pageX-data.pageX ) - + squared( event.pageY-data.pageY ) // xІ + yІ = distanceІ - < data.distance ) break; // distance tolerance not reached - event.target = data.target; // force target from "mousedown" event (fix distance issue) - returned = hijack( event, "dragstart", elem ); // trigger "dragstart", return proxy element - if ( returned !== false ){ // "dragstart" not rejected - drag.dragging = elem; // activate element - drag.proxy = event.dragProxy = $( returned || elem )[0]; // set proxy - } - // mousemove, dragging - case 'mousemove': - if ( drag.dragging ){ - returned = hijack( event, "drag", elem ); // trigger "drag" - if ( $special.drop ){ // manage drop events - $special.drop.allowed = ( returned !== false ); // prevent drop - $special.drop.handler( event ); // "dropstart", "dropend" - } - if ( returned !== false ) break; // "drag" not rejected, stop - event.type = "mouseup"; // helps "drop" handler behave - } - // mouseup, stop dragging - case 'mouseup': - if (drag.dragging === false) break; - $event.remove( document, "mousemove mouseup", handler ); // remove page events - if ( drag.dragging ){ - if ( $special.drop ) $special.drop.handler( event ); // "drop" - hijack( event, "dragend", elem ); // trigger "dragend" - } - selectable( elem, true ); // enable text selection - drag.dragging = drag.proxy = data.elem = false; // deactivate element - break; - } - return true; - }; - -// set event type to custom value, and handle it -function hijack ( event, type, elem ){ - event.type = type; // force the event type - var result = $.event.handle.call( elem, event ); - return result===false ? false : result || event.result; - }; - -// return the value squared -function squared ( value ){ return Math.pow( value, 2 ); }; - -// suppress default dragstart IE events... -function dontStart(){ return ( drag.dragging === false ); }; - -// toggles text selection attributes -function selectable ( elem, bool ){ - if ( !elem ) return; // maybe element was removed ? - elem.unselectable = bool ? "off" : "on"; // IE - elem.onselectstart = function(){ return bool; }; // IE - //if ( document.selection && document.selection.empty ) document.selection.empty(); // IE - if ( elem.style ) elem.style.MozUserSelect = bool ? "" : "none"; // FF - }; - -/*******************************************************************************************/ -})( jQuery ); // confine scope \ No newline at end of file diff --git a/lib/jquery.event.drop-2.0.min.js b/lib/jquery.event.drop-2.0.min.js new file mode 100644 index 0000000..b988575 --- /dev/null +++ b/lib/jquery.event.drop-2.0.min.js @@ -0,0 +1,6 @@ +/*! + * jquery.event.drop - v 2.0.0 + * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com + * Open Source MIT License - http://threedubmedia.com/code/license + */ +;(function(f){f.fn.drop=function(c,a,d){var g=typeof c=="string"?c:"",e=f.isFunction(c)?c:f.isFunction(a)?a:null;if(g.indexOf("drop")!==0)g="drop"+g;d=(c==e?a:d)||{};return e?this.bind(g,d,e):this.trigger(g)};f.drop=function(c){c=c||{};b.multi=c.multi===true?Infinity:c.multi===false?1:!isNaN(c.multi)?c.multi:b.multi;b.delay=c.delay||b.delay;b.tolerance=f.isFunction(c.tolerance)?c.tolerance:c.tolerance===null?null:b.tolerance;b.mode=c.mode||b.mode||"intersect"};var l=f.event,i=l.special,b=f.event.special.drop= {multi:1,delay:20,mode:"overlap",targets:[],datakey:"dropdata",livekey:"livedrop",add:function(c){var a=f.data(this,b.datakey);a.related+=1;if(!a.live&&c.selector){a.live=true;l.add(this,"dropinit."+b.livekey,b.delegate)}},remove:function(){f.data(this,b.datakey).related-=1},setup:function(){if(!f.data(this,b.datakey)){f.data(this,b.datakey,{related:0,active:[],anyactive:0,winner:0,location:{}});b.targets.push(this)}},teardown:function(){if(!f.data(this,b.datakey).related){f.removeData(this,b.datakey); l.remove(this,"dropinit",b.delegate);var c=this;b.targets=f.grep(b.targets,function(a){return a!==c})}},handler:function(c,a){var d;if(a)switch(c.type){case "mousedown":d=f(b.targets);if(typeof a.drop=="string")d=d.filter(a.drop);d.each(function(){var g=f.data(this,b.datakey);g.active=[];g.anyactive=0;g.winner=0});a.droppable=d;b.delegates=[];i.drag.hijack(c,"dropinit",a);b.delegates=f.unique(i.drag.flatten(b.delegates));break;case "mousemove":b.event=c;b.timer||b.tolerate(a);break;case "mouseup":b.timer= clearTimeout(b.timer);if(a.propagates){i.drag.hijack(c,"drop",a);i.drag.hijack(c,"dropend",a);f.each(b.delegates||[],function(){l.remove(this,"."+b.livekey)})}break}},delegate:function(c){var a=[],d,g=f.data(this,"events")||{};f.each(g.live||[],function(e,h){if(h.preType.indexOf("drop")===0){d=f(c.currentTarget).find(h.selector);d.length&&d.each(function(){l.add(this,h.origType+"."+b.livekey,h.origHandler,h.data);f.inArray(this,a)<0&&a.push(this)})}});b.delegates.push(a);return a.length?f(a):false}, locate:function(c,a){var d=f.data(c,b.datakey),g=f(c),e=g.offset()||{},h=g.outerHeight();g=g.outerWidth();e={elem:c,width:g,height:h,top:e.top,left:e.left,right:e.left+g,bottom:e.top+h};if(d){d.location=e;d.index=a;d.elem=c}return e},contains:function(c,a){return(a[0]||a.left)>=c.left&&(a[0]||a.right)<=c.right&&(a[1]||a.top)>=c.top&&(a[1]||a.bottom)<=c.bottom},modes:{intersect:function(c,a,d){return this.contains(d,[c.pageX,c.pageY])?1E9:this.modes.overlap.apply(this,arguments)},overlap:function(c, a,d){return Math.max(0,Math.min(d.bottom,a.bottom)-Math.max(d.top,a.top))*Math.max(0,Math.min(d.right,a.right)-Math.max(d.left,a.left))},fit:function(c,a,d){return this.contains(d,a)?1:0},middle:function(c,a,d){return this.contains(d,[a.left+a.width*0.5,a.top+a.height*0.5])?1:0}},sort:function(c,a){return a.winner-c.winner||c.index-a.index},tolerate:function(c){var a,d,g,e,h,m,j=0,k,p=c.interactions.length,n=[b.event.pageX,b.event.pageY],o=b.tolerance||b.modes[b.mode];do if(k=c.interactions[j]){if(!k)return; k.drop=[];h=[];m=k.droppable.length;if(o)g=b.locate(k.proxy);a=0;do if(d=k.droppable[a]){e=f.data(d,b.datakey);if(d=e.location){e.winner=o?o.call(b,b.event,g,d):b.contains(d,n)?1:0;h.push(e)}}while(++a Date: Fri, 10 Sep 2010 18:48:47 +0800 Subject: [PATCH 0279/1043] Added metaKey to allow Ctrl-select behaviour on OS X --- slick.grid.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index 7f53536..fd954d5 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -1701,14 +1701,14 @@ if (!jQuery.fn.drag) { var selection = getSelectedRows(); var idx = $.inArray(row, selection); - if (!e.ctrlKey && !e.shiftKey) { + if (!e.ctrlKey && !e.shiftKey && !e.metaKey) { selection = [row]; } else if (options.multiSelect) { - if (idx === -1 && e.ctrlKey) { + if (idx === -1 && (e.ctrlKey || e.metaKey)) { selection.push(row); } - else if (idx !== -1 && e.ctrlKey) { + else if (idx !== -1 && (e.ctrlKey || e.metaKey)) { selection = $.grep(selection, function(o, i) { return (o !== row); }); } else if (selection.length && e.shiftKey) { From 52672eab26fdffdd421be7128d6c28c623d43d80 Mon Sep 17 00:00:00 2001 From: mleibman Date: Thu, 7 Oct 2010 10:20:52 -0700 Subject: [PATCH 0280/1043] - FIXED: corrected variable reference in YesNoSelectCellEditor --- slick.editors.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slick.editors.js b/slick.editors.js index 72bf56c..04bd33d 100644 --- a/slick.editors.js +++ b/slick.editors.js @@ -285,12 +285,12 @@ }; this.loadValue = function(item) { - $input.val((defaultValue = item[args.column.field]) ? "yes" : "no"); - $input.select(); + $select.val((defaultValue = item[args.column.field]) ? "yes" : "no"); + $select.select(); }; this.serializeValue = function() { - return ($input.val() == "yes"); + return ($select.val() == "yes"); }; this.applyValue = function(item,state) { From 1274d0f1d88182b7a2c51be15d694e173ac3741f Mon Sep 17 00:00:00 2001 From: mleibman Date: Mon, 18 Oct 2010 14:36:16 -0700 Subject: [PATCH 0281/1043] Updated jQuery to 1.4.3 and uQueryUI to 1.8.5. --- css/smoothness/images/ui-anim_basic_16x16.gif | Bin 1553 -> 0 bytes ....custom.css => jquery-ui-1.8.5.custom.css} | 175 ++- examples/example1-simple.html | 4 +- examples/example10-async-post-render.html | 6 +- examples/example11-autoheight.html | 4 +- examples/example12-fillbrowser.html | 2 +- examples/example13-getItem-sorting.html | 2 +- examples/example14-highlighting.html | 6 +- examples/example2-formatters.html | 6 +- examples/example3-editing.html | 6 +- examples/example3a-compound-editors.html | 6 +- examples/example3b-editing-with-undo.html | 6 +- examples/example4-model.html | 6 +- examples/example5-collapsing.html | 6 +- examples/example6-ajax-loading.html | 6 +- examples/example7-events.html | 6 +- examples/example8-alternative-display.html | 4 +- examples/example9-row-reordering.html | 6 +- lib/jquery-1.4.2.min.js | 154 --- lib/jquery-1.4.3.min.js | 166 +++ lib/jquery-ui-1.8.2.custom.min.js | 1012 ----------------- lib/jquery-ui-1.8.5.custom.min.js | 778 +++++++++++++ tests/dataview/index.html | 2 +- tests/grid/index.html | 4 +- tests/model benchmarks.html | 2 +- tests/scrolling benchmarks.html | 6 +- 26 files changed, 1121 insertions(+), 1260 deletions(-) delete mode 100644 css/smoothness/images/ui-anim_basic_16x16.gif rename css/smoothness/{jquery-ui-1.8.2.custom.css => jquery-ui-1.8.5.custom.css} (82%) delete mode 100644 lib/jquery-1.4.2.min.js create mode 100644 lib/jquery-1.4.3.min.js delete mode 100644 lib/jquery-ui-1.8.2.custom.min.js create mode 100644 lib/jquery-ui-1.8.5.custom.min.js diff --git a/css/smoothness/images/ui-anim_basic_16x16.gif b/css/smoothness/images/ui-anim_basic_16x16.gif deleted file mode 100644 index 085ccaecaf5fa5c34bc14cd2c2ed5cbbd8e25dcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1553 zcma)+TTl~c6vwlh>nb99Af5rT)t{mCEg5urg=A(g z{C|6SPb~9Xage|wB`SrZk2FOMYM!buln2sX?5Y+T78iB(Zu9cS7|LZyZ++}u$^oi1 z_j@S}bW9OzU2R+RMy&~OT>X-oZ98$jq#ogNfJ!BM-42wHGZk*6s2KD}U*IA%epmxb zm}|6BK9YoIF;*xSL!+z@<64lB7->LTW2Vi4ostCA(z&2XniwNIv}fFo-`MbG;)u4G z^p@F!)|9HhZprHd_vXjDoxs6WkK-6P0@lfxnGT>*p(QHoUV=u1FAqb@b%*W=a3{`LsH5k^AvQNL>6fPpy#oU(&MuH(*aEX4b35*} zn4n7)`I2U%=+Z=?BVZQ?vjQFW4gD@~XSOO6b{qu81`4&LFuU2(ilxW+1|ZkNMnWe79C$gs zWT?Ele|HR{JGPe)5BTW>0Ey?-Ls6S#GoV0tbt6ku7B&*0 z;i9QM$W1Rj*rRIdceL)rAOSl+sDe3LkB87<%){;ZdHp6|SNlopDXRx< zxBDF9-lTo&v`8$humFygUij@qgT=Qzhj8{ym2-{Xciwqq_Xwk%=O3B-MNAL_6e`3U zyxwmXex4`g0^1RYw~Dth3av3Dl^AAlpO3mG!nLr#&ZZ7c_wUboI+deC+&%TFjK2Lm z!Y&f1h|T_On%RCV&=4bx`!>(YezqGVhl&QpED?N6GV)HmzJ9&rh$x*i?*@o9#6QI< z5ZI_MRX;0+pY8$`j)eF#TlUyG(eE%E7S!rj;mj^M5vhUicPm zVWQ2z+imFyg}SRABmOBY_@osR!>7Ov!ioK`NB6_Rv}7Ud?35ed5Sb@?yND?kv~RCa wqs^a3Sh>&&L4)!LKI?D2&k@))k(LESaga|C278ChSzn3NWVkcuNoY&{0f?~U_5c6? diff --git a/css/smoothness/jquery-ui-1.8.2.custom.css b/css/smoothness/jquery-ui-1.8.5.custom.css similarity index 82% rename from css/smoothness/jquery-ui-1.8.2.custom.css rename to css/smoothness/jquery-ui-1.8.5.custom.css index 3c4a611..0cb22be 100644 --- a/css/smoothness/jquery-ui-1.8.2.custom.css +++ b/css/smoothness/jquery-ui-1.8.5.custom.css @@ -1,8 +1,12 @@ /* -* jQuery UI CSS Framework -* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) -* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -*/ + * jQuery UI CSS Framework @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ /* Layout helpers ----------------------------------*/ @@ -38,11 +42,16 @@ /* -* jQuery UI CSS Framework -* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) -* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px -*/ + * jQuery UI CSS Framework @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px + */ /* Component containers @@ -283,8 +292,15 @@ /* Overlays */ .ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Resizable -----------------------------------*/ +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* + * jQuery UI Resizable @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ .ui-resizable { position: relative;} .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } @@ -295,35 +311,63 @@ .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Selectable -----------------------------------*/ -.ui-selectable-helper { border:1px dotted black } -/* Accordion -----------------------------------*/ +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } .ui-accordion .ui-accordion-li-fix { display: inline; } .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } -/* IE7-/Win - Fix extra vertical space in lists */ -.ui-accordion a { zoom: 1; } .ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } -.ui-accordion .ui-accordion-content-active { display: block; }/* Autocomplete -----------------------------------*/ +.ui-accordion .ui-accordion-content-active { display: block; }/* + * jQuery UI Autocomplete @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ .ui-autocomplete { position: absolute; cursor: default; } -.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; } /* workarounds */ * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ -/* Menu -----------------------------------*/ +/* + * jQuery UI Menu @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ .ui-menu { list-style:none; padding: 2px; margin: 0; display:block; + float: left; } .ui-menu .ui-menu { margin-top: -3px; @@ -348,9 +392,15 @@ font-weight: normal; margin: -1px; } -/* Button -----------------------------------*/ - +/* + * jQuery UI Button @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ .ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ .ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ @@ -361,15 +411,17 @@ button.ui-button-icons-only { width: 3.7em; } .ui-button .ui-button-text { display: block; line-height: 1.4; } .ui-button-text-only .ui-button-text { padding: .4em 1em; } .ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } .ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } /* no icon support for input elements, provide padding by default */ input.ui-button { padding: .4em 1em; } /*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } .ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } /*button sets*/ @@ -378,26 +430,36 @@ input.ui-button { padding: .4em 1em; } /* workarounds */ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ - - - - - -/* Dialog -----------------------------------*/ +/* + * jQuery UI Dialog @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ .ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } .ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; } .ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } .ui-draggable .ui-dialog-titlebar { cursor: move; } -/* Slider -----------------------------------*/ +/* + * jQuery UI Slider @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ .ui-slider { position: relative; text-align: left; } .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } @@ -412,8 +474,15 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } .ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs -----------------------------------*/ +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ .ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ .ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } .ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } @@ -423,8 +492,15 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ .ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } .ui-tabs .ui-tabs-hide { display: none !important; } -/* Datepicker -----------------------------------*/ +/* + * jQuery UI Datepicker @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ .ui-datepicker { width: 17em; padding: .2em .2em 0; } .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } @@ -483,7 +559,14 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad left: -4px; /*must have*/ width: 200px; /*must have*/ height: 200px; /*must have*/ -}/* Progressbar -----------------------------------*/ +}/* + * jQuery UI Progressbar @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ .ui-progressbar { height:2em; text-align: left; } .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/examples/example1-simple.html b/examples/example1-simple.html index 42b30bc..93a7a1d 100644 --- a/examples/example1-simple.html +++ b/examples/example1-simple.html @@ -4,7 +4,7 @@ SlickGrid example 1: Basic grid - + @@ -22,7 +22,7 @@

      Demonstrates:

      - + diff --git a/examples/example10-async-post-render.html b/examples/example10-async-post-render.html index 7f3b8cd..b8f6122 100644 --- a/examples/example10-async-post-render.html +++ b/examples/example10-async-post-render.html @@ -4,7 +4,7 @@ SlickGrid example 10: Async post render - + - -
      @@ -43,6 +41,7 @@

      Options:

      + @@ -54,12 +53,8 @@

      Options:

      return {valid:true, msg:null}; } - - var grid; - var data = []; - var columns = [ {id:"title", name:"Title", field:"title", width:120, cssClass:"cell-title", editor:TextCellEditor, validator:requiredFieldValidator}, {id:"desc", name:"Description", field:"description", width:100, editor:LongTextCellEditor}, @@ -69,16 +64,14 @@

      Options:

      {id:"finish", name:"Finish", field:"finish", minWidth:60, editor:DateCellEditor}, {id:"effort-driven", name:"Effort Driven", width:80, minWidth:20, maxWidth:80, cssClass:"cell-effort-driven", field:"effortDriven", formatter:BoolCellFormatter, editor:YesNoCheckboxCellEditor} ]; - var options = { editable: true, enableAddRow: true, enableCellNavigation: true, - asyncEditorLoading: false + asyncEditorLoading: false, + autoEdit: false }; - - $(function() { for (var i=0; i<500; i++) { @@ -93,18 +86,17 @@

      Options:

      d["effortDriven"] = (i % 5 == 0); } + grid = new Slick.Grid("#myGrid", data, columns, options); - grid = new Slick.Grid($("#myGrid"), data, columns, options); - - grid.onAddNewRow = function(item,colDef) { - grid.removeRow(data.length); + grid.onAddNewRow.subscribe(function(e, args) { + var item = args.item; + var column = args.column; + grid.invalidateRow(data.length); data.push(item); grid.updateRowCount(); grid.render(); - } + }); }) - - diff --git a/examples/example3a-compound-editors.html b/examples/example3a-compound-editors.html index 931ac68..d6b8d8f 100644 --- a/examples/example3a-compound-editors.html +++ b/examples/example3a-compound-editors.html @@ -34,6 +34,7 @@

      Demonstrates:

      + @@ -120,8 +121,6 @@

      Demonstrates:

      this.init(); } - - $(function() { for (var i=0; i<500; i++) { @@ -132,14 +131,12 @@

      Demonstrates:

      d["to"] = d["from"] + Math.round(Math.random() * 100); } - grid = new Slick.Grid($("#myGrid"), data, columns, options); + grid = new Slick.Grid("#myGrid", data, columns, options); - grid.onValidationError = function(currentCellNode, validationResults, currentRow, currentCell, column) { - alert(validationResults.msg); - } + grid.onValidationError.subscribe(function(e,args) { + alert(args.validationResults.msg); + }); }) - - diff --git a/examples/example3b-editing-with-undo.html b/examples/example3b-editing-with-undo.html index 4102dff..76adb66 100644 --- a/examples/example3b-editing-with-undo.html +++ b/examples/example3b-editing-with-undo.html @@ -39,6 +39,7 @@

      Controls:

      + @@ -101,10 +102,8 @@

      Controls:

      d["effortDriven"] = (i % 5 == 0); } - grid = new Slick.Grid($("#myGrid"), data, columns, options); + grid = new Slick.Grid("#myGrid", data, columns, options); }) - - diff --git a/examples/example4-model.html b/examples/example4-model.html index d800c70..5118c2d 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -4,10 +4,10 @@ SlickGrid example 4: Model - + - + @@ -61,6 +82,11 @@ + + + + + @@ -115,11 +141,6 @@ return {valid:true, msg:null}; } - function selectMultipleRows() { - if (!Slick.GlobalEditorLock.commitCurrentEdit()) { return; } - grid.setSelectedRows([0,1,2]); - } - $(function() { data = [ @@ -129,98 +150,31 @@ { name: "Find out who's nice", complete: false} ]; - grid = new Slick.Grid($("#myGrid"), data, columns, options); - - $("#myGrid") - .bind("draginit", function(e,dd) { - var cell = grid.getCellFromEvent(e); - if (!cell) - return false; - - dd.row = cell.row; - if (!data[dd.row]) - return false; - - if (Slick.GlobalEditorLock.isActive() && !Slick.GlobalEditorLock.cancelCurrentEdit()) - return false; - }) - .bind("dragstart", function(e,dd) { - var selectedRows = grid.getSelectedRows(); - - if (!selectedRows.length || $.inArray(dd.row,selectedRows) == -1) { - selectedRows = [dd.row]; - grid.setSelectedRows(selectedRows); - } - - dd.rows = selectedRows; - dd.count = selectedRows.length; - - var proxy = $("") - .css({ - position: "absolute", - display: "inline-block", - padding: "4px 10px", - background: "#e0e0e0", - border: "1px solid gray", - "z-index": 99999, - "-moz-border-radius": "8px", - "-moz-box-shadow": "2px 2px 6px silver" - }) - .text("Drag to Recycle Bin to delete " + dd.count + " selected row(s)") - .appendTo("body"); - - dd.helper = proxy; - - $(dd.available).css("background","pink"); + data = data.concat(data); + data = data.concat(data); - return proxy; - }) - .bind("drag", function(e,dd) { - dd.helper.css({top: e.pageY + 5, left: e.pageX + 5}); - }) - .bind("dragend", function(e,dd) { - dd.helper.remove(); - $(dd.available).css("background","beige"); - }); + grid = new Slick.Grid("#myGrid", data, columns, options); + grid.setSelectionModel(new Slick.RowSelectionModel()); - $("#dropzone") - .bind("dropstart", function(e,dd) { - $(this).css("background","yellow"); - }) - .bind("dropend", function(e,dd) { - $(dd.available).css("background","pink"); - }) - .bind("drop", function(e,dd) { - var rowsToDelete = dd.rows.sort().reverse(); - for (var i=0; i") + .css({ + position: "absolute", + display: "inline-block", + padding: "4px 10px", + background: "#e0e0e0", + border: "1px solid gray", + "z-index": 99999, + "-moz-border-radius": "8px", + "-moz-box-shadow": "2px 2px 6px silver" + }) + .text("Drag to Recycle Bin to delete " + dd.count + " selected row(s)") + .appendTo("body"); + + dd.helper = proxy; + + $(dd.available).css("background","pink"); + + return proxy; + }); + + grid.onDrag.subscribe(function(e,dd) { + if (dd.mode != "recycle") { + return; + } + e.stopImmediatePropagation(); + dd.helper.css({top: e.pageY + 5, left: e.pageX + 5}); + }); + + grid.onDragEnd.subscribe(function(e,dd) { + if (dd.mode != "recycle") { + return; + } + e.stopImmediatePropagation(); + dd.helper.remove(); + $(dd.available).css("background","beige"); + }); + + + $("#dropzone") + .bind("dropstart", function(e,dd) { + $(this).css("background","yellow"); + }) + .bind("dropend", function(e,dd) { + $(dd.available).css("background","pink"); + }) + .bind("drop", function(e,dd) { + var rowsToDelete = dd.rows.sort().reverse(); + for (var i=0; i diff --git a/examples/slick-default-theme.css b/examples/slick-default-theme.css index 46e837e..797a6ce 100644 --- a/examples/slick-default-theme.css +++ b/examples/slick-default-theme.css @@ -41,6 +41,10 @@ classes should alter those! } .slick-cell.selected { + background-color: beige; +} + +.slick-cell.active { border-color: gray; border-style: solid; } diff --git a/plugins/slick.cellselectionmodel.js b/plugins/slick.cellselectionmodel.js new file mode 100644 index 0000000..0407de1 --- /dev/null +++ b/plugins/slick.cellselectionmodel.js @@ -0,0 +1,159 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "CellSelectionModel": CellSelectionModel + } + }); + + + function CellSelectionModel() { + var _grid; + var _canvas; + var _ranges = []; + var _dragging; + var _self = this; + + function returnFalse() { + return false; + } + + function init(grid) { + _grid = grid; + _canvas = _grid.getCanvasNode(); + _grid.onActiveCellChanged.subscribe(handleActiveCellChange); + _grid.onDragInit.subscribe(handleDragInit); + _grid.onDragStart.subscribe(handleDragStart); + _grid.onDrag.subscribe(handleDrag); + _grid.onDragEnd.subscribe(handleDragEnd); + } + + function destroy() { + _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange); + _grid.onDragInit.unsubscribe(handleDragInit); + _grid.onDragStart.unsubscribe(handleDragStart); + _grid.onDrag.unsubscribe(handleDrag); + _grid.onDragEnd.unsubscribe(handleDragEnd); + } + + function removeInvalidRanges(ranges) { + var result = []; + + for (var i = 0; i < ranges.length; i++) { + var r = ranges[i]; + if (_grid.canCellBeSelected(r.fromRow,r.fromCell) && _grid.canCellBeSelected(r.toRow,r.toCell)) { + result.push(r); + } + } + + return result; + } + + function setSelectedRanges(ranges) { + _ranges = removeInvalidRanges(ranges); + _self.onSelectedRangesChanged.notify(_ranges); } + + function getSelectedRanges() { + return _ranges; + } + + function fixUpRange(range) { + var r1 = Math.min(range.start.row,range.end.row); + var c1 = Math.min(range.start.cell,range.end.cell); + var r2 = Math.max(range.start.row,range.end.row); + var c2 = Math.max(range.start.cell,range.end.cell); + return { + start: {row:r1, cell:c1}, + end: {row:r2, cell:c2} + }; + } + + function handleDragInit(e,dd) { + var cell = _grid.getCellFromEvent(e); + + if (!_grid.getEditorLock().isActive()) { + if (_grid.canCellBeSelected(cell.row,cell.cell)/* && e.ctrlKey*/) { + _dragging = true; + e.stopImmediatePropagation(); + } + } + } + + function handleDragStart(e,dd) { + if (!_dragging) { + return; + } + + var start = _grid.getCellFromPoint( + dd.startX - $(_canvas).offset().left, + dd.startY - $(_canvas).offset().top); + + e.stopImmediatePropagation(); + + dd.range = {start:start,end:{}}; + + return $("
      ").appendTo(_canvas); + } + + function handleDrag(e,dd) { + if (!_dragging) { + return; + } + + e.stopImmediatePropagation(); + + var end = _grid.getCellFromPoint( + e.pageX - $(_canvas).offset().left, + e.pageY - $(_canvas).offset().top); + + if (!_grid.canCellBeSelected(end.row,end.cell)) { + return; + } + + dd.range.end = end; + var r = fixUpRange(dd.range); + var from = _grid.getCellNodeBox(r.start.row,r.start.cell); + var to = _grid.getCellNodeBox(r.end.row,r.end.cell); + + $(dd.proxy).css({ + top: from.top - 1, + left: from.left - 1, + height: to.bottom - from.top - 2, + width: to.right - from.left - 2 + }); + } + + function handleDragEnd(e,dd) { + if (!_dragging) { + return; + } + + _dragging = false; + e.stopImmediatePropagation(); + $(dd.proxy).remove(); + + setSelectedRanges([ + new Slick.Range( + dd.range.start.row, + dd.range.start.cell, + dd.range.end.row, + dd.range.end.cell + ) + ]); + } + + function handleActiveCellChange(e, data) { + setSelectedRanges([new Slick.Range(data.row,data.cell)]); + } + + $.extend(this, { + "getSelectedRanges": getSelectedRanges, + "setSelectedRanges": setSelectedRanges, + + "init": init, + "destroy": destroy, + + "onSelectedRangesChanged": new Slick.Event() + }); + } +})(jQuery); \ No newline at end of file diff --git a/plugins/slick.rowmovemanager.js b/plugins/slick.rowmovemanager.js new file mode 100644 index 0000000..6b037ac --- /dev/null +++ b/plugins/slick.rowmovemanager.js @@ -0,0 +1,138 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "RowMoveManager": RowMoveManager + } + }); + + function RowMoveManager() { + var _grid; + var _canvas; + var _dragging; + var _self = this; + + function init(grid) { + _grid = grid; + _canvas = _grid.getCanvasNode(); + _grid.onDragInit.subscribe(handleDragInit); + _grid.onDragStart.subscribe(handleDragStart); + _grid.onDrag.subscribe(handleDrag); + _grid.onDragEnd.subscribe(handleDragEnd); + } + + function destroy() { + _grid.onDragInit.unsubscribe(handleDragInit); + _grid.onDragStart.unsubscribe(handleDragStart); + _grid.onDrag.unsubscribe(handleDrag); + _grid.onDragEnd.unsubscribe(handleDragEnd); + } + + function handleDragInit(e,dd) { + var cell = _grid.getCellFromEvent(e); + + if (!_grid.getEditorLock().isActive()) { + if (/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)) { + _dragging = true; + e.stopImmediatePropagation(); + } + } + } + + function handleDragStart(e,dd) { + if (!_dragging) { + return; + } + + e.stopImmediatePropagation(); + + var cell = _grid.getCellFromEvent(e); + var selectedRows = _grid.getSelectedRows(); + + if (selectedRows.length == 0 || $.inArray(cell.row, selectedRows) == -1) { + selectedRows = [cell.row]; + _grid.setSelectedRows(selectedRows); + } + + var rowHeight = _grid.getOptions().rowHeight; + + dd.selectedRows = selectedRows; + + dd.selectionProxy = $("
      ") + .css("position", "absolute") + .css("zIndex", "99999") + .css("width", $(_canvas).innerWidth()) + .css("height", rowHeight*selectedRows.length) + .appendTo(_canvas); + + dd.guide = $("
      ") + .css("position", "absolute") + .css("zIndex", "99998") + .css("width", $(_canvas).innerWidth()) + .css("top", -1000) + .appendTo(_canvas); + + dd.insertBefore = -1; + + return $("
      ").appendTo(_canvas); + } + + function handleDrag(e,dd) { + if (!_dragging) { + return; + } + + e.stopImmediatePropagation(); + + var top = e.pageY - $(_canvas).offset().top; + dd.selectionProxy.css("top",top-5); + + var insertBefore = Math.max(0,Math.min(Math.round(top/_grid.getOptions().rowHeight),_grid.getDataLength())); + if (insertBefore !== dd.insertBefore) { + var eventData = { + "rows": dd.selectedRows, + "insertBefore": insertBefore + }; + + if (_self.onBeforeMoveRows.notify(eventData) === false) { + dd.guide.css("top", -1000); + dd.canMove = false; + } + else { + dd.guide.css("top",insertBefore*_grid.getOptions().rowHeight); + dd.canMove = true; + } + + dd.insertBefore = insertBefore; + } + } + + function handleDragEnd(e,dd) { + if (!_dragging) { + return; + } + _dragging = false; + e.stopImmediatePropagation(); + + dd.guide.remove(); + dd.selectionProxy.remove(); + + if (dd.canMove) { + var eventData = { + "rows": dd.selectedRows, + "insertBefore": dd.insertBefore + }; + // TODO: _grid.remapCellCssClasses ? + _self.onMoveRows.notify(eventData); + } + } + + $.extend(this, { + "onBeforeMoveRows": new Slick.Event(), + "onMoveRows": new Slick.Event(), + + "init": init, + "destroy": destroy + }); + } +})(jQuery); \ No newline at end of file diff --git a/plugins/slick.rowselectionmodel.js b/plugins/slick.rowselectionmodel.js new file mode 100644 index 0000000..eb03db8 --- /dev/null +++ b/plugins/slick.rowselectionmodel.js @@ -0,0 +1,180 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "RowSelectionModel": RowSelectionModel + } + }); + + function RowSelectionModel() { + var _grid; + var _ranges = []; + var _self = this; + + function init(grid) { + _grid = grid; + _grid.onActiveCellChanged.subscribe(handleActiveCellChange); + _grid.onKeyDown.subscribe(handleKeyDown); + _grid.onClick.subscribe(handleClick); + } + + function destroy() { + _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange); + _grid.onKeyDown.unsubscribe(handleKeyDown); + _grid.onClick.unsubscribe(handleClick()); + } + + function rangesToRows(ranges) { + var rows = []; + for (var i = 0; i < ranges.length; i++) { + for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) { + rows.push(j); + } + } + return rows; + } + + function rowsToRanges(rows) { + var ranges = []; + var lastCell = _grid.getColumns().length - 1; + for (var i = 0; i < rows.length; i++) { + ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell)); + } + return ranges; + } + + function getRowsRange(from,to) { + var i, rows = []; + for (i = from; i <= to; i++) { + rows.push(i); + } + for (i = to; i < from; i++) { + rows.push(i); + } + return rows; + } + + function getSelectedRows() { + return rangesToRows(_ranges); + } + + function setSelectedRows(rows) { + setSelectedRanges(rowsToRanges(rows)); + } + + function setSelectedRanges(ranges) { + _ranges = ranges; + _self.onSelectedRangesChanged.notify(_ranges); + } + + function getSelectedRanges() { + return _ranges; + } + + function handleActiveCellChange(e, data) { + setSelectedRanges([new Slick.Range(data.row, 0, data.row, _grid.getColumns().length - 1)]); + } + + function handleKeyDown(e) { + var activeRow = _grid.getActiveCell(); + if (activeRow && e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey && (e.which == 38 || e.which == 40)) { + var selectedRows = getSelectedRows(); + selectedRows.sort(function(x,y) { return x-y }); + + if (!selectedRows.length) { + selectedRows = [activeRow.row]; + } + + var top = selectedRows[0]; + var bottom = selectedRows[selectedRows.length - 1]; + + if (e.which == 40) { + if (activeRow.row < bottom || top == bottom) { + bottom++; + _grid.scrollRowIntoView(bottom); + } + else { + top++; + _grid.scrollRowIntoView(top); + } + } + else { + if (activeRow.row < bottom) { + bottom--; + _grid.scrollRowIntoView(bottom); + } else { + top--; + _grid.scrollRowIntoView(top); + } + } + + selectedRows = getRowsRange(top,bottom); + _ranges = rowsToRanges(selectedRows); + + setSelectedRanges(_ranges); + + e.preventDefault(); + e.stopPropagation(); + return true; + } + + return false; + } + + function handleClick(e) { + var cell = _grid.getCellFromEvent(e); + if (!cell || !_grid.canCellBeSelected(cell.row, cell.cell)) { + return false; + } + + var selection = rangesToRows(_ranges); + var idx = $.inArray(cell.row, selection); + + if (!e.ctrlKey && !e.shiftKey && !e.metaKey) { + return false; + } + else if (_grid.getOptions().multiSelect) { + if (idx === -1 && (e.ctrlKey || e.metaKey)) { + selection.push(cell.row); + _grid.setActiveCell(cell.row, cell.cell); + } + else if (idx !== -1 && (e.ctrlKey || e.metaKey)) { + selection = $.grep(selection, function(o, i) { return (o !== cell.row); }); + _grid.setActiveCell(cell.row, cell.cell); + } + else if (selection.length && e.shiftKey) { + var last = selection.pop(); + var from = Math.min(cell.row, last); + var to = Math.max(cell.row, last); + selection = []; + for (var i = from; i <= to; i++) { + if (i !== last) { + selection.push(i); + } + } + selection.push(last); + _grid.setActiveCell(cell.row, cell.cell); + } + } + + _ranges = rowsToRanges(selection); + setSelectedRanges(_ranges); + e.stopImmediatePropagation(); + + return true; + } + + $.extend(this, { + "getSelectedRows": getSelectedRows, + "setSelectedRows": setSelectedRows, + + "getSelectedRanges": getSelectedRanges, + "setSelectedRanges": setSelectedRanges, + + "init": init, + "destroy": destroy, + + "onSelectedRangesChanged": new Slick.Event() + }); + } +})(jQuery); \ No newline at end of file diff --git a/slick.core.js b/slick.core.js new file mode 100644 index 0000000..dfc6ef8 --- /dev/null +++ b/slick.core.js @@ -0,0 +1,188 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "Event": Event, + "EventData": EventData, + "Range": Range, + "EditorLock": EditorLock, + "GlobalEditorLock": new EditorLock() + } + }); + + + function EventData() { + var isPropagationStopped = false; + var isImmediatePropagationStopped = false; + + this.stopPropagation = function() { + isPropagationStopped = true; + }; + + this.isPropagationStopped = function() { + return isPropagationStopped; + }; + + this.stopImmediatePropagation = function() { + isImmediatePropagationStopped = true; + }; + + this.isImmediatePropagationStopped = function() { + return isImmediatePropagationStopped; + } + } + + function Event() { + var handlers = []; + + this.subscribe = function(fn) { + handlers.push(fn); + }; + + this.unsubscribe = function(fn) { + for (var i = handlers.length - 1; i >= 0; i--) { + if (handlers[i] === fn) { + handlers.splice(i, 1); + } + } + }; + + this.notify = function(arg1, arg2) { + var e; + var data; + var returnValue; + if (arguments.length === 2) { + e = arg1; + data = arg2; + } + else { + e = new EventData(); + data = arg1; + } + + for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) { + returnValue = handlers[i].call(this, e, data); + } + + return returnValue; + }; + } + + function Range(fromRow, fromCell, toRow, toCell) { + if (toRow === undefined && toCell === undefined) { + toRow = fromRow; + toCell = fromCell; + } + + this.fromRow = Math.min(fromRow, toRow); + this.fromCell = Math.min(fromCell, toCell); + this.toRow = Math.max(fromRow, toRow); + this.toCell = Math.max(fromCell, toCell); + + this.isSingleRow = function() { + return this.fromRow == this.toRow; + }; + + this.isSingleCell = function() { + return this.fromRow == this.toRow && this.fromCell == this.toCell; + }; + + this.toString = function() { + if (this.isSingleCell()) { + return "(" + this.fromRow + ":" + this.fromCell + ")"; + } + else { + return "(" + this.fromRow + ":" + this.fromCell + " - " + this.toRow + ":" + this.toCell + ")"; + } + } + } + + function EditorLock() { + /// + /// Track currently active edit controller and ensure + /// that onle a single controller can be active at a time. + /// Edit controller is an object that is responsible for + /// gory details of looking after editor in the browser, + /// and allowing EditorLock clients to either accept + /// or cancel editor changes without knowing any of the + /// implementation details. SlickGrid instance is used + /// as edit controller for cell editors. + /// + + var currentEditController = null; + + this.isActive = function isActive(editController) { + /// + /// Return true if the specified editController + /// is currently active in this lock instance + /// (i.e. if that controller acquired edit lock). + /// If invoked without parameters ("editorLock.isActive()"), + /// return true if any editController is currently + /// active in this lock instance. + /// + return (editController ? currentEditController === editController : currentEditController !== null); + }; + + this.activate = function activate(editController) { + /// + /// Set the specified editController as the active + /// controller in this lock instance (acquire edit lock). + /// If another editController is already active, + /// an error will be thrown (i.e. before calling + /// this method isActive() must be false, + /// afterwards isActive() will be true). + /// + if (editController === currentEditController) { // already activated? + return; + } + if (currentEditController !== null) { + throw "SlickGrid.EditorLock.activate: an editController is still active, can't activate another editController"; + } + if (!editController.commitCurrentEdit) { + throw "SlickGrid.EditorLock.activate: editController must implement .commitCurrentEdit()"; + } + if (!editController.cancelCurrentEdit) { + throw "SlickGrid.EditorLock.activate: editController must implement .cancelCurrentEdit()"; + } + currentEditController = editController; + }; + + this.deactivate = function deactivate(editController) { + /// + /// Unset the specified editController as the active + /// controller in this lock instance (release edit lock). + /// If the specified editController is not the editController + /// that is currently active in this lock instance, + /// an error will be thrown. + /// + if (currentEditController !== editController) { + throw "SlickGrid.EditorLock.deactivate: specified editController is not the currently active one"; + } + currentEditController = null; + }; + + this.commitCurrentEdit = function commitCurrentEdit() { + /// + /// Invoke the "commitCurrentEdit" method on the + /// editController that is active in this lock + /// instance and return the return value of that method + /// (if no controller is active, return true). + /// "commitCurrentEdit" is expected to return true + /// to indicate successful commit, false otherwise. + /// + return (currentEditController ? currentEditController.commitCurrentEdit() : true); + }; + + this.cancelCurrentEdit = function cancelCurrentEdit() { + /// + /// Invoke the "cancelCurrentEdit" method on the + /// editController that is active in this lock + /// instance (if no controller is active, do nothing). + /// Returns true if the edit was succesfully cancelled. + /// + return (currentEditController ? currentEditController.cancelCurrentEdit() : true); + }; + } +})(jQuery); + + diff --git a/slick.model.js b/slick.dataview.js similarity index 94% rename from slick.model.js rename to slick.dataview.js index ec52b74..a0599d4 100644 --- a/slick.model.js +++ b/slick.dataview.js @@ -1,23 +1,3 @@ -/*** - * A simple observer pattern implementation. - */ -function EventHelper() { - this.handlers = []; - - this.subscribe = function(fn) { - this.handlers.push(fn); - }; - - this.notify = function(args) { - for (var i = 0; i < this.handlers.length; i++) { - this.handlers[i].call(this, args); - } - }; - - return this; -} - - (function($) { /*** * A sample Model implementation. @@ -46,9 +26,9 @@ function EventHelper() { var totalRows = 0; // events - var onRowCountChanged = new EventHelper(); - var onRowsChanged = new EventHelper(); - var onPagingInfoChanged = new EventHelper(); + var onRowCountChanged = new Slick.Event(); + var onRowsChanged = new Slick.Event(); + var onPagingInfoChanged = new Slick.Event(); function beginUpdate() { diff --git a/slick.grid.css b/slick.grid.css index 73d37d9..d311142 100644 --- a/slick.grid.css +++ b/slick.grid.css @@ -143,11 +143,5 @@ classes should alter those! .slick-selection { z-index: 10; position: absolute; - background: gray; - border: 1px solid black; - opacity: 0.3; - filter: alpha(opacity=30); - -webkit-box-shadow: 0px 0px 10px black; - -moz-box-shadow: 0px 0px 10px black; - box-shadow: 0px 0px 10px black; + border: 2px dashed black; } \ No newline at end of file diff --git a/slick.grid.js b/slick.grid.js index 13b8a7a..b4e9994 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -1,213 +1,52 @@ /** * @license - * (c) 2009-2010 Michael Leibman (michael.leibman@gmail.com) + * (c) 2009-2010 Michael Leibman + * michael{dot}leibman{at}gmail{dot}com * http://github.com/mleibman/slickgrid * Distributed under MIT license. * All rights reserved. * - * SlickGrid v1.4.3 - * - * TODO: - * - frozen columns - * - consistent events (EventHelper? jQuery events?) - * - * - * OPTIONS: - * rowHeight - (default 25px) Row height in pixels. - * enableAddRow - (default false) If true, a blank row will be displayed at the bottom - typing values in that row will add a new one. - * leaveSpaceForNewRows - (default false) - * editable - (default false) If false, no cells will be switched into edit mode. - * autoEdit - (default true) Cell will not automatically go into edit mode when selected. - * enableCellNavigation - (default true) If false, no cells will be selectable. - * enableCellRangeSelection - (default false) If true, user will be able to select a cell range. onCellRangeSelected event will be fired. - * defaultColumnWidth - (default 80px) Default column width in pixels (if columns[cell].width is not specified). - * enableColumnReorder - (default true) Allows the user to reorder columns. - * asyncEditorLoading - (default false) Makes cell editors load asynchronously after a small delay. - * This greatly increases keyboard navigation speed. - * asyncEditorLoadDelay - (default 100msec) Delay after which cell editor is loaded. Ignored unless asyncEditorLoading is true. - * forceFitColumns - (default false) Force column sizes to fit into the viewport (avoid horizontal scrolling). - * enableAsyncPostRender - (default false) If true, async post rendering will occur and asyncPostRender delegates on columns will be called. - * asyncPostRenderDelay - (default 60msec) Delay after which async post renderer delegate is called. - * autoHeight - (default false) If true, vertically resizes to fit all rows. - * editorLock - (default Slick.GlobalEditorLock) A Slick.EditorLock instance to use for controlling concurrent data edits. - * showSecondaryHeaderRow - (default false) If true, an extra blank (to be populated externally) row will be displayed just below the header columns. - * secondaryHeaderRowHeight - (default 25px) The height of the secondary header row. - * syncColumnCellResize - (default false) Synchronously resize column cells when column headers are resized - * rowCssClasses - (default null) A function which (given a row's data item as an argument) returns a space-delimited string of CSS classes that will be applied to the slick-row element. Note that this should be fast, as it is called every time a row is displayed. - * cellHighlightCssClass - (default "highlighted") A CSS class to apply to cells highlighted via setHighlightedCells(). - * cellFlashingCssClass - (default "flashing") A CSS class to apply to flashing cells (flashCell()). - * formatterFactory - (default null) A factory object responsible to creating a formatter for a given cell. - * Must implement getFormatter(column). - * editorFactory - (default null) A factory object responsible to creating an editor for a given cell. - * Must implement getEditor(column). - * multiSelect - (default true) Enable multiple row selection. - * - * COLUMN DEFINITION (columns) OPTIONS: - * id - Column ID. - * name - Column name to put in the header. - * toolTip - Tooltip (if different from name). - * field - Property of the data context to bind to. - * formatter - (default 'return value || ""') Function responsible for rendering the contents of a cell. Signature: function formatter(row, cell, value, columnDef, dataContext) { ... return "..."; } - * editor - An Editor class. - * validator - An extra validation function to be passed to the editor. - * unselectable - If true, the cell cannot be selected (and therefore edited). - * cannotTriggerInsert - If true, a new row cannot be created from just the value of this cell. - * width - Width of the column in pixels. - * resizable - (default true) If false, the column cannot be resized. - * sortable - (default false) If true, the column can be sorted (onSort will be called). - * minWidth - Minimum allowed column width for resizing. - * maxWidth - Maximum allowed column width for resizing. - * cssClass - A CSS class to add to the cell. - * rerenderOnResize - Rerender the column when it is resized (useful for columns relying on cell width or adaptive formatters). - * asyncPostRender - Function responsible for manipulating the cell DOM node after it has been rendered (called in the background). - * behavior - Configures the column with one of several available predefined behaviors: "select", "move", "selectAndMove". - * - * - * EVENTS: - * onSort - - * onHeaderContextMenu - - * onHeaderClick - - * onClick - - * onDblClick - - * onContextMenu - - * onKeyDown - - * onAddNewRow - - * onValidationError - - * onViewportChanged - - * onSelectedRowsChanged - - * onColumnsReordered - - * onColumnsResized - - * onBeforeMoveRows - - * onMoveRows - - * onCellChange - Raised when cell has been edited. Args: row,cell,dataContext. - * onBeforeEditCell - Raised before a cell goes into edit mode. Return false to cancel. Args: row,cell,dataContext. - * onBeforeCellEditorDestroy - Raised before a cell editor is destroyed. Args: current cell editor. - * onBeforeDestroy - Raised just before the grid control is destroyed (part of the destroy() method). - * onCurrentCellChanged - Raised when the selected (active) cell changed. Args: {row:currentRow, cell:currentCell}. - * onCellRangeSelected - Raised when a user selects a range of cells. Args: {from:{row,cell}, to:{row,cell}}. + * SlickGrid v2.0 alpha * * NOTES: * Cell/row DOM manipulations are done directly bypassing jQuery's DOM manipulation methods. * This increases the speed dramatically, but can only be done safely because there are no event handlers * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy() * and do proper cleanup. - * - * - * @param {Node} container Container node to create the grid in. - * @param {Array} or {Object} data An array of objects for databinding. - * @param {Array} columns An array of column definitions. - * @param {Object} options Grid options. */ // make sure required JavaScript modules are loaded if (typeof jQuery === "undefined") { - throw new Error("SlickGrid requires jquery module to be loaded"); + throw "SlickGrid requires jquery module to be loaded"; } if (!jQuery.fn.drag) { - throw new Error("SlickGrid requires jquery.event.drag module to be loaded"); + throw "SlickGrid requires jquery.event.drag module to be loaded"; +} +if (typeof Slick === "undefined") { + throw "slick.core.js not loaded"; } -(function($) { - var scrollbarDimensions; // shared across all grids on this page - - - ////////////////////////////////////////////////////////////////////////////////////////////// - // EditorLock class implementation (available as Slick.EditorLock) - - /** @constructor */ - function EditorLock() { - /// - /// Track currently active edit controller and ensure - /// that onle a single controller can be active at a time. - /// Edit controller is an object that is responsible for - /// gory details of looking after editor in the browser, - /// and allowing EditorLock clients to either accept - /// or cancel editor changes without knowing any of the - /// implementation details. SlickGrid instance is used - /// as edit controller for cell editors. - /// - - var currentEditController = null; - - this.isActive = function isActive(editController) { - /// - /// Return true if the specified editController - /// is currently active in this lock instance - /// (i.e. if that controller acquired edit lock). - /// If invoked without parameters ("editorLock.isActive()"), - /// return true if any editController is currently - /// active in this lock instance. - /// - return (editController ? currentEditController === editController : currentEditController !== null); - }; - - this.activate = function activate(editController) { - /// - /// Set the specified editController as the active - /// controller in this lock instance (acquire edit lock). - /// If another editController is already active, - /// an error will be thrown (i.e. before calling - /// this method isActive() must be false, - /// afterwards isActive() will be true). - /// - if (editController === currentEditController) { // already activated? - return; - } - if (currentEditController !== null) { - throw "SlickGrid.EditorLock.activate: an editController is still active, can't activate another editController"; - } - if (!editController.commitCurrentEdit) { - throw "SlickGrid.EditorLock.activate: editController must implement .commitCurrentEdit()"; - } - if (!editController.cancelCurrentEdit) { - throw "SlickGrid.EditorLock.activate: editController must implement .cancelCurrentEdit()"; - } - currentEditController = editController; - }; - - this.deactivate = function deactivate(editController) { - /// - /// Unset the specified editController as the active - /// controller in this lock instance (release edit lock). - /// If the specified editController is not the editController - /// that is currently active in this lock instance, - /// an error will be thrown. - /// - if (currentEditController !== editController) { - throw "SlickGrid.EditorLock.deactivate: specified editController is not the currently active one"; - } - currentEditController = null; - }; - - this.commitCurrentEdit = function commitCurrentEdit() { - /// - /// Invoke the "commitCurrentEdit" method on the - /// editController that is active in this lock - /// instance and return the return value of that method - /// (if no controller is active, return true). - /// "commitCurrentEdit" is expected to return true - /// to indicate successful commit, false otherwise. - /// - return (currentEditController ? currentEditController.commitCurrentEdit() : true); - }; - - this.cancelCurrentEdit = function cancelCurrentEdit() { - /// - /// Invoke the "cancelCurrentEdit" method on the - /// editController that is active in this lock - /// instance (if no controller is active, do nothing). - /// Returns true if the edit was succesfully cancelled. - /// - return (currentEditController ? currentEditController.cancelCurrentEdit() : true); - }; - } // end of EditorLock function (class) +(function($) { + // Slick.Grid + $.extend(true, window, { + Slick: { + Grid: SlickGrid + } + }); + var scrollbarDimensions; // shared across all grids on this page ////////////////////////////////////////////////////////////////////////////////////////////// // SlickGrid class implementation (available as Slick.Grid) - /** @constructor */ + /** + * @constructor + * @param {Node} container Container node to create the grid in. + * @param {Array,Object} data An array of objects for databinding. + * @param {Array} columns An array of column definitions. + * @param {Object} options Grid options. + **/ function SlickGrid(container,data,columns,options) { /// /// Create and manage virtual grid in the specified $container, @@ -241,11 +80,11 @@ if (!jQuery.fn.drag) { toolTipMaxLength: null, formatterFactory: null, editorFactory: null, - cellHighlightCssClass: "highlighted", cellFlashingCssClass: "flashing", + selectedCellCssClass: "selected", multiSelect: true }, - gridData, gridDataGetLength, gridDataGetItem; + gridData; var columnDefaults = { name: "", @@ -283,8 +122,8 @@ if (!jQuery.fn.drag) { var headerColumnWidthDiff, headerColumnHeightDiff, cellWidthDiff, cellHeightDiff; // padding+border var absoluteColumnMinWidth; - var currentRow, currentCell; - var currentCellNode = null; + var activeRow, activeCell; + var activeCellNode = null; var currentEditor = null; var serializedEditorValue; var editController; @@ -298,10 +137,12 @@ if (!jQuery.fn.drag) { var prevScrollLeft = 0; var avgRowRenderTime = 10; - var selectedRows = []; - var selectedRowsLookup = {}; + var selectionModel; + + var plugins = []; + var cellCssClasses = {}; + var columnsById = {}; - var highlightedCells; var sortColumnId; var sortAsc = true; @@ -330,8 +171,6 @@ if (!jQuery.fn.drag) { $container = $(container); gridData = data; - gridDataGetLength = gridData.getLength || defaultGetLength; - gridDataGetItem = gridData.getItem || defaultGetItem; maxSupportedCssHeight = getMaxSupportedCssHeight(); @@ -394,7 +233,6 @@ if (!jQuery.fn.drag) { createColumnHeaders(); setupColumnSort(); - setupDragEvents(); createCssRules(); resizeAndRender(); @@ -402,13 +240,59 @@ if (!jQuery.fn.drag) { bindAncestorScrollEvents(); $viewport.bind("scroll.slickgrid", handleScroll); $container.bind("resize.slickgrid", resizeAndRender); - $canvas.bind("keydown.slickgrid", handleKeyDown); - $canvas.bind("click.slickgrid", handleClick); - $canvas.bind("dblclick.slickgrid", handleDblClick); - $canvas.bind("contextmenu.slickgrid", handleContextMenu); - $canvas.bind("mouseover.slickgrid", handleHover); - $headerScroller.bind("contextmenu.slickgrid", handleHeaderContextMenu); - $headerScroller.bind("click.slickgrid", handleHeaderClick); + $headerScroller + .bind("contextmenu.slickgrid", handleHeaderContextMenu) + .bind("click.slickgrid", handleHeaderClick); + + $canvas + .bind("keydown.slickgrid", handleKeyDown) + .bind("click.slickgrid", handleClick) + .bind("dblclick.slickgrid", handleDblClick) + .bind("contextmenu.slickgrid", handleContextMenu) + .bind("mouseover.slickgrid", handleHover) + .bind("draginit", handleDragInit) + .bind("dragstart", handleDragStart) + .bind("drag", handleDrag) + .bind("dragend", handleDragEnd); + } + + function registerPlugin(plugin) { + plugins.unshift(plugin); + plugin.init(self); + } + + function unregisterPlugin(plugin) { + for (var i = plugins.length; i >= 0; i--) { + if (plugins[i] === plugin) { + if (plugins[i].destroy) { + plugins[i].destroy(); + } + plugins.splice(i, 1); + break; + } + } + } + + function setSelectionModel(model) { + if (selectionModel) { + selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged); + if (selectionModel.destroy) { + selectionModel.destroy(); + } + } + + selectionModel = model; + selectionModel.init(self); + + selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged); + } + + function getSelectionModel() { + return selectionModel; + } + + function getCanvasNode() { + return $canvas[0]; } function measureScrollbar() { @@ -440,23 +324,6 @@ if (!jQuery.fn.drag) { } } - function defaultGetLength() { - /// - /// Default implementation of getLength method - /// returns the length of the array. - /// - /// Default implementation of getItem method - /// returns the item at specified position in - /// the array. - /// ") .appendTo(e) .bind("dragstart", function(e,dd) { - if (!options.editorLock.commitCurrentEdit()) { return false; } + if (!getEditorLock().commitCurrentEdit()) { return false; } pageX = e.pageX; $(this).parent().addClass("slick-header-column-active"); var shrinkLeewayOnRight = null, stretchLeewayOnRight = null; @@ -737,7 +600,7 @@ if (!jQuery.fn.drag) { newWidth = $(columnElements[j]).outerWidth(); if (c.previousWidth !== newWidth && c.rerenderOnResize) { - removeAllRows(); + invalidateAllRows(); } if (options.forceFitColumns) { c.width = Math.floor(c.width * (newWidth - c.previousWidth) / c.previousWidth) + c.width; @@ -749,134 +612,11 @@ if (!jQuery.fn.drag) { } } resizeCanvas(); - if (self.onColumnsResized) { - self.onColumnsResized(); - } + self.onColumnsResized.notify({}); }); }); } - function setupDragEvents() { - var MOVE_ROWS = 1; - var SELECT_CELLS = 2; - - function fixUpRange(range) { - var r1 = Math.min(range.start.row,range.end.row); - var c1 = Math.min(range.start.cell,range.end.cell); - var r2 = Math.max(range.start.row,range.end.row); - var c2 = Math.max(range.start.cell,range.end.cell); - return { - start: {row:r1, cell:c1}, - end: {row:r2, cell:c2} - }; - } - - $canvas - .bind("draginit", function(e,dd) { - var $cell = $(e.target).closest(".slick-cell"); - if ($cell.length === 0) { return false; } - if (parseInt($cell.parent().attr("row"), 10) >= gridDataGetLength()) - return false; - - var colDef = columns[getSiblingIndex($cell[0])]; - if (colDef.behavior == "move" || colDef.behavior == "selectAndMove") { - dd.mode = MOVE_ROWS; - } - else if (options.enableCellRangeSelection) { - dd.mode = SELECT_CELLS; - } - else - return false; - }) - .bind("dragstart", function(e,dd) { - if (!options.editorLock.commitCurrentEdit()) { return false; } - var row = parseInt($(e.target).closest(".slick-row").attr("row"), 10); - - if (dd.mode == MOVE_ROWS) { - if (!selectedRowsLookup[row]) { - setSelectedRows([row]); - } - - dd.selectionProxy = $("
      ") - .css("position", "absolute") - .css("zIndex", "99999") - .css("width", $(this).innerWidth()) - .css("height", options.rowHeight*selectedRows.length) - .appendTo($viewport); - - dd.guide = $("
      ") - .css("position", "absolute") - .css("zIndex", "99998") - .css("width", $(this).innerWidth()) - .css("top", -1000) - .appendTo($viewport); - - dd.insertBefore = -1; - } - - if (dd.mode == SELECT_CELLS) { - var start = getCellFromPoint(dd.startX - $canvas.offset().left, dd.startY - $canvas.offset().top); - if (!cellExists(start.row,start.cell)) - return false; - - dd.range = {start:start,end:{}}; - return $("
      ").appendTo($canvas); - } - }) - .bind("drag", function(e,dd) { - if (dd.mode == MOVE_ROWS) { - var top = e.pageY - $(this).offset().top; - dd.selectionProxy.css("top",top-5); - - var insertBefore = Math.max(0,Math.min(Math.round(top/options.rowHeight),gridDataGetLength())); - if (insertBefore !== dd.insertBefore) { - if (self.onBeforeMoveRows && self.onBeforeMoveRows(getSelectedRows(),insertBefore) === false) { - dd.guide.css("top", -1000); - dd.canMove = false; - } - else { - dd.guide.css("top",insertBefore*options.rowHeight); - dd.canMove = true; - } - dd.insertBefore = insertBefore; - } - } - - if (dd.mode == SELECT_CELLS) { - var end = getCellFromPoint(e.clientX - $canvas.offset().left, e.clientY - $canvas.offset().top); - if (!cellExists(end.row,end.cell)) - return; - - dd.range.end = end; - var r = fixUpRange(dd.range); - var from = getCellNodeBox(r.start.row,r.start.cell); - var to = getCellNodeBox(r.end.row,r.end.cell); - $(dd.proxy).css({ - top: from.top, - left: from.left, - height: to.bottom - from.top - 2, - width: to.right - from.left - 2 - }); - } - }) - .bind("dragend", function(e,dd) { - if (dd.mode == MOVE_ROWS) { - dd.guide.remove(); - dd.selectionProxy.remove(); - if (self.onMoveRows && dd.canMove) { - self.onMoveRows(getSelectedRows(),dd.insertBefore); - } - } - - if (dd.mode == SELECT_CELLS) { - $(dd.proxy).remove(); - - if (self.onCellRangeSelected) - self.onCellRangeSelected(fixUpRange(dd.range)); - } - }); - } - function measureCellPaddingAndBorder() { var tmp = $("").appendTo($headers); headerColumnWidthDiff = tmp.outerWidth() - tmp.width(); @@ -945,12 +685,15 @@ if (!jQuery.fn.drag) { } function destroy() { - options.editorLock.cancelCurrentEdit(); + getEditorLock().cancelCurrentEdit(); - if (self.onBeforeDestroy) - self.onBeforeDestroy(); + self.onBeforeDestroy.notify({}); - if (options.enableColumnReorder && $headers.sortable) + for (var i = 0; i < plugins.length; i++) { + unregisterPlugin(plugin); + } + + if (options.enableColumnReorder && $headers.sortable) $headers.sortable("destroy"); unbindAncestorScrollEvents(); @@ -965,6 +708,10 @@ if (!jQuery.fn.drag) { ////////////////////////////////////////////////////////////////////////////////////////////// // General + function getEditorLock() { + return options.editorLock; + } + function getEditController() { return editController; } @@ -991,7 +738,7 @@ if (!jQuery.fn.drag) { total = existingTotal; - removeAllRows(); + invalidateAllRows(); // shrink while (total > availWidth) { @@ -1052,35 +799,21 @@ if (!jQuery.fn.drag) { } } - function getSelectedRows() { - return selectedRows.concat(); - } + function handleSelectedRangesChanged(e, ranges) { + var hash = {}; - function setSelectedRows(rows) { - var i, row; - var lookup = {}; - for (i=0; i"); @@ -1223,7 +975,7 @@ if (!jQuery.fn.drag) { function cleanupRows(rangeToKeep) { for (var i in rowsCache) { - if (((i = parseInt(i, 10)) !== currentRow) && (i < rangeToKeep.top || i > rangeToKeep.bottom)) { + if (((i = parseInt(i, 10)) !== activeRow) && (i < rangeToKeep.top || i > rangeToKeep.bottom)) { removeRowFromCache(i); } } @@ -1231,19 +983,17 @@ if (!jQuery.fn.drag) { function invalidate() { updateRowCount(); - removeAllRows(); + invalidateAllRows(); render(); } - function removeAllRows() { + function invalidateAllRows() { if (currentEditor) { - makeSelectedCellNormal(); + makeActiveCellNormal(); + } + for (var row in rowsCache) { + removeRowFromCache(row); } - $canvas[0].innerHTML = ""; - rowsCache= {}; - postProcessedRows = {}; - counter_rows_removed += renderedRows; - renderedRows = 0; } function removeRowFromCache(row) { @@ -1257,46 +1007,37 @@ if (!jQuery.fn.drag) { counter_rows_removed++; } - function removeRows(rows) { - var i, rl, nl; + function invalidateRows(rows) { + var i, rl; if (!rows || !rows.length) { return; } scrollDir = 0; - var nodes = []; for (i=0, rl=rows.length; i 10 && nodes.length === renderedRows) { - removeAllRows(); - } - else { - for (i=0, nl=nodes.length; i= l) { removeRowFromCache(i); @@ -1434,7 +1175,7 @@ if (!jQuery.fn.drag) { } range.top = Math.max(0,range.top); - range.bottom = Math.min(options.enableAddRow ? gridDataGetLength() : gridDataGetLength() - 1,range.bottom); + range.bottom = Math.min(options.enableAddRow ? getDataLength() : getDataLength() - 1,range.bottom); return range; } @@ -1453,7 +1194,7 @@ if (!jQuery.fn.drag) { renderedRows++; rows.push(i); appendRowHtml(stringArray,i); - if (currentCellNode && currentRow === i) + if (activeCellNode && activeRow === i) needToReselectCell = true; counter_rows_rendered++; } @@ -1466,8 +1207,7 @@ if (!jQuery.fn.drag) { } if (needToReselectCell) { - currentCellNode = $(rowsCache[currentRow]).children().eq(currentCell)[0]; - setSelectedCell(currentCellNode,false); + setActiveCellInternal(getCellNode(activeRow,activeCell),false); } if (renderedRows - rowsBefore > 5) { @@ -1505,7 +1245,7 @@ if (!jQuery.fn.drag) { renderRows(rendered); postProcessFromRow = visible.top; - postProcessToRow = Math.min(options.enableAddRow ? gridDataGetLength() : gridDataGetLength() - 1, visible.bottom); + postProcessToRow = Math.min(options.enableAddRow ? getDataLength() : getDataLength() - 1, visible.bottom); startPostProcessing(); lastRenderedScrollTop = scrollTop; @@ -1537,7 +1277,7 @@ if (!jQuery.fn.drag) { page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph))); offset = Math.round(page * cj); if (oldOffset != offset) - removeAllRows(); + invalidateAllRows(); } if (h_render) @@ -1548,18 +1288,16 @@ if (!jQuery.fn.drag) { else h_render = setTimeout(render, 50); - if (self.onViewportChanged) { - self.onViewportChanged(); - } + self.onViewportChanged.notify({}); } function asyncPostProcessRows() { while (postProcessFromRow <= postProcessToRow) { var row = (scrollDir >= 0) ? postProcessFromRow++ : postProcessToRow--; var rowNode = rowsCache[row]; - if (!rowNode || postProcessedRows[row] || row>=gridDataGetLength()) { continue; } + if (!rowNode || postProcessedRows[row] || row>=getDataLength()) { continue; } - var d = gridDataGetItem(row), cellNodes = rowNode.childNodes; + var d = getDataItem(row), cellNodes = rowNode.childNodes; for (var i=0, j=0, l=columns.length; i= gridDataGetLength() || cell < 0 || cell >= columns.length); + return !(row < 0 || row >= getDataLength() || cell < 0 || cell >= columns.length); } function getCellFromPoint(x,y) { @@ -1869,7 +1567,7 @@ if (!jQuery.fn.drag) { var w = 0; for (var i=0; i= gridDataGetLength()) { + if (columns[cell].cannotTriggerInsert && row >= getDataLength()) { return false; } @@ -2020,22 +1706,19 @@ if (!jQuery.fn.drag) { return true; } - function makeSelectedCellNormal() { + function makeActiveCellNormal() { if (!currentEditor) { return; } - - if (self.onBeforeCellEditorDestroy) { - self.onBeforeCellEditorDestroy(currentEditor); - } + self.onBeforeCellEditorDestroy.notify({editor:currentEditor}); currentEditor.destroy(); currentEditor = null; - if (currentCellNode) { - $(currentCellNode).removeClass("editable invalid"); + if (activeCellNode) { + $(activeCellNode).removeClass("editable invalid"); - if (gridDataGetItem(currentRow)) { - var column = columns[currentCell]; - currentCellNode.innerHTML = getFormatter(column)(currentRow, currentCell, gridDataGetItem(currentRow)[column.field], column, gridDataGetItem(currentRow)); - invalidatePostProcessingResults(currentRow); + if (getDataItem(activeRow)) { + var column = columns[activeCell]; + activeCellNode.innerHTML = getFormatter(column)(activeRow, activeCell, getDataItem(activeRow)[column.field], column, getDataItem(activeRow)); + invalidatePostProcessingResults(activeRow); } } @@ -2043,40 +1726,40 @@ if (!jQuery.fn.drag) { // IE can't set focus to anything else correctly if ($.browser.msie) { clearTextSelection(); } - options.editorLock.deactivate(editController); + getEditorLock().deactivate(editController); } - function makeSelectedCellEditable() { - if (!currentCellNode) { return; } + function makeActiveCellEditable() { + if (!activeCellNode) { return; } if (!options.editable) { - throw "Grid : makeSelectedCellEditable : should never get called when options.editable is false"; + throw "Grid : makeActiveCellEditable : should never get called when options.editable is false"; } // cancel pending async call if there is one clearTimeout(h_editorLoader); - if (!isCellPotentiallyEditable(currentRow,currentCell)) { + if (!isCellPotentiallyEditable(activeRow,activeCell)) { return; } - if (self.onBeforeEditCell && self.onBeforeEditCell(currentRow,currentCell,gridDataGetItem(currentRow)) === false) { - focusOnCurrentCell(); + if (self.onBeforeEditCell.notify({row:activeRow, cell:activeCell,item:getDataItem(activeRow)}) === false) { + focusOnActiveCell(); return; } - options.editorLock.activate(editController); - $(currentCellNode).addClass("editable"); + getEditorLock().activate(editController); + $(activeCellNode).addClass("editable"); - currentCellNode.innerHTML = ""; + activeCellNode.innerHTML = ""; - var columnDef = columns[currentCell]; - var item = gridDataGetItem(currentRow); + var columnDef = columns[activeCell]; + var item = getDataItem(activeRow); currentEditor = new (getEditor(columnDef))({ grid: self, gridPosition: absBox($container[0]), - position: absBox(currentCellNode), - container: currentCellNode, + position: absBox(activeCellNode), + container: activeCellNode, column: columnDef, item: item || {}, commitChanges: commitEditAndSetFocus, @@ -2089,14 +1772,14 @@ if (!jQuery.fn.drag) { serializedEditorValue = currentEditor.serializeValue(); if (currentEditor.position) - handleCurrentCellPositionChange(); + handleActiveCellPositionChange(); } function commitEditAndSetFocus() { // if the commit fails, it would do so due to a validation error // if so, do not steal the focus from the editor - if (options.editorLock.commitCurrentEdit()) { - focusOnCurrentCell(); + if (getEditorLock().commitCurrentEdit()) { + focusOnActiveCell(); if (options.autoEdit) { navigateDown(); @@ -2105,8 +1788,8 @@ if (!jQuery.fn.drag) { } function cancelEditAndSetFocus() { - if (options.editorLock.cancelCurrentEdit()) { - focusOnCurrentCell(); + if (getEditorLock().cancelCurrentEdit()) { + focusOnActiveCell(); } } @@ -2140,25 +1823,22 @@ if (!jQuery.fn.drag) { return box; } - function getCurrentCellPosition(){ - return absBox(currentCellNode); + function getActiveCellPosition(){ + return absBox(activeCellNode); } function getGridPosition(){ return absBox($container[0]) } - function handleCurrentCellPositionChange() { - if (!currentCellNode) return; + function handleActiveCellPositionChange() { + if (!activeCellNode) return; var cellBox; - if (self.onCurrentCellPositionChanged){ - cellBox = getCurrentCellPosition(); - self.onCurrentCellPositionChanged(cellBox); - } + self.onActiveCellPositionChanged.notify({}); if (currentEditor) { - cellBox = cellBox || getCurrentCellPosition(); + cellBox = cellBox || getActiveCellPosition(); if (currentEditor.show && currentEditor.hide) { if (!cellBox.visible) currentEditor.hide(); @@ -2175,15 +1855,15 @@ if (!jQuery.fn.drag) { return currentEditor; } - function getCurrentCell() { - if (!currentCellNode) + function getActiveCell() { + if (!activeCellNode) return null; else - return {row: currentRow, cell: currentCell}; + return {row: activeRow, cell: activeCell}; } - function getCurrentCellNode() { - return currentCellNode; + function getActiveCellNode() { + return activeCellNode; } function scrollRowIntoView(row, doPaging) { @@ -2204,21 +1884,21 @@ if (!jQuery.fn.drag) { } function gotoDir(dy, dx, rollover) { - if (!currentCellNode || !options.enableCellNavigation) { return; } - if (!options.editorLock.commitCurrentEdit()) { return; } + if (!activeCellNode || !options.enableCellNavigation) { return; } + if (!getEditorLock().commitCurrentEdit()) { return; } function selectableCellFilter() { return !columns[getSiblingIndex(this)].unselectable } - var nextRow = rowsCache[currentRow + dy]; - var nextCell = (nextRow && currentCell + dx >= 0) - ? $(nextRow).children().eq(currentCell+dx).filter(selectableCellFilter) + var nextRow = rowsCache[activeRow + dy]; + var nextCell = (nextRow && activeCell + dx >= 0) + ? $(nextRow).children().eq(activeCell+dx).filter(selectableCellFilter) : null; if (nextCell && !nextCell.length) { var nodes = $(nextRow).children() - .filter(function(index) { return (dx>0) ? index > currentCell + dx : index < currentCell + dx }) + .filter(function(index) { return (dx>0) ? index > activeCell + dx : index < activeCell + dx }) .filter(selectableCellFilter); if (nodes && nodes.length) { @@ -2230,7 +1910,7 @@ if (!jQuery.fn.drag) { if (rollover && dy === 0 && !(nextRow && nextCell && nextCell.length)) { if (!nextCell || !nextCell.length) { - nextRow = rowsCache[currentRow + dy + ((dx>0)?1:-1)]; + nextRow = rowsCache[activeRow + dy + ((dx>0)?1:-1)]; var nodes = $(nextRow).children().filter(selectableCellFilter); if (dx > 0) { nextCell = nextRow @@ -2248,39 +1928,67 @@ if (!jQuery.fn.drag) { if (nextRow && nextCell && nextCell.length) { // if selecting the 'add new' row, start editing right away var row = parseInt($(nextRow).attr("row"), 10); - var isAddNewRow = (row == defaultGetLength()); + var isAddNewRow = (row == getDataLength()); scrollRowIntoView(row,!isAddNewRow); - setSelectedCellAndRow(nextCell[0], isAddNewRow || options.autoEdit); + setActiveCellInternal(nextCell[0], isAddNewRow || options.autoEdit); // if no editor was created, set the focus back on the cell if (!currentEditor) { - focusOnCurrentCell(); + focusOnActiveCell(); } } else { - focusOnCurrentCell(); + focusOnActiveCell(); + } + } + + function getCellNode(row, cell) { + if (rowsCache[row]) { + return $(rowsCache[row]).children().eq(cell)[0]; } + return null; + } + + function setActiveCell(row, cell) { + if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0) { + return; + } + + if (!options.enableCellNavigation) { + return; + } + + scrollRowIntoView(row,false); + setActiveCellInternal(getCellNode(row,cell),false); + } + + function canCellBeSelected(row,cell) { + return row < getDataLength() + && row >= 0 + && cell < columns.length + && cell >= 0 + && !columns[cell].unselectable; } function gotoCell(row, cell, forceEdit) { - if (row > gridDataGetLength() || row < 0 || cell >= columns.length || cell < 0) { return; } + if (row > getDataLength() || row < 0 || cell >= columns.length || cell < 0) { return; } if (!options.enableCellNavigation || columns[cell].unselectable) { return; } - if (!options.editorLock.commitCurrentEdit()) { return; } + if (!getEditorLock().commitCurrentEdit()) { return; } scrollRowIntoView(row,false); var newCell = null; if (!columns[cell].unselectable) { - newCell = $(rowsCache[row]).children().eq(cell)[0]; + newCell = getCellNode(row,cell); } // if selecting the 'add new' row, start editing right away - setSelectedCellAndRow(newCell, forceEdit || (row === gridDataGetLength()) || options.autoEdit); + setActiveCellInternal(newCell, forceEdit || (row === getDataLength()) || options.autoEdit); // if no editor was created, set the focus back on the cell if (!currentEditor) { - focusOnCurrentCell(); + focusOnActiveCell(); } } @@ -2312,18 +2020,18 @@ if (!jQuery.fn.drag) { // IEditor implementation for the editor lock function commitCurrentEdit() { - var item = gridDataGetItem(currentRow); - var column = columns[currentCell]; + var item = getDataItem(activeRow); + var column = columns[activeCell]; if (currentEditor) { if (currentEditor.isValueChanged()) { var validationResults = currentEditor.validate(); if (validationResults.valid) { - if (currentRow < gridDataGetLength()) { + if (activeRow < getDataLength()) { var editCommand = { - row: currentRow, - cell: currentCell, + row: activeRow, + cell: activeCell, editor: currentEditor, serializedValue: currentEditor.serializeValue(), prevSerializedValue: serializedEditorValue, @@ -2338,53 +2046,92 @@ if (!jQuery.fn.drag) { }; if (options.editCommandHandler) { - makeSelectedCellNormal(); + makeActiveCellNormal(); options.editCommandHandler(item,column,editCommand); } else { editCommand.execute(); - makeSelectedCellNormal(); + makeActiveCellNormal(); } - if (self.onCellChange) { - self.onCellChange(currentRow,currentCell,item); - } + self.onCellChange.notify({ + row: activeRow, + cell: activeCell, + item: item + }); } - else if (self.onAddNewRow) { + else { var newItem = {}; currentEditor.applyValue(newItem,currentEditor.serializeValue()); - makeSelectedCellNormal(); - self.onAddNewRow(newItem,column); + makeActiveCellNormal(); + self.onAddNewRow.notify({item:newItem, column:column}); } // check whether the lock has been re-acquired by event handlers - return !options.editorLock.isActive(); + return !getEditorLock().isActive(); } else { // TODO: remove and put in onValidationError handlers in examples - $(currentCellNode).addClass("invalid"); - $(currentCellNode).stop(true,true).effect("highlight", {color:"red"}, 300); - - if (self.onValidationError) { - self.onValidationError(currentCellNode, validationResults, currentRow, currentCell, column); - } + $(activeCellNode).addClass("invalid"); + $(activeCellNode).stop(true,true).effect("highlight", {color:"red"}, 300); + + self.onValidationError.notify({ + cellNode: activeCellNode, + validationResults: validationResults, + row: activeRow, + cell: activeCell, + column: column + }); currentEditor.focus(); return false; } } - makeSelectedCellNormal(); + makeActiveCellNormal(); } return true; } function cancelCurrentEdit() { - makeSelectedCellNormal(); + makeActiveCellNormal(); return true; } + function rangesToRows(ranges) { + var rows = []; + for (var i = 0; i < ranges.length; i++) { + for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) { + rows.push(j); + } + } + return rows; + } + + function rowsToRanges(rows) { + var ranges = []; + var lastCell = columns.length - 1; + for (var i = 0; i < rows.length; i++) { + ranges.push(new Slick.Range(rows[i], 0, rows[i], lastCell)); + } + return ranges; + } + + function getSelectedRows() { + if (!selectionModel) { + throw "Selection model is not set"; + } + return rangesToRows(selectionModel.getSelectedRanges()); + } + + function setSelectedRows(rows) { + if (!selectionModel) { + throw "Selection model is not set"; + } + selectionModel.setSelectedRanges(rowsToRanges(rows)); + } + ////////////////////////////////////////////////////////////////////////////////////////////// // Debug @@ -2410,95 +2157,104 @@ if (!jQuery.fn.drag) { return eval(expr); }; - init(); - - ////////////////////////////////////////////////////////////////////////////////////////////// // Public API $.extend(this, { - "slickGridVersion": "1.4.3", + "slickGridVersion": "2.0a1", // Events - "onSort": null, - "onHeaderContextMenu": null, - "onClick": null, - "onDblClick": null, - "onContextMenu": null, - "onKeyDown": null, - "onAddNewRow": null, - "onValidationError": null, - "onViewportChanged": null, - "onSelectedRowsChanged": null, - "onColumnsReordered": null, - "onColumnsResized": null, - "onBeforeMoveRows": null, - "onMoveRows": null, - "onCellChange": null, - "onBeforeEditCell": null, - "onBeforeCellEditorDestroy": null, - "onBeforeDestroy": null, - "onCurrentCellChanged": null, - "onCurrentCellPositionChanged": null, - "onCellRangeSelected": null, + "onSort": new Slick.Event(), + "onHeaderContextMenu": new Slick.Event(), + "onClick": new Slick.Event(), + "onDblClick": new Slick.Event(), + "onContextMenu": new Slick.Event(), + "onKeyDown": new Slick.Event(), + "onAddNewRow": new Slick.Event(), + "onValidationError": new Slick.Event(), + "onViewportChanged": new Slick.Event(), + "onColumnsReordered": new Slick.Event(), + "onColumnsResized": new Slick.Event(), + "onCellChange": new Slick.Event(), + "onBeforeEditCell": new Slick.Event(), + "onBeforeCellEditorDestroy": new Slick.Event(), + "onBeforeDestroy": new Slick.Event(), + "onActiveCellChanged": new Slick.Event(), + "onActiveCellPositionChanged": new Slick.Event(), + "onDragInit": new Slick.Event(), + "onDragStart": new Slick.Event(), + "onDrag": new Slick.Event(), + "onDragEnd": new Slick.Event(), + "onSelectedRowsChanged": new Slick.Event(), // Methods - "getColumns": getColumns, - "setColumns": setColumns, - "getOptions": getOptions, - "setOptions": setOptions, - "getData": getData, - "setData": setData, - "destroy": destroy, - "getColumnIndex": getColumnIndex, - "autosizeColumns": autosizeColumns, - "updateCell": updateCell, - "updateRow": updateRow, - "removeRow": removeRow, - "removeRows": removeRows, - "removeAllRows": removeAllRows, - "render": render, - "invalidate": invalidate, - "setHighlightedCells": setHighlightedCells, - "flashCell": flashCell, - "getViewport": getVisibleRange, - "resizeCanvas": resizeCanvas, - "updateRowCount": updateRowCount, - "getCellFromPoint": getCellFromPoint, - "getCellFromEvent": getCellFromEvent, - "getCurrentCell": getCurrentCell, - "getCurrentCellNode": getCurrentCellNode, - "resetCurrentCell": resetCurrentCell, - "navigatePrev": navigatePrev, - "navigateNext": navigateNext, - "navigateUp": navigateUp, - "navigateDown": navigateDown, - "navigateLeft": navigateLeft, - "navigateRight": navigateRight, - "gotoCell": gotoCell, - "editCurrentCell": makeSelectedCellEditable, - "getCellEditor": getCellEditor, - "scrollRowIntoView": scrollRowIntoView, - "getSelectedRows": getSelectedRows, - "setSelectedRows": setSelectedRows, - "getSecondaryHeaderRow": getSecondaryHeaderRow, - "showSecondaryHeaderRow": showSecondaryHeaderRow, - "hideSecondaryHeaderRow": hideSecondaryHeaderRow, - "setSortColumn": setSortColumn, - "getCurrentCellPosition" : getCurrentCellPosition, - "getGridPosition": getGridPosition, + "registerPlugin": registerPlugin, + "unregisterPlugin": unregisterPlugin, + "getColumns": getColumns, + "setColumns": setColumns, + "getColumnIndex": getColumnIndex, + "setSortColumn": setSortColumn, + "autosizeColumns": autosizeColumns, + "getOptions": getOptions, + "setOptions": setOptions, + "getData": getData, + "getDataLength": getDataLength, + "getDataItem": getDataItem, + "setData": setData, + "getSelectionModel": getSelectionModel, + "setSelectionModel": setSelectionModel, + "getSelectedRows": getSelectedRows, + "setSelectedRows": setSelectedRows, + + "render": render, + "invalidate": invalidate, + "invalidateRow": invalidateRow, + "invalidateRows": invalidateRows, + "invalidateAllRows": invalidateAllRows, + "updateCell": updateCell, + "updateRow": updateRow, + "getViewport": getVisibleRange, + "resizeCanvas": resizeCanvas, + "updateRowCount": updateRowCount, + "scrollRowIntoView": scrollRowIntoView, + "getCanvasNode": getCanvasNode, + + "getCellFromPoint": getCellFromPoint, + "getCellFromEvent": getCellFromEvent, + "getActiveCell": getActiveCell, + "setActiveCell": setActiveCell, + "getActiveCellNode": getActiveCellNode, + "getActiveCellPosition": getActiveCellPosition, + "resetActiveCell": resetActiveCell, + "editActiveCell": makeActiveCellEditable, + "getCellEditor": getCellEditor, + "getCellNode": getCellNode, + "getCellNodeBox": getCellNodeBox, + "canCellBeSelected": canCellBeSelected, + "navigatePrev": navigatePrev, + "navigateNext": navigateNext, + "navigateUp": navigateUp, + "navigateDown": navigateDown, + "navigateLeft": navigateLeft, + "navigateRight": navigateRight, + "gotoCell": gotoCell, + "getSecondaryHeaderRow": getSecondaryHeaderRow, + "showSecondaryHeaderRow": showSecondaryHeaderRow, + "hideSecondaryHeaderRow": hideSecondaryHeaderRow, + "getGridPosition": getGridPosition, + + "flashCell": flashCell, + "addCellCssStyles": addCellCssStyles, + "setCellCssStyles": setCellCssStyles, + "removeCellCssStyles": removeCellCssStyles, + + "destroy": destroy, // IEditor implementation - "getEditController": getEditController + "getEditorLock": getEditorLock, + "getEditController": getEditController }); - } - // Slick.Grid - $.extend(true, window, { - Slick: { - Grid: SlickGrid, - EditorLock: EditorLock, - GlobalEditorLock: new EditorLock() - } - }); + init(); + } }(jQuery)); \ No newline at end of file diff --git a/slick.remotemodel.js b/slick.remotemodel.js index 23de6b6..372731a 100644 --- a/slick.remotemodel.js +++ b/slick.remotemodel.js @@ -1,23 +1,3 @@ -/*** - * A simple observer pattern implementation. - */ -function EventHelper() { - this.handlers = []; - - this.subscribe = function(fn) { - this.handlers.push(fn); - }; - - this.notify = function(args) { - for (var i = 0; i < this.handlers.length; i++) { - this.handlers[i].call(this, args); - } - }; - - return this; -} - - (function($) { /*** * A sample AJAX data store implementation. @@ -33,11 +13,10 @@ function EventHelper() { var sortdir = 1; var h_request = null; var req = null; // ajax request - var req_page; // events - var onDataLoading = new EventHelper(); - var onDataLoaded = new EventHelper(); + var onDataLoading = new Slick.Event(); + var onDataLoaded = new Slick.Event(); function init() { @@ -83,15 +62,11 @@ function EventHelper() { if (fromPage > toPage || ((fromPage == toPage) && data[fromPage*PAGESIZE] !== undefined)) { // TODO: lookeahead - - //if () - return; } var url = "http://services.digg.com/search/stories?query=" + searchstr + "&offset=" + (fromPage * PAGESIZE) + "&count=" + (((toPage - fromPage) * PAGESIZE) + PAGESIZE) + "&appkey=http://slickgrid.googlecode.com&type=javascript"; - switch (sortcol) { case "diggs": url += ("&sort=" + ((sortdir>0)?"digg_count-asc":"digg_count-desc")); @@ -183,4 +158,4 @@ function EventHelper() { // Slick.Data.RemoteModel $.extend(true, window, { Slick: { Data: { RemoteModel: RemoteModel }}}); -})(jQuery); +})(jQuery); \ No newline at end of file diff --git a/tests/dataview/dataview.js b/tests/dataview/dataview.js index 1b9c7aa..492546d 100644 --- a/tests/dataview/dataview.js +++ b/tests/dataview/dataview.js @@ -100,17 +100,17 @@ test("requires a unique id on objects (alternative idProperty)", function() { test("events fired on setItems", function() { var count = 0; var dv = new Slick.Data.DataView(); - dv.onRowsChanged.subscribe(function() { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); same(args.previous, 0, "previous arg"); same(args.current, 2, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); same(args.pageSize, 0, "pageSize arg"); same(args.pageNum, 0, "pageNum arg"); @@ -161,18 +161,18 @@ test("refresh fires after resume", function() { dv.refresh(); var count = 0; - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [0,1], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); same(args.previous, 0, "previous arg"); same(args.current, 2, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); same(args.pageSize, 0, "pageSize arg"); same(args.pageNum, 0, "pageNum arg"); @@ -322,18 +322,18 @@ test("applied immediately", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [0], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); same(args.previous, 3, "previous arg"); same(args.current, 1, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); same(args.pageSize, 0, "pageSize arg"); same(args.pageNum, 0, "pageNum arg"); @@ -356,18 +356,18 @@ test("re-applied on refresh", function() { same(dv.rows.length, 3, "nothing is filtered out"); assertConsistency(dv); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [0], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); same(args.previous, 3, "previous arg"); same(args.current, 1, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); same(args.pageSize, 0, "pageSize arg"); same(args.pageNum, 0, "pageNum arg"); @@ -401,16 +401,16 @@ test("all", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(false, "onRowsChanged called"); }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); same(args.previous, 3, "previous arg"); same(args.current, 0, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); same(args.pageSize, 0, "pageSize arg"); same(args.pageNum, 0, "pageNum arg"); @@ -432,18 +432,18 @@ test("all then none", function() { dv.setFilter(function(o) { return filterResult }); same(dv.rows.length, 0, "all rows are filtered out"); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [0,1,2], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); same(args.previous, 0, "previous arg"); same(args.current, 3, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); same(args.pageSize, 0, "pageSize arg"); same(args.pageNum, 0, "pageNum arg"); @@ -465,15 +465,15 @@ test("basic", function() { var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [1], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(false, "onRowCountChanged called"); }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(false, "onPagingInfoChanged called"); }); @@ -487,13 +487,13 @@ test("updating an item not passing the filter", function() { var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2},{id:3,val:1337}]); dv.setFilter(function(o) { return o["val"] !== 1337 }); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(false, "onRowsChanged called"); }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(false, "onRowCountChanged called"); }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(false, "onPagingInfoChanged called"); }); dv.updateItem(3,{id:3,val:1337}); @@ -506,18 +506,18 @@ test("updating an item to pass the filter", function() { var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2},{id:3,val:1337}]); dv.setFilter(function(o) { return o["val"] !== 1337 }); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [3], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 3, "previous arg"); equal(args.current, 4, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); same(args.pageSize, 0, "pageSize arg"); same(args.pageNum, 0, "pageNum arg"); @@ -535,17 +535,17 @@ test("updating an item to not pass the filter", function() { var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2},{id:3,val:3}]); dv.setFilter(function(o) { return o["val"] !== 1337 }); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { console.log(args) ok(false, "onRowsChanged called"); }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 4, "previous arg"); equal(args.current, 3, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); same(args.pageSize, 0, "pageSize arg"); same(args.pageNum, 0, "pageNum arg"); @@ -587,18 +587,18 @@ test("basic", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [3], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 3, "previous arg"); equal(args.current, 4, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); equal(args.pageSize, 0, "pageSize arg"); equal(args.pageNum, 0, "pageNum arg"); @@ -616,13 +616,13 @@ test("add an item not passing the filter", function() { var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); dv.setFilter(function(o) { return o["val"] !== 1337 }); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(false, "onRowsChanged called"); }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(false, "onRowCountChanged called"); }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(false, "onPagingInfoChanged called"); }); dv.addItem({id:3,val:1337}); @@ -658,18 +658,18 @@ test("insert at the beginning", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [0,1,2,3], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 3, "previous arg"); equal(args.current, 4, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); equal(args.pageSize, 0, "pageSize arg"); equal(args.pageNum, 0, "pageNum arg"); @@ -688,18 +688,18 @@ test("insert in the middle", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [2,3], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 3, "previous arg"); equal(args.current, 4, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); equal(args.pageSize, 0, "pageSize arg"); equal(args.pageNum, 0, "pageNum arg"); @@ -718,18 +718,18 @@ test("insert at the end", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [3], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 3, "previous arg"); equal(args.current, 4, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); equal(args.pageSize, 0, "pageSize arg"); equal(args.pageNum, 0, "pageNum arg"); @@ -802,18 +802,18 @@ test("delete at the beginning", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:05,val:0},{id:15,val:1},{id:25,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [0,1], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 3, "previous arg"); equal(args.current, 2, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); equal(args.pageSize, 0, "pageSize arg"); equal(args.pageNum, 0, "pageNum arg"); @@ -831,18 +831,18 @@ test("delete in the middle", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:05,val:0},{id:15,val:1},{id:25,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, [1], "args"); count++; }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 3, "previous arg"); equal(args.current, 2, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); equal(args.pageSize, 0, "pageSize arg"); equal(args.pageNum, 0, "pageNum arg"); @@ -860,16 +860,16 @@ test("delete at the end", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:05,val:0},{id:15,val:1},{id:25,val:2}]); - dv.onRowsChanged.subscribe(function(args) { + dv.onRowsChanged.subscribe(function(e,args) { ok(false, "onRowsChanged called"); }); - dv.onRowCountChanged.subscribe(function(args) { + dv.onRowCountChanged.subscribe(function(e,args) { ok(true, "onRowCountChanged called"); equal(args.previous, 3, "previous arg"); equal(args.current, 2, "current arg"); count++; }); - dv.onPagingInfoChanged.subscribe(function(args) { + dv.onPagingInfoChanged.subscribe(function(e,args) { ok(true, "onPagingInfoChanged called"); equal(args.pageSize, 0, "pageSize arg"); equal(args.pageNum, 0, "pageNum arg"); diff --git a/tests/dataview/index.html b/tests/dataview/index.html index 339d3d9..05d1684 100644 --- a/tests/dataview/index.html +++ b/tests/dataview/index.html @@ -19,7 +19,8 @@

      - + + diff --git a/tests/grid/grid.js b/tests/grid/grid.js index aab783e..5106a20 100755 --- a/tests/grid/grid.js +++ b/tests/grid/grid.js @@ -43,7 +43,7 @@ for (var i=0; i - + diff --git a/tests/model benchmarks.html b/tests/model benchmarks.html index 2599e04..42632f5 100644 --- a/tests/model benchmarks.html +++ b/tests/model benchmarks.html @@ -7,7 +7,8 @@ - + + + @@ -82,7 +83,7 @@ // initialize the grid - grid = new Slick.Grid($("#myGrid"), data, columns, options); + grid = new Slick.Grid("#myGrid", data, columns, options); $grid = $("#myGrid div.grid-canvas").parent(); }); From 17b1bb8f3c43022ee6aec89dcab185cd368b8785 Mon Sep 17 00:00:00 2001 From: mleibman Date: Fri, 26 Nov 2010 20:22:55 -0800 Subject: [PATCH 0293/1043] Fixed the onDragInit event handlers interfering with each other on click. Added CellRangeSelector and refactored CellSelectionModel to make use of it. Added a sample FormulaEditor cell editor that uses CellRangeSelector to let the user drag-select a range of cells and have them appended to the currently edited cell. --- examples/example3-editing.html | 45 +++++++++- plugins/slick.cellrangeselector.js | 127 ++++++++++++++++++++++++++++ plugins/slick.cellselectionmodel.js | 117 +++++-------------------- plugins/slick.rowmovemanager.js | 20 +---- slick.editors.js | 8 ++ slick.grid.js | 2 - 6 files changed, 204 insertions(+), 115 deletions(-) create mode 100644 plugins/slick.cellrangeselector.js diff --git a/examples/example3-editing.html b/examples/example3-editing.html index 9dc8011..bad4149 100644 --- a/examples/example3-editing.html +++ b/examples/example3-editing.html @@ -42,6 +42,8 @@

      Options:

      + + @@ -58,7 +60,7 @@

      Options:

      var columns = [ {id:"title", name:"Title", field:"title", width:120, cssClass:"cell-title", editor:TextCellEditor, validator:requiredFieldValidator}, {id:"desc", name:"Description", field:"description", width:100, editor:LongTextCellEditor}, - {id:"duration", name:"Duration", field:"duration", editor:TextCellEditor}, + {id:"duration", name:"Duration", field:"duration", editor:FormulaEditor}, {id:"%", name:"% Complete", field:"percentComplete", width:80, resizable:false, formatter:GraphicalPercentCompleteCellFormatter, editor:PercentCompleteCellEditor}, {id:"start", name:"Start", field:"start", minWidth:60, editor:DateCellEditor}, {id:"finish", name:"Finish", field:"finish", minWidth:60, editor:DateCellEditor}, @@ -72,6 +74,43 @@

      Options:

      autoEdit: false }; + + /*** + * A proof-of-concept cell editor with Excel-like range selection and insertion. + */ + function FormulaEditor(args) { + var _self = this; + var _editor = new TextCellEditor(args); + var _selector; + + $.extend(this, _editor); + + function init() { + // register a plugin to select a range and append it to the textbox + // since events are fired in reverse order (most recently added are executed first), + // this will override other plugins like moverows or selection model and will + // not require the grid to not be in the edit mode + _selector = new Slick.CellRangeSelector(); + _selector.onCellRangeSelected.subscribe(_self.handleCellRangeSelected); + args.grid.registerPlugin(_selector); + } + + this.destroy = function() { + _selector.onCellRangeSelected.unsubscribe(_self.handleCellRangeSelected); + grid.unregisterPlugin(_selector); + _editor.destroy(); + }; + + this.handleCellRangeSelected = function(e, args) { + _editor.setValue(_editor.getValue() + args.range); + }; + + + init(); + } + + + $(function() { for (var i=0; i<500; i++) { @@ -88,6 +127,10 @@

      Options:

      grid = new Slick.Grid("#myGrid", data, columns, options); + //grid.registerPlugin(new Slick.CellRangeSelector()); + + grid.setSelectionModel(new Slick.CellSelectionModel()); + grid.onAddNewRow.subscribe(function(e, args) { var item = args.item; var column = args.column; diff --git a/plugins/slick.cellrangeselector.js b/plugins/slick.cellrangeselector.js new file mode 100644 index 0000000..ade3135 --- /dev/null +++ b/plugins/slick.cellrangeselector.js @@ -0,0 +1,127 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "CellRangeSelector": CellRangeSelector + } + }); + + + function CellRangeSelector(options) { + var _grid; + var _canvas; + var _dragging; + var _self = this; + var _defaults = { + selectionCss: { + "border": "2px dashed blue" + } + }; + + + function init(grid) { + options = $.extend(true, {}, _defaults, options); + _grid = grid; + _canvas = _grid.getCanvasNode(); + _grid.onDragStart.subscribe(handleDragStart); + _grid.onDrag.subscribe(handleDrag); + _grid.onDragEnd.subscribe(handleDragEnd); + } + + function destroy() { + _grid.onDragStart.unsubscribe(handleDragStart); + _grid.onDrag.unsubscribe(handleDrag); + _grid.onDragEnd.unsubscribe(handleDragEnd); + } + + function fixUpRange(range) { + var r1 = Math.min(range.start.row,range.end.row); + var c1 = Math.min(range.start.cell,range.end.cell); + var r2 = Math.max(range.start.row,range.end.row); + var c2 = Math.max(range.start.cell,range.end.cell); + return { + start: {row:r1, cell:c1}, + end: {row:r2, cell:c2} + }; + } + + function handleDragStart(e,dd) { + var cell = _grid.getCellFromEvent(e); + if (_self.onBeforeCellRangeSelected.notify(cell) !== false) { + if (_grid.canCellBeSelected(cell.row,cell.cell)) { + _dragging = true; + e.stopImmediatePropagation(); + } + } + if (!_dragging) { + return; + } + + var start = _grid.getCellFromPoint( + dd.startX - $(_canvas).offset().left, + dd.startY - $(_canvas).offset().top); + + dd.range = {start:start,end:{}}; + + // TODO: use a decorator + return $("
      ", {css: options.selectionCss}) + .css("position", "absolute") + .appendTo(_canvas); + } + + function handleDrag(e,dd) { + if (!_dragging) { + return; + } + + e.stopImmediatePropagation(); + + var end = _grid.getCellFromPoint( + e.pageX - $(_canvas).offset().left, + e.pageY - $(_canvas).offset().top); + + if (!_grid.canCellBeSelected(end.row,end.cell)) { + return; + } + + dd.range.end = end; + var r = fixUpRange(dd.range); + var from = _grid.getCellNodeBox(r.start.row,r.start.cell); + var to = _grid.getCellNodeBox(r.end.row,r.end.cell); + + $(dd.proxy).css({ + top: from.top - 1, + left: from.left - 1, + height: to.bottom - from.top - 2, + width: to.right - from.left - 2 + }); + } + + function handleDragEnd(e,dd) { + if (!_dragging) { + return; + } + + _dragging = false; + e.stopImmediatePropagation(); + $(dd.proxy).remove(); + + _self.onCellRangeSelected.notify({ + range: new Slick.Range( + dd.range.start.row, + dd.range.start.cell, + dd.range.end.row, + dd.range.end.cell + ) + }); + } + + $.extend(this, { + "init": init, + "destroy": destroy, + + "onBeforeCellRangeSelected": new Slick.Event(), + "onCellRangeSelected": new Slick.Event() + }); + } +})(jQuery); \ No newline at end of file diff --git a/plugins/slick.cellselectionmodel.js b/plugins/slick.cellselectionmodel.js index 0407de1..d1e68da 100644 --- a/plugins/slick.cellselectionmodel.js +++ b/plugins/slick.cellselectionmodel.js @@ -11,29 +11,27 @@ var _grid; var _canvas; var _ranges = []; - var _dragging; var _self = this; - - function returnFalse() { - return false; - } + var _selector = new Slick.CellRangeSelector({ + "selectionCss": { + "border": "2px solid black" + } + }); function init(grid) { _grid = grid; _canvas = _grid.getCanvasNode(); _grid.onActiveCellChanged.subscribe(handleActiveCellChange); - _grid.onDragInit.subscribe(handleDragInit); - _grid.onDragStart.subscribe(handleDragStart); - _grid.onDrag.subscribe(handleDrag); - _grid.onDragEnd.subscribe(handleDragEnd); + grid.registerPlugin(_selector); + _selector.onCellRangeSelected.subscribe(handleCellRangeSelected); + _selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected); } function destroy() { _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange); - _grid.onDragInit.unsubscribe(handleDragInit); - _grid.onDragStart.unsubscribe(handleDragStart); - _grid.onDrag.unsubscribe(handleDrag); - _grid.onDragEnd.unsubscribe(handleDragEnd); + _selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected); + _selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected); + _grid.unregisterPlugin(_selector); } function removeInvalidRanges(ranges) { @@ -51,99 +49,26 @@ function setSelectedRanges(ranges) { _ranges = removeInvalidRanges(ranges); - _self.onSelectedRangesChanged.notify(_ranges); } + _self.onSelectedRangesChanged.notify(_ranges); + } function getSelectedRanges() { return _ranges; } - function fixUpRange(range) { - var r1 = Math.min(range.start.row,range.end.row); - var c1 = Math.min(range.start.cell,range.end.cell); - var r2 = Math.max(range.start.row,range.end.row); - var c2 = Math.max(range.start.cell,range.end.cell); - return { - start: {row:r1, cell:c1}, - end: {row:r2, cell:c2} - }; - } - - function handleDragInit(e,dd) { - var cell = _grid.getCellFromEvent(e); - - if (!_grid.getEditorLock().isActive()) { - if (_grid.canCellBeSelected(cell.row,cell.cell)/* && e.ctrlKey*/) { - _dragging = true; - e.stopImmediatePropagation(); - } - } - } - - function handleDragStart(e,dd) { - if (!_dragging) { - return; - } - - var start = _grid.getCellFromPoint( - dd.startX - $(_canvas).offset().left, - dd.startY - $(_canvas).offset().top); - - e.stopImmediatePropagation(); - - dd.range = {start:start,end:{}}; - - return $("
      ").appendTo(_canvas); - } - - function handleDrag(e,dd) { - if (!_dragging) { - return; - } - - e.stopImmediatePropagation(); - - var end = _grid.getCellFromPoint( - e.pageX - $(_canvas).offset().left, - e.pageY - $(_canvas).offset().top); - - if (!_grid.canCellBeSelected(end.row,end.cell)) { - return; + function handleBeforeCellRangeSelected(e, args) { + if (_grid.getEditorLock().isActive()) { + e.stopPropagation(); + return false; } - - dd.range.end = end; - var r = fixUpRange(dd.range); - var from = _grid.getCellNodeBox(r.start.row,r.start.cell); - var to = _grid.getCellNodeBox(r.end.row,r.end.cell); - - $(dd.proxy).css({ - top: from.top - 1, - left: from.left - 1, - height: to.bottom - from.top - 2, - width: to.right - from.left - 2 - }); } - function handleDragEnd(e,dd) { - if (!_dragging) { - return; - } - - _dragging = false; - e.stopImmediatePropagation(); - $(dd.proxy).remove(); - - setSelectedRanges([ - new Slick.Range( - dd.range.start.row, - dd.range.start.cell, - dd.range.end.row, - dd.range.end.cell - ) - ]); + function handleCellRangeSelected(e, args) { + setSelectedRanges([args.range]); } - function handleActiveCellChange(e, data) { - setSelectedRanges([new Slick.Range(data.row,data.cell)]); + function handleActiveCellChange(e, args) { + setSelectedRanges([new Slick.Range(args.row,args.cell)]); } $.extend(this, { diff --git a/plugins/slick.rowmovemanager.js b/plugins/slick.rowmovemanager.js index 6b037ac..4ecb279 100644 --- a/plugins/slick.rowmovemanager.js +++ b/plugins/slick.rowmovemanager.js @@ -15,38 +15,26 @@ function init(grid) { _grid = grid; _canvas = _grid.getCanvasNode(); - _grid.onDragInit.subscribe(handleDragInit); _grid.onDragStart.subscribe(handleDragStart); _grid.onDrag.subscribe(handleDrag); _grid.onDragEnd.subscribe(handleDragEnd); } function destroy() { - _grid.onDragInit.unsubscribe(handleDragInit); _grid.onDragStart.unsubscribe(handleDragStart); _grid.onDrag.unsubscribe(handleDrag); _grid.onDragEnd.unsubscribe(handleDragEnd); } - function handleDragInit(e,dd) { - var cell = _grid.getCellFromEvent(e); - - if (!_grid.getEditorLock().isActive()) { - if (/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)) { - _dragging = true; - e.stopImmediatePropagation(); - } - } - } - function handleDragStart(e,dd) { - if (!_dragging) { - return; + var cell = _grid.getCellFromEvent(e); + if (_grid.getEditorLock().isActive() || !/move|selectAndMove/.test(_grid.getColumns()[cell.cell].behavior)) { + return false; } + _dragging = true; e.stopImmediatePropagation(); - var cell = _grid.getCellFromEvent(e); var selectedRows = _grid.getSelectedRows(); if (selectedRows.length == 0 || $.inArray(cell.row, selectedRows) == -1) { diff --git a/slick.editors.js b/slick.editors.js index 04bd33d..a458195 100644 --- a/slick.editors.js +++ b/slick.editors.js @@ -90,6 +90,14 @@ $input.focus(); }; + this.getValue = function() { + return $input.val(); + }; + + this.setValue = function(val) { + $input.val(val); + }; + this.loadValue = function(item) { defaultValue = item[args.column.field] || ""; $input.val(defaultValue); diff --git a/slick.grid.js b/slick.grid.js index b4e9994..8a5a0af 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -1391,8 +1391,6 @@ if (typeof Slick === "undefined") { if (e.isImmediatePropagationStopped()) { return retval; } - - return false; } function handleDragStart(e,dd) { From ef9f69c9576a373702fea66202cca1193e5c5f84 Mon Sep 17 00:00:00 2001 From: mleibman Date: Sat, 27 Nov 2010 03:18:16 -0800 Subject: [PATCH 0294/1043] Rolled back a change to example3 (this has been moved to the spreadsheet example). Implemented a CellCopyManager plugin. Added a spreadsheet example page with formula editor and cell range copy and paste. --- examples/example-spreadsheet.html | 166 ++++++++++++++++++++++++++++++ examples/example3-editing.html | 39 +------ plugins/slick.cellcopymanager.js | 85 +++++++++++++++ slick.core.js | 5 + 4 files changed, 257 insertions(+), 38 deletions(-) create mode 100644 examples/example-spreadsheet.html create mode 100644 plugins/slick.cellcopymanager.js diff --git a/examples/example-spreadsheet.html b/examples/example-spreadsheet.html new file mode 100644 index 0000000..c381ac4 --- /dev/null +++ b/examples/example-spreadsheet.html @@ -0,0 +1,166 @@ + + + + + SlickGrid example 3: Editing + + + + + + +
      +
      +
      + +
      +

      Demonstrates:

      +
        +
      • Select a range of cells with a mouse
      • +
      • Use Ctrl-C and Ctrl-V keyboard shortcuts to cut and paste cells
      • +
      • Use Esc to cancel a copy and paste operation
      • +
      +
      + + + + + + + + + + + + + + + + + diff --git a/examples/example3-editing.html b/examples/example3-editing.html index bad4149..ae3e7b3 100644 --- a/examples/example3-editing.html +++ b/examples/example3-editing.html @@ -60,7 +60,7 @@

      Options:

      var columns = [ {id:"title", name:"Title", field:"title", width:120, cssClass:"cell-title", editor:TextCellEditor, validator:requiredFieldValidator}, {id:"desc", name:"Description", field:"description", width:100, editor:LongTextCellEditor}, - {id:"duration", name:"Duration", field:"duration", editor:FormulaEditor}, + {id:"duration", name:"Duration", field:"duration", editor:TextCellEditor}, {id:"%", name:"% Complete", field:"percentComplete", width:80, resizable:false, formatter:GraphicalPercentCompleteCellFormatter, editor:PercentCompleteCellEditor}, {id:"start", name:"Start", field:"start", minWidth:60, editor:DateCellEditor}, {id:"finish", name:"Finish", field:"finish", minWidth:60, editor:DateCellEditor}, @@ -74,43 +74,6 @@

      Options:

      autoEdit: false }; - - /*** - * A proof-of-concept cell editor with Excel-like range selection and insertion. - */ - function FormulaEditor(args) { - var _self = this; - var _editor = new TextCellEditor(args); - var _selector; - - $.extend(this, _editor); - - function init() { - // register a plugin to select a range and append it to the textbox - // since events are fired in reverse order (most recently added are executed first), - // this will override other plugins like moverows or selection model and will - // not require the grid to not be in the edit mode - _selector = new Slick.CellRangeSelector(); - _selector.onCellRangeSelected.subscribe(_self.handleCellRangeSelected); - args.grid.registerPlugin(_selector); - } - - this.destroy = function() { - _selector.onCellRangeSelected.unsubscribe(_self.handleCellRangeSelected); - grid.unregisterPlugin(_selector); - _editor.destroy(); - }; - - this.handleCellRangeSelected = function(e, args) { - _editor.setValue(_editor.getValue() + args.range); - }; - - - init(); - } - - - $(function() { for (var i=0; i<500; i++) { diff --git a/plugins/slick.cellcopymanager.js b/plugins/slick.cellcopymanager.js new file mode 100644 index 0000000..bd1951f --- /dev/null +++ b/plugins/slick.cellcopymanager.js @@ -0,0 +1,85 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "CellCopyManager": CellCopyManager + } + }); + + + function CellCopyManager() { + var _grid; + var _self = this; + var _copiedRanges; + + function init(grid) { + _grid = grid; + _grid.onKeyDown.subscribe(handleKeyDown); + } + + function destroy() { + _grid.onKeyDown.unsubscribe(handleKeyDown); + } + + function handleKeyDown(e, args) { + var ranges; + if (!_grid.getEditorLock().isActive()) { + if (e.which == $.ui.keyCode.ESCAPE) { + if (_copiedRanges) { + e.preventDefault(); + clearCopySelection(); + _self.onCopyCancelled.notify({ranges:_copiedRanges}); + _copiedRanges = null; + } + } + + if (e.which == 67 && e.ctrlKey) { + ranges = _grid.getSelectionModel().getSelectedRanges(); + if (ranges.length != 0) { + e.preventDefault(); + _copiedRanges = ranges; + markCopySelection(ranges); + _self.onCopyCells.notify({ranges:ranges}); + } + } + + if (e.which == 86 && e.ctrlKey) { + if (_copiedRanges) { + e.preventDefault(); + clearCopySelection(); + ranges = _grid.getSelectionModel().getSelectedRanges(); + _self.onPasteCells.notify({from:_copiedRanges, to:ranges}); + _copiedRanges = null; + } + } + } + } + + function markCopySelection(ranges) { + var hash = {}; + for (var i = 0; i < ranges.length; i++) { + for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) { + hash[j] = {}; + for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) { + hash[j][columns[k].id] = "copied"; + } + } + } + _grid.setCellCssStyles("copy-manager", hash); + } + + function clearCopySelection() { + _grid.removeCellCssStyles("copy-manager"); + } + + $.extend(this, { + "init": init, + "destroy": destroy, + "clearCopySelection": clearCopySelection, + + "onCopyCells": new Slick.Event(), + "onCopyCancelled": new Slick.Event(), + "onPasteCells": new Slick.Event() + }); + } +})(jQuery); \ No newline at end of file diff --git a/slick.core.js b/slick.core.js index dfc6ef8..d54243a 100644 --- a/slick.core.js +++ b/slick.core.js @@ -87,6 +87,11 @@ return this.fromRow == this.toRow && this.fromCell == this.toCell; }; + this.contains = function(row, cell) { + return row >= this.fromRow && row <= this.toRow && + cell >= this.fromCell && cell <= this.toCell; + } + this.toString = function() { if (this.isSingleCell()) { return "(" + this.fromRow + ":" + this.fromCell + ")"; From 4e6859b47e2064b6a9e16f868509336ea64069bd Mon Sep 17 00:00:00 2001 From: mleibman Date: Sat, 27 Nov 2010 17:23:59 -0800 Subject: [PATCH 0295/1043] Added CellRangeDecorator and refactored CellRangeSelector to use it. Added onHeaderClick event. Added onMouseEnter & onMouseLeave events. Extracted auto tooltips into a separate plugin - AutoTooltips. --- examples/example-spreadsheet.html | 6 +-- examples/example9-row-reordering.html | 3 +- plugins/slick.autotooltips.js | 49 ++++++++++++++++++++ plugins/slick.cellrangedecorator.js | 65 +++++++++++++++++++++++++++ plugins/slick.cellrangeselector.js | 32 +++---------- slick.grid.js | 46 ++++++++----------- 6 files changed, 142 insertions(+), 59 deletions(-) create mode 100644 plugins/slick.autotooltips.js create mode 100644 plugins/slick.cellrangedecorator.js diff --git a/examples/example-spreadsheet.html b/examples/example-spreadsheet.html index c381ac4..8f56671 100644 --- a/examples/example-spreadsheet.html +++ b/examples/example-spreadsheet.html @@ -35,6 +35,8 @@

      Demonstrates:

      + + @@ -122,6 +124,7 @@

      Demonstrates:

      grid = new Slick.Grid("#myGrid", data, columns, options); grid.setSelectionModel(new Slick.CellSelectionModel()); + grid.registerPlugin(new Slick.AutoTooltips()); // set keyboard focus on the grid grid.getCanvasNode().focus(); @@ -149,9 +152,6 @@

      Demonstrates:

      grid.render(); }); - - - grid.onAddNewRow.subscribe(function(e, args) { var item = args.item; var column = args.column; diff --git a/examples/example9-row-reordering.html b/examples/example9-row-reordering.html index dfc4684..016d4ea 100644 --- a/examples/example9-row-reordering.html +++ b/examples/example9-row-reordering.html @@ -83,6 +83,7 @@ + @@ -155,7 +156,7 @@ grid = new Slick.Grid("#myGrid", data, columns, options); - grid.setSelectionModel(new Slick.RowSelectionModel()); + grid.setSelectionModel(new Slick.CellSelectionModel()); var moveRowsPlugin = new Slick.RowMoveManager(); diff --git a/plugins/slick.autotooltips.js b/plugins/slick.autotooltips.js new file mode 100644 index 0000000..fc5e33e --- /dev/null +++ b/plugins/slick.autotooltips.js @@ -0,0 +1,49 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "AutoTooltips": AutoTooltips + } + }); + + + function AutoTooltips(options) { + var _grid; + var _self = this; + var _defaults = { + maxToolTipLength: null + }; + + function init(grid) { + options = $.extend(true,{},_defaults,options); + _grid = grid; + _grid.onMouseEnter.subscribe(handleMouseEnter); + } + + function destroy() { + _grid.onMouseEnter.subscribe(handleMouseEnter); + } + + function handleMouseEnter(e,args) { + var cell = _grid.getCellFromEvent(e); + if (cell) { + var node = _grid.getCellNode(cell.row, cell.cell); + if ($(node).innerWidth() < node.scrollWidth) { + var text = $.trim($(node).text()); + if (options.maxToolTipLength && text.length > options.maxToolTipLength) { + text = text.substr(0, options.maxToolTipLength - 3) + "..."; + } + $(node).attr("title",text); + } + else { + $(node).attr("title",""); + } + } + } + + $.extend(this, { + "init": init, + "destroy": destroy + }); + } +})(jQuery); \ No newline at end of file diff --git a/plugins/slick.cellrangedecorator.js b/plugins/slick.cellrangedecorator.js new file mode 100644 index 0000000..38df0b6 --- /dev/null +++ b/plugins/slick.cellrangedecorator.js @@ -0,0 +1,65 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "CellRangeDecorator": CellRangeDecorator + } + }); + + /*** + * Displays an overlay on top of a given cell range. + * + * TODO: + * Currently, it blocks mouse events to DOM nodes behind it. + * Use FF and WebKit-specific "pointer-events" CSS style, or some kind of event forwarding. + * Could also construct the borders separately using 4 individual DIVs. + * + * @param {Grid} grid + * @param {Object} options + */ + function CellRangeDecorator(grid, options) { + var _elem; + var _defaults = { + selectionCss: { + "zIndex": "9999", + "border": "2px dashed red" + } + }; + + options = $.extend(true, {}, _defaults, options); + + + function show(range) { + if (!_elem) { + _elem = $("
      ", {css: options.selectionCss}) + .css("position", "absolute") + .appendTo(grid.getCanvasNode()); + + } + + var from = grid.getCellNodeBox(range.fromRow,range.fromCell); + var to = grid.getCellNodeBox(range.toRow,range.toCell); + + _elem.css({ + top: from.top - 1, + left: from.left - 1, + height: to.bottom - from.top - 2, + width: to.right - from.left - 2 + }); + + return _elem; + } + + function hide() { + if (_elem) { + _elem.remove(); + _elem = null; + } + } + + $.extend(this, { + "show": show, + "hide": hide + }); + } +})(jQuery); \ No newline at end of file diff --git a/plugins/slick.cellrangeselector.js b/plugins/slick.cellrangeselector.js index ade3135..1ed8000 100644 --- a/plugins/slick.cellrangeselector.js +++ b/plugins/slick.cellrangeselector.js @@ -11,6 +11,7 @@ var _grid; var _canvas; var _dragging; + var _decorator; var _self = this; var _defaults = { selectionCss: { @@ -21,6 +22,7 @@ function init(grid) { options = $.extend(true, {}, _defaults, options); + _decorator = new Slick.CellRangeDecorator(grid, options); _grid = grid; _canvas = _grid.getCanvasNode(); _grid.onDragStart.subscribe(handleDragStart); @@ -34,17 +36,6 @@ _grid.onDragEnd.unsubscribe(handleDragEnd); } - function fixUpRange(range) { - var r1 = Math.min(range.start.row,range.end.row); - var c1 = Math.min(range.start.cell,range.end.cell); - var r2 = Math.max(range.start.row,range.end.row); - var c2 = Math.max(range.start.cell,range.end.cell); - return { - start: {row:r1, cell:c1}, - end: {row:r2, cell:c2} - }; - } - function handleDragStart(e,dd) { var cell = _grid.getCellFromEvent(e); if (_self.onBeforeCellRangeSelected.notify(cell) !== false) { @@ -63,17 +54,13 @@ dd.range = {start:start,end:{}}; - // TODO: use a decorator - return $("
      ", {css: options.selectionCss}) - .css("position", "absolute") - .appendTo(_canvas); + return _decorator.show(new Slick.Range(start.row,start.cell)); } function handleDrag(e,dd) { if (!_dragging) { return; } - e.stopImmediatePropagation(); var end = _grid.getCellFromPoint( @@ -85,16 +72,7 @@ } dd.range.end = end; - var r = fixUpRange(dd.range); - var from = _grid.getCellNodeBox(r.start.row,r.start.cell); - var to = _grid.getCellNodeBox(r.end.row,r.end.cell); - - $(dd.proxy).css({ - top: from.top - 1, - left: from.left - 1, - height: to.bottom - from.top - 2, - width: to.right - from.left - 2 - }); + _decorator.show(new Slick.Range(dd.range.start.row,dd.range.start.cell,end.row,end.cell)); } function handleDragEnd(e,dd) { @@ -104,8 +82,8 @@ _dragging = false; e.stopImmediatePropagation(); - $(dd.proxy).remove(); + _decorator.hide(); _self.onCellRangeSelected.notify({ range: new Slick.Range( dd.range.start.row, diff --git a/slick.grid.js b/slick.grid.js index 8a5a0af..b49fc79 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -76,8 +76,6 @@ if (typeof Slick === "undefined") { showSecondaryHeaderRow: false, secondaryHeaderRowHeight: 25, syncColumnCellResize: false, - enableAutoTooltips: true, - toolTipMaxLength: null, formatterFactory: null, editorFactory: null, cellFlashingCssClass: "flashing", @@ -249,11 +247,13 @@ if (typeof Slick === "undefined") { .bind("click.slickgrid", handleClick) .bind("dblclick.slickgrid", handleDblClick) .bind("contextmenu.slickgrid", handleContextMenu) - .bind("mouseover.slickgrid", handleHover) .bind("draginit", handleDragInit) .bind("dragstart", handleDragStart) .bind("drag", handleDrag) .bind("dragend", handleDragEnd); + + $canvas.delegate(".slick-cell", "mouseenter", handleMouseEnter); + $canvas.delegate(".slick-cell", "mouseleave", handleMouseLeave); } function registerPlugin(plugin) { @@ -852,8 +852,7 @@ if (typeof Slick === "undefined") { function setData(newData,scrollToTop) { invalidateAllRows(); - data = newData; - gridData = data; + gridData = newData; if (scrollToTop) scrollTo(0); } @@ -1524,35 +1523,23 @@ if (typeof Slick === "undefined") { } function handleHeaderContextMenu(e) { - var selectedElement = $(e.target).closest(".slick-header-column", ".slick-header-columns"); - self.onHeaderContextMenu.notify(e, { - column: columns[self.getColumnIndex(selectedElement.data("fieldId"))] - }); + var $header = $(e.target).closest(".slick-header-column", ".slick-header-columns"); + var column = $header && columns[self.getColumnIndex($header.data("fieldId"))]; + self.onHeaderContextMenu.notify(e, {column: column}); } function handleHeaderClick(e) { - var $col = $(e.target).closest(".slick-header-column"); - if ($col.length ==0) { return; } - var column = columns[getSiblingIndex($col[0])]; + var $header = $(e.target).closest(".slick-header-column", ".slick-header-columns"); + var column = $header && columns[self.getColumnIndex($header.data("fieldId"))]; + self.onHeaderClick.notify(e, {column: column}); + } - if (self.onHeaderClick && getEditorLock().commitCurrentEdit()) { - e.preventDefault(); - self.onHeaderClick(e, column); - } + function handleMouseEnter(e) { + self.onMouseEnter.notify(e,{}); } - function handleHover(e) { - if (!options.enableAutoTooltips) return; - var $cell = $(e.target).closest(".slick-cell",$canvas); - if ($cell.length) { - if ($cell.innerWidth() < $cell[0].scrollWidth) { - var text = $.trim($cell.text()); - $cell.attr("title", (options.toolTipMaxLength && text.length > options.toolTipMaxLength) ? text.substr(0, options.toolTipMaxLength - 3) + "..." : text); - } - else { - $cell.attr("title",""); - } - } + function handleMouseLeave(e) { + self.onMouseLeave.notify(e,{}); } function cellExists(row,cell) { @@ -2164,6 +2151,9 @@ if (typeof Slick === "undefined") { // Events "onSort": new Slick.Event(), "onHeaderContextMenu": new Slick.Event(), + "onHeaderClick": new Slick.Event(), + "onMouseEnter": new Slick.Event(), + "onMouseLeave": new Slick.Event(), "onClick": new Slick.Event(), "onDblClick": new Slick.Event(), "onContextMenu": new Slick.Event(), From 6fe438fbd5efdef171031d3141c3cefa5fbebe27 Mon Sep 17 00:00:00 2001 From: mleibman Date: Sun, 28 Nov 2010 04:02:32 -0800 Subject: [PATCH 0296/1043] Added "updateColumnHeader" grid method. Added selected row caching and de-duplication to the grid. Added an option to selection models on whether to select active cell/row. Added an example of a checkbox select column implementation. --- examples/example-checkbox-row-select.html | 176 ++++++++++++++++++++++ plugins/slick.cellselectionmodel.js | 12 +- plugins/slick.rowselectionmodel.js | 11 +- slick.grid.js | 32 ++-- 4 files changed, 214 insertions(+), 17 deletions(-) create mode 100644 examples/example-checkbox-row-select.html diff --git a/examples/example-checkbox-row-select.html b/examples/example-checkbox-row-select.html new file mode 100644 index 0000000..f014a8f --- /dev/null +++ b/examples/example-checkbox-row-select.html @@ -0,0 +1,176 @@ + + + + + + + + + + +
      +
      +
      + +
      +

      Demonstrates:

      +
        +
      +
      + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/slick.cellselectionmodel.js b/plugins/slick.cellselectionmodel.js index d1e68da..e1dd565 100644 --- a/plugins/slick.cellselectionmodel.js +++ b/plugins/slick.cellselectionmodel.js @@ -7,7 +7,7 @@ }); - function CellSelectionModel() { + function CellSelectionModel(options) { var _grid; var _canvas; var _ranges = []; @@ -17,8 +17,14 @@ "border": "2px solid black" } }); + var _options; + var _defaults = { + selectActiveCell: true + }; + function init(grid) { + _options = $.extend(true, {}, _defaults, options); _grid = grid; _canvas = _grid.getCanvasNode(); _grid.onActiveCellChanged.subscribe(handleActiveCellChange); @@ -68,7 +74,9 @@ } function handleActiveCellChange(e, args) { - setSelectedRanges([new Slick.Range(args.row,args.cell)]); + if (_options.selectActiveCell) { + setSelectedRanges([new Slick.Range(args.row,args.cell)]); + } } $.extend(this, { diff --git a/plugins/slick.rowselectionmodel.js b/plugins/slick.rowselectionmodel.js index eb03db8..19b7333 100644 --- a/plugins/slick.rowselectionmodel.js +++ b/plugins/slick.rowselectionmodel.js @@ -6,12 +6,17 @@ } }); - function RowSelectionModel() { + function RowSelectionModel(options) { var _grid; var _ranges = []; var _self = this; + var _options; + var _defaults = { + selectActiveRow: true + }; function init(grid) { + _options = $.extend(true, {}, _defaults, options); _grid = grid; _grid.onActiveCellChanged.subscribe(handleActiveCellChange); _grid.onKeyDown.subscribe(handleKeyDown); @@ -72,7 +77,9 @@ } function handleActiveCellChange(e, data) { - setSelectedRanges([new Slick.Range(data.row, 0, data.row, _grid.getColumns().length - 1)]); + if (_options.selectActiveRow) { + setSelectedRanges([new Slick.Range(data.row, 0, data.row, _grid.getColumns().length - 1)]); + } } function handleKeyDown(e) { diff --git a/slick.grid.js b/slick.grid.js index b49fc79..08e982f 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -136,6 +136,7 @@ if (typeof Slick === "undefined") { var avgRowRenderTime = 10; var selectionModel; + var selectedRows = []; var plugins = []; var cellCssClasses = {}; @@ -357,6 +358,18 @@ if (typeof Slick === "undefined") { $canvas.parents().unbind("scroll.slickgrid"); } + function updateColumnHeader(columnId, title, toolTip) { + var idx = getColumnIndex(columnId); + var $header = $headers.children().eq(idx); + if ($header) { + columns[idx].name = title; + columns[idx].toolTip = toolTip; + $header + .attr("title", toolTip || title || "") + .children().eq(0).html(title); + } + } + function createColumnHeaders() { var i; @@ -800,10 +813,13 @@ if (typeof Slick === "undefined") { } function handleSelectedRangesChanged(e, ranges) { + selectedRows = []; var hash = {}; - for (var i = 0; i < ranges.length; i++) { for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) { + if (!hash[j]) { // prevent duplicates + selectedRows.push(j); + } hash[j] = {}; for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) { hash[j][columns[k].id] = options.selectedCellCssClass; @@ -935,7 +951,6 @@ if (typeof Slick === "undefined") { var d = getDataItem(row); var dataLoading = row < getDataLength() && !d; var cellCss; - // TODO: apply css class to selected cells var css = "slick-row " + (dataLoading ? " loading" : "") + (row % 2 == 1 ? ' odd' : ' even'); @@ -2084,16 +2099,6 @@ if (typeof Slick === "undefined") { return true; } - function rangesToRows(ranges) { - var rows = []; - for (var i = 0; i < ranges.length; i++) { - for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) { - rows.push(j); - } - } - return rows; - } - function rowsToRanges(rows) { var ranges = []; var lastCell = columns.length - 1; @@ -2107,7 +2112,7 @@ if (typeof Slick === "undefined") { if (!selectionModel) { throw "Selection model is not set"; } - return rangesToRows(selectionModel.getSelectedRanges()); + return selectedRows; } function setSelectedRows(rows) { @@ -2181,6 +2186,7 @@ if (typeof Slick === "undefined") { "getColumns": getColumns, "setColumns": setColumns, "getColumnIndex": getColumnIndex, + "updateColumnHeader": updateColumnHeader, "setSortColumn": setSortColumn, "autosizeColumns": autosizeColumns, "getOptions": getOptions, From 677d4a25e7c3c3284fb7a029a5d8c85029d760a2 Mon Sep 17 00:00:00 2001 From: mleibman Date: Sun, 28 Nov 2010 04:06:09 -0800 Subject: [PATCH 0297/1043] Fixed indentation in "example-checkbox-row-select.html". --- examples/example-checkbox-row-select.html | 315 +++++++++++----------- 1 file changed, 158 insertions(+), 157 deletions(-) diff --git a/examples/example-checkbox-row-select.html b/examples/example-checkbox-row-select.html index f014a8f..d326e71 100644 --- a/examples/example-checkbox-row-select.html +++ b/examples/example-checkbox-row-select.html @@ -1,176 +1,177 @@ - - - - - - - - -
      -
      -
      - -
      -

      Demonstrates:

      -
        -
      -
      - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + else { + grid.setSelectedRows([]); + } + // could update the existing dom nodes instead, but whatever + grid.invalidate(); + e.stopPropagation(); + e.stopImmediatePropagation(); + } + }) + }) + + From 5853812289fce2d400b66e7ec9007b5e43398f72 Mon Sep 17 00:00:00 2001 From: mleibman Date: Tue, 30 Nov 2010 14:41:58 -0800 Subject: [PATCH 0298/1043] Fixed AJAX sample. Sorting still seems to be broken though. --- examples/example6-ajax-loading.html | 20 +++++++++++++------- slick.remotemodel.js | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/example6-ajax-loading.html b/examples/example6-ajax-loading.html index ab16ae6..621e049 100644 --- a/examples/example6-ajax-loading.html +++ b/examples/example6-ajax-loading.html @@ -52,6 +52,11 @@

      Demonstrates:

    • loading data through AJAX
    • custom row height
    • + +

      WARNING:

      +
        +
      • Digg API uses request rate limiting. You may occasionally get an error if you do a frequent scrolling/resorting/searching.
      • +
      @@ -61,6 +66,7 @@

      Demonstrates:

      + @@ -95,16 +101,16 @@

      Demonstrates:

      { grid = new Slick.Grid("#myGrid", loader.data, columns, options); - grid.onViewportChanged = function() { + grid.onViewportChanged.subscribe(function(e,args) { var vp = grid.getViewport(); loader.ensureData(vp.top, vp.bottom); - }; + }); - grid.onSort = function(sortCol, sortAsc) { - loader.setSort(sortCol.field, sortAsc ? 1 : -1); + grid.onSort.subscribe(function(e,args) { + loader.setSort(args.sortCol.field, args.sortAsc ? 1 : -1); var vp = grid.getViewport(); loader.ensureData(vp.top, vp.bottom); - }; + }); loader.onDataLoading.subscribe(function() { if (!loadingIndicator) @@ -121,7 +127,7 @@

      Demonstrates:

      loadingIndicator.show(); }); - loader.onDataLoaded.subscribe(function(args) { + loader.onDataLoaded.subscribe(function(e,args) { for (var i = args.from; i <= args.to; i++) { grid.invalidateRow(i); } @@ -143,7 +149,7 @@

      Demonstrates:

      // load the first page - grid.onViewportChanged(); + grid.onViewportChanged.notify(); }) diff --git a/slick.remotemodel.js b/slick.remotemodel.js index 372731a..dc41b64 100644 --- a/slick.remotemodel.js +++ b/slick.remotemodel.js @@ -61,7 +61,7 @@ toPage--; if (fromPage > toPage || ((fromPage == toPage) && data[fromPage*PAGESIZE] !== undefined)) { - // TODO: lookeahead + // TODO: look-ahead return; } @@ -102,7 +102,7 @@ } function onSuccess(resp) { - var from = resp.offset, to = resp.offset + resp.count; + var from = this.fromPage*PAGESIZE, to = from + resp.count; data.length = parseInt(resp.total); for (var i = 0; i < resp.stories.length; i++) { From e60c34b2bf3985e02cdf32855ab3d8f61f93bbab Mon Sep 17 00:00:00 2001 From: mleibman Date: Sat, 4 Dec 2010 19:10:19 -0800 Subject: [PATCH 0299/1043] Added a fixed header row and an example of how to use it to implement inline column filters. Renamed "secondary header row" to "top panel" for clarity. --- examples/example-header-row.html | 137 +++++++++++++++++++++++++++++++ examples/example4-model.html | 12 +-- examples/slick-default-theme.css | 10 +++ slick.grid.css | 10 ++- slick.grid.js | 108 +++++++++++++++++------- 5 files changed, 237 insertions(+), 40 deletions(-) create mode 100644 examples/example-header-row.html diff --git a/examples/example-header-row.html b/examples/example-header-row.html new file mode 100644 index 0000000..bcba6d1 --- /dev/null +++ b/examples/example-header-row.html @@ -0,0 +1,137 @@ + + + + + + + + + + +
      +
      +
      + +
      +

      Demonstrates:

      +
        +
      • Using a fixed header row to implement column-level filters
      • +
      • Type numbers in textboxes to filter grid data
      • +
      +
      + + + + + + + + + + + + + + diff --git a/examples/example4-model.html b/examples/example4-model.html index 5118c2d..260cd63 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -118,7 +118,7 @@

      Demonstrates:

      enableCellNavigation: true, asyncEditorLoading: true, forceFitColumns: false, - secondaryHeaderRowHeight: 25 + topPanelHeight: 25 }; var sortcol = "title"; @@ -153,10 +153,10 @@

      Demonstrates:

      } function toggleFilterRow() { - if ($(grid.getSecondaryHeaderRow()).is(":visible")) - grid.hideSecondaryHeaderRow(); + if ($(grid.getTopPanel()).is(":visible")) + grid.hideTopPanel(); else - grid.showSecondaryHeaderRow(); + grid.showTopPanel(); } @@ -194,9 +194,9 @@

      Demonstrates:

      var columnpicker = new Slick.Controls.ColumnPicker(columns, grid, options); - // move the filter panel defined in a hidden div into an inline secondary grid header row + // move the filter panel defined in a hidden div into grid top panel $("#inlineFilterPanel") - .appendTo(grid.getSecondaryHeaderRow()) + .appendTo(grid.getTopPanel()) .show(); grid.onCellChange.subscribe(function(e,args) { diff --git a/examples/slick-default-theme.css b/examples/slick-default-theme.css index 797a6ce..0a8d93b 100644 --- a/examples/slick-default-theme.css +++ b/examples/slick-default-theme.css @@ -19,6 +19,16 @@ classes should alter those! background: white url('../images/header-columns-over-bg.gif') repeat-x center bottom; } +.slick-headerrow { + background: #fafafa; +} + +.slick-headerrow-column { + background: #fafafa; + border-bottom: 0; + height: 100%; +} + .slick-row.ui-state-active { background: #F5F7D7; } diff --git a/slick.grid.css b/slick.grid.css index d311142..f868b07 100644 --- a/slick.grid.css +++ b/slick.grid.css @@ -6,13 +6,13 @@ classes should alter those! */ -.slick-header.ui-state-default { +.slick-header.ui-state-default, .slick-headerrow.ui-state-default { width: 100%; overflow: hidden; border-left: 0px; } -.slick-header-columns { +.slick-header-columns, .slick-headerrow-columns { width: 999999px; position: relative; white-space: nowrap; @@ -36,6 +36,10 @@ classes should alter those! float: left; } +.slick-headerrow-column.ui-state-default { + padding: 4px; +} + .slick-header-column-sorted { font-style: italic; } @@ -80,7 +84,7 @@ classes should alter those! border: 0px; } -.slick-cell { +.slick-cell, .slick-headerrow-column { float: left; border: 1px solid transparent; diff --git a/slick.grid.js b/slick.grid.js index 08e982f..8a3a09b 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -73,8 +73,10 @@ if (typeof Slick === "undefined") { asyncPostRenderDelay: 60, autoHeight: false, editorLock: Slick.GlobalEditorLock, - showSecondaryHeaderRow: false, - secondaryHeaderRowHeight: 25, + showHeaderRow: false, + headerRowHeight: 25, + showTopPanel: false, + topPanelHeight: 25, syncColumnCellResize: false, formatterFactory: null, editorFactory: null, @@ -88,7 +90,9 @@ if (typeof Slick === "undefined") { name: "", resizable: true, sortable: false, - minWidth: 30 + minWidth: 30, + rerenderOnResize: false, + unselectable: false }; // scroller @@ -109,8 +113,9 @@ if (typeof Slick === "undefined") { var self = this; var $headerScroller; var $headers; - var $secondaryHeaderScroller; - var $secondaryHeaders; + var $headerRow, $headerRowScroller; + var $topPanelScroller; + var $topPanel; var $viewport; var $canvas; var $style; @@ -203,11 +208,18 @@ if (typeof Slick === "undefined") { $headerScroller = $("
      ").appendTo($container); $headers = $("
      ").appendTo($headerScroller); - $secondaryHeaderScroller = $("
      ").appendTo($container); - $secondaryHeaders = $("
      ").appendTo($secondaryHeaderScroller); + $headerRowScroller = $("
      ").appendTo($container); + $headerRow = $("
      ").appendTo($headerRowScroller); - if (!options.showSecondaryHeaderRow) { - $secondaryHeaderScroller.hide(); + $topPanelScroller = $("
      ").appendTo($container); + $topPanel = $("
      ").appendTo($topPanelScroller); + + if (!options.showTopPanel) { + $topPanelScroller.hide(); + } + + if (!options.showHeaderRow) { + $headerRowScroller.hide(); } $viewport = $("
      ").appendTo($container); @@ -217,10 +229,7 @@ if (typeof Slick === "undefined") { // calculate the diff so we can set consistent sizes measureCellPaddingAndBorder(); - $viewport.height( - $container.innerHeight() - - $headerScroller.outerHeight() - - (options.showSecondaryHeaderRow ? $secondaryHeaderScroller.outerHeight() : 0)); + resizeViewport(); // for usability reasons, all text selection in SlickGrid is disabled // with the exception of input and textarea elements (selection must @@ -370,6 +379,17 @@ if (typeof Slick === "undefined") { } } + function getHeaderRow() { + return $headerRow[0]; + } + + function getHeaderRowColumn(columnId) { + var idx = getColumnIndex(columnId); + var $header = $headerRow.children().eq(idx); + return $header && $header[0]; + } + + function createColumnHeaders() { var i; @@ -381,6 +401,7 @@ if (typeof Slick === "undefined") { } $headers.empty(); + $headerRow.empty(); columnsById = {}; for (i = 0; i < columns.length; i++) { @@ -401,6 +422,10 @@ if (typeof Slick === "undefined") { if (m.sortable) { header.append(""); } + + if (options.showHeaderRow) { + $("
      ").appendTo($headerRow); + } } setSortColumn(sortColumnId,sortAsc); @@ -651,7 +676,8 @@ if (typeof Slick === "undefined") { var rules = [ "." + uid + " .slick-header-column { left: 10000px; }", - "." + uid + " .slick-header-columns-secondary { height:" + options.secondaryHeaderRowHeight + "px; }", + "." + uid + " .slick-top-panel { height:" + options.topPanelHeight + "px; }", + "." + uid + " .slick-headerrow-columns { height:" + options.headerRowHeight + "px; }", "." + uid + " .slick-cell { height:" + rowHeight + "px; }" ]; @@ -895,18 +921,28 @@ if (typeof Slick === "undefined") { } } - function getSecondaryHeaderRow() { - return $secondaryHeaders[0]; + function getTopPanel() { + return $topPanel[0]; + } + + function showTopPanel() { + options.showTopPanel = true; + $topPanelScroller.slideDown("fast", resizeCanvas); + } + + function hideTopPanel() { + options.showTopPanel = false; + $topPanelScroller.slideUp("fast", resizeCanvas); } - function showSecondaryHeaderRow() { - options.showSecondaryHeaderRow = true; - $secondaryHeaderScroller.slideDown("fast", resizeCanvas); + function showHeaderRowColumns() { + options.showHeaderRow = true; + $headerRowScroller.slideDown("fast", resizeCanvas); } - function hideSecondaryHeaderRow() { - options.showSecondaryHeaderRow = false; - $secondaryHeaderScroller.slideUp("fast", resizeCanvas); + function hideHeaderRowColumns() { + options.showHeaderRow = false; + $headerRowScroller.slideUp("fast", resizeCanvas); } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -1075,16 +1111,21 @@ if (typeof Slick === "undefined") { invalidatePostProcessingResults(row); } + function resizeViewport() { + $viewport.height( + $container.innerHeight() - + $headerScroller.outerHeight() - + (options.showTopPanel ? $topPanelScroller.outerHeight() : 0) - + (options.showHeaderRow ? $headerRow.outerHeight() : 0)); + } + function resizeCanvas() { var newViewportH = options.rowHeight * (getDataLength() + (options.enableAddRow ? 1 : 0) + (options.leaveSpaceForNewRows? numVisibleRows - 1 : 0)); if (options.autoHeight) { // use computed height to set both canvas _and_ divMainScroller, effectively hiding scroll bars. $viewport.height(newViewportH); } else { - $viewport.height( - $container.innerHeight() - - $headerScroller.outerHeight() - - (options.showSecondaryHeaderRow ? $secondaryHeaderScroller.outerHeight() : 0)); + resizeViewport(); } viewportW = $viewport.innerWidth(); @@ -1274,7 +1315,8 @@ if (typeof Slick === "undefined") { if (scrollLeft !== prevScrollLeft) { prevScrollLeft = scrollLeft; $headerScroller[0].scrollLeft = scrollLeft; - $secondaryHeaderScroller[0].scrollLeft = scrollLeft; + $topPanelScroller[0].scrollLeft = scrollLeft; + $headerRowScroller[0].scrollLeft = scrollLeft; } if (!scrollDist) return; @@ -2232,11 +2274,15 @@ if (typeof Slick === "undefined") { "navigateLeft": navigateLeft, "navigateRight": navigateRight, "gotoCell": gotoCell, - "getSecondaryHeaderRow": getSecondaryHeaderRow, - "showSecondaryHeaderRow": showSecondaryHeaderRow, - "hideSecondaryHeaderRow": hideSecondaryHeaderRow, + "getTopPanel": getTopPanel, + "showTopPanel": showTopPanel, + "hideTopPanel": hideTopPanel, + + "showHeaderRowColumns": showHeaderRowColumns, + "hideHeaderRowColumns": hideHeaderRowColumns, + "getHeaderRow": getHeaderRow, + "getHeaderRowColumn": getHeaderRowColumn, "getGridPosition": getGridPosition, - "flashCell": flashCell, "addCellCssStyles": addCellCssStyles, "setCellCssStyles": setCellCssStyles, From b93b4e3ac3bc232ae8065efe5cea43d88f8a6cd9 Mon Sep 17 00:00:00 2001 From: mleibman Date: Sat, 4 Dec 2010 19:38:27 -0800 Subject: [PATCH 0300/1043] Added an onScroll event. --- slick.grid.js | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index 8a3a09b..7804539 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -1319,32 +1319,34 @@ if (typeof Slick === "undefined") { $headerRowScroller[0].scrollLeft = scrollLeft; } - if (!scrollDist) return; + if (scrollDist) { + scrollDir = prevScrollTop < scrollTop ? 1 : -1; + prevScrollTop = scrollTop; - scrollDir = prevScrollTop < scrollTop ? 1 : -1; - prevScrollTop = scrollTop; + // switch virtual pages if needed + if (scrollDist < viewportH) { + scrollTo(scrollTop + offset); + } + else { + var oldOffset = offset; + page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph))); + offset = Math.round(page * cj); + if (oldOffset != offset) + invalidateAllRows(); + } - // switch virtual pages if needed - if (scrollDist < viewportH) { - scrollTo(scrollTop + offset); - } - else { - var oldOffset = offset; - page = Math.min(n - 1, Math.floor(scrollTop * ((th - viewportH) / (h - viewportH)) * (1 / ph))); - offset = Math.round(page * cj); - if (oldOffset != offset) - invalidateAllRows(); - } + if (h_render) + clearTimeout(h_render); - if (h_render) - clearTimeout(h_render); + if (Math.abs(lastRenderedScrollTop - scrollTop) < viewportH) + render(); + else + h_render = setTimeout(render, 50); - if (Math.abs(lastRenderedScrollTop - scrollTop) < viewportH) - render(); - else - h_render = setTimeout(render, 50); + self.onViewportChanged.notify({}); + } - self.onViewportChanged.notify({}); + self.onScroll.notify({scrollLeft:scrollLeft, scrollTop:scrollTop}); } function asyncPostProcessRows() { @@ -2196,6 +2198,7 @@ if (typeof Slick === "undefined") { "slickGridVersion": "2.0a1", // Events + "onScroll": new Slick.Event(), "onSort": new Slick.Event(), "onHeaderContextMenu": new Slick.Event(), "onHeaderClick": new Slick.Event(), @@ -2277,7 +2280,6 @@ if (typeof Slick === "undefined") { "getTopPanel": getTopPanel, "showTopPanel": showTopPanel, "hideTopPanel": hideTopPanel, - "showHeaderRowColumns": showHeaderRowColumns, "hideHeaderRowColumns": hideHeaderRowColumns, "getHeaderRow": getHeaderRow, From 667b9b0d5a5dff77ff2444fc87aa5358bf76fe0f Mon Sep 17 00:00:00 2001 From: mleibman Date: Sun, 5 Dec 2010 13:13:40 -0800 Subject: [PATCH 0301/1043] Added a CheckboxSelectColumn plugin. --- examples/example-checkbox-row-select.html | 125 +++---------------- plugins/slick.checkboxselectcolumn.js | 139 ++++++++++++++++++++++ 2 files changed, 157 insertions(+), 107 deletions(-) create mode 100644 plugins/slick.checkboxselectcolumn.js diff --git a/examples/example-checkbox-row-select.html b/examples/example-checkbox-row-select.html index d326e71..9ce8132 100644 --- a/examples/example-checkbox-row-select.html +++ b/examples/example-checkbox-row-select.html @@ -32,6 +32,7 @@

      Demonstrates:

      + @@ -42,7 +43,6 @@

      Demonstrates:

      diff --git a/plugins/slick.checkboxselectcolumn.js b/plugins/slick.checkboxselectcolumn.js new file mode 100644 index 0000000..768d395 --- /dev/null +++ b/plugins/slick.checkboxselectcolumn.js @@ -0,0 +1,139 @@ +(function($) { + // register namespace + $.extend(true, window, { + "Slick": { + "CheckboxSelectColumn": CheckboxSelectColumn + } + }); + + + function CheckboxSelectColumn(options) { + var _grid; + var _self = this; + var _selectedRowsLookup = {}; + var _defaults = { + columnId: "_checkbox_selector", + cssClass: null, + toolTip: "Select/Deselect All", + width: 30 + }; + + var _options = $.extend(true,{},_defaults,options); + + function init(grid) { + _grid = grid; + _grid.onSelectedRowsChanged.subscribe(handleSelectedRowsChanged); + _grid.onClick.subscribe(handleClick); + _grid.onHeaderClick.subscribe(handleHeaderClick); + } + + function destroy() { + _grid.onSelectedRowsChanged.unsubscribe(handleSelectedRowsChanged); + _grid.onClick.unsubscribe(handleClick); + _grid.onHeaderClick.unsubscribe(handleHeaderClick); + } + + function handleSelectedRowsChanged(e, args) { + var selectedRows = _grid.getSelectedRows(); + var lookup = {}, row, i; + for (i = 0; i < selectedRows.length; i++) { + row = selectedRows[i]; + lookup[row] = true; + if (lookup[row] !== _selectedRowsLookup[row]) { + _grid.invalidateRow(row); + delete _selectedRowsLookup[row]; + } + } + for (i in _selectedRowsLookup) { + _grid.invalidateRow(i); + } + _selectedRowsLookup = lookup; + _grid.render(); + + if (selectedRows.length == _grid.getDataLength()) { + _grid.updateColumnHeader(_options.columnId, "", _options.toolTip); + } + else { + _grid.updateColumnHeader(_options.columnId, "", _options.toolTip); + } + } + + function handleClick(e, args) { + // clicking on a row select checkbox + if (_grid.getColumns()[args.cell].id === _options.columnId && $(e.target).is(":checkbox")) { + // if editing, try to commit + if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) { + e.preventDefault(); + e.stopImmediatePropagation(); + return; + } + + if (_selectedRowsLookup[args.row]) { + _grid.setSelectedRows($.grep(_grid.getSelectedRows(),function(n) { return n != args.row })); + } + else { + _grid.setSelectedRows(_grid.getSelectedRows().concat(args.row)); + } + e.stopPropagation(); + e.stopImmediatePropagation(); + } + } + + function handleHeaderClick(e, args) { + if (args.column.id == _options.columnId && $(e.target).is(":checkbox")) { + // if editing, try to commit + if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) { + e.preventDefault(); + e.stopImmediatePropagation(); + return; + } + + if ($(e.target).is(":checked")) { + var rows = []; + for (var i = 0; i < _grid.getDataLength(); i++) { + rows.push(i); + } + _grid.setSelectedRows(rows); + } + else { + _grid.setSelectedRows([]); + } + // could update the existing dom nodes instead, but whatever + _grid.invalidate(); + e.stopPropagation(); + e.stopImmediatePropagation(); + } + } + + function getColumnDefinition() { + return { + id: _options.columnId, + name: "", + toolTip: _options.toolTip, + field: "sel", + width: _options.width, + unselectable: true, + resizable: false, + sortable: false, + cssClass: _options.cssClass, + formatter: checkboxSelectionFormatter + }; + } + + function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext) { + if (dataContext) { + return _selectedRowsLookup[row] + ? "" + : ""; + } + return null; + } + + $.extend(this, { + "init": init, + "destroy": destroy, + + "getColumnDefinition": getColumnDefinition + }); + } +})(jQuery); \ No newline at end of file From 2f944d7a8bdeb30d1205529e0f8d706d82f64d06 Mon Sep 17 00:00:00 2001 From: mleibman Date: Mon, 6 Dec 2010 00:09:11 -0800 Subject: [PATCH 0302/1043] Small bug fix in getCellFromPoint. --- slick.grid.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/slick.grid.js b/slick.grid.js index 7804539..5ca3446 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -1615,6 +1615,10 @@ if (typeof Slick === "undefined") { cell++; } + if (cell < 0) { + cell = 0; + } + return {row:row,cell:cell-1}; } @@ -2277,7 +2281,7 @@ if (typeof Slick === "undefined") { "navigateLeft": navigateLeft, "navigateRight": navigateRight, "gotoCell": gotoCell, - "getTopPanel": getTopPanel, + "getTopPanel": getTopPanel, "showTopPanel": showTopPanel, "hideTopPanel": hideTopPanel, "showHeaderRowColumns": showHeaderRowColumns, From 5f88203f4b3c70eed7feaf31e65d71d95d2272c5 Mon Sep 17 00:00:00 2001 From: mleibman Date: Mon, 6 Dec 2010 08:27:05 -0800 Subject: [PATCH 0303/1043] Fixed setSelectionModel not unsubscribing from the previous selection model's events. --- slick.grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slick.grid.js b/slick.grid.js index 5ca3446..12f5750 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -285,7 +285,7 @@ if (typeof Slick === "undefined") { function setSelectionModel(model) { if (selectionModel) { - selectionModel.onSelectedRangesChanged.subscribe(handleSelectedRangesChanged); + selectionModel.onSelectedRangesChanged.unsubscribe(handleSelectedRangesChanged); if (selectionModel.destroy) { selectionModel.destroy(); } From cc45b923a484f72e236fa3d527a2df331ab96d3c Mon Sep 17 00:00:00 2001 From: mleibman Date: Thu, 9 Dec 2010 21:45:14 -0800 Subject: [PATCH 0304/1043] Added a mechanism to set scope ("this") in events. Grid and DataView now set the scope to the instance. Corrected args format in events in DataView. --- examples/example-header-row.html | 4 +- examples/example4-model.html | 4 +- examples/example5-collapsing.html | 4 +- slick.core.js | 20 +++------- slick.dataview.js | 8 ++-- slick.grid.js | 61 +++++++++++++++++-------------- tests/dataview/dataview.js | 24 ++++++------ 7 files changed, 62 insertions(+), 63 deletions(-) diff --git a/examples/example-header-row.html b/examples/example-header-row.html index bcba6d1..16d5cb2 100644 --- a/examples/example-header-row.html +++ b/examples/example-header-row.html @@ -105,8 +105,8 @@

      Demonstrates:

      grid.render(); }); - dataView.onRowsChanged.subscribe(function(e,rows) { - grid.invalidateRows(rows); + dataView.onRowsChanged.subscribe(function(e,args) { + grid.invalidateRows(args.rows); grid.render(); }); diff --git a/examples/example4-model.html b/examples/example4-model.html index 260cd63..5154b58 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -268,8 +268,8 @@

      Demonstrates:

      grid.render(); }); - dataView.onRowsChanged.subscribe(function(e,rows) { - grid.invalidateRows(rows); + dataView.onRowsChanged.subscribe(function(e,args) { + grid.invalidateRows(args.rows); grid.render(); if (selectedRowIds.length > 0) diff --git a/examples/example5-collapsing.html b/examples/example5-collapsing.html index e363a36..008293e 100644 --- a/examples/example5-collapsing.html +++ b/examples/example5-collapsing.html @@ -221,8 +221,8 @@

      Demonstrates:

      grid.render(); }); - dataView.onRowsChanged.subscribe(function(e,rows) { - grid.invalidateRows(rows); + dataView.onRowsChanged.subscribe(function(e,args) { + grid.invalidateRows(args.rows); grid.render(); }); diff --git a/slick.core.js b/slick.core.js index d54243a..dc97e09 100644 --- a/slick.core.js +++ b/slick.core.js @@ -47,21 +47,13 @@ } }; - this.notify = function(arg1, arg2) { - var e; - var data; - var returnValue; - if (arguments.length === 2) { - e = arg1; - data = arg2; - } - else { - e = new EventData(); - data = arg1; - } + this.notify = function(args, e, scope) { + e = e || new EventData(); + scope = scope || this; + var returnValue; for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) { - returnValue = handlers[i].call(this, e, data); + returnValue = handlers[i].call(scope, e, args); } return returnValue; @@ -90,7 +82,7 @@ this.contains = function(row, cell) { return row >= this.fromRow && row <= this.toRow && cell >= this.fromCell && cell <= this.toCell; - } + }; this.toString = function() { if (this.isSingleCell()) { diff --git a/slick.dataview.js b/slick.dataview.js index a0599d4..f8272e7 100644 --- a/slick.dataview.js +++ b/slick.dataview.js @@ -68,7 +68,7 @@ if (args.pageNum != undefined) pagenum = Math.min(args.pageNum, Math.ceil(totalRows / pagesize)); - onPagingInfoChanged.notify(getPagingInfo()); + onPagingInfoChanged.notify(getPagingInfo(), null, self); refresh(); } @@ -231,9 +231,9 @@ updated = null; - if (totalRowsBefore != totalRows) onPagingInfoChanged.notify(getPagingInfo()); - if (countBefore != rows.length) onRowCountChanged.notify({previous:countBefore, current:rows.length}); - if (diff.length > 0) onRowsChanged.notify(diff); + if (totalRowsBefore != totalRows) onPagingInfoChanged.notify(getPagingInfo(), null, self); + if (countBefore != rows.length) onRowCountChanged.notify({previous:countBefore, current:rows.length}, null, self); + if (diff.length > 0) onRowsChanged.notify({rows:diff}, null, self); } diff --git a/slick.grid.js b/slick.grid.js index 12f5750..fe99047 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -459,7 +459,7 @@ if (typeof Slick === "undefined") { } setSortColumn(sortColumnId,sortAsc); - self.onSort.notify({sortCol:column,sortAsc:sortAsc}); + trigger(self.onSort, {sortCol:column,sortAsc:sortAsc}); } }); } @@ -488,7 +488,7 @@ if (typeof Slick === "undefined") { } setColumns(reorderedColumns); - self.onColumnsReordered.notify({}); + trigger(self.onColumnsReordered, {}); e.stopPropagation(); setupColumnResize(); } @@ -650,7 +650,7 @@ if (typeof Slick === "undefined") { } } resizeCanvas(); - self.onColumnsResized.notify({}); + trigger(self.onColumnsResized, {}); }); }); } @@ -726,7 +726,7 @@ if (typeof Slick === "undefined") { function destroy() { getEditorLock().cancelCurrentEdit(); - self.onBeforeDestroy.notify({}); + trigger(self.onBeforeDestro, {}); for (var i = 0; i < plugins.length; i++) { unregisterPlugin(plugin); @@ -747,6 +747,13 @@ if (typeof Slick === "undefined") { ////////////////////////////////////////////////////////////////////////////////////////////// // General + function trigger(evt, args, e) { + e = e || new Slick.EventData(); + args = args || args; + args.grid = self; + return evt.notify(args, e, self); + } + function getEditorLock() { return options.editorLock; } @@ -855,7 +862,7 @@ if (typeof Slick === "undefined") { setCellCssStyles(options.selectedCellCssClass, hash); - self.onSelectedRowsChanged.notify(e, getSelectedRows()); + trigger(self.onSelectedRowsChanged, {rows:getSelectedRows()}, e); } function getColumns() { @@ -965,7 +972,7 @@ if (typeof Slick === "undefined") { scrollDir = (prevScrollTop + oldOffset < newScrollTop + offset) ? 1 : -1; $viewport[0].scrollTop = (lastRenderedScrollTop = scrollTop = prevScrollTop = newScrollTop); - self.onViewportChanged.notify({}); + trigger(self.onViewportChanged, {}); } } @@ -1343,10 +1350,10 @@ if (typeof Slick === "undefined") { else h_render = setTimeout(render, 50); - self.onViewportChanged.notify({}); + trigger(self.onViewportChanged, {}); } - self.onScroll.notify({scrollLeft:scrollLeft, scrollTop:scrollTop}); + trigger(self.onScroll, {scrollLeft:scrollLeft, scrollTop:scrollTop}); } function asyncPostProcessRows() { @@ -1445,7 +1452,7 @@ if (typeof Slick === "undefined") { return false; } - retval = self.onDragInit.notify(e,dd); + retval = trigger(self.onDragInit, dd, e); if (e.isImmediatePropagationStopped()) { return retval; } @@ -1457,7 +1464,7 @@ if (typeof Slick === "undefined") { return false; } - var retval = self.onDragStart.notify(e,dd); + var retval = trigger(self.onDragStart, dd, e); if (e.isImmediatePropagationStopped()) { return retval; } @@ -1466,15 +1473,15 @@ if (typeof Slick === "undefined") { } function handleDrag(e,dd) { - return self.onDrag.notify(e,dd); + return trigger(self.onDrag, dd, e); } function handleDragEnd(e,dd) { - self.onDragEnd.notify(e,dd); + trigger(self.onDragEnd, dd, e); } function handleKeyDown(e) { - self.onKeyDown.notify(e, {}); + trigger(self.onKeyDown, {}, e); var handled = e.isImmediatePropagationStopped(); if (!handled) { @@ -1542,7 +1549,7 @@ if (typeof Slick === "undefined") { return; } - self.onClick.notify(e, {row:cell.row, cell:cell.cell}); + trigger(self.onClick, {row:cell.row, cell:cell.cell}, e); if (e.isImmediatePropagationStopped()) { return; } @@ -1562,7 +1569,7 @@ if (typeof Slick === "undefined") { // are we editing this cell? if (activeCellNode === $cell[0] && currentEditor !== null) { return; } - self.onContextMenu.notify(e,{}); + trigger(self.onContextMenu, {}, e); } function handleDblClick(e) { @@ -1571,7 +1578,7 @@ if (typeof Slick === "undefined") { return; } - self.onDblClick.notify(e, {row:cell.row, cell:cell.cell}); + trigger(self.onDblClick, {row:cell.row, cell:cell.cell}, e); if (e.isImmediatePropagationStopped()) { return; } @@ -1584,21 +1591,21 @@ if (typeof Slick === "undefined") { function handleHeaderContextMenu(e) { var $header = $(e.target).closest(".slick-header-column", ".slick-header-columns"); var column = $header && columns[self.getColumnIndex($header.data("fieldId"))]; - self.onHeaderContextMenu.notify(e, {column: column}); + trigger(self.onHeaderContextMenu, {column: column}, e); } function handleHeaderClick(e) { var $header = $(e.target).closest(".slick-header-column", ".slick-header-columns"); var column = $header && columns[self.getColumnIndex($header.data("fieldId"))]; - self.onHeaderClick.notify(e, {column: column}); + trigger(self.onHeaderClick, {column: column}, e); } function handleMouseEnter(e) { - self.onMouseEnter.notify(e,{}); + trigger(self.onMouseEnter, {}, e); } function handleMouseLeave(e) { - self.onMouseLeave.notify(e,{}); + trigger(self.onMouseLeave, {}, e); } function cellExists(row,cell) { @@ -1719,7 +1726,7 @@ if (typeof Slick === "undefined") { } if (activeCellChanged) { - self.onActiveCellChanged.notify(getActiveCell()); + trigger(self.onActiveCellChanged, getActiveCell()); } } @@ -1756,7 +1763,7 @@ if (typeof Slick === "undefined") { function makeActiveCellNormal() { if (!currentEditor) { return; } - self.onBeforeCellEditorDestroy.notify({editor:currentEditor}); + trigger(self.onBeforeCellEditorDestroy, {editor:currentEditor}); currentEditor.destroy(); currentEditor = null; @@ -1790,7 +1797,7 @@ if (typeof Slick === "undefined") { return; } - if (self.onBeforeEditCell.notify({row:activeRow, cell:activeCell,item:getDataItem(activeRow)}) === false) { + if (trigger(self.onBeforeEditCell, {row:activeRow, cell:activeCell,item:getDataItem(activeRow)}) === false) { focusOnActiveCell(); return; } @@ -1883,7 +1890,7 @@ if (typeof Slick === "undefined") { if (!activeCellNode) return; var cellBox; - self.onActiveCellPositionChanged.notify({}); + trigger(self.onActiveCellPositionChanged, {}); if (currentEditor) { cellBox = cellBox || getActiveCellPosition(); @@ -2103,7 +2110,7 @@ if (typeof Slick === "undefined") { makeActiveCellNormal(); } - self.onCellChange.notify({ + trigger(self.onCellChange, { row: activeRow, cell: activeCell, item: item @@ -2113,7 +2120,7 @@ if (typeof Slick === "undefined") { var newItem = {}; currentEditor.applyValue(newItem,currentEditor.serializeValue()); makeActiveCellNormal(); - self.onAddNewRow.notify({item:newItem, column:column}); + trigger(self.onAddNewRow, {item:newItem, column:column}); } // check whether the lock has been re-acquired by event handlers @@ -2124,7 +2131,7 @@ if (typeof Slick === "undefined") { $(activeCellNode).addClass("invalid"); $(activeCellNode).stop(true,true).effect("highlight", {color:"red"}, 300); - self.onValidationError.notify({ + trigger(self.onValidationError, { cellNode: activeCellNode, validationResults: validationResults, row: activeRow, diff --git a/tests/dataview/dataview.js b/tests/dataview/dataview.js index 492546d..6616248 100644 --- a/tests/dataview/dataview.js +++ b/tests/dataview/dataview.js @@ -163,7 +163,7 @@ test("refresh fires after resume", function() { var count = 0; dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [0,1], "args"); + same(args, {rows:[0,1]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -324,7 +324,7 @@ test("applied immediately", function() { dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [0], "args"); + same(args, {rows:[0]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -358,7 +358,7 @@ test("re-applied on refresh", function() { dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [0], "args"); + same(args, {rows:[0]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -434,7 +434,7 @@ test("all then none", function() { dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [0,1,2], "args"); + same(args, {rows:[0,1,2]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -467,7 +467,7 @@ test("basic", function() { dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [1], "args"); + same(args, {rows:[1]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -508,7 +508,7 @@ test("updating an item to pass the filter", function() { dv.setFilter(function(o) { return o["val"] !== 1337 }); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [3], "args"); + same(args, {rows:[3]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -589,7 +589,7 @@ test("basic", function() { dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [3], "args"); + same(args, {rows:[3]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -660,7 +660,7 @@ test("insert at the beginning", function() { dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [0,1,2,3], "args"); + same(args, {rows:[0,1,2,3]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -690,7 +690,7 @@ test("insert in the middle", function() { dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [2,3], "args"); + same(args, {rows:[2,3]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -720,7 +720,7 @@ test("insert at the end", function() { dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [3], "args"); + same(args, {rows:[3]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -804,7 +804,7 @@ test("delete at the beginning", function() { dv.setItems([{id:05,val:0},{id:15,val:1},{id:25,val:2}]); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [0,1], "args"); + same(args, {rows:[0,1]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { @@ -833,7 +833,7 @@ test("delete in the middle", function() { dv.setItems([{id:05,val:0},{id:15,val:1},{id:25,val:2}]); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); - same(args, [1], "args"); + same(args, {rows:[1]}, "args"); count++; }); dv.onRowCountChanged.subscribe(function(e,args) { From eeec6b216e33fcb43d974b2749578a01ed47e2c1 Mon Sep 17 00:00:00 2001 From: mleibman Date: Tue, 14 Dec 2010 17:21:26 -0800 Subject: [PATCH 0305/1043] Exposed getItem/getLength on the DataView to make it usable as a datasource for the grid directly (and not just through dataView.rows). That may help keep things a bit cleaner as the event handlers would be able to get the DataView by calling grid.getData(). --- examples/example4-model.html | 2 +- slick.dataview.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/example4-model.html b/examples/example4-model.html index 5154b58..8f9f316 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -187,7 +187,7 @@

      Demonstrates:

      dataView = new Slick.Data.DataView(); - grid = new Slick.Grid("#myGrid", dataView.rows, columns, options); + grid = new Slick.Grid("#myGrid", dataView, columns, options); grid.setSelectionModel(new Slick.RowSelectionModel()); var pager = new Slick.Controls.Pager(dataView, grid, $("#pager")); diff --git a/slick.dataview.js b/slick.dataview.js index f8272e7..4069c85 100644 --- a/slick.dataview.js +++ b/slick.dataview.js @@ -174,6 +174,14 @@ refresh(); } + function getLength() { + return rows.length; + } + + function getItem(i) { + return rows[i]; + } + function recalc(_items, _rows, _filter, _updated) { var diff = []; var items = _items, rows = _rows, filter = _filter, updated = _updated; // cache as local vars @@ -262,6 +270,9 @@ "addItem": addItem, "deleteItem": deleteItem, + "getLength": getLength, + "getItem": getItem, + // events "onRowCountChanged": onRowCountChanged, "onRowsChanged": onRowsChanged, From ad76e92c9ba8afcb01563837223bb790a86cf66b Mon Sep 17 00:00:00 2001 From: mleibman Date: Tue, 14 Dec 2010 18:11:14 -0800 Subject: [PATCH 0306/1043] Keyboard focus is now set on the canvas and not the individual cells to prevent forced scrolling by the browser. Re-rendering row with active cell no longer resets keyboard focus. --- slick.grid.js | 60 +++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index fe99047..a05a999 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -1009,6 +1009,9 @@ if (typeof Slick === "undefined") { var m = columns[i]; cellCss = "slick-cell c" + i + (m.cssClass ? " " + m.cssClass : ""); + if (row === activeRow && i === activeCell) { + cellCss += (" active"); + } // TODO: merge them together in the setter for (var key in cellCssClasses) { @@ -1256,8 +1259,9 @@ if (typeof Slick === "undefined") { renderedRows++; rows.push(i); appendRowHtml(stringArray,i); - if (activeCellNode && activeRow === i) + if (activeCellNode && activeRow === i) { needToReselectCell = true; + } counter_rows_rendered++; } @@ -1269,7 +1273,7 @@ if (typeof Slick === "undefined") { } if (needToReselectCell) { - setActiveCellInternal(getCellNode(activeRow,activeCell),false); + activeCellNode = getCellNode(activeRow,activeCell); } if (renderedRows - rowsBefore > 5) { @@ -1667,28 +1671,27 @@ if (typeof Slick === "undefined") { setActiveCellInternal(null,false); } - function focusOnActiveCell() { - // lazily enable the cell to receive keyboard focus - $(activeCellNode) - .attr("tabIndex",0) - .attr("hideFocus",true); - + function setFocus() { // IE7 tries to scroll the viewport so that the item being focused is aligned to the left border // IE-specific .setActive() sets the focus, but doesn't scroll if ($.browser.msie && parseInt($.browser.version) < 8) - activeCellNode.setActive(); + $canvas[0].setActive(); else - activeCellNode.focus(); - - var left = $(activeCellNode).position().left, - right = left + $(activeCellNode).outerWidth(), - scrollLeft = $viewport.scrollLeft(), - scrollRight = scrollLeft + $viewport.width(); + $canvas[0].focus(); + } - if (left < scrollLeft) - $viewport.scrollLeft(left); - else if (right > scrollRight) - $viewport.scrollLeft(Math.min(left, right - $viewport[0].clientWidth)); + function scrollActiveCellIntoView() { + if (activeCellNode) { + var left = $(activeCellNode).position().left, + right = left + $(activeCellNode).outerWidth(), + scrollLeft = $viewport.scrollLeft(), + scrollRight = scrollLeft + $viewport.width(); + + if (left < scrollLeft) + $viewport.scrollLeft(left); + else if (right > scrollRight) + $viewport.scrollLeft(Math.min(left, right - $viewport[0].clientWidth)); + } } function setActiveCellInternal(newCell,editMode) { @@ -1717,7 +1720,7 @@ if (typeof Slick === "undefined") { } } else { - focusOnActiveCell() + setFocus(); } } else { @@ -1726,6 +1729,7 @@ if (typeof Slick === "undefined") { } if (activeCellChanged) { + scrollActiveCellIntoView(); trigger(self.onActiveCellChanged, getActiveCell()); } } @@ -1798,7 +1802,7 @@ if (typeof Slick === "undefined") { } if (trigger(self.onBeforeEditCell, {row:activeRow, cell:activeCell,item:getDataItem(activeRow)}) === false) { - focusOnActiveCell(); + setFocus(); return; } @@ -1834,7 +1838,7 @@ if (typeof Slick === "undefined") { // if the commit fails, it would do so due to a validation error // if so, do not steal the focus from the editor if (getEditorLock().commitCurrentEdit()) { - focusOnActiveCell(); + setFocus(); if (options.autoEdit) { navigateDown(); @@ -1844,7 +1848,7 @@ if (typeof Slick === "undefined") { function cancelEditAndSetFocus() { if (getEditorLock().cancelCurrentEdit()) { - focusOnActiveCell(); + setFocus(); } } @@ -1987,13 +1991,13 @@ if (typeof Slick === "undefined") { scrollRowIntoView(row,!isAddNewRow); setActiveCellInternal(nextCell[0], isAddNewRow || options.autoEdit); - // if no editor was created, set the focus back on the cell + // if no editor was created, set the focus back on the grid if (!currentEditor) { - focusOnActiveCell(); + setFocus(); } } else { - focusOnActiveCell(); + setFocus(); } } @@ -2041,9 +2045,9 @@ if (typeof Slick === "undefined") { // if selecting the 'add new' row, start editing right away setActiveCellInternal(newCell, forceEdit || (row === getDataLength()) || options.autoEdit); - // if no editor was created, set the focus back on the cell + // if no editor was created, set the focus back on the grid if (!currentEditor) { - focusOnActiveCell(); + setFocus(); } } From 60f0bac398c1fb6930a327a48cdc022e8033f5de Mon Sep 17 00:00:00 2001 From: mleibman Date: Wed, 15 Dec 2010 12:12:46 -0800 Subject: [PATCH 0307/1043] Fixed the scroll position jumping when trying to set focus in IE. --- slick.grid.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index a05a999..8df306b 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -1672,12 +1672,14 @@ if (typeof Slick === "undefined") { } function setFocus() { - // IE7 tries to scroll the viewport so that the item being focused is aligned to the left border + // IE tries to scroll the viewport so that the item being focused is aligned to the left border // IE-specific .setActive() sets the focus, but doesn't scroll - if ($.browser.msie && parseInt($.browser.version) < 8) + if ($.browser.msie) { $canvas[0].setActive(); - else + } + else { $canvas[0].focus(); + } } function scrollActiveCellIntoView() { @@ -1691,7 +1693,7 @@ if (typeof Slick === "undefined") { $viewport.scrollLeft(left); else if (right > scrollRight) $viewport.scrollLeft(Math.min(left, right - $viewport[0].clientWidth)); - } + } } function setActiveCellInternal(newCell,editMode) { From 856ea33f2d67379bfa908902425ffe93ae4ce514 Mon Sep 17 00:00:00 2001 From: mleibman Date: Fri, 17 Dec 2010 10:49:58 -0800 Subject: [PATCH 0308/1043] Minor fixes to examples. --- examples/example5-collapsing.html | 2 +- examples/example9-row-reordering.html | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/example5-collapsing.html b/examples/example5-collapsing.html index 008293e..03126ed 100644 --- a/examples/example5-collapsing.html +++ b/examples/example5-collapsing.html @@ -210,7 +210,7 @@

      Demonstrates:

      dataView.updateItem(item.id, item); } - e.stopPropagation(); + e.stopImmediatePropagation(); } }); diff --git a/examples/example9-row-reordering.html b/examples/example9-row-reordering.html index 016d4ea..cc32a4d 100644 --- a/examples/example9-row-reordering.html +++ b/examples/example9-row-reordering.html @@ -83,6 +83,7 @@ + @@ -151,12 +152,9 @@ { name: "Find out who's nice", complete: false} ]; - data = data.concat(data); - data = data.concat(data); - grid = new Slick.Grid("#myGrid", data, columns, options); - grid.setSelectionModel(new Slick.CellSelectionModel()); + grid.setSelectionModel(new Slick.RowSelectionModel()); var moveRowsPlugin = new Slick.RowMoveManager(); From aef2ee2cda172d134f8359d6b6780b6791a5f077 Mon Sep 17 00:00:00 2001 From: mleibman Date: Fri, 17 Dec 2010 22:18:33 -0800 Subject: [PATCH 0309/1043] Changed the grid to read the dimensions from the computed style instead of actual elements. This fixes the issues displaying the grid in an initially hidden container. --- examples/example-checkbox-row-select.html | 1 + examples/example-header-row.html | 1 + examples/example-spreadsheet.html | 1 + examples/example1-simple.html | 11 ++-- examples/example10-async-post-render.html | 19 +++--- examples/example11-autoheight.html | 11 ++-- examples/example12-fillbrowser.html | 9 +-- examples/example13-getItem-sorting.html | 9 +-- examples/example14-highlighting.html | 23 ++++--- examples/example2-formatters.html | 17 +++--- examples/example3-editing.html | 21 ++++--- examples/example3a-compound-editors.html | 17 +++--- examples/example3b-editing-with-undo.html | 19 +++--- examples/example4-model.html | 25 ++++---- examples/example5-collapsing.html | 19 +++--- examples/example6-ajax-loading.html | 19 +++--- examples/example7-events.html | 17 +++--- examples/example8-alternative-display.html | 13 ++-- examples/example9-row-reordering.html | 27 ++++---- lib/jquery.curstyles.min.js | 2 + slick.grid.js | 71 +++++++++++++--------- tests/model benchmarks.html | 10 +-- tests/scrolling benchmarks.html | 20 +++--- 23 files changed, 208 insertions(+), 174 deletions(-) create mode 100644 lib/jquery.curstyles.min.js diff --git a/examples/example-checkbox-row-select.html b/examples/example-checkbox-row-select.html index 9ce8132..b16a04f 100644 --- a/examples/example-checkbox-row-select.html +++ b/examples/example-checkbox-row-select.html @@ -30,6 +30,7 @@

      Demonstrates:

      + diff --git a/examples/example-header-row.html b/examples/example-header-row.html index 16d5cb2..2ef383b 100644 --- a/examples/example-header-row.html +++ b/examples/example-header-row.html @@ -34,6 +34,7 @@

      Demonstrates:

      + diff --git a/examples/example-spreadsheet.html b/examples/example-spreadsheet.html index 8f56671..3534322 100644 --- a/examples/example-spreadsheet.html +++ b/examples/example-spreadsheet.html @@ -33,6 +33,7 @@

      Demonstrates:

      + diff --git a/examples/example1-simple.html b/examples/example1-simple.html index 648e56a..1f5dcf1 100644 --- a/examples/example1-simple.html +++ b/examples/example1-simple.html @@ -1,4 +1,4 @@ - + @@ -22,11 +22,12 @@

      Demonstrates:

      - - + + + - - + + + - - - - + + + + + - - - + + + - - + + + + - - + + - + + + - - + + - - - + + + + + + - - - + + + + - - - - - + + + + + + - - - + + + + - - - + + + + - - - + + + + - - - - - + + + + + + - - - + + + + - - - + + + + - - - + + + + - - - + + + + - - - + + + + - - - - - - - + + + + + + + + - - - + + + + - - - - + + + + + - - - - + + + + + - - - + + + + - - - + + + + - - - + + + - + - - + + + - - + + + - - - - + + + + + - - - - - + + + + + - - + + - - - + + + + - - - + + + + + - - - + + + @@ -62,7 +63,8 @@ editable: false, enableAddRow: false, enableCellNavigation: true, - enableAsyncPostRender: true + enableAsyncPostRender: true, + forceFitColumns: true }; From 7b1b2870b0a3c4f999e143e31e7a5f6e19943f6e Mon Sep 17 00:00:00 2001 From: mleibman Date: Sun, 19 Dec 2010 14:45:06 -0800 Subject: [PATCH 0310/1043] Added range checking to RowSelectionModel. --- plugins/slick.rowselectionmodel.js | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/plugins/slick.rowselectionmodel.js b/plugins/slick.rowselectionmodel.js index 19b7333..40986c7 100644 --- a/plugins/slick.rowselectionmodel.js +++ b/plugins/slick.rowselectionmodel.js @@ -94,38 +94,24 @@ var top = selectedRows[0]; var bottom = selectedRows[selectedRows.length - 1]; + var active; if (e.which == 40) { - if (activeRow.row < bottom || top == bottom) { - bottom++; - _grid.scrollRowIntoView(bottom); - } - else { - top++; - _grid.scrollRowIntoView(top); - } + active = activeRow.row < bottom || top == bottom ? ++bottom : ++top; } else { - if (activeRow.row < bottom) { - bottom--; - _grid.scrollRowIntoView(bottom); - } else { - top--; - _grid.scrollRowIntoView(top); - } + active = activeRow.row < bottom ? --bottom : --top; } - selectedRows = getRowsRange(top,bottom); - _ranges = rowsToRanges(selectedRows); - - setSelectedRanges(_ranges); + if (active >= 0 && active < _grid.getDataLength()) { + _grid.scrollRowIntoView(active); + _ranges = rowsToRanges(getRowsRange(top,bottom)); + setSelectedRanges(_ranges); + } e.preventDefault(); e.stopPropagation(); - return true; } - - return false; } function handleClick(e) { From 0348f082ee7faf067aa3c099103cb5b5c2576544 Mon Sep 17 00:00:00 2001 From: mleibman Date: Sun, 19 Dec 2010 14:47:07 -0800 Subject: [PATCH 0311/1043] Added comments to the spreadsheet example. --- examples/example-spreadsheet.html | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/example-spreadsheet.html b/examples/example-spreadsheet.html index 3534322..1d4a99c 100644 --- a/examples/example-spreadsheet.html +++ b/examples/example-spreadsheet.html @@ -25,6 +25,7 @@

      Demonstrates:

    • Select a range of cells with a mouse
    • Use Ctrl-C and Ctrl-V keyboard shortcuts to cut and paste cells
    • Use Esc to cancel a copy and paste operation
    • +
    • Edit the cell and select a cell range to paste the range
    • From 4c5133600fc0a23a6a72750fbe8bb86e38575aad Mon Sep 17 00:00:00 2001 From: mleibman Date: Sun, 19 Dec 2010 16:27:06 -0800 Subject: [PATCH 0312/1043] Fixed RowSelectionModel destructor. Added a check for jQuery.curStyles to Slick.Grid. --- plugins/slick.rowselectionmodel.js | 2 +- slick.grid.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/slick.rowselectionmodel.js b/plugins/slick.rowselectionmodel.js index 40986c7..c745073 100644 --- a/plugins/slick.rowselectionmodel.js +++ b/plugins/slick.rowselectionmodel.js @@ -26,7 +26,7 @@ function destroy() { _grid.onActiveCellChanged.unsubscribe(handleActiveCellChange); _grid.onKeyDown.unsubscribe(handleKeyDown); - _grid.onClick.unsubscribe(handleClick()); + _grid.onClick.unsubscribe(handleClick); } function rangesToRows(ranges) { diff --git a/slick.grid.js b/slick.grid.js index fbe0e80..ad42650 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -22,6 +22,9 @@ if (typeof jQuery === "undefined") { if (!jQuery.fn.drag) { throw "SlickGrid requires jquery.event.drag module to be loaded"; } +if (!jQuery.fn.curStyles) { + throw "SlickGrid requires jquery.curstyles module to be loaded"; +} if (typeof Slick === "undefined") { throw "slick.core.js not loaded"; } From d3879b9b20c9322f623e806239e3614d17b72fac Mon Sep 17 00:00:00 2001 From: mleibman Date: Mon, 20 Dec 2010 12:03:14 -0800 Subject: [PATCH 0313/1043] Fixed a typo in onBeforeDestroy. --- slick.grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slick.grid.js b/slick.grid.js index ad42650..a1fa7da 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -746,7 +746,7 @@ if (typeof Slick === "undefined") { function destroy() { getEditorLock().cancelCurrentEdit(); - trigger(self.onBeforeDestro, {}); + trigger(self.onBeforeDestroy, {}); for (var i = 0; i < plugins.length; i++) { unregisterPlugin(plugin); From 9e40119ca280e0f3046cd4dfd27bf41058280332 Mon Sep 17 00:00:00 2001 From: mleibman Date: Mon, 20 Dec 2010 12:44:31 -0800 Subject: [PATCH 0314/1043] Removed jquery.curStyles pluging and replaced all uses of curStyles and the now deprecated curCSS with the regular jQuery css() since it now returns computed styles and normalizes the units. Changed dimensions variables from ints to floats to better work with browser zooming. Zooming is still mostly broken though due to buggy browser implementations. IE and FF can be worked around, but Chrome rounds up all returned computed styles, so we're out of luck. --- examples/example-checkbox-row-select.html | 1 - examples/example-header-row.html | 1 - examples/example-spreadsheet.html | 1 - examples/example1-simple.html | 5 +++-- examples/example10-async-post-render.html | 1 - examples/example11-autoheight.html | 1 - examples/example12-fillbrowser.html | 1 - examples/example13-getItem-sorting.html | 1 - examples/example14-highlighting.html | 1 - examples/example2-formatters.html | 1 - examples/example3-editing.html | 1 - examples/example3a-compound-editors.html | 1 - examples/example3b-editing-with-undo.html | 1 - examples/example4-model.html | 1 - examples/example5-collapsing.html | 1 - examples/example6-ajax-loading.html | 1 - examples/example7-events.html | 1 - examples/example8-alternative-display.html | 1 - examples/example9-row-reordering.html | 1 - lib/jquery.curstyles.min.js | 2 -- slick.grid.js | 24 ++++++++-------------- tests/scrolling benchmarks.html | 1 - 22 files changed, 12 insertions(+), 38 deletions(-) delete mode 100644 lib/jquery.curstyles.min.js diff --git a/examples/example-checkbox-row-select.html b/examples/example-checkbox-row-select.html index b16a04f..9ce8132 100644 --- a/examples/example-checkbox-row-select.html +++ b/examples/example-checkbox-row-select.html @@ -30,7 +30,6 @@

      Demonstrates:

      - diff --git a/examples/example-header-row.html b/examples/example-header-row.html index 2ef383b..16d5cb2 100644 --- a/examples/example-header-row.html +++ b/examples/example-header-row.html @@ -34,7 +34,6 @@

      Demonstrates:

      - diff --git a/examples/example-spreadsheet.html b/examples/example-spreadsheet.html index 1d4a99c..df31fec 100644 --- a/examples/example-spreadsheet.html +++ b/examples/example-spreadsheet.html @@ -34,7 +34,6 @@

      Demonstrates:

      - diff --git a/examples/example1-simple.html b/examples/example1-simple.html index 1f5dcf1..2abbc4c 100644 --- a/examples/example1-simple.html +++ b/examples/example1-simple.html @@ -11,7 +11,7 @@ @@ -60,11 +59,7 @@

      Demonstrates:

      var options = { editable: false, enableAddRow: false, - enableCellNavigation: true, - rowCssClasses: function(item) { - // if a task is 100% done then its row gets an additional CSS class - return (item.percentComplete == 100) ? 'complete' : ''; - } + enableCellNavigation: true }; diff --git a/examples/example3-editing.html b/examples/example3-editing.html index 8cb96b8..dcedf94 100644 --- a/examples/example3-editing.html +++ b/examples/example3-editing.html @@ -17,23 +17,25 @@ -
      -
      -
      +
      +
      +
      +
      -
      -

      Demonstrates:

      -
        -
      • adding basic keyboard navigation and editing
      • -
      • custom editors and validators
      • -
      • auto-edit settings
      • -
      +
      +

      Demonstrates:

      +
        +
      • adding basic keyboard navigation and editing
      • +
      • custom editors and validators
      • +
      • auto-edit settings
      • +
      -

      Options:

      - -   - -
      +

      Options:

      + +   + +
      +
      diff --git a/examples/example3a-compound-editors.html b/examples/example3a-compound-editors.html index dc738eb..4f1e6c5 100644 --- a/examples/example3a-compound-editors.html +++ b/examples/example3a-compound-editors.html @@ -14,12 +14,12 @@ - -
      +
      +
      -
      +

      Demonstrates:

      • compound cell editors driving multiple fields from one cell
      • @@ -27,6 +27,7 @@

        Demonstrates:

      • hooking into validation events
      +
      diff --git a/examples/example3b-editing-with-undo.html b/examples/example3b-editing-with-undo.html index 64af216..6c14b98 100644 --- a/examples/example3b-editing-with-undo.html +++ b/examples/example3b-editing-with-undo.html @@ -17,11 +17,12 @@ -
      +
      +
      -
      +

      Demonstrates:

      • Using "editCommandHandler" option to intercept edit commands and implement undo support
      • @@ -30,6 +31,7 @@

        Demonstrates:

        Controls:

      +
      diff --git a/examples/example4-model.html b/examples/example4-model.html index 0bfe897..d961d6b 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -32,7 +32,8 @@ -
      +
      +
      @@ -41,7 +42,7 @@
      -
      +
      Search:
      @@ -54,28 +55,27 @@

      + +
      +

      Demonstrates:

      +
        +
      • a filtered Model (DataView) as a data source instead of a simple array
      • +
      • grid reacting to model events (onRowCountChanged, onRowsChanged)
      • +
      • + FAST DataView recalculation and real-time grid updating in response to data changes.
        + The grid holds 50'000 rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows. +
      • +
      • adding new rows, bidirectional sorting
      • +
      • column options: cannotTriggerInsert
      • +
      • events: onCellChange, onAddNewRow, onKeyDown, onSelectedRowsChanged, onSort
      • +
      • NOTE: all filters are immediately applied to new/edited rows
      • +
      • Handling row selection against model changes.
      • +
      • Paging.
      • +
      • inline filter panel
      • +
      - -
      -

      Demonstrates:

      - -
        -
      • a filtered Model (DataView) as a data source instead of a simple array
      • -
      • grid reacting to model events (onRowCountChanged, onRowsChanged)
      • -
      • - FAST DataView recalculation and real-time grid updating in response to data changes.
        - The grid holds 50'000 rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 rows. -
      • -
      • adding new rows, bidirectional sorting
      • -
      • column options: cannotTriggerInsert
      • -
      • events: onCellChange, onAddNewRow, onKeyDown, onSelectedRowsChanged, onSort
      • -
      • NOTE: all filters are immediately applied to new/edited rows
      • -
      • Handling row selection against model changes.
      • -
      • Paging.
      • -
      • inline filter panel
      • -
      -
      +
      -
      -

      Demonstrates:

      - -
        -
      • - Fully dynamic and interactive grouping with filtering and aggregates over 10'000 items
        - Personally, this is just the coolest slickest thing I've ever seen done with DHTML grids! -
      • -
      -
      @@ -103,21 +101,18 @@

      Demonstrates:

      var sortcol = "title"; var sortdir = 1; var percentCompleteThreshold = 0; + var prevPercentCompleteThreshold = 0; var searchString = ""; function avgTotalsFormatter(totals, columnDef) { return "avg: " + Math.round(totals.avg[columnDef.field]) + "%"; } - function myFilter(item) { - if (item["percentComplete"] < percentCompleteThreshold) - return false; - - if (searchString != "" && item["title"].indexOf(searchString) == -1) - return false; - - return true; - } + function myFilter(item, args) { + return item["percentComplete"] >= args.percentComplete && + (args.searchString == "" || + item["title"].indexOf(args.searchString) == -1); + } function percentCompleteSort(a,b) { return a["percentComplete"] - b["percentComplete"]; @@ -226,7 +221,6 @@

      Demonstrates:

      // register the group item metadata provider to add expand/collapse group handlers grid.registerPlugin(groupItemMetadataProvider); - grid.setSelectionModel(new Slick.CellSelectionModel()); var pager = new Slick.Controls.Pager(dataView, grid, $("#pager")); @@ -284,7 +278,7 @@

      Demonstrates:

      if (percentCompleteThreshold != ui.value) { window.clearTimeout(h_runfilters); - h_runfilters = window.setTimeout(function() { dataView.refresh() }, 10); + h_runfilters = window.setTimeout(filterAndUpdate, 10); percentCompleteThreshold = ui.value; } } @@ -304,10 +298,34 @@

      Demonstrates:

      }); + function filterAndUpdate() { + var isNarrowing = percentCompleteThreshold > prevPercentCompleteThreshold; + var isExpanding = percentCompleteThreshold < prevPercentCompleteThreshold; + var renderedRange = grid.getRenderedRange(); + + dataView.setFilterArgs({ + percentComplete: percentCompleteThreshold, + searchString: searchString + }); + dataView.setRefreshHints({ + ignoreDiffsBefore:renderedRange.top, + ignoreDiffsAfter:renderedRange.bottom + 1, + isFilterNarrowing:isNarrowing, + isFilterExpanding:isExpanding + }); + dataView.refresh(); + + prevPercentCompleteThreshold = percentCompleteThreshold; + } + // initialize the model after all the events have been hooked up dataView.beginUpdate(); dataView.setItems(data); dataView.setFilter(myFilter); + dataView.setFilterArgs({ + percentComplete: percentCompleteThreshold, + searchString: searchString + }); dataView.groupBy( "duration", function (g) { diff --git a/examples/example-optimizing-dataview.html b/examples/example-optimizing-dataview.html index 988e12a..b08df7f 100644 --- a/examples/example-optimizing-dataview.html +++ b/examples/example-optimizing-dataview.html @@ -100,20 +100,10 @@ var searchString = ""; var h_runfilters = null; - - function myFilter(items, args) { - var item, idx = 0; - var out = []; - for (var i = 0, il = items.length; i < il; i++) { - item = items[i]; - if (item["percentComplete"] >= args) { - out[idx++] = item; - } - } - return out; + function myFilter(item, args) { + return item["percentComplete"] >= args; } - function DataItem(i) { this.num = i; this.id = "id_" + i; @@ -132,9 +122,7 @@ data[i] = new DataItem(i); } - dataView = new Slick.Data.DataView({ - batchFilter: true - }); + dataView = new Slick.Data.DataView(); grid = new Slick.Grid("#myGrid", dataView, columns, options); var pager = new Slick.Controls.Pager(dataView, grid, $("#pager")); diff --git a/slick.dataview.js b/slick.dataview.js index 94d3018..56370ce 100644 --- a/slick.dataview.js +++ b/slick.dataview.js @@ -23,8 +23,7 @@ var self = this; var defaults = { - groupItemMetadataProvider: null, - batchFilter: false + groupItemMetadataProvider: null }; @@ -44,6 +43,9 @@ var prevRefreshHints = {}; var filterArgs; var filteredItems = []; + var compiledFilter; + var compiledFilterWithCaching; + var filterCache = []; // grouping var groupingGetter; @@ -181,6 +183,8 @@ function setFilter(filterFn) { filter = filterFn; + compiledFilter = compileFilter(); + compiledFilterWithCaching = compileFilterWithCaching(); refresh(); } @@ -316,7 +320,7 @@ var group; var val; var groups = []; - var groupsByVal = {}; + var groupsByVal = []; var r; for (var i = 0, l = rows.length; i < l; i++) { @@ -339,20 +343,6 @@ return groups; } - function compileAccumulatorLoop(aggregator) { - var fnRegex = /^function[^(]*\(([^)]*)\)\s*{([\s\S]*)}$/; - var fnParts = aggregator.accumulate.toString().match(fnRegex); - var itemParamName = fnParts[1], body = fnParts[2]; - - return new Function( - "_items", - "for (var " + itemParamName + ", _i=0, _il=_items.length; _i<_il; _i++) {" + - itemParamName + " = _items[_i]; " + - body + - "}" - ); - } - // TODO: lazy totals calculation function calculateGroupTotals(group) { if (group.collapsed && !aggregateCollapsed) { @@ -407,28 +397,87 @@ return groupedRows; } - // TODO: inline filter execution similar to accumulators - function getBatchFilteringFn() { - return function(data, args) { - var item, retval = [], idx = 0; - for (var i = 0, il = data.length; i < il; i++) { - item = data[i]; - if (filter(item)) { - retval[idx++] = item; + function getFunctionInfo(fn) { + var fnRegex = /^function[^(]*\(([^)]*)\)\s*{([\s\S]*)}$/; + var matches = fn.toString().match(fnRegex); + return { + params: matches[1].split(","), + body: matches[2] + }; + } + + function compileAccumulatorLoop(aggregator) { + var accumulatorInfo = getFunctionInfo(aggregator.accumulate); + + return new Function( + "_items", + "for (var " + accumulatorInfo.params[0] + ", _i=0, _il=_items.length; _i<_il; _i++) {" + + accumulatorInfo.params[0] + " = _items[_i]; " + + accumulatorInfo.body + + "}" + ); + } + + function compileFilter() { + var filterInfo = getFunctionInfo(filter); + + var filterBody = filterInfo.body.replace(/return ([^;]+?);/gi, + "if ($1) { _retval[_idx++] = $item$; }; continue;"); + + var fnTemplate = function(_items, _args) { + var _retval = [], _idx = 0; + var $item$, $args$ = _args; + for (var _i = 0, _il = _items.length; _i < _il; _i++) { + $item$ = _items[_i]; + $filter$; + } + return _retval; + }; + + var tpl = getFunctionInfo(fnTemplate).body; + tpl = tpl.replace(/\$filter\$/gi, filterBody); + tpl = tpl.replace(/\$item\$/gi, filterInfo.params[0]); + tpl = tpl.replace(/\$args\$/gi, filterInfo.params[1]); + + return new Function("_items,_args", tpl); + } + + function compileFilterWithCaching() { + var filterInfo = getFunctionInfo(filter); + + var filterBody = filterInfo.body.replace(/return ([^;]+?);/gi, + "if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue;"); + + var fnTemplate = function(_items, _args, _cache) { + var _retval = [], _idx = 0; + var $item$, $args$ = _args; + for (var _i = 0, _il = _items.length; _i < _il; _i++) { + $item$ = _items[_i]; + if (_cache[_i]) { + _retval[_idx++] = $item$; + continue; } + $filter$; } - return retval; + return _retval; }; + + var tpl = getFunctionInfo(fnTemplate).body; + tpl = tpl.replace(/\$filter\$/gi, filterBody); + tpl = tpl.replace(/\$item\$/gi, filterInfo.params[0]); + tpl = tpl.replace(/\$args\$/gi, filterInfo.params[1]); + + return new Function("_items,_args,_cache", tpl); } function getFilteredAndPagedItems(items) { if (filter && !refreshHints.isFilterUnchanged) { - var filterFn = options.batchFilter ? filter : getBatchFilteringFn(); - if (refreshHints.isFilterNarrowing) { - filteredItems = filterFn(filteredItems, filterArgs); + filteredItems = compiledFilter(filteredItems, filterArgs); + } else if (refreshHints.isFilterExpanding) { + filteredItems = compiledFilterWithCaching(items, filterArgs, filterCache); } else { - filteredItems = filterFn(items, filterArgs); + filteredItems = compiledFilter(items, filterArgs); } } else { // special case: if not filtering and not paging, the resulting @@ -495,6 +544,11 @@ function recalc(_items) { rowsById = null; + if (refreshHints.isFilterNarrowing != prevRefreshHints.isFilterNarrowing || + refreshHints.isFilterExpanding != prevRefreshHints.isFilterExpanding) { + filterCache = []; + } + var filteredItems = getFilteredAndPagedItems(_items); totalRows = filteredItems.totalRows; var newRows = filteredItems.rows; diff --git a/tests/dataview/dataview.js b/tests/dataview/dataview.js index b0c9260..04278c1 100644 --- a/tests/dataview/dataview.js +++ b/tests/dataview/dataview.js @@ -155,7 +155,7 @@ test("refresh fires after resume", function() { dv.beginUpdate(); dv.setItems([{id:0},{id:1}]); same(dv.getItems().length, 2, "items updated immediately"); - dv.setFilter(function(o) { return true }); + dv.setFilter(function(o) { return true; }); dv.refresh(); var count = 0; @@ -259,7 +259,7 @@ test("applied immediately", function() { same(args.totalRows, 1, "totalRows arg"); count++; }); - dv.setFilter(function(o) { return o.val === 1 }); + dv.setFilter(function(o) { return o.val === 1; }); equal(count, 3, "events fired"); same(dv.getItems().length, 3, "original data is still there"); same(dv.getLength(), 1, "rows are filtered"); @@ -268,10 +268,10 @@ test("applied immediately", function() { test("re-applied on refresh", function() { var count = 0; - var filterVal = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.setFilter(function(o) { return o.val >= filterVal }); + dv.setFilterArgs(0); + dv.setFilter(function(o, args) { return o.val >= args; }); same(dv.getLength(), 3, "nothing is filtered out"); assertConsistency(dv); @@ -293,7 +293,7 @@ test("re-applied on refresh", function() { same(args.totalRows, 1, "totalRows arg"); count++; }); - filterVal = 2; + dv.setFilterArgs(2); dv.refresh(); equal(count, 3, "events fired"); same(dv.getItems().length, 3, "original data is still there"); @@ -304,13 +304,13 @@ test("re-applied on refresh", function() { test("re-applied on sort", function() { var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.setFilter(function(o) { return o.val === 1 }); + dv.setFilter(function(o) { return o.val === 1; }); same(dv.getLength(), 1, "one row is remaining"); dv.onRowsChanged.subscribe(function() { ok(false, "onRowsChanged called") }); dv.onRowCountChanged.subscribe(function() { ok(false, "onRowCountChanged called") }); dv.onPagingInfoChanged.subscribe(function() { ok(false, "onPagingInfoChanged called") }); - dv.sort(function(x,y) { return x.val-y.val }, false); + dv.sort(function(x,y) { return x.val-y.val; }, false); same(dv.getItems().length, 3, "original data is still there"); same(dv.getLength(), 1, "rows are filtered"); assertConsistency(dv); @@ -336,7 +336,7 @@ test("all", function() { same(args.totalRows, 0, "totalRows arg"); count++; }); - dv.setFilter(function(o) { return false }); + dv.setFilter(function(o) { return false; }); equal(count, 2, "events fired"); same(dv.getItems().length, 3, "original data is still there"); same(dv.getLength(), 0, "rows are filtered"); @@ -344,11 +344,11 @@ test("all", function() { }); test("all then none", function() { - var filterResult = false; var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.setFilter(function(o) { return filterResult }); + dv.setFilterArgs(false); + dv.setFilter(function(o, args) { return args; }); same(dv.getLength(), 0, "all rows are filtered out"); dv.onRowsChanged.subscribe(function(e,args) { @@ -369,7 +369,7 @@ test("all then none", function() { same(args.totalRows, 3, "totalRows arg"); count++; }); - filterResult = true; + dv.setFilterArgs(true); dv.refresh(); equal(count, 3, "events fired"); same(dv.getItems().length, 3, "original data is still there"); @@ -405,7 +405,7 @@ test("basic", function() { test("updating an item not passing the filter", function() { var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2},{id:3,val:1337}]); - dv.setFilter(function(o) { return o["val"] !== 1337 }); + dv.setFilter(function(o) { return o["val"] !== 1337; }); dv.onRowsChanged.subscribe(function(e,args) { ok(false, "onRowsChanged called"); }); @@ -424,7 +424,7 @@ test("updating an item to pass the filter", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2},{id:3,val:1337}]); - dv.setFilter(function(o) { return o["val"] !== 1337 }); + dv.setFilter(function(o) { return o["val"] !== 1337; }); dv.onRowsChanged.subscribe(function(e,args) { ok(true, "onRowsChanged called"); same(args, {rows:[3]}, "args"); @@ -453,7 +453,7 @@ test("updating an item to not pass the filter", function() { var count = 0; var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2},{id:3,val:3}]); - dv.setFilter(function(o) { return o["val"] !== 1337 }); + dv.setFilter(function(o) { return o["val"] !== 1337; }); dv.onRowsChanged.subscribe(function(e,args) { console.log(args) ok(false, "onRowsChanged called"); @@ -534,7 +534,7 @@ test("basic", function() { test("add an item not passing the filter", function() { var dv = new Slick.Data.DataView(); dv.setItems([{id:0,val:0},{id:1,val:1},{id:2,val:2}]); - dv.setFilter(function(o) { return o["val"] !== 1337 }); + dv.setFilter(function(o) { return o["val"] !== 1337; }); dv.onRowsChanged.subscribe(function(e,args) { ok(false, "onRowsChanged called"); }); diff --git a/tests/model benchmarks.html b/tests/model benchmarks.html index 86eed7a..ffd3470 100644 --- a/tests/model benchmarks.html +++ b/tests/model benchmarks.html @@ -1,64 +1,97 @@ - - - SlickGrid Model Benchmark - - - - - - - - - - + + + SlickGrid Model Benchmark + + + + + + + + + From 0f196f62c6ae1ce642c683b81fb37a97fa2eac6f Mon Sep 17 00:00:00 2001 From: Michael Leibman Date: Sat, 5 Nov 2011 10:46:52 -0700 Subject: [PATCH 0356/1043] Fixed example4 and a bug in a DataView filter compilation. --- examples/example4-model.html | 22 +++++++++++++++++----- slick.dataview.js | 4 ++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/examples/example4-model.html b/examples/example4-model.html index d961d6b..4c85975 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -133,11 +133,11 @@

      Demonstrates:

      return {valid:true, msg:null}; } - function myFilter(item) { - if (item["percentComplete"] < percentCompleteThreshold) + function myFilter(item, args) { + if (item["percentComplete"] < args.percentCompleteThreshold) return false; - if (searchString != "" && item["title"].indexOf(searchString) == -1) + if (args.searchString != "" && item["title"].indexOf(args.searchString) == -1) return false; return true; @@ -311,7 +311,7 @@

      Demonstrates:

      if (percentCompleteThreshold != ui.value) { window.clearTimeout(h_runfilters); - h_runfilters = window.setTimeout(dataView.refresh, 10); + h_runfilters = window.setTimeout(updateFilter, 10); percentCompleteThreshold = ui.value; } } @@ -327,9 +327,17 @@

      Demonstrates:

      this.value = ""; searchString = this.value; - dataView.refresh(); + updateFilter(); }); + function updateFilter() { + dataView.setFilterArgs({ + percentCompleteThreshold: percentCompleteThreshold, + searchString: searchString + }); + dataView.refresh(); + } + $("#btnSelectRows").click(function() { if (!Slick.GlobalEditorLock.commitCurrentEdit()) { return; } @@ -348,6 +356,10 @@

      Demonstrates:

      // initialize the model after all the events have been hooked up dataView.beginUpdate(); dataView.setItems(data); + dataView.setFilterArgs({ + percentCompleteThreshold: percentCompleteThreshold, + searchString: searchString + }); dataView.setFilter(myFilter); dataView.endUpdate(); diff --git a/slick.dataview.js b/slick.dataview.js index 56370ce..e3708f8 100644 --- a/slick.dataview.js +++ b/slick.dataview.js @@ -422,7 +422,7 @@ var filterInfo = getFunctionInfo(filter); var filterBody = filterInfo.body.replace(/return ([^;]+?);/gi, - "if ($1) { _retval[_idx++] = $item$; }; continue;"); + "{ if ($1) { _retval[_idx++] = $item$; }; continue; }"); var fnTemplate = function(_items, _args) { var _retval = [], _idx = 0; @@ -446,7 +446,7 @@ var filterInfo = getFunctionInfo(filter); var filterBody = filterInfo.body.replace(/return ([^;]+?);/gi, - "if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue;"); + "{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue; }"); var fnTemplate = function(_items, _args, _cache) { var _retval = [], _idx = 0; From 2cf1754957815f655a261f7e5daa1a96f27529e6 Mon Sep 17 00:00:00 2001 From: Michael Leibman Date: Mon, 7 Nov 2011 19:42:37 -0800 Subject: [PATCH 0357/1043] Fixed issue 229. - Updated filter loop compiler to handle loops. - Added specific handling of "return true" and "return false" to the filter loop compiler. Makes the compiled function easier to read. --- slick.dataview.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/slick.dataview.js b/slick.dataview.js index e3708f8..955d807 100644 --- a/slick.dataview.js +++ b/slick.dataview.js @@ -421,12 +421,16 @@ function compileFilter() { var filterInfo = getFunctionInfo(filter); - var filterBody = filterInfo.body.replace(/return ([^;]+?);/gi, - "{ if ($1) { _retval[_idx++] = $item$; }; continue; }"); + var filterBody = filterInfo.body + .replace(/return false;/gi, "{ continue _coreloop; }") + .replace(/return true;/gi, "{ _retval[_idx++] = $item$; continue _coreloop; }") + .replace(/return ([^;]+?);/gi, + "{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }"); var fnTemplate = function(_items, _args) { var _retval = [], _idx = 0; var $item$, $args$ = _args; + _coreloop: for (var _i = 0, _il = _items.length; _i < _il; _i++) { $item$ = _items[_i]; $filter$; @@ -445,12 +449,16 @@ function compileFilterWithCaching() { var filterInfo = getFunctionInfo(filter); - var filterBody = filterInfo.body.replace(/return ([^;]+?);/gi, - "{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue; }"); + var filterBody = filterInfo.body + .replace(/return false;/gi, "{ continue _coreloop; }") + .replace(/return true;/gi, "{ _retval[_idx++] = $item$; continue _coreloop; }") + .replace(/return ([^;]+?);/gi, + "{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }"); var fnTemplate = function(_items, _args, _cache) { var _retval = [], _idx = 0; var $item$, $args$ = _args; + _coreloop: for (var _i = 0, _il = _items.length; _i < _il; _i++) { $item$ = _items[_i]; if (_cache[_i]) { From 904163042df04cfe59fba9a4de4d1a55e7b68b8a Mon Sep 17 00:00:00 2001 From: mleibman Date: Fri, 11 Nov 2011 23:10:23 -0800 Subject: [PATCH 0358/1043] Upgraded to the latest jQuery and jQuery UI versions. --- ...custom.css => jquery-ui-1.8.16.custom.css} | 207 +---- examples/example-checkbox-row-select.html | 6 +- examples/example-colspan.html | 4 +- ...example-composite-editor-item-details.html | 6 +- examples/example-grouping.html | 6 +- examples/example-header-row.html | 6 +- examples/example-optimizing-dataview.html | 6 +- examples/example-spreadsheet.html | 6 +- examples/example1-simple.html | 4 +- examples/example10-async-post-render.html | 6 +- examples/example11-autoheight.html | 4 +- examples/example12-fillbrowser.html | 2 +- examples/example13-getItem-sorting.html | 2 +- examples/example14-highlighting.html | 6 +- examples/example2-formatters.html | 6 +- examples/example3-editing.html | 6 +- examples/example3a-compound-editors.html | 6 +- examples/example3b-editing-with-undo.html | 6 +- examples/example4-model.html | 6 +- examples/example5-collapsing.html | 6 +- examples/example6-ajax-loading.html | 6 +- examples/example7-events.html | 6 +- examples/example8-alternative-display.html | 4 +- examples/example9-row-reordering.html | 6 +- lib/jquery-1.4.3.min.js | 166 ---- lib/jquery-1.7.min.js | 4 + lib/jquery-ui-1.8.16.custom.min.js | 611 ++++++++++++++ lib/jquery-ui-1.8.5.custom.min.js | 778 ------------------ tests/dataview/index.html | 2 +- tests/grid/index.html | 4 +- tests/model benchmarks.html | 2 +- tests/scrolling benchmarks.html | 6 +- 32 files changed, 705 insertions(+), 1197 deletions(-) rename css/smoothness/{jquery-ui-1.8.5.custom.css => jquery-ui-1.8.16.custom.css} (70%) delete mode 100644 lib/jquery-1.4.3.min.js create mode 100644 lib/jquery-1.7.min.js create mode 100644 lib/jquery-ui-1.8.16.custom.min.js delete mode 100644 lib/jquery-ui-1.8.5.custom.min.js diff --git a/css/smoothness/jquery-ui-1.8.5.custom.css b/css/smoothness/jquery-ui-1.8.16.custom.css similarity index 70% rename from css/smoothness/jquery-ui-1.8.5.custom.css rename to css/smoothness/jquery-ui-1.8.16.custom.css index 0cb22be..527338f 100644 --- a/css/smoothness/jquery-ui-1.8.5.custom.css +++ b/css/smoothness/jquery-ui-1.8.16.custom.css @@ -1,7 +1,7 @@ /* - * jQuery UI CSS Framework @VERSION + * jQuery UI CSS Framework 1.8.16 * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -11,7 +11,7 @@ /* Layout helpers ----------------------------------*/ .ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .ui-helper-clearfix { display: inline-block; } @@ -42,9 +42,9 @@ /* - * jQuery UI CSS Framework @VERSION + * jQuery UI CSS Framework 1.8.16 * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -280,29 +280,24 @@ ----------------------------------*/ /* Corner radius */ -.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } -.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } -.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } -.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } -.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } /* Overlays */ .ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* - * jQuery UI Resizable @VERSION +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* + * jQuery UI Resizable 1.8.16 * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Resizable#theming */ .ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } @@ -312,9 +307,9 @@ .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* - * jQuery UI Selectable @VERSION + * jQuery UI Selectable 1.8.16 * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -322,139 +317,9 @@ */ .ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } /* - * jQuery UI Accordion @VERSION + * jQuery UI Slider 1.8.16 * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion#theming - */ -/* IE/Win - Fix animation bug - #4615 */ -.ui-accordion { width: 100%; } -.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } -.ui-accordion .ui-accordion-li-fix { display: inline; } -.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } -.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } -.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } -.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } -.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } -.ui-accordion .ui-accordion-content-active { display: block; }/* - * jQuery UI Autocomplete @VERSION - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu @VERSION - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/* - * jQuery UI Button @VERSION - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/* - * jQuery UI Dialog @VERSION - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog#theming - */ -.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } -/* - * jQuery UI Slider @VERSION - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * @@ -475,33 +340,15 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } .ui-slider-vertical .ui-slider-range-min { bottom: 0; } .ui-slider-vertical .ui-slider-range-max { top: 0; }/* - * jQuery UI Tabs @VERSION + * jQuery UI Datepicker 1.8.16 * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs#theming - */ -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } -.ui-tabs .ui-tabs-hide { display: none !important; } -/* - * jQuery UI Datepicker @VERSION - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Datepicker#theming */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; } +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } @@ -533,7 +380,7 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } /* RTL support */ .ui-datepicker-rtl { direction: rtl; } @@ -559,14 +406,4 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad left: -4px; /*must have*/ width: 200px; /*must have*/ height: 200px; /*must have*/ -}/* - * jQuery UI Progressbar @VERSION - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar#theming - */ -.ui-progressbar { height:2em; text-align: left; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file +} \ No newline at end of file diff --git a/examples/example-checkbox-row-select.html b/examples/example-checkbox-row-select.html index 3499cb2..99b78d1 100644 --- a/examples/example-checkbox-row-select.html +++ b/examples/example-checkbox-row-select.html @@ -3,7 +3,7 @@ - + - - -
      -
      +

      Demonstrates:

      @@ -24,7 +24,6 @@

      Demonstrates:

      - @@ -61,6 +60,8 @@

      Demonstrates:

      } grid = new Slick.Grid("#myGrid", data, columns, options); + + $("#myGrid").show(); }) diff --git a/examples/example10-async-post-render.html b/examples/example10-async-post-render.html index fe48bfe..10d292f 100644 --- a/examples/example10-async-post-render.html +++ b/examples/example10-async-post-render.html @@ -53,7 +53,6 @@

      Demonstrates:

      - diff --git a/examples/example11-autoheight.html b/examples/example11-autoheight.html index acd7f7e..a429918 100644 --- a/examples/example11-autoheight.html +++ b/examples/example11-autoheight.html @@ -25,7 +25,6 @@

      Demonstrates:

      - diff --git a/examples/example12-fillbrowser.html b/examples/example12-fillbrowser.html index 4572df8..a260c50 100644 --- a/examples/example12-fillbrowser.html +++ b/examples/example12-fillbrowser.html @@ -27,7 +27,6 @@

      Demonstrates:

      - diff --git a/examples/example13-getItem-sorting.html b/examples/example13-getItem-sorting.html index f56deec..53f5ae0 100644 --- a/examples/example13-getItem-sorting.html +++ b/examples/example13-getItem-sorting.html @@ -26,7 +26,6 @@

      Demonstrates:

      - diff --git a/examples/example14-highlighting.html b/examples/example14-highlighting.html index 5c9da0f..9236d07 100644 --- a/examples/example14-highlighting.html +++ b/examples/example14-highlighting.html @@ -50,7 +50,6 @@

      Controls

      - diff --git a/examples/example2-formatters.html b/examples/example2-formatters.html index 120261f..d6aec66 100644 --- a/examples/example2-formatters.html +++ b/examples/example2-formatters.html @@ -38,7 +38,6 @@

      Demonstrates:

      - diff --git a/examples/example3-editing.html b/examples/example3-editing.html index 14787b4..8cb96b8 100644 --- a/examples/example3-editing.html +++ b/examples/example3-editing.html @@ -40,7 +40,6 @@

      Options:

      - diff --git a/examples/example3a-compound-editors.html b/examples/example3a-compound-editors.html index 65ec078..dc738eb 100644 --- a/examples/example3a-compound-editors.html +++ b/examples/example3a-compound-editors.html @@ -33,7 +33,6 @@

      Demonstrates:

      - diff --git a/examples/example3b-editing-with-undo.html b/examples/example3b-editing-with-undo.html index 6625a92..64af216 100644 --- a/examples/example3b-editing-with-undo.html +++ b/examples/example3b-editing-with-undo.html @@ -36,7 +36,6 @@

      Controls:

      - diff --git a/examples/example4-model.html b/examples/example4-model.html index 4b0ac61..02647b4 100644 --- a/examples/example4-model.html +++ b/examples/example4-model.html @@ -87,7 +87,6 @@

      Demonstrates:

      - diff --git a/examples/example5-collapsing.html b/examples/example5-collapsing.html index fdb0135..c64fc77 100644 --- a/examples/example5-collapsing.html +++ b/examples/example5-collapsing.html @@ -61,7 +61,6 @@

      Demonstrates:

      - diff --git a/examples/example6-ajax-loading.html b/examples/example6-ajax-loading.html index 8b6f378..543fb38 100644 --- a/examples/example6-ajax-loading.html +++ b/examples/example6-ajax-loading.html @@ -65,7 +65,6 @@

      WARNING:

      - diff --git a/examples/example7-events.html b/examples/example7-events.html index b23db57..f67c0d7 100644 --- a/examples/example7-events.html +++ b/examples/example7-events.html @@ -67,7 +67,6 @@

      Demonstrates:

      - diff --git a/examples/example8-alternative-display.html b/examples/example8-alternative-display.html index ef8b289..48dbf2d 100644 --- a/examples/example8-alternative-display.html +++ b/examples/example8-alternative-display.html @@ -91,7 +91,6 @@

      Demonstrates:

      - diff --git a/examples/example9-row-reordering.html b/examples/example9-row-reordering.html index f527e89..b410783 100644 --- a/examples/example9-row-reordering.html +++ b/examples/example9-row-reordering.html @@ -81,7 +81,6 @@ - diff --git a/lib/jquery.curstyles.min.js b/lib/jquery.curstyles.min.js deleted file mode 100644 index a47d240..0000000 --- a/lib/jquery.curstyles.min.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(f){var i=document.defaultView&&document.defaultView.getComputedStyle,n=/([A-Z])/g,l=/-([a-z])/ig,m=function(a,g){return g.toUpperCase()},o=function(a){if(i)return i(a,null);else if(a.currentStyle)return a.currentStyle},p=/float/i,q=/^-?\d+(?:px)?$/i,r=/^-?\d/;f.curStyles=function(a,g){if(!a)return null;for(var j=o(a),c,d,h=a.style,e={},k=0,b;k
      - - - - -
      -
      -
      -

      Demonstrates:

      -
        -
      • handling events from the grid:
      • -
      • Right-click the row to open the context menu
      • -
      • Click the priority cell to toggle values
      • -
      -
      - - - - - - - - - - - - - - + + + SlickGrid example 7: Events + + + + + + + + + + + +
      +
      +
      +

      Demonstrates:

      +
        +
      • handling events from the grid:
      • +
      • Right-click the row to open the context menu
      • +
      • Click the priority cell to toggle values
      • +
      +
      + + + + + + + + + + + + + + From 6634f168da6a03ce36a4a63c83f9acd1c33cbd5d Mon Sep 17 00:00:00 2001 From: Michael Leibman Date: Mon, 16 Jan 2012 15:02:21 -0800 Subject: [PATCH 0371/1043] Fixed issue #200 - Calculate maxSupportedCssHeight only once and share between grid instances. --- slick.grid.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/slick.grid.js b/slick.grid.js index 35a4b0a..37500e3 100644 --- a/slick.grid.js +++ b/slick.grid.js @@ -35,7 +35,9 @@ if (typeof Slick === "undefined") { } }); - var scrollbarDimensions; // shared across all grids on this page + // shared across all grids on the page + var scrollbarDimensions; + var maxSupportedCssHeight; // browser's breaking point ////////////////////////////////////////////////////////////////////////////////////////////// // SlickGrid class implementation (available as Slick.Grid) @@ -95,7 +97,6 @@ if (typeof Slick === "undefined") { }; // scroller - var maxSupportedCssHeight; // browser's breaking point var th; // virtual height var h; // real scrollable height var ph; // page height @@ -356,6 +357,11 @@ if (typeof Slick === "undefined") { } function getMaxSupportedCssHeight() { + // return cached value if already calculated + if (maxSupportedCssHeight) { + return maxSupportedCssHeight; + } + var increment = 1000000; var supportedHeight = increment; // FF reports the height back but still renders blank after ~6M px From 061ac59fb6a4c09a49d5abe1fa86c26f9d13bf66 Mon Sep 17 00:00:00 2001 From: Michael Leibman Date: Tue, 17 Jan 2012 12:29:57 -0800 Subject: [PATCH 0372/1043] Reformatted code. --- controls/slick.columnpicker.css | 32 +- controls/slick.columnpicker.js | 209 +- controls/slick.pager.css | 63 +- controls/slick.pager.js | 261 +- examples/example-checkbox-row-select.html | 110 +- examples/example-colspan.html | 154 +- ...example-composite-editor-item-details.html | 457 +- ...example-custom-column-value-extractor.html | 126 +- examples/example-grouping.html | 699 +-- examples/example-header-row.html | 269 +- examples/example-optimizing-dataview.html | 297 +- examples/example-spreadsheet.html | 330 +- examples/example1-simple.html | 113 +- examples/example10-async-post-render.html | 254 +- examples/example11-autoheight.html | 131 +- examples/example12-fillbrowser.html | 183 +- examples/example13-getItem-sorting.html | 197 +- examples/example14-highlighting.html | 299 +- examples/example2-formatters.html | 140 +- examples/example3-editing.html | 185 +- examples/example3a-compound-editors.html | 281 +- examples/example3b-editing-with-undo.html | 213 +- examples/example4-model.html | 745 +-- examples/example5-collapsing.html | 531 +- examples/example6-ajax-loading.html | 296 +- examples/example7-events.html | 17 +- examples/example8-alternative-display.html | 344 +- examples/example9-row-reordering.html | 611 +-- examples/examples.css | 253 +- examples/slick-default-theme.css | 73 +- examples/slick.compositeeditor.js | 404 +- plugins/slick.autotooltips.js | 81 +- plugins/slick.cellcopymanager.js | 144 +- plugins/slick.cellrangedecorator.js | 109 +- plugins/slick.cellrangeselector.js | 196 +- plugins/slick.cellselectionmodel.js | 154 +- plugins/slick.checkboxselectcolumn.js | 231 +- plugins/slick.rowmovemanager.js | 227 +- plugins/slick.rowselectionmodel.js | 319 +- slick.core.js | 756 +-- slick.dataview.js | 1349 ++--- slick.editors.js | 1228 ++--- slick.grid.css | 163 +- slick.grid.js | 4614 +++++++++-------- slick.groupitemmetadataprovider.js | 245 +- slick.remotemodel.js | 281 +- 46 files changed, 9284 insertions(+), 9090 deletions(-) diff --git a/controls/slick.columnpicker.css b/controls/slick.columnpicker.css index aaf5fbe..a2845cc 100644 --- a/controls/slick.columnpicker.css +++ b/controls/slick.columnpicker.css @@ -1,30 +1,30 @@ .slick-columnpicker { - border: 1px solid #718BB7; - background: #f0f0f0; - padding: 6px; - -moz-box-shadow: 2px 2px 2px silver; - -webkit-box-shadow: 2px 2px 2px silver; - min-width: 100px; - cursor: default; + border: 1px solid #718BB7; + background: #f0f0f0; + padding: 6px; + -moz-box-shadow: 2px 2px 2px silver; + -webkit-box-shadow: 2px 2px 2px silver; + min-width: 100px; + cursor: default; } .slick-columnpicker li { - list-style: none; - margin: 0; - padding: 0; - background: none; + list-style: none; + margin: 0; + padding: 0; + background: none; } .slick-columnpicker input { - margin: 4px; + margin: 4px; } .slick-columnpicker li a { - display: block; - padding: 4px; - font-weight: bold; + display: block; + padding: 4px; + font-weight: bold; } .slick-columnpicker li a:hover { - background: white; + background: white; } \ No newline at end of file diff --git a/controls/slick.columnpicker.js b/controls/slick.columnpicker.js index 4b84e0d..ca95211 100644 --- a/controls/slick.columnpicker.js +++ b/controls/slick.columnpicker.js @@ -1,105 +1,106 @@ -(function($) { - function SlickColumnPicker(columns,grid,options) - { - var $menu; - - var defaults = { - fadeSpeed: 250 - }; - - function init() { - grid.onHeaderContextMenu.subscribe(handleHeaderContextMenu); - options = $.extend({}, defaults, options); - - $menu = $("