Changed over to V3 of footable, fixed icon display in the repeatable icon selections.
This commit is contained in:
@ -1,4 +0,0 @@
|
||||
Copyright 2012 Steven Usher & Brad Vincent
|
||||
|
||||
Released under the MIT license
|
||||
You are free to use FooTable in commercial projects as long as this copyright header is left intact.
|
14
media/footable/LICENSE-GPLv3
Normal file
14
media/footable/LICENSE-GPLv3
Normal file
@ -0,0 +1,14 @@
|
||||
Copyright (c) 2015 Steven Usher & Brad Vincent
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
Binary file not shown.
@ -1,78 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>
|
||||
This is a custom SVG font generated by IcoMoon.
|
||||
<iconset grid="16"></iconset>
|
||||
</metadata>
|
||||
<defs>
|
||||
<font id="footable" horiz-adv-x="512" >
|
||||
<font-face units-per-em="512" ascent="480" descent="-32" />
|
||||
<missing-glyph horiz-adv-x="512" />
|
||||
<glyph class="hidden" unicode="" d="M0,480L 512 -32L0 -32 z" horiz-adv-x="0" />
|
||||
<glyph unicode="" d="M 496,288L 320,288 L 320,464 c0,8.836-7.164,16-16,16l-96,0 c-8.836,0-16-7.164-16-16l0-176 L 16,288 c-8.836,0-16-7.164-16-16l0-96
|
||||
c0-8.836, 7.164-16, 16-16l 176,0 l0-176 c0-8.836, 7.164-16, 16-16l 96,0 c 8.836,0, 16,7.164, 16,16L 320,160 l 176,0 c 8.836,0, 16,7.164, 16,16l0,96
|
||||
C 512,280.836, 504.836,288, 496,288z" />
|
||||
<glyph unicode="" d="M0,272l0-96 c0-8.836, 7.164-16, 16-16l 480,0 c 8.836,0, 16,7.164, 16,16l0,96 c0,8.836-7.164,16-16,16L 16,288 C 7.164,288,0,280.836,0,272z" />
|
||||
<glyph unicode="" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 288,192l0-128 l-64,0 L 224,192 L 96,192 l0,64
|
||||
l 128,0 L 224,384 l 64,0 l0-128 l 128,0 l0-64 L 288,192 z" />
|
||||
<glyph unicode="" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 416,192L 96,192 l0,64 l 320,0 L 416,192 z" />
|
||||
<glyph unicode="" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 256,32
|
||||
c-106.039,0-192,85.961-192,192c0,106.039, 85.961,192, 192,192c 106.039,0, 192-85.961, 192-192C 448,117.961, 362.039,32, 256,32zM 384,192 L 288,192 L 288,96 L 224,96 L 224,192 L 128,192 L 128,256 L 224,256 L 224,352 L 288,352 L 288,256 L 384,256 Z" />
|
||||
<glyph unicode="" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 256,32
|
||||
c-106.039,0-192,85.961-192,192c0,106.039, 85.961,192, 192,192c 106.039,0, 192-85.961, 192-192C 448,117.961, 362.039,32, 256,32zM 128,256L 384,256L 384,192L 128,192z" />
|
||||
<glyph unicode="" d="M 256,214.857l0-18.286 q0-4 -2.571-6.571t-6.571-2.571l-64,0 l0-64 q0-4 -2.571-6.571t-6.571-2.571l-18.286,0 q-4,0 -6.571,2.571t-2.571,6.571l0,64 l-64,0 q-4,0 -6.571,2.571t-2.571,6.571l0,18.286 q0,4 2.571,6.571t 6.571,2.571l 64,0 l0,64 q0,4 2.571,6.571t 6.571,2.571l 18.286,0 q 4,0 6.571-2.571t 2.571-6.571l0-64 l 64,0 q 4,0 6.571-2.571t 2.571-6.571zM 292.571,105.143l0,201.143 q0,11.429 -8,19.429t-19.429,8l-201.143,0 q-11.429,0 -19.429-8 t-8-19.429l0-201.143 q0-11.429 8-19.429t 19.429-8l 201.143,0 q 11.429,0 19.429,8t 8,19.429zM 329.143,306.286l0-201.143 q0-26.286 -18.714-45.143t-45.286-18.857l-201.143,0 q-26.571,0 -45.286,18.857t-18.714,45.143l0,201.143 q0,26.571 18.714,45.286t 45.286,18.714l 201.143,0 q 26.571,0 45.286-18.714t 18.714-45.286z" horiz-adv-x="329.143" />
|
||||
<glyph unicode="" d="M 265.143,370.286q 26.571,0 45.286-18.714t 18.714-45.286l0-201.143 q0-26.286 -18.714-45.143t-45.286-18.857l-201.143,0 q-26.571,0 -45.286,18.857t-18.714,45.143l0,201.143 q0,26.571 18.714,45.286t 45.286,18.714l 201.143,0 zM 292.571,105.143l0,201.143 q0,11.429 -8,19.429t-19.429,8l-201.143,0 q-11.429,0 -19.429-8t-8-19.429l0-201.143 q0-11.429 8-19.429t 19.429-8l 201.143,0 q 11.429,0 19.429,8t 8,19.429z M 246.857,224q 4,0 6.571-2.571t 2.571-6.571l0-18.286 q0-4 -2.571-6.571t-6.571-2.571l-164.571,0 q-4,0 -6.571,2.571t-2.571,6.571l0,18.286 q0,4 2.571,6.571t 6.571,2.571l 164.571,0 z" horiz-adv-x="329.143" />
|
||||
<glyph unicode="" d="M 365.714,205.714l0,36.571 q0,7.429 -5.429,12.857t-12.857,5.429l-91.429,0 l0,91.429 q0,7.429 -5.429,12.857t-12.857,5.429l-36.571,0 q-7.429,0 -12.857-5.429t-5.429-12.857l0-91.429 l-91.429,0 q-7.429,0 -12.857-5.429t-5.429-12.857l0-36.571 q0-7.429 5.429-12.857t 12.857-5.429l 91.429,0 l0-91.429 q0-7.429 5.429-12.857t 12.857-5.429l 36.571,0 q 7.429,0 12.857,5.429t 5.429,12.857l0,91.429 l 91.429,0 q 7.429,0 12.857,5.429t 5.429,12.857zM 438.857,361.143l0-274.286 q0-34 -24.143-58.143t-58.143-24.143l-274.286,0 q-34,0 -58.143,24.143t-24.143,58.143l0,274.286 q0,34 24.143,58.143t 58.143,24.143l 274.286,0 q 34,0 58.143-24.143t 24.143-58.143z" horiz-adv-x="438.857" />
|
||||
<glyph unicode="" d="M 365.714,205.714l0,36.571 q0,7.429 -5.429,12.857t-12.857,5.429l-256,0 q-7.429,0 -12.857-5.429t-5.429-12.857l0-36.571 q0-7.429 5.429-12.857t 12.857-5.429l 256,0 q 7.429,0 12.857,5.429t 5.429,12.857zM 438.857,361.143l0-274.286 q0-34 -24.143-58.143t-58.143-24.143l-274.286,0 q-34,0 -58.143,24.143t-24.143,58.143l0,274.286 q0,34 24.143,58.143t 58.143,24.143l 274.286,0 q 34,0 58.143-24.143 t 24.143-58.143z" horiz-adv-x="438.857" />
|
||||
<glyph unicode="" d="M 512,224C 512,82.615, 397.385-32, 256-32s -256,114.615, -256,256s 114.615,256, 256,256S 512,365.385, 512,224z M 233.372,374.628
|
||||
l -128-128.001C 99.124,240.379, 96,232.189, 96,224s 3.124-16.379 9.372-22.627c 12.497-12.497 32.759-12.497, 45.256,0L 224,274.745
|
||||
L 224,96 c 0-17.673 14.327-32 32-32c 17.673,0, 32,14.327, 32,32l0,178.745 l 73.373-73.373c 12.497-12.497 32.758-12.497, 45.255,0
|
||||
c 12.497,12.497, 12.497,32.758, 0,45.254l -128,128.001C 266.131,387.124, 245.869,387.124, 233.372,374.628z" />
|
||||
<glyph unicode="" d="M 512,224C 512,365.385, 397.385,480, 256,480s -256-114.615, -256-256s 114.615-256, 256-256S 512,82.615, 512,224z M 233.372,73.372
|
||||
l -128,128.001C 99.124,207.621, 96,215.811, 96,224s 3.124,16.379 9.372,22.627c 12.497,12.497 32.759,12.497, 45.256,0L 224,173.255
|
||||
L 224,352 c 0,17.673 14.327,32 32,32c 17.673,0, 32-14.327, 32-32l0-178.745 l 73.373,73.373c 12.497,12.497 32.758,12.497, 45.255,0
|
||||
c 12.497-12.497, 12.497-32.758, 0-45.254l -128-128.001C 266.131,60.876, 245.869,60.876, 233.372,73.372z" />
|
||||
<glyph unicode="" d="M 256,480C 397.385,480, 512,365.385, 512,224s -114.615-256, -256-256s -256,114.615, -256,256S 114.615,480, 256,480z M 105.372,201.372
|
||||
l 128.001-128C 239.621,67.124, 247.811,64, 256,64s 16.379,3.124 22.627,9.372c 12.497,12.497 12.497,32.759,0,45.256L 205.255,192
|
||||
L 384,192 c 17.673,0 32,14.327 32,32c0,17.673, -14.327,32, -32,32l-178.745,0 l 73.373,73.373c 12.497,12.497 12.497,32.758,0,45.255
|
||||
c -12.497,12.497, -32.758,12.497, -45.254,0l -128.001-128C 92.876,234.131, 92.876,213.869, 105.372,201.372z" />
|
||||
<glyph unicode="" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 406.628,201.372
|
||||
l-128.001-128C 272.379,67.124, 264.189,64, 256,64s-16.379,3.124-22.627,9.372c-12.497,12.497-12.497,32.759,0,45.256L 306.745,192
|
||||
L 128,192 c-17.673,0-32,14.327-32,32c0,17.673, 14.327,32, 32,32l 178.745,0 l-73.373,73.373c-12.497,12.497-12.497,32.758,0,45.255
|
||||
c 12.497,12.497, 32.758,12.497, 45.254,0l 128.001-128C 419.124,234.131, 419.124,213.869, 406.628,201.372z" />
|
||||
<glyph unicode="" d="M0,160L 96,64L 256,224L 416,64L 512,160L 256.001,416 z" />
|
||||
<glyph unicode="" d="M 512,288L 416,384L 256,224L 96,384L0,288L 256,32.001 z" />
|
||||
<glyph unicode="" d="M 320-32L 416,64L 256,224L 416,384L 320,480L 64,224 z" />
|
||||
<glyph unicode="" d="M 192,480L 96,384L 256,224L 96,64L 192-32L 448,224 z" />
|
||||
<glyph unicode="" d="M 292.571,132.571q0-7.429 -5.429-12.857t-12.857-5.429l-256,0 q-7.429,0 -12.857,5.429t-5.429,12.857t 5.429,12.857l 128,128q 5.429,5.429 12.857,5.429t 12.857-5.429l 128-128q 5.429-5.429 5.429-12.857z" horiz-adv-x="292.571" />
|
||||
<glyph unicode="" d="M 292.571,278.857q0-7.429 -5.429-12.857l-128-128q-5.429-5.429 -12.857-5.429t-12.857,5.429l-128,128q-5.429,5.429 -5.429,12.857t 5.429,12.857t 12.857,5.429l 256,0 q 7.429,0 12.857-5.429t 5.429-12.857z" horiz-adv-x="292.571" />
|
||||
<glyph unicode="" d="M 182.857,352l0-256 q0-7.429 -5.429-12.857t-12.857-5.429t-12.857,5.429l-128,128q-5.429,5.429 -5.429,12.857t 5.429,12.857l 128,128q 5.429,5.429 12.857,5.429t 12.857-5.429t 5.429-12.857z" horiz-adv-x="182.857" />
|
||||
<glyph unicode="" d="M 164.571,224q0-7.429 -5.429-12.857l-128-128q-5.429-5.429 -12.857-5.429t-12.857,5.429t-5.429,12.857l0,256 q0,7.429 5.429,12.857t 12.857,5.429t 12.857-5.429l 128-128q 5.429-5.429 5.429-12.857z" horiz-adv-x="182.857" />
|
||||
<glyph unicode="" d="M 256,480L 32-32L 256,64L 480-32 z" />
|
||||
<glyph unicode="" d="M 256-32L 480,480L 256,384L 32,480 z" />
|
||||
<glyph unicode="" d="M0,224L 512,0L 416,224L 512,448 z" />
|
||||
<glyph unicode="" d="M 512,224L0,448L 96,224L0,0 z" />
|
||||
<glyph unicode="" d="M 512,224C 512,82.615, 397.385-32, 256-32s -256,114.615, -256,256s 114.615,256, 256,256S 512,365.385, 512,224z M 48,224
|
||||
c 0-114.875 93.125-208 208-208S 464,109.125, 464,224s -93.125,208, -208,208S 48,338.875, 48,224zM 278.627,374.628l 128-128.001c 12.497-12.496 12.497-32.757 0-45.254c -12.497-12.497 -32.758-12.497,-45.255,0L 288,274.745
|
||||
L 288,96 c 0-17.673 -14.327-32 -32-32c-17.673,0, -32,14.327, -32,32l0,178.745 l -73.372-73.373c -12.497-12.497 -32.759-12.497,-45.256,0
|
||||
C 99.124,207.621, 96,215.811, 96,224s 3.124,16.379, 9.372,22.627l 128,128.001C 245.869,387.124, 266.131,387.124, 278.627,374.628z" />
|
||||
<glyph unicode="" d="M 512,224C 512,365.385, 397.385,480, 256,480s -256-114.615, -256-256s 114.615-256, 256-256S 512,82.615, 512,224z M 48,224
|
||||
c 0,114.875 93.125,208 208,208S 464,338.875, 464,224s -93.125-208, -208-208S 48,109.125, 48,224zM 278.627,73.372l 128,128.001c 12.497,12.496 12.497,32.757 0,45.254c -12.497,12.497 -32.758,12.497,-45.255,0L 288,173.255
|
||||
L 288,352 c 0,17.673 -14.327,32 -32,32c-17.673,0, -32-14.327, -32-32l0-178.745 l -73.372,73.373c -12.497,12.497 -32.759,12.497,-45.256,0
|
||||
C 99.124,240.379, 96,232.189, 96,224s 3.124-16.379, 9.372-22.627l 128-128.001C 245.869,60.876, 266.131,60.876, 278.627,73.372z" />
|
||||
<glyph unicode="" d="M 256,480C 397.385,480, 512,365.385, 512,224s -114.615-256, -256-256s -256,114.615, -256,256S 114.615,480, 256,480z M 256,16
|
||||
c 114.875,0 208,93.125 208,208S 370.875,432, 256,432s -208-93.125, -208-208S 141.125,16, 256,16zM 105.372,246.627l 128.001,128c 12.496,12.497 32.757,12.497 45.254,0c 12.497-12.497 12.497-32.758,0-45.255L 205.255,256
|
||||
L 384,256 c 17.673,0 32-14.327 32-32c0-17.673, -14.327-32, -32-32l-178.745,0 l 73.373-73.372c 12.497-12.497 12.497-32.759,0-45.256
|
||||
C 272.379,67.124, 264.189,64, 256,64s -16.379,3.124, -22.627,9.372l -128.001,128C 92.876,213.869, 92.876,234.131, 105.372,246.627z" />
|
||||
<glyph unicode="" d="M 256,480C 114.615,480,0,365.385,0,224s 114.615-256, 256-256s 256,114.615, 256,256S 397.385,480, 256,480z M 256,16
|
||||
c-114.875,0-208,93.125-208,208S 141.125,432, 256,432s 208-93.125, 208-208S 370.875,16, 256,16zM 406.628,246.627l-128.001,128c-12.496,12.497-32.757,12.497-45.254,0c-12.497-12.497-12.497-32.758,0-45.255L 306.745,256
|
||||
L 128,256 c-17.673,0-32-14.327-32-32c0-17.673, 14.327-32, 32-32l 178.745,0 l-73.373-73.372c-12.497-12.497-12.497-32.759,0-45.256
|
||||
C 239.621,67.124, 247.811,64, 256,64s 16.379,3.124, 22.627,9.372l 128.001,128C 419.124,213.869, 419.124,234.131, 406.628,246.627z" />
|
||||
<glyph unicode="" d="M 307.143,141.714q0-3.714 -2.857-6.571l-14.286-14.286q-2.857-2.857 -6.571-2.857t-6.571,2.857l-112.286,112.286l-112.286-112.286q-2.857-2.857 -6.571-2.857t-6.571,2.857l-14.286,14.286q-2.857,2.857 -2.857,6.571t 2.857,6.571l 133.143,133.143q 2.857,2.857 6.571,2.857t 6.571-2.857l 133.143-133.143q 2.857-2.857 2.857-6.571z" horiz-adv-x="329.143" />
|
||||
<glyph unicode="" d="M 307.143,269.714q0-3.714 -2.857-6.571l-133.143-133.143q-2.857-2.857 -6.571-2.857t-6.571,2.857l-133.143,133.143q-2.857,2.857 -2.857,6.571t 2.857,6.571l 14.286,14.286q 2.857,2.857 6.571,2.857t 6.571-2.857l 112.286-112.286l 112.286,112.286q 2.857,2.857 6.571,2.857t 6.571-2.857l 14.286-14.286q 2.857-2.857 2.857-6.571z" horiz-adv-x="329.143" />
|
||||
<glyph unicode="" d="M 179.143,324.571q0-3.714 -2.857-6.571l-112.286-112.286l 112.286-112.286q 2.857-2.857 2.857-6.571t-2.857-6.571l-14.286-14.286q-2.857-2.857 -6.571-2.857t-6.571,2.857l-133.143,133.143q-2.857,2.857 -2.857,6.571t 2.857,6.571l 133.143,133.143q 2.857,2.857 6.571,2.857t 6.571-2.857l 14.286-14.286q 2.857-2.857 2.857-6.571z" horiz-adv-x="182.857" />
|
||||
<glyph unicode="" d="M 170,205.714q0-3.714 -2.857-6.571l-133.143-133.143q-2.857-2.857 -6.571-2.857t-6.571,2.857l-14.286,14.286q-2.857,2.857 -2.857,6.571t 2.857,6.571l 112.286,112.286l-112.286,112.286q-2.857,2.857 -2.857,6.571t 2.857,6.571l 14.286,14.286q 2.857,2.857 6.571,2.857t 6.571-2.857l 133.143-133.143q 2.857-2.857 2.857-6.571z" horiz-adv-x="182.857" />
|
||||
<glyph unicode="" d="M 292.571,169.143q0-7.429 -5.429-12.857l-128-128q-5.429-5.429 -12.857-5.429t-12.857,5.429l-128,128q-5.429,5.429 -5.429,12.857t 5.429,12.857t 12.857,5.429l 256,0 q 7.429,0 12.857-5.429t 5.429-12.857zM 292.571,278.857q0-7.429 -5.429-12.857t-12.857-5.429l-256,0 q-7.429,0 -12.857,5.429t-5.429,12.857t 5.429,12.857l 128,128q 5.429,5.429 12.857,5.429t 12.857-5.429l 128-128q 5.429-5.429 5.429-12.857z" horiz-adv-x="292.571" />
|
||||
<glyph unicode=" " horiz-adv-x="256" />
|
||||
</font></defs></svg>
|
Before Width: | Height: | Size: 13 KiB |
Binary file not shown.
Binary file not shown.
@ -1 +0,0 @@
|
||||
<html><body bgcolor="#FFFFFF"></body></html>
|
266
media/footable/css/footable.bootstrap.css
Normal file
266
media/footable/css/footable.bootstrap.css
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
table.footable,
|
||||
table.footable-details {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.footable-details {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table > tbody > tr > td > span.footable-toggle {
|
||||
margin-right: 8px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
table > tbody > tr > td > span.footable-toggle.last-column {
|
||||
margin-left: 8px;
|
||||
float: right;
|
||||
}
|
||||
table.table-condensed > tbody > tr > td > span.footable-toggle {
|
||||
margin-right: 5px;
|
||||
}
|
||||
table.footable-details > tbody > tr > th:nth-child(1) {
|
||||
min-width: 40px;
|
||||
width: 120px;
|
||||
}
|
||||
table.footable-details > tbody > tr > td:nth-child(2) {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
table.footable-details > thead > tr:first-child > th,
|
||||
table.footable-details > thead > tr:first-child > td,
|
||||
table.footable-details > tbody > tr:first-child > th,
|
||||
table.footable-details > tbody > tr:first-child > td,
|
||||
table.footable-details > tfoot > tr:first-child > th,
|
||||
table.footable-details > tfoot > tr:first-child > td {
|
||||
border-top-width: 0;
|
||||
}
|
||||
table.footable-details.table-bordered > thead > tr:first-child > th,
|
||||
table.footable-details.table-bordered > thead > tr:first-child > td,
|
||||
table.footable-details.table-bordered > tbody > tr:first-child > th,
|
||||
table.footable-details.table-bordered > tbody > tr:first-child > td,
|
||||
table.footable-details.table-bordered > tfoot > tr:first-child > th,
|
||||
table.footable-details.table-bordered > tfoot > tr:first-child > td {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
div.footable-loader {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
height: 300px;
|
||||
position: relative;
|
||||
}
|
||||
div.footable-loader > span.fooicon {
|
||||
display: inline-block;
|
||||
opacity: 0.3;
|
||||
font-size: 30px;
|
||||
line-height: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-top: -16px;
|
||||
margin-left: -16px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-animation: fooicon-spin-r 2s infinite linear;
|
||||
animation: fooicon-spin-r 2s infinite linear;
|
||||
}
|
||||
table.footable > tbody > tr.footable-empty > td {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
}
|
||||
table.footable > tbody > tr > td,
|
||||
table.footable > tbody > tr > th {
|
||||
display: none;
|
||||
}
|
||||
table.footable > tbody > tr.footable-empty > td,
|
||||
table.footable > tbody > tr.footable-empty > th,
|
||||
table.footable > tbody > tr.footable-detail-row > td,
|
||||
table.footable > tbody > tr.footable-detail-row > th {
|
||||
display: table-cell;
|
||||
}
|
||||
@-webkit-keyframes fooicon-spin-r {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fooicon-spin-r {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
.fooicon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
display: inline-block;
|
||||
font-family: 'Glyphicons Halflings' !important;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.fooicon:before,
|
||||
.fooicon:after {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.fooicon-loader:before {
|
||||
content: "\e030";
|
||||
}
|
||||
.fooicon-plus:before {
|
||||
content: "\2b";
|
||||
}
|
||||
.fooicon-minus:before {
|
||||
content: "\2212";
|
||||
}
|
||||
.fooicon-search:before {
|
||||
content: "\e003";
|
||||
}
|
||||
.fooicon-remove:before {
|
||||
content: "\e014";
|
||||
}
|
||||
.fooicon-sort:before {
|
||||
content: "\e150";
|
||||
}
|
||||
.fooicon-sort-asc:before {
|
||||
content: "\e155";
|
||||
}
|
||||
.fooicon-sort-desc:before {
|
||||
content: "\e156";
|
||||
}
|
||||
.fooicon-pencil:before {
|
||||
content: "\270f";
|
||||
}
|
||||
.fooicon-trash:before {
|
||||
content: "\e020";
|
||||
}
|
||||
.fooicon-eye-close:before {
|
||||
content: "\e106";
|
||||
}
|
||||
.fooicon-flash:before {
|
||||
content: "\e162";
|
||||
}
|
||||
.fooicon-cog:before {
|
||||
content: "\e019";
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th {
|
||||
border-bottom-width: 1px;
|
||||
font-weight: normal;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th,
|
||||
table.footable.footable-filtering-right > thead > tr.footable-filtering > th {
|
||||
text-align: right;
|
||||
}
|
||||
table.footable.footable-filtering-left > thead > tr.footable-filtering > th {
|
||||
text-align: left;
|
||||
}
|
||||
table.footable.footable-filtering-center > thead > tr.footable-filtering > th {
|
||||
text-align: center;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
|
||||
margin-top: 5px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.input-group {
|
||||
width: 100%;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox {
|
||||
margin: 0;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox > label {
|
||||
display: block;
|
||||
padding-left: 20px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox input[type="checkbox"] {
|
||||
position: absolute;
|
||||
margin-left: -20px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
table.footable > thead > tr.footable-filtering > th div.input-group {
|
||||
width: auto;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
td.footable-sortable,
|
||||
th.footable-sortable {
|
||||
position: relative;
|
||||
padding-right: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
td.footable-sortable > span.fooicon,
|
||||
th.footable-sortable > span.fooicon {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease-in;
|
||||
}
|
||||
td.footable-sortable:hover > span.fooicon,
|
||||
th.footable-sortable:hover > span.fooicon {
|
||||
opacity: 1;
|
||||
}
|
||||
td.footable-sortable.footable-asc > span.fooicon,
|
||||
th.footable-sortable.footable-asc > span.fooicon,
|
||||
td.footable-sortable.footable-desc > span.fooicon,
|
||||
th.footable-sortable.footable-desc > span.fooicon {
|
||||
opacity: 1;
|
||||
}
|
||||
table.footable > tfoot > tr.footable-paging > td > ul.pagination {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
table.footable > tfoot > tr.footable-paging > td > span.label {
|
||||
display: inline-block;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
table.footable > tfoot > tr.footable-paging > td,
|
||||
table.footable-paging-center > tfoot > tr.footable-paging > td {
|
||||
text-align: center;
|
||||
}
|
||||
table.footable-paging-left > tfoot > tr.footable-paging > td {
|
||||
text-align: left;
|
||||
}
|
||||
table.footable-paging-right > tfoot > tr.footable-paging > td {
|
||||
text-align: right;
|
||||
}
|
||||
ul.pagination > li.footable-page {
|
||||
display: none;
|
||||
}
|
||||
ul.pagination > li.footable-page.visible {
|
||||
display: inline;
|
||||
}
|
1
media/footable/css/footable.bootstrap.min.css
vendored
Normal file
1
media/footable/css/footable.bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
169
media/footable/css/footable.core.bootstrap.css
Normal file
169
media/footable/css/footable.core.bootstrap.css
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
table.footable,
|
||||
table.footable-details {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.footable-details {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table > tbody > tr > td > span.footable-toggle {
|
||||
margin-right: 8px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
table > tbody > tr > td > span.footable-toggle.last-column {
|
||||
margin-left: 8px;
|
||||
float: right;
|
||||
}
|
||||
table.table-condensed > tbody > tr > td > span.footable-toggle {
|
||||
margin-right: 5px;
|
||||
}
|
||||
table.footable-details > tbody > tr > th:nth-child(1) {
|
||||
min-width: 40px;
|
||||
width: 120px;
|
||||
}
|
||||
table.footable-details > tbody > tr > td:nth-child(2) {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
table.footable-details > thead > tr:first-child > th,
|
||||
table.footable-details > thead > tr:first-child > td,
|
||||
table.footable-details > tbody > tr:first-child > th,
|
||||
table.footable-details > tbody > tr:first-child > td,
|
||||
table.footable-details > tfoot > tr:first-child > th,
|
||||
table.footable-details > tfoot > tr:first-child > td {
|
||||
border-top-width: 0;
|
||||
}
|
||||
table.footable-details.table-bordered > thead > tr:first-child > th,
|
||||
table.footable-details.table-bordered > thead > tr:first-child > td,
|
||||
table.footable-details.table-bordered > tbody > tr:first-child > th,
|
||||
table.footable-details.table-bordered > tbody > tr:first-child > td,
|
||||
table.footable-details.table-bordered > tfoot > tr:first-child > th,
|
||||
table.footable-details.table-bordered > tfoot > tr:first-child > td {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
div.footable-loader {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
height: 300px;
|
||||
position: relative;
|
||||
}
|
||||
div.footable-loader > span.fooicon {
|
||||
display: inline-block;
|
||||
opacity: 0.3;
|
||||
font-size: 30px;
|
||||
line-height: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-top: -16px;
|
||||
margin-left: -16px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-animation: fooicon-spin-r 2s infinite linear;
|
||||
animation: fooicon-spin-r 2s infinite linear;
|
||||
}
|
||||
table.footable > tbody > tr.footable-empty > td {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
}
|
||||
table.footable > tbody > tr > td,
|
||||
table.footable > tbody > tr > th {
|
||||
display: none;
|
||||
}
|
||||
table.footable > tbody > tr.footable-empty > td,
|
||||
table.footable > tbody > tr.footable-empty > th,
|
||||
table.footable > tbody > tr.footable-detail-row > td,
|
||||
table.footable > tbody > tr.footable-detail-row > th {
|
||||
display: table-cell;
|
||||
}
|
||||
@-webkit-keyframes fooicon-spin-r {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fooicon-spin-r {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
.fooicon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
display: inline-block;
|
||||
font-family: 'Glyphicons Halflings' !important;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.fooicon:before,
|
||||
.fooicon:after {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.fooicon-loader:before {
|
||||
content: "\e030";
|
||||
}
|
||||
.fooicon-plus:before {
|
||||
content: "\2b";
|
||||
}
|
||||
.fooicon-minus:before {
|
||||
content: "\2212";
|
||||
}
|
||||
.fooicon-search:before {
|
||||
content: "\e003";
|
||||
}
|
||||
.fooicon-remove:before {
|
||||
content: "\e014";
|
||||
}
|
||||
.fooicon-sort:before {
|
||||
content: "\e150";
|
||||
}
|
||||
.fooicon-sort-asc:before {
|
||||
content: "\e155";
|
||||
}
|
||||
.fooicon-sort-desc:before {
|
||||
content: "\e156";
|
||||
}
|
||||
.fooicon-pencil:before {
|
||||
content: "\270f";
|
||||
}
|
||||
.fooicon-trash:before {
|
||||
content: "\e020";
|
||||
}
|
||||
.fooicon-eye-close:before {
|
||||
content: "\e106";
|
||||
}
|
||||
.fooicon-flash:before {
|
||||
content: "\e162";
|
||||
}
|
||||
.fooicon-cog:before {
|
||||
content: "\e019";
|
||||
}
|
@ -1,178 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'footable';
|
||||
src: url('fonts/footable.eot');
|
||||
src: url('fonts/footable.eot?#iefix') format('embedded-opentype'), url('fonts/footable.woff') format('woff'), url('fonts/footable.ttf') format('truetype'), url('fonts/footable.svg#footable') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||
@font-face {
|
||||
font-family: 'footable';
|
||||
src: url('fonts/footable.svg#footable') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
}
|
||||
.footable {
|
||||
width: 100%;
|
||||
/** SORTING **/
|
||||
|
||||
/** PAGINATION **/
|
||||
|
||||
}
|
||||
.footable.breakpoint > tbody > tr.footable-detail-show > td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e001";
|
||||
}
|
||||
.footable.breakpoint > tbody > tr:hover:not(.footable-row-detail) {
|
||||
cursor: pointer;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr > td.footable-cell-detail {
|
||||
background: #eee;
|
||||
border-top: none;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr > td > span.footable-toggle {
|
||||
display: inline-block;
|
||||
font-family: 'footable';
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
padding-right: 5px;
|
||||
font-size: 14px;
|
||||
color: #888888;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e000";
|
||||
}
|
||||
.footable.breakpoint.toggle-circle > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e005";
|
||||
}
|
||||
.footable.breakpoint.toggle-circle > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e004";
|
||||
}
|
||||
.footable.breakpoint.toggle-circle-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e003";
|
||||
}
|
||||
.footable.breakpoint.toggle-circle-filled > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e002";
|
||||
}
|
||||
.footable.breakpoint.toggle-square > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e007";
|
||||
}
|
||||
.footable.breakpoint.toggle-square > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e006";
|
||||
}
|
||||
.footable.breakpoint.toggle-square-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e009";
|
||||
}
|
||||
.footable.breakpoint.toggle-square-filled > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e008";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e00f";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e011";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-small > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e013";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-small > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e015";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-circle > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e01b";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-circle > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e01d";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-circle-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e00b";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-circle-filled > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e00d";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-tiny > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e01f";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-tiny > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e021";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-alt > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
|
||||
content: "\e017";
|
||||
}
|
||||
.footable.breakpoint.toggle-arrow-alt > tbody > tr > td > span.footable-toggle:before {
|
||||
content: "\e019";
|
||||
}
|
||||
.footable.breakpoint.toggle-medium > tbody > tr > td > span.footable-toggle {
|
||||
font-size: 18px;
|
||||
}
|
||||
.footable.breakpoint.toggle-large > tbody > tr > td > span.footable-toggle {
|
||||
font-size: 24px;
|
||||
}
|
||||
.footable > thead > tr > th {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: -moz-none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.footable > thead > tr > th.footable-sortable:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.footable > thead > tr > th.footable-sorted > span.footable-sort-indicator:before {
|
||||
content: "\e013";
|
||||
}
|
||||
.footable > thead > tr > th.footable-sorted-desc > span.footable-sort-indicator:before {
|
||||
content: "\e012";
|
||||
}
|
||||
.footable > thead > tr > th > span.footable-sort-indicator {
|
||||
display: inline-block;
|
||||
font-family: 'footable';
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.footable > thead > tr > th > span.footable-sort-indicator:before {
|
||||
content: "\e022";
|
||||
}
|
||||
.footable > tfoot .pagination {
|
||||
margin: 0;
|
||||
}
|
||||
.footable.no-paging .hide-if-no-paging {
|
||||
display: none;
|
||||
}
|
||||
.footable-row-detail-inner {
|
||||
display: table;
|
||||
}
|
||||
.footable-row-detail-row {
|
||||
display: table-row;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
.footable-row-detail-group {
|
||||
display: block;
|
||||
line-height: 2em;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.footable-row-detail-name {
|
||||
display: table-cell;
|
||||
font-weight: bold;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.footable-row-detail-value {
|
||||
display: table-cell;
|
||||
}
|
||||
.footable-odd {
|
||||
background-color: #f7f7f7;
|
||||
}
|
1
media/footable/css/footable.core.min.css
vendored
1
media/footable/css/footable.core.min.css
vendored
@ -1 +0,0 @@
|
||||
@font-face{font-family:'footable';src:url('fonts/footable.eot');src:url('fonts/footable.eot?#iefix') format('embedded-opentype'),url('fonts/footable.woff') format('woff'),url('fonts/footable.ttf') format('truetype'),url('fonts/footable.svg#footable') format('svg');font-weight:normal;font-style:normal}@media screen and (-webkit-min-device-pixel-ratio:0){@font-face{font-family:'footable';src:url('fonts/footable.svg#footable') format('svg');font-weight:normal;font-style:normal}}.footable{width:100%}.footable.breakpoint>tbody>tr.footable-detail-show>td{border-bottom:0}.footable.breakpoint>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e001"}.footable.breakpoint>tbody>tr:hover:not(.footable-row-detail){cursor:pointer}.footable.breakpoint>tbody>tr>td.footable-cell-detail{background:#eee;border-top:0}.footable.breakpoint>tbody>tr>td>span.footable-toggle{display:inline-block;font-family:'footable';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;padding-right:5px;font-size:14px;color:#888}.footable.breakpoint>tbody>tr>td>span.footable-toggle:before{content:"\e000"}.footable.breakpoint.toggle-circle>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e005"}.footable.breakpoint.toggle-circle>tbody>tr>td>span.footable-toggle:before{content:"\e004"}.footable.breakpoint.toggle-circle-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e003"}.footable.breakpoint.toggle-circle-filled>tbody>tr>td>span.footable-toggle:before{content:"\e002"}.footable.breakpoint.toggle-square>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e007"}.footable.breakpoint.toggle-square>tbody>tr>td>span.footable-toggle:before{content:"\e006"}.footable.breakpoint.toggle-square-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e009"}.footable.breakpoint.toggle-square-filled>tbody>tr>td>span.footable-toggle:before{content:"\e008"}.footable.breakpoint.toggle-arrow>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e00f"}.footable.breakpoint.toggle-arrow>tbody>tr>td>span.footable-toggle:before{content:"\e011"}.footable.breakpoint.toggle-arrow-small>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e013"}.footable.breakpoint.toggle-arrow-small>tbody>tr>td>span.footable-toggle:before{content:"\e015"}.footable.breakpoint.toggle-arrow-circle>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e01b"}.footable.breakpoint.toggle-arrow-circle>tbody>tr>td>span.footable-toggle:before{content:"\e01d"}.footable.breakpoint.toggle-arrow-circle-filled>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e00b"}.footable.breakpoint.toggle-arrow-circle-filled>tbody>tr>td>span.footable-toggle:before{content:"\e00d"}.footable.breakpoint.toggle-arrow-tiny>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e01f"}.footable.breakpoint.toggle-arrow-tiny>tbody>tr>td>span.footable-toggle:before{content:"\e021"}.footable.breakpoint.toggle-arrow-alt>tbody>tr.footable-detail-show>td>span.footable-toggle:before{content:"\e017"}.footable.breakpoint.toggle-arrow-alt>tbody>tr>td>span.footable-toggle:before{content:"\e019"}.footable.breakpoint.toggle-medium>tbody>tr>td>span.footable-toggle{font-size:18px}.footable.breakpoint.toggle-large>tbody>tr>td>span.footable-toggle{font-size:24px}.footable>thead>tr>th{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-ms-user-select:none;user-select:none}.footable>thead>tr>th.footable-sortable:hover{cursor:pointer}.footable>thead>tr>th.footable-sorted>span.footable-sort-indicator:before{content:"\e013"}.footable>thead>tr>th.footable-sorted-desc>span.footable-sort-indicator:before{content:"\e012"}.footable>thead>tr>th>span.footable-sort-indicator{display:inline-block;font-family:'footable';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;padding-left:5px}.footable>thead>tr>th>span.footable-sort-indicator:before{content:"\e022"}.footable>tfoot .pagination{margin:0}.footable.no-paging .hide-if-no-paging{display:none}.footable-row-detail-inner{display:table}.footable-row-detail-row{display:table-row;line-height:1.5em}.footable-row-detail-group{display:block;line-height:2em;font-size:1.2em;font-weight:bold}.footable-row-detail-name{display:table-cell;font-weight:bold;padding-right:.5em}.footable-row-detail-value{display:table-cell}.footable-odd{background-color:#f7f7f7}
|
630
media/footable/css/footable.core.standalone.css
Normal file
630
media/footable/css/footable.core.standalone.css
Normal file
@ -0,0 +1,630 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
/* globals - instead we house them under the .footable.table class as the root of FooTable is always the table itself. */
|
||||
.footable.table, .footable.table *,
|
||||
.footable-details.table, .footable-details.table * {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.footable.table th,
|
||||
.footable-details.table th {
|
||||
text-align: left;
|
||||
}
|
||||
/* tables */
|
||||
.footable.table,
|
||||
.footable-details.table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.footable.table > caption + thead > tr:first-child > th,
|
||||
.footable.table > colgroup + thead > tr:first-child > th,
|
||||
.footable.table > thead:first-child > tr:first-child > th,
|
||||
.footable.table > caption + thead > tr:first-child > td,
|
||||
.footable.table > colgroup + thead > tr:first-child > td,
|
||||
.footable.table > thead:first-child > tr:first-child > td,
|
||||
.footable-details.table > caption + thead > tr:first-child > th,
|
||||
.footable-details.table > colgroup + thead > tr:first-child > th,
|
||||
.footable-details.table > thead:first-child > tr:first-child > th,
|
||||
.footable-details.table > caption + thead > tr:first-child > td,
|
||||
.footable-details.table > colgroup + thead > tr:first-child > td,
|
||||
.footable-details.table > thead:first-child > tr:first-child > td {
|
||||
border-top: 0;
|
||||
}
|
||||
.footable.table > thead > tr > th,
|
||||
.footable.table > tbody > tr > th,
|
||||
.footable.table > tfoot > tr > th,
|
||||
.footable.table > thead > tr > td,
|
||||
.footable.table > tbody > tr > td,
|
||||
.footable.table > tfoot > tr > td,
|
||||
.footable-details.table > thead > tr > th,
|
||||
.footable-details.table > tbody > tr > th,
|
||||
.footable-details.table > tfoot > tr > th,
|
||||
.footable-details.table > thead > tr > td,
|
||||
.footable-details.table > tbody > tr > td,
|
||||
.footable-details.table > tfoot > tr > td {
|
||||
padding: 8px;
|
||||
line-height: 1.42857143;
|
||||
vertical-align: top;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.footable.table > thead > tr > th,
|
||||
.footable.table > thead > tr > td,
|
||||
.footable-details.table > thead > tr > th,
|
||||
.footable-details.table > thead > tr > td {
|
||||
vertical-align: bottom;
|
||||
border-bottom: 2px solid #ddd;
|
||||
}
|
||||
.footable.table-condensed > thead > tr > th,
|
||||
.footable.table-condensed > tbody > tr > th,
|
||||
.footable.table-condensed > tfoot > tr > th,
|
||||
.footable.table-condensed > thead > tr > td,
|
||||
.footable.table-condensed > tbody > tr > td,
|
||||
.footable.table-condensed > tfoot > tr > td,
|
||||
.footable-details.table-condensed > thead > tr > th,
|
||||
.footable-details.table-condensed > tbody > tr > th,
|
||||
.footable-details.table-condensed > tfoot > tr > th,
|
||||
.footable-details.table-condensed > thead > tr > td,
|
||||
.footable-details.table-condensed > tbody > tr > td,
|
||||
.footable-details.table-condensed > tfoot > tr > td {
|
||||
padding: 5px;
|
||||
}
|
||||
.footable.table-bordered,
|
||||
.footable-details.table-bordered {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.footable.table-bordered > thead > tr > th,
|
||||
.footable.table-bordered > tbody > tr > th,
|
||||
.footable.table-bordered > tfoot > tr > th,
|
||||
.footable.table-bordered > thead > tr > td,
|
||||
.footable.table-bordered > tbody > tr > td,
|
||||
.footable.table-bordered > tfoot > tr > td,
|
||||
.footable-details.table-bordered > thead > tr > th,
|
||||
.footable-details.table-bordered > tbody > tr > th,
|
||||
.footable-details.table-bordered > tfoot > tr > th,
|
||||
.footable-details.table-bordered > thead > tr > td,
|
||||
.footable-details.table-bordered > tbody > tr > td,
|
||||
.footable-details.table-bordered > tfoot > tr > td {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.footable.table-bordered > thead > tr > th,
|
||||
.footable.table-bordered > thead > tr > td,
|
||||
.footable-details.table-bordered > thead > tr > th,
|
||||
.footable-details.table-bordered > thead > tr > td {
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
.footable.table-striped > tbody > tr:nth-child(odd),
|
||||
.footable-details.table-striped > tbody > tr:nth-child(odd) {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.footable.table-hover > tbody > tr:hover,
|
||||
.footable-details.table-hover > tbody > tr:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
/* buttons */
|
||||
.footable .btn {
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
margin-bottom: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 1.42857143;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
-webkit-appearance: button;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
overflow: visible;
|
||||
text-transform: none;
|
||||
}
|
||||
.footable .btn:hover,
|
||||
.footable .btn:focus,
|
||||
.footable .btn.focus {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
.footable .btn-default {
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.footable .btn-default:hover,
|
||||
.footable .btn-default:focus,
|
||||
.footable .btn-default.focus,
|
||||
.footable .btn-default:active,
|
||||
.footable .btn-default.active,
|
||||
.footable .open > .dropdown-toggle.btn-default {
|
||||
color: #333;
|
||||
background-color: #e6e6e6;
|
||||
border-color: #adadad;
|
||||
}
|
||||
.footable .btn-primary {
|
||||
color: #fff;
|
||||
background-color: #337ab7;
|
||||
border-color: #2e6da4;
|
||||
}
|
||||
.footable .btn-primary:hover,
|
||||
.footable .btn-primary:focus,
|
||||
.footable .btn-primary.focus,
|
||||
.footable .btn-primary:active,
|
||||
.footable .btn-primary.active,
|
||||
.footable .open > .dropdown-toggle.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #286090;
|
||||
border-color: #204d74;
|
||||
}
|
||||
/* caret */
|
||||
.footable .caret {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: 2px;
|
||||
vertical-align: middle;
|
||||
border-top: 4px solid;
|
||||
border-right: 4px solid transparent;
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
.footable .btn .caret {
|
||||
margin-left: 0;
|
||||
}
|
||||
/* form-group */
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
/* form-control */
|
||||
.footable .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
padding: 6px 12px;
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
line-height: 1.42857143;
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
}
|
||||
/* input-group */
|
||||
.footable .input-group {
|
||||
position: relative;
|
||||
display: table;
|
||||
border-collapse: separate;
|
||||
}
|
||||
.footable .input-group .form-control {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.footable .input-group-btn {
|
||||
position: relative;
|
||||
font-size: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.footable .input-group-addon,
|
||||
.footable .input-group-btn {
|
||||
width: 1%;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.footable .input-group-addon,
|
||||
.footable .input-group-btn,
|
||||
.footable .input-group .form-control {
|
||||
display: table-cell;
|
||||
}
|
||||
.footable .input-group-btn > .btn + .btn,
|
||||
.footable .input-group-btn:last-child > .btn,
|
||||
.footable .input-group-btn:last-child > .btn-group {
|
||||
margin-left: -1px;
|
||||
}
|
||||
.footable .input-group-btn > .btn {
|
||||
position: relative;
|
||||
}
|
||||
.footable .input-group-btn > .btn:hover,
|
||||
.footable .input-group-btn > .btn:focus,
|
||||
.footable .input-group-btn > .btn:active {
|
||||
z-index: 2;
|
||||
}
|
||||
.footable .input-group .form-control:first-child,
|
||||
.footable .input-group-addon:first-child,
|
||||
.footable .input-group-btn:first-child > .btn,
|
||||
.footable .input-group-btn:first-child > .btn-group > .btn,
|
||||
.footable .input-group-btn:first-child > .dropdown-toggle,
|
||||
.footable .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
||||
.footable .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
.footable .input-group .form-control:last-child,
|
||||
.footable .input-group-addon:last-child,
|
||||
.footable .input-group-btn:last-child > .btn,
|
||||
.footable .input-group-btn:last-child > .btn-group > .btn,
|
||||
.footable .input-group-btn:last-child > .dropdown-toggle,
|
||||
.footable .input-group-btn:first-child > .btn:not(:first-child),
|
||||
.footable .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
/* checkboxes & radios */
|
||||
.footable .radio,
|
||||
.footable .checkbox {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.footable .radio label,
|
||||
.footable .checkbox label {
|
||||
max-width: 100%;
|
||||
min-height: 20px;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 0;
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
}
|
||||
.footable .radio input[type=radio],
|
||||
.footable .radio-inline input[type=radio],
|
||||
.footable .checkbox input[type=checkbox],
|
||||
.footable .checkbox-inline input[type=checkbox] {
|
||||
position: absolute;
|
||||
margin: 4px 0 0 -20px;
|
||||
line-height: normal;
|
||||
}
|
||||
/* dropdown-menu */
|
||||
.footable .dropdown-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
float: left;
|
||||
min-width: 160px;
|
||||
padding: 5px 0;
|
||||
margin: 2px 0 0;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
list-style: none;
|
||||
background-color: #fff;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid rgba(0, 0, 0, .15);
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
|
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
|
||||
}
|
||||
.footable .open > .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
.footable .dropdown-menu-right {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
.footable .dropdown-menu > li > a {
|
||||
display: block;
|
||||
padding: 3px 20px;
|
||||
clear: both;
|
||||
font-weight: 400;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.footable .dropdown-menu > li > a:hover,
|
||||
.footable .dropdown-menu > li > a:focus {
|
||||
color: #262626;
|
||||
text-decoration: none;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
/* pagination */
|
||||
.footable .pagination {
|
||||
display: inline-block;
|
||||
padding-left: 0;
|
||||
margin: 20px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.footable .pagination > li {
|
||||
display: inline;
|
||||
}
|
||||
.footable .pagination > li:first-child > a,
|
||||
.footable .pagination > li:first-child > span {
|
||||
margin-left: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.footable .pagination > li > a,
|
||||
.footable .pagination > li > span {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 6px 12px;
|
||||
margin-left: -1px;
|
||||
line-height: 1.42857143;
|
||||
color: #337ab7;
|
||||
text-decoration: none;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.footable .pagination > li > a:hover,
|
||||
.footable .pagination > li > span:hover,
|
||||
.footable .pagination > li > a:focus,
|
||||
.footable .pagination > li > span:focus {
|
||||
color: #23527c;
|
||||
background-color: #eee;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.footable .pagination > .active > a,
|
||||
.footable .pagination > .active > span,
|
||||
.footable .pagination > .active > a:hover,
|
||||
.footable .pagination > .active > span:hover,
|
||||
.footable .pagination > .active > a:focus,
|
||||
.footable .pagination > .active > span:focus {
|
||||
z-index: 2;
|
||||
color: #fff;
|
||||
cursor: default;
|
||||
background-color: #337ab7;
|
||||
border-color: #337ab7;
|
||||
}
|
||||
.footable .pagination > .disabled > span,
|
||||
.footable .pagination > .disabled > span:hover,
|
||||
.footable .pagination > .disabled > span:focus,
|
||||
.footable .pagination > .disabled > a,
|
||||
.footable .pagination > .disabled > a:hover,
|
||||
.footable .pagination > .disabled > a:focus {
|
||||
color: #777;
|
||||
cursor: not-allowed;
|
||||
background-color: #fff;
|
||||
border-color: #ddd;
|
||||
}
|
||||
/* labels */
|
||||
.footable .label {
|
||||
display: inline;
|
||||
padding: .2em .6em .3em;
|
||||
font-size: 75%;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
border-radius: .25em;
|
||||
}
|
||||
.footable .label-default {
|
||||
background-color: #777;
|
||||
}
|
||||
/* wells */
|
||||
.footable-loader.well {
|
||||
min-height: 20px;
|
||||
padding: 19px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #e3e3e3;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
|
||||
}
|
||||
/* screen reader only */
|
||||
.footable .sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0,0,0,0);
|
||||
border: 0;
|
||||
}
|
||||
/* form-inline */
|
||||
@media (min-width: 768px) {
|
||||
.footable .form-inline .form-group {
|
||||
display:inline-block;
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.footable .form-inline .form-control {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.footable .form-inline .input-group {
|
||||
display: inline-table;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.footable .form-inline .input-group .input-group-addon,
|
||||
.footable .form-inline .input-group .input-group-btn,
|
||||
.footable .form-inline .input-group .form-control {
|
||||
width: auto
|
||||
}
|
||||
|
||||
.footable .form-inline .input-group>.form-control {
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
table.footable,
|
||||
table.footable-details {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.footable-details {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table > tbody > tr > td > span.footable-toggle {
|
||||
margin-right: 8px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
table > tbody > tr > td > span.footable-toggle.last-column {
|
||||
margin-left: 8px;
|
||||
float: right;
|
||||
}
|
||||
table.table-condensed > tbody > tr > td > span.footable-toggle {
|
||||
margin-right: 5px;
|
||||
}
|
||||
table.footable-details > tbody > tr > th:nth-child(1) {
|
||||
min-width: 40px;
|
||||
width: 120px;
|
||||
}
|
||||
table.footable-details > tbody > tr > td:nth-child(2) {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
table.footable-details > thead > tr:first-child > th,
|
||||
table.footable-details > thead > tr:first-child > td,
|
||||
table.footable-details > tbody > tr:first-child > th,
|
||||
table.footable-details > tbody > tr:first-child > td,
|
||||
table.footable-details > tfoot > tr:first-child > th,
|
||||
table.footable-details > tfoot > tr:first-child > td {
|
||||
border-top-width: 0;
|
||||
}
|
||||
table.footable-details.table-bordered > thead > tr:first-child > th,
|
||||
table.footable-details.table-bordered > thead > tr:first-child > td,
|
||||
table.footable-details.table-bordered > tbody > tr:first-child > th,
|
||||
table.footable-details.table-bordered > tbody > tr:first-child > td,
|
||||
table.footable-details.table-bordered > tfoot > tr:first-child > th,
|
||||
table.footable-details.table-bordered > tfoot > tr:first-child > td {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
div.footable-loader {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
height: 300px;
|
||||
position: relative;
|
||||
}
|
||||
div.footable-loader > span.fooicon {
|
||||
display: inline-block;
|
||||
opacity: 0.3;
|
||||
font-size: 30px;
|
||||
line-height: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-top: -16px;
|
||||
margin-left: -16px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-animation: fooicon-spin-r 2s infinite linear;
|
||||
animation: fooicon-spin-r 2s infinite linear;
|
||||
}
|
||||
table.footable > tbody > tr.footable-empty > td {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
}
|
||||
table.footable > tbody > tr > td,
|
||||
table.footable > tbody > tr > th {
|
||||
display: none;
|
||||
}
|
||||
table.footable > tbody > tr.footable-empty > td,
|
||||
table.footable > tbody > tr.footable-empty > th,
|
||||
table.footable > tbody > tr.footable-detail-row > td,
|
||||
table.footable > tbody > tr.footable-detail-row > th {
|
||||
display: table-cell;
|
||||
}
|
||||
@-webkit-keyframes fooicon-spin-r {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fooicon-spin-r {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
.fooicon {
|
||||
display: inline-block;
|
||||
font-size: inherit;
|
||||
font-family: FontAwesome !important;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
.fooicon:before,
|
||||
.fooicon:after {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.fooicon-loader:before {
|
||||
content: "\f01e";
|
||||
}
|
||||
.fooicon-plus:before {
|
||||
content: "\f067";
|
||||
}
|
||||
.fooicon-minus:before {
|
||||
content: "\f068";
|
||||
}
|
||||
.fooicon-search:before {
|
||||
content: "\f002";
|
||||
}
|
||||
.fooicon-remove:before {
|
||||
content: "\f00d";
|
||||
}
|
||||
.fooicon-sort:before {
|
||||
content: "\f0dc";
|
||||
}
|
||||
.fooicon-sort-asc:before {
|
||||
content: "\f160";
|
||||
}
|
||||
.fooicon-sort-desc:before {
|
||||
content: "\f161";
|
||||
}
|
||||
.fooicon-pencil:before {
|
||||
content: "\f040";
|
||||
}
|
||||
.fooicon-trash:before {
|
||||
content: "\f1f8";
|
||||
}
|
||||
.fooicon-eye-close:before {
|
||||
content: "\f070";
|
||||
}
|
||||
.fooicon-flash:before {
|
||||
content: "\f0e7";
|
||||
}
|
||||
.fooicon-cog:before {
|
||||
content: "\f013";
|
||||
}
|
55
media/footable/css/footable.filtering.css
Normal file
55
media/footable/css/footable.filtering.css
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
table.footable > thead > tr.footable-filtering > th {
|
||||
border-bottom-width: 1px;
|
||||
font-weight: normal;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th,
|
||||
table.footable.footable-filtering-right > thead > tr.footable-filtering > th {
|
||||
text-align: right;
|
||||
}
|
||||
table.footable.footable-filtering-left > thead > tr.footable-filtering > th {
|
||||
text-align: left;
|
||||
}
|
||||
table.footable.footable-filtering-center > thead > tr.footable-filtering > th {
|
||||
text-align: center;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
|
||||
margin-top: 5px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.input-group {
|
||||
width: 100%;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox {
|
||||
margin: 0;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox > label {
|
||||
display: block;
|
||||
padding-left: 20px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox input[type="checkbox"] {
|
||||
position: absolute;
|
||||
margin-left: -20px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
table.footable > thead > tr.footable-filtering > th div.input-group {
|
||||
width: auto;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
1
media/footable/css/footable.filtering.min.css
vendored
Normal file
1
media/footable/css/footable.filtering.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
table.footable>thead>tr.footable-filtering>th{border-bottom-width:1px;font-weight:400}table.footable.footable-filtering-right>thead>tr.footable-filtering>th,table.footable>thead>tr.footable-filtering>th{text-align:right}table.footable.footable-filtering-left>thead>tr.footable-filtering>th{text-align:left}table.footable.footable-filtering-center>thead>tr.footable-filtering>th{text-align:center}table.footable>thead>tr.footable-filtering>th div.form-group{margin-bottom:0}table.footable>thead>tr.footable-filtering>th div.form-group+div.form-group{margin-top:5px}table.footable>thead>tr.footable-filtering>th div.input-group{width:100%}table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox{margin:0;display:block;position:relative}table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox>label{display:block;padding-left:20px}table.footable>thead>tr.footable-filtering>th ul.dropdown-menu>li>a.checkbox input[type=checkbox]{position:absolute;margin-left:-20px}@media (min-width:768px){table.footable>thead>tr.footable-filtering>th div.input-group{width:auto}table.footable>thead>tr.footable-filtering>th div.form-group{margin-left:2px;margin-right:2px}table.footable>thead>tr.footable-filtering>th div.form-group+div.form-group{margin-top:0}}
|
@ -1,152 +0,0 @@
|
||||
.footable {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
border: 3px solid #52b9e9;
|
||||
font-family: "Open Sans", Arial, Helvetica, sans-serif;
|
||||
color: #444444;
|
||||
background: #efefef;
|
||||
-moz-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr.footable-row-detail {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr:hover:not(.footable-row-detail) {
|
||||
cursor: pointer;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr > td.footable-row-detail-cell {
|
||||
background: #fff;
|
||||
}
|
||||
.footable > tbody img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.footable > tbody > tr:hover:not(.footable-row-detail) {
|
||||
background: #dddddd;
|
||||
}
|
||||
.footable > tbody > tr:hover:not(.footable-row-detail) > td {
|
||||
color: #000000;
|
||||
}
|
||||
.footable > tbody > tr:last-child > td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.footable > tbody > tr > td {
|
||||
border-top: 1px solid #dddddd;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
border-left: none;
|
||||
}
|
||||
.footable > tbody > tr > td.footable-row-detail-cell,
|
||||
.footable > tbody > tr > td.footable-first-column {
|
||||
border-left: none;
|
||||
}
|
||||
.footable > thead > tr > th {
|
||||
border-bottom: 1px solid #dddddd;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.footable > thead > tr > th,
|
||||
.footable > thead > tr > td {
|
||||
background-color: #52b9e9;
|
||||
border: 1px solid #52b9e9;
|
||||
color: #ffffff;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
.footable > thead > tr > th.footable-first-column,
|
||||
.footable > thead > tr > td.footable-first-column {
|
||||
border-left: none;
|
||||
}
|
||||
.footable > tfoot > tr > th,
|
||||
.footable > tfoot > tr > td {
|
||||
background-color: #52b9e9;
|
||||
border: 1px solid #52b9e9;
|
||||
color: #ffffff;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
padding: 5px;
|
||||
}
|
||||
.footable > tfoot .pagination {
|
||||
text-align: center;
|
||||
}
|
||||
.footable > tfoot .pagination ul {
|
||||
display: inline-block;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
vertical-align: middle;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.footable > tfoot .pagination ul > li {
|
||||
display: inline;
|
||||
}
|
||||
.footable > tfoot .pagination ul > li > a,
|
||||
.footable > tfoot .pagination ul > li > span {
|
||||
float: left;
|
||||
border: 2px solid transparent;
|
||||
margin: 0 3px;
|
||||
color: #ffffff;
|
||||
background: transparent;
|
||||
padding: 1px 5px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.footable > tfoot .pagination ul > li.disabled > a {
|
||||
color: #888;
|
||||
}
|
||||
.footable > tfoot .pagination ul > li.active > a {
|
||||
border-color: #ffffff;
|
||||
}
|
||||
.footable > tfoot .pagination ul > li:first-child > a,
|
||||
.footable > tfoot .pagination ul > li:last-child > a,
|
||||
.footable > tfoot .pagination ul > li:first-child > span,
|
||||
.footable > tfoot .pagination ul > li:last-child > span {
|
||||
-moz-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
.footable.metro-red {
|
||||
border-color: #fa3031;
|
||||
}
|
||||
.footable.metro-red > tfoot > tr > th,
|
||||
.footable.metro-red > thead > tr > th,
|
||||
.footable.metro-red > tfoot > tr > td,
|
||||
.footable.metro-red > thead > tr > td {
|
||||
background-color: #fa3031;
|
||||
border-color: #fa3031;
|
||||
}
|
||||
.footable.metro-purple {
|
||||
border-color: #932ab6;
|
||||
}
|
||||
.footable.metro-purple > tfoot > tr > th,
|
||||
.footable.metro-purple > thead > tr > th,
|
||||
.footable.metro-purple > tfoot > tr > td,
|
||||
.footable.metro-purple > thead > tr > td {
|
||||
background-color: #932ab6;
|
||||
border-color: #932ab6;
|
||||
}
|
||||
.footable.metro-green {
|
||||
border-color: #43c83c;
|
||||
}
|
||||
.footable.metro-green > tfoot > tr > th,
|
||||
.footable.metro-green > thead > tr > th,
|
||||
.footable.metro-green > tfoot > tr > td,
|
||||
.footable.metro-green > thead > tr > td {
|
||||
background-color: #43c83c;
|
||||
border-color: #43c83c;
|
||||
}
|
||||
.footable.metro-blue {
|
||||
border-color: #1171a3;
|
||||
}
|
||||
.footable.metro-blue > tfoot > tr > th,
|
||||
.footable.metro-blue > thead > tr > th,
|
||||
.footable.metro-blue > tfoot > tr > td,
|
||||
.footable.metro-blue > thead > tr > td {
|
||||
background-color: #1171a3;
|
||||
border-color: #1171a3;
|
||||
}
|
||||
.footable-odd {
|
||||
background-color: #f7f7f7;
|
||||
}
|
1
media/footable/css/footable.metro.min.css
vendored
1
media/footable/css/footable.metro.min.css
vendored
@ -1 +0,0 @@
|
||||
.footable{border-collapse:separate;border-spacing:0;width:100%;border:3px solid #52b9e9;font-family:"Open Sans",Arial,Helvetica,sans-serif;color:#444;background:#efefef;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.footable.breakpoint>tbody>tr.footable-row-detail{background:#eee}.footable.breakpoint>tbody>tr:hover:not(.footable-row-detail){cursor:pointer}.footable.breakpoint>tbody>tr>td.footable-row-detail-cell{background:#fff}.footable>tbody img{vertical-align:middle}.footable>tbody>tr:hover:not(.footable-row-detail){background:#ddd}.footable>tbody>tr:hover:not(.footable-row-detail)>td{color:#000}.footable>tbody>tr:last-child>td{border-bottom:0}.footable>tbody>tr>td{border-top:1px solid #ddd;padding:10px;text-align:left;border-left:none}.footable>tbody>tr>td.footable-row-detail-cell,.footable>tbody>tr>td.footable-first-column{border-left:none}.footable>thead>tr>th{border-bottom:1px solid #ddd;padding:10px;text-align:left}.footable>thead>tr>th,.footable>thead>tr>td{background-color:#52b9e9;border:1px solid #52b9e9;color:#fff;border-top:0;border-left:none;font-weight:normal}.footable>thead>tr>th.footable-first-column,.footable>thead>tr>td.footable-first-column{border-left:none}.footable>tfoot>tr>th,.footable>tfoot>tr>td{background-color:#52b9e9;border:1px solid #52b9e9;color:#fff;border-top:0;border-left:none;padding:5px}.footable>tfoot .pagination{text-align:center}.footable>tfoot .pagination ul{display:inline-block;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;vertical-align:middle;margin:0;padding:0}.footable>tfoot .pagination ul>li{display:inline}.footable>tfoot .pagination ul>li>a,.footable>tfoot .pagination ul>li>span{float:left;border:2px solid transparent;margin:0 3px;color:#fff;background:transparent;padding:1px 5px;text-decoration:none}.footable>tfoot .pagination ul>li.disabled>a{color:#888}.footable>tfoot .pagination ul>li.active>a{border-color:#fff}.footable>tfoot .pagination ul>li:first-child>a,.footable>tfoot .pagination ul>li:last-child>a,.footable>tfoot .pagination ul>li:first-child>span,.footable>tfoot .pagination ul>li:last-child>span{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.footable.metro-red{border-color:#fa3031}.footable.metro-red>tfoot>tr>th,.footable.metro-red>thead>tr>th,.footable.metro-red>tfoot>tr>td,.footable.metro-red>thead>tr>td{background-color:#fa3031;border-color:#fa3031}.footable.metro-purple{border-color:#932ab6}.footable.metro-purple>tfoot>tr>th,.footable.metro-purple>thead>tr>th,.footable.metro-purple>tfoot>tr>td,.footable.metro-purple>thead>tr>td{background-color:#932ab6;border-color:#932ab6}.footable.metro-green{border-color:#43c83c}.footable.metro-green>tfoot>tr>th,.footable.metro-green>thead>tr>th,.footable.metro-green>tfoot>tr>td,.footable.metro-green>thead>tr>td{background-color:#43c83c;border-color:#43c83c}.footable.metro-blue{border-color:#1171a3}.footable.metro-blue>tfoot>tr>th,.footable.metro-blue>thead>tr>th,.footable.metro-blue>tfoot>tr>td,.footable.metro-blue>thead>tr>td{background-color:#1171a3;border-color:#1171a3}.footable-odd{background-color:#f7f7f7}
|
31
media/footable/css/footable.paging.css
Normal file
31
media/footable/css/footable.paging.css
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
table.footable > tfoot > tr.footable-paging > td > ul.pagination {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
table.footable > tfoot > tr.footable-paging > td > span.label {
|
||||
display: inline-block;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
table.footable > tfoot > tr.footable-paging > td,
|
||||
table.footable-paging-center > tfoot > tr.footable-paging > td {
|
||||
text-align: center;
|
||||
}
|
||||
table.footable-paging-left > tfoot > tr.footable-paging > td {
|
||||
text-align: left;
|
||||
}
|
||||
table.footable-paging-right > tfoot > tr.footable-paging > td {
|
||||
text-align: right;
|
||||
}
|
||||
ul.pagination > li.footable-page {
|
||||
display: none;
|
||||
}
|
||||
ul.pagination > li.footable-page.visible {
|
||||
display: inline;
|
||||
}
|
1
media/footable/css/footable.paging.min.css
vendored
Normal file
1
media/footable/css/footable.paging.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
table.footable>tfoot>tr.footable-paging>td>ul.pagination{margin:10px 0 0}table.footable>tfoot>tr.footable-paging>td>span.label{display:inline-block;margin:0 0 10px;padding:4px 10px}table.footable-paging-center>tfoot>tr.footable-paging>td,table.footable>tfoot>tr.footable-paging>td{text-align:center}table.footable-paging-left>tfoot>tr.footable-paging>td{text-align:left}table.footable-paging-right>tfoot>tr.footable-paging>td{text-align:right}ul.pagination>li.footable-page{display:none}ul.pagination>li.footable-page.visible{display:inline}
|
32
media/footable/css/footable.sorting.css
Normal file
32
media/footable/css/footable.sorting.css
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
td.footable-sortable,
|
||||
th.footable-sortable {
|
||||
position: relative;
|
||||
padding-right: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
td.footable-sortable > span.fooicon,
|
||||
th.footable-sortable > span.fooicon {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease-in;
|
||||
}
|
||||
td.footable-sortable:hover > span.fooicon,
|
||||
th.footable-sortable:hover > span.fooicon {
|
||||
opacity: 1;
|
||||
}
|
||||
td.footable-sortable.footable-asc > span.fooicon,
|
||||
th.footable-sortable.footable-asc > span.fooicon,
|
||||
td.footable-sortable.footable-desc > span.fooicon,
|
||||
th.footable-sortable.footable-desc > span.fooicon {
|
||||
opacity: 1;
|
||||
}
|
1
media/footable/css/footable.sorting.min.css
vendored
Normal file
1
media/footable/css/footable.sorting.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
td.footable-sortable,th.footable-sortable{position:relative;padding-right:30px;cursor:pointer}td.footable-sortable>span.fooicon,th.footable-sortable>span.fooicon{position:absolute;right:6px;top:50%;margin-top:-7px;opacity:0;transition:opacity .3s ease-in}td.footable-sortable.footable-asc>span.fooicon,td.footable-sortable.footable-desc>span.fooicon,td.footable-sortable:hover>span.fooicon,th.footable-sortable.footable-asc>span.fooicon,th.footable-sortable.footable-desc>span.fooicon,th.footable-sortable:hover>span.fooicon{opacity:1}
|
@ -1,181 +1,727 @@
|
||||
.footable {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
border: 1px solid #cccccc;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
font-family: 'trebuchet MS', 'Lucida sans', Arial;
|
||||
font-size: 14px;
|
||||
color: #444444;
|
||||
background: #ffffff;
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
/* globals - instead we house them under the .footable.table class as the root of FooTable is always the table itself. */
|
||||
.footable.table, .footable.table *,
|
||||
.footable-details.table, .footable-details.table * {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.footable > thead > tr:first-child > th.footable-first-column,
|
||||
.footable > thead > tr:first-child > td.footable-first-column {
|
||||
-moz-border-radius: 6px 0 0 0;
|
||||
-webkit-border-radius: 6px 0 0 0;
|
||||
border-radius: 6px 0 0 0;
|
||||
.footable.table th,
|
||||
.footable-details.table th {
|
||||
text-align: left;
|
||||
}
|
||||
.footable > thead > tr:first-child > th.footable-last-column,
|
||||
.footable > thead > tr:first-child > td.footable-last-column {
|
||||
-moz-border-radius: 0 6px 0 0;
|
||||
-webkit-border-radius: 0 6px 0 0;
|
||||
border-radius: 0 6px 0 0;
|
||||
/* tables */
|
||||
.footable.table,
|
||||
.footable-details.table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.footable > thead > tr:first-child > th.footable-first-column.footable-last-column,
|
||||
.footable > thead > tr:first-child > td.footable-first-column.footable-last-column {
|
||||
-moz-border-radius: 6px 6px 0 0;
|
||||
-webkit-border-radius: 6px 6px 0 0;
|
||||
border-radius: 6px 6px 0 0;
|
||||
.footable.table > caption + thead > tr:first-child > th,
|
||||
.footable.table > colgroup + thead > tr:first-child > th,
|
||||
.footable.table > thead:first-child > tr:first-child > th,
|
||||
.footable.table > caption + thead > tr:first-child > td,
|
||||
.footable.table > colgroup + thead > tr:first-child > td,
|
||||
.footable.table > thead:first-child > tr:first-child > td,
|
||||
.footable-details.table > caption + thead > tr:first-child > th,
|
||||
.footable-details.table > colgroup + thead > tr:first-child > th,
|
||||
.footable-details.table > thead:first-child > tr:first-child > th,
|
||||
.footable-details.table > caption + thead > tr:first-child > td,
|
||||
.footable-details.table > colgroup + thead > tr:first-child > td,
|
||||
.footable-details.table > thead:first-child > tr:first-child > td {
|
||||
border-top: 0;
|
||||
}
|
||||
.footable > thead > tr > th {
|
||||
border-left: 1px solid #cccccc;
|
||||
border-top: 1px solid #cccccc;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
.footable.table > thead > tr > th,
|
||||
.footable.table > tbody > tr > th,
|
||||
.footable.table > tfoot > tr > th,
|
||||
.footable.table > thead > tr > td,
|
||||
.footable.table > tbody > tr > td,
|
||||
.footable.table > tfoot > tr > td,
|
||||
.footable-details.table > thead > tr > th,
|
||||
.footable-details.table > tbody > tr > th,
|
||||
.footable-details.table > tfoot > tr > th,
|
||||
.footable-details.table > thead > tr > td,
|
||||
.footable-details.table > tbody > tr > td,
|
||||
.footable-details.table > tfoot > tr > td {
|
||||
padding: 8px;
|
||||
line-height: 1.42857143;
|
||||
vertical-align: top;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.footable > thead > tr > th,
|
||||
.footable > thead > tr > td {
|
||||
background-color: #dce9f9;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebf3fc), to(#dce9f9));
|
||||
background-image: -webkit-linear-gradient(top, #ebf3fc, #dce9f9);
|
||||
background-image: -moz-linear-gradient(top, #ebf3fc, #dce9f9);
|
||||
background-image: -ms-linear-gradient(top, #ebf3fc, #dce9f9);
|
||||
background-image: -o-linear-gradient(top, #ebf3fc, #dce9f9);
|
||||
background-image: linear-gradient(to bottom, #ebf3fc, #dce9f9);
|
||||
-webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset;
|
||||
-moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset;
|
||||
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset;
|
||||
border-top: none;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
.footable.table > thead > tr > th,
|
||||
.footable.table > thead > tr > td,
|
||||
.footable-details.table > thead > tr > th,
|
||||
.footable-details.table > thead > tr > td {
|
||||
vertical-align: bottom;
|
||||
border-bottom: 2px solid #ddd;
|
||||
}
|
||||
.footable > thead > tr > th.footable-first-column,
|
||||
.footable > thead > tr > td.footable-first-column {
|
||||
border-left: none;
|
||||
.footable.table-condensed > thead > tr > th,
|
||||
.footable.table-condensed > tbody > tr > th,
|
||||
.footable.table-condensed > tfoot > tr > th,
|
||||
.footable.table-condensed > thead > tr > td,
|
||||
.footable.table-condensed > tbody > tr > td,
|
||||
.footable.table-condensed > tfoot > tr > td,
|
||||
.footable-details.table-condensed > thead > tr > th,
|
||||
.footable-details.table-condensed > tbody > tr > th,
|
||||
.footable-details.table-condensed > tfoot > tr > th,
|
||||
.footable-details.table-condensed > thead > tr > td,
|
||||
.footable-details.table-condensed > tbody > tr > td,
|
||||
.footable-details.table-condensed > tfoot > tr > td {
|
||||
padding: 5px;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr.footable-row-detail {
|
||||
background: #eeeeee;
|
||||
.footable.table-bordered,
|
||||
.footable-details.table-bordered {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.footable.breakpoint > tbody > tr.footable-row-detail > .footable-row-detail-cell {
|
||||
border-left: none;
|
||||
.footable.table-bordered > thead > tr > th,
|
||||
.footable.table-bordered > tbody > tr > th,
|
||||
.footable.table-bordered > tfoot > tr > th,
|
||||
.footable.table-bordered > thead > tr > td,
|
||||
.footable.table-bordered > tbody > tr > td,
|
||||
.footable.table-bordered > tfoot > tr > td,
|
||||
.footable-details.table-bordered > thead > tr > th,
|
||||
.footable-details.table-bordered > tbody > tr > th,
|
||||
.footable-details.table-bordered > tfoot > tr > th,
|
||||
.footable-details.table-bordered > thead > tr > td,
|
||||
.footable-details.table-bordered > tbody > tr > td,
|
||||
.footable-details.table-bordered > tfoot > tr > td {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.footable > tbody img {
|
||||
vertical-align: middle;
|
||||
.footable.table-bordered > thead > tr > th,
|
||||
.footable.table-bordered > thead > tr > td,
|
||||
.footable-details.table-bordered > thead > tr > th,
|
||||
.footable-details.table-bordered > thead > tr > td {
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
.footable > tbody > tr:hover {
|
||||
background: #fbf8e9;
|
||||
.footable.table-striped > tbody > tr:nth-child(odd),
|
||||
.footable-details.table-striped > tbody > tr:nth-child(odd) {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.footable > tbody > tr:last-child > td.footable-first-column {
|
||||
-moz-border-radius: 0 0 0 6px;
|
||||
-webkit-border-radius: 0 0 0 6px;
|
||||
border-radius: 0 0 0 6px;
|
||||
.footable.table-hover > tbody > tr:hover,
|
||||
.footable-details.table-hover > tbody > tr:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.footable > tbody > tr:last-child > td.footable-last-column {
|
||||
-moz-border-radius: 0 0 6px 0;
|
||||
-webkit-border-radius: 0 0 6px 0;
|
||||
border-radius: 0 0 6px 0;
|
||||
/* buttons */
|
||||
.footable .btn {
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
margin-bottom: 0;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 1.42857143;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
-webkit-appearance: button;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
overflow: visible;
|
||||
text-transform: none;
|
||||
}
|
||||
.footable > tbody > tr:last-child > td.footable-first-column.footable-last-column {
|
||||
-moz-border-radius: 0 0 6px 6px;
|
||||
-webkit-border-radius: 0 0 6px 6px;
|
||||
border-radius: 0 0 6px 6px;
|
||||
.footable .btn:hover,
|
||||
.footable .btn:focus,
|
||||
.footable .btn.focus {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
.footable > tbody > tr > td {
|
||||
border-top: 1px solid #cccccc;
|
||||
border-left: 1px solid #cccccc;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
.footable .btn-default {
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
border-color: #ccc;
|
||||
}
|
||||
.footable > tbody > tr > td.footable-first-column {
|
||||
border-left: none;
|
||||
.footable .btn-default:hover,
|
||||
.footable .btn-default:focus,
|
||||
.footable .btn-default.focus,
|
||||
.footable .btn-default:active,
|
||||
.footable .btn-default.active,
|
||||
.footable .open > .dropdown-toggle.btn-default {
|
||||
color: #333;
|
||||
background-color: #e6e6e6;
|
||||
border-color: #adadad;
|
||||
}
|
||||
.footable > tfoot > tr > th,
|
||||
.footable > tfoot > tr > td {
|
||||
background-color: #dce9f9;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebf3fc), to(#dce9f9));
|
||||
background-image: -webkit-linear-gradient(top, #ebf3fc, #dce9f9);
|
||||
background-image: -moz-linear-gradient(top, #ebf3fc, #dce9f9);
|
||||
background-image: -ms-linear-gradient(top, #ebf3fc, #dce9f9);
|
||||
background-image: -o-linear-gradient(top, #ebf3fc, #dce9f9);
|
||||
background-image: linear-gradient(to bottom, #ebf3fc, #dce9f9);
|
||||
-webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset;
|
||||
-moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset;
|
||||
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset;
|
||||
border-top: 1px solid #cccccc;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
|
||||
padding: 10px;
|
||||
.footable .btn-primary {
|
||||
color: #fff;
|
||||
background-color: #337ab7;
|
||||
border-color: #2e6da4;
|
||||
}
|
||||
.footable .btn-primary:hover,
|
||||
.footable .btn-primary:focus,
|
||||
.footable .btn-primary.focus,
|
||||
.footable .btn-primary:active,
|
||||
.footable .btn-primary.active,
|
||||
.footable .open > .dropdown-toggle.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #286090;
|
||||
border-color: #204d74;
|
||||
}
|
||||
/* caret */
|
||||
.footable .caret {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: 2px;
|
||||
vertical-align: middle;
|
||||
border-top: 4px solid;
|
||||
border-right: 4px solid transparent;
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
.footable .btn .caret {
|
||||
margin-left: 0;
|
||||
}
|
||||
/* form-group */
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
/* form-control */
|
||||
.footable .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
padding: 6px 12px;
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
line-height: 1.42857143;
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
|
||||
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
}
|
||||
/* input-group */
|
||||
.footable .input-group {
|
||||
position: relative;
|
||||
display: table;
|
||||
border-collapse: separate;
|
||||
}
|
||||
.footable .input-group .form-control {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.footable .input-group-btn {
|
||||
position: relative;
|
||||
font-size: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.footable .input-group-addon,
|
||||
.footable .input-group-btn {
|
||||
width: 1%;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.footable .input-group-addon,
|
||||
.footable .input-group-btn,
|
||||
.footable .input-group .form-control {
|
||||
display: table-cell;
|
||||
}
|
||||
.footable .input-group-btn > .btn + .btn,
|
||||
.footable .input-group-btn:last-child > .btn,
|
||||
.footable .input-group-btn:last-child > .btn-group {
|
||||
margin-left: -1px;
|
||||
}
|
||||
.footable .input-group-btn > .btn {
|
||||
position: relative;
|
||||
}
|
||||
.footable .input-group-btn > .btn:hover,
|
||||
.footable .input-group-btn > .btn:focus,
|
||||
.footable .input-group-btn > .btn:active {
|
||||
z-index: 2;
|
||||
}
|
||||
.footable .input-group .form-control:first-child,
|
||||
.footable .input-group-addon:first-child,
|
||||
.footable .input-group-btn:first-child > .btn,
|
||||
.footable .input-group-btn:first-child > .btn-group > .btn,
|
||||
.footable .input-group-btn:first-child > .dropdown-toggle,
|
||||
.footable .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
||||
.footable .input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
.footable .input-group .form-control:last-child,
|
||||
.footable .input-group-addon:last-child,
|
||||
.footable .input-group-btn:last-child > .btn,
|
||||
.footable .input-group-btn:last-child > .btn-group > .btn,
|
||||
.footable .input-group-btn:last-child > .dropdown-toggle,
|
||||
.footable .input-group-btn:first-child > .btn:not(:first-child),
|
||||
.footable .input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
/* checkboxes & radios */
|
||||
.footable .radio,
|
||||
.footable .checkbox {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.footable .radio label,
|
||||
.footable .checkbox label {
|
||||
max-width: 100%;
|
||||
min-height: 20px;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 0;
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
}
|
||||
.footable .radio input[type=radio],
|
||||
.footable .radio-inline input[type=radio],
|
||||
.footable .checkbox input[type=checkbox],
|
||||
.footable .checkbox-inline input[type=checkbox] {
|
||||
position: absolute;
|
||||
margin: 4px 0 0 -20px;
|
||||
line-height: normal;
|
||||
}
|
||||
/* dropdown-menu */
|
||||
.footable .dropdown-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
float: left;
|
||||
min-width: 160px;
|
||||
padding: 5px 0;
|
||||
margin: 2px 0 0;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
list-style: none;
|
||||
background-color: #fff;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid rgba(0, 0, 0, .15);
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
|
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
|
||||
}
|
||||
.footable .open > .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
.footable .dropdown-menu-right {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
.footable .dropdown-menu > li > a {
|
||||
display: block;
|
||||
padding: 3px 20px;
|
||||
clear: both;
|
||||
font-weight: 400;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.footable .dropdown-menu > li > a:hover,
|
||||
.footable .dropdown-menu > li > a:focus {
|
||||
color: #262626;
|
||||
text-decoration: none;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
/* pagination */
|
||||
.footable .pagination {
|
||||
margin: 20px 0;
|
||||
display: inline-block;
|
||||
padding-left: 0;
|
||||
margin: 20px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.footable .pagination > ul {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
background-color: #ffffff;
|
||||
.footable .pagination > li {
|
||||
display: inline;
|
||||
}
|
||||
.footable .pagination > ul > li {
|
||||
display: inline;
|
||||
.footable .pagination > li:first-child > a,
|
||||
.footable .pagination > li:first-child > span {
|
||||
margin-left: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.footable .pagination > ul > li > a,
|
||||
.footable .pagination > ul > li > span {
|
||||
float: left;
|
||||
padding: 4px 12px;
|
||||
line-height: 20px;
|
||||
text-decoration: none;
|
||||
border: 1px solid #cccccc;
|
||||
border-left-width: 0;
|
||||
.footable .pagination > li > a,
|
||||
.footable .pagination > li > span {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 6px 12px;
|
||||
margin-left: -1px;
|
||||
line-height: 1.42857143;
|
||||
color: #337ab7;
|
||||
text-decoration: none;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.footable .pagination > ul > li:first-child > a,
|
||||
.footable .pagination > ul > li:first-child > span {
|
||||
-webkit-border-bottom-left-radius: 4px;
|
||||
-moz-border-radius-bottomleft: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
-webkit-border-top-left-radius: 4px;
|
||||
-moz-border-radius-topleft: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
border-left-width: 1px;
|
||||
.footable .pagination > li > a:hover,
|
||||
.footable .pagination > li > span:hover,
|
||||
.footable .pagination > li > a:focus,
|
||||
.footable .pagination > li > span:focus {
|
||||
color: #23527c;
|
||||
background-color: #eee;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.footable .pagination > ul > li:last-child > a,
|
||||
.footable .pagination > ul > li:last-child > span {
|
||||
-webkit-border-top-right-radius: 4px;
|
||||
-moz-border-radius-topright: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
-webkit-border-bottom-right-radius: 4px;
|
||||
-moz-border-radius-bottomright: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
.footable .pagination > .active > a,
|
||||
.footable .pagination > .active > span,
|
||||
.footable .pagination > .active > a:hover,
|
||||
.footable .pagination > .active > span:hover,
|
||||
.footable .pagination > .active > a:focus,
|
||||
.footable .pagination > .active > span:focus {
|
||||
z-index: 2;
|
||||
color: #fff;
|
||||
cursor: default;
|
||||
background-color: #337ab7;
|
||||
border-color: #337ab7;
|
||||
}
|
||||
.footable .pagination > ul > li > a:hover,
|
||||
.footable .pagination > ul > li > a:focus,
|
||||
.footable .pagination > ul > .active > a,
|
||||
.footable .pagination > ul > .active > span {
|
||||
background-color: #eeeeee;
|
||||
.footable .pagination > .disabled > span,
|
||||
.footable .pagination > .disabled > span:hover,
|
||||
.footable .pagination > .disabled > span:focus,
|
||||
.footable .pagination > .disabled > a,
|
||||
.footable .pagination > .disabled > a:hover,
|
||||
.footable .pagination > .disabled > a:focus {
|
||||
color: #777;
|
||||
cursor: not-allowed;
|
||||
background-color: #fff;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.footable .pagination > ul > .active > a,
|
||||
.footable .pagination > ul > .active > span {
|
||||
color: #444444;
|
||||
cursor: default;
|
||||
/* labels */
|
||||
.footable .label {
|
||||
display: inline;
|
||||
padding: .2em .6em .3em;
|
||||
font-size: 75%;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
border-radius: .25em;
|
||||
}
|
||||
.footable .pagination > ul > .disabled > span,
|
||||
.footable .pagination > ul > .disabled > a,
|
||||
.footable .pagination > ul > .disabled > a:hover,
|
||||
.footable .pagination > ul > .disabled > a:focus {
|
||||
color: #cccccc;
|
||||
cursor: default;
|
||||
background-color: #ebf3fc;
|
||||
.footable .label-default {
|
||||
background-color: #777;
|
||||
}
|
||||
.footable .pagination.pagination-centered {
|
||||
text-align: center;
|
||||
/* wells */
|
||||
.footable-loader.well {
|
||||
min-height: 20px;
|
||||
padding: 19px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #e3e3e3;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
|
||||
}
|
||||
.footable .pagination.pagination-right {
|
||||
text-align: center;
|
||||
/* screen reader only */
|
||||
.footable .sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0,0,0,0);
|
||||
border: 0;
|
||||
}
|
||||
.footable-odd {
|
||||
background-color: #f7f7f7;
|
||||
/* form-inline */
|
||||
@media (min-width: 768px) {
|
||||
.footable .form-inline .form-group {
|
||||
display:inline-block;
|
||||
margin-bottom: 0;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.footable .form-inline .form-control {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.footable .form-inline .input-group {
|
||||
display: inline-table;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.footable .form-inline .input-group .input-group-addon,
|
||||
.footable .form-inline .input-group .input-group-btn,
|
||||
.footable .form-inline .input-group .form-control {
|
||||
width: auto
|
||||
}
|
||||
|
||||
.footable .form-inline .input-group>.form-control {
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
table.footable,
|
||||
table.footable-details {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.footable-details {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table > tbody > tr > td > span.footable-toggle {
|
||||
margin-right: 8px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
table > tbody > tr > td > span.footable-toggle.last-column {
|
||||
margin-left: 8px;
|
||||
float: right;
|
||||
}
|
||||
table.table-condensed > tbody > tr > td > span.footable-toggle {
|
||||
margin-right: 5px;
|
||||
}
|
||||
table.footable-details > tbody > tr > th:nth-child(1) {
|
||||
min-width: 40px;
|
||||
width: 120px;
|
||||
}
|
||||
table.footable-details > tbody > tr > td:nth-child(2) {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
table.footable-details > thead > tr:first-child > th,
|
||||
table.footable-details > thead > tr:first-child > td,
|
||||
table.footable-details > tbody > tr:first-child > th,
|
||||
table.footable-details > tbody > tr:first-child > td,
|
||||
table.footable-details > tfoot > tr:first-child > th,
|
||||
table.footable-details > tfoot > tr:first-child > td {
|
||||
border-top-width: 0;
|
||||
}
|
||||
table.footable-details.table-bordered > thead > tr:first-child > th,
|
||||
table.footable-details.table-bordered > thead > tr:first-child > td,
|
||||
table.footable-details.table-bordered > tbody > tr:first-child > th,
|
||||
table.footable-details.table-bordered > tbody > tr:first-child > td,
|
||||
table.footable-details.table-bordered > tfoot > tr:first-child > th,
|
||||
table.footable-details.table-bordered > tfoot > tr:first-child > td {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
div.footable-loader {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
height: 300px;
|
||||
position: relative;
|
||||
}
|
||||
div.footable-loader > span.fooicon {
|
||||
display: inline-block;
|
||||
opacity: 0.3;
|
||||
font-size: 30px;
|
||||
line-height: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-top: -16px;
|
||||
margin-left: -16px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-animation: fooicon-spin-r 2s infinite linear;
|
||||
animation: fooicon-spin-r 2s infinite linear;
|
||||
}
|
||||
table.footable > tbody > tr.footable-empty > td {
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
}
|
||||
table.footable > tbody > tr > td,
|
||||
table.footable > tbody > tr > th {
|
||||
display: none;
|
||||
}
|
||||
table.footable > tbody > tr.footable-empty > td,
|
||||
table.footable > tbody > tr.footable-empty > th,
|
||||
table.footable > tbody > tr.footable-detail-row > td,
|
||||
table.footable > tbody > tr.footable-detail-row > th {
|
||||
display: table-cell;
|
||||
}
|
||||
@-webkit-keyframes fooicon-spin-r {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fooicon-spin-r {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
|
||||
.fooicon {
|
||||
display: inline-block;
|
||||
font-size: inherit;
|
||||
font-family: FontAwesome !important;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
.fooicon:before,
|
||||
.fooicon:after {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.fooicon-loader:before {
|
||||
content: "\f01e";
|
||||
}
|
||||
.fooicon-plus:before {
|
||||
content: "\f067";
|
||||
}
|
||||
.fooicon-minus:before {
|
||||
content: "\f068";
|
||||
}
|
||||
.fooicon-search:before {
|
||||
content: "\f002";
|
||||
}
|
||||
.fooicon-remove:before {
|
||||
content: "\f00d";
|
||||
}
|
||||
.fooicon-sort:before {
|
||||
content: "\f0dc";
|
||||
}
|
||||
.fooicon-sort-asc:before {
|
||||
content: "\f160";
|
||||
}
|
||||
.fooicon-sort-desc:before {
|
||||
content: "\f161";
|
||||
}
|
||||
.fooicon-pencil:before {
|
||||
content: "\f040";
|
||||
}
|
||||
.fooicon-trash:before {
|
||||
content: "\f1f8";
|
||||
}
|
||||
.fooicon-eye-close:before {
|
||||
content: "\f070";
|
||||
}
|
||||
.fooicon-flash:before {
|
||||
content: "\f0e7";
|
||||
}
|
||||
.fooicon-cog:before {
|
||||
content: "\f013";
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th {
|
||||
border-bottom-width: 1px;
|
||||
font-weight: normal;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th,
|
||||
table.footable.footable-filtering-right > thead > tr.footable-filtering > th {
|
||||
text-align: right;
|
||||
}
|
||||
table.footable.footable-filtering-left > thead > tr.footable-filtering > th {
|
||||
text-align: left;
|
||||
}
|
||||
table.footable.footable-filtering-center > thead > tr.footable-filtering > th {
|
||||
text-align: center;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
|
||||
margin-top: 5px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.input-group {
|
||||
width: 100%;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox {
|
||||
margin: 0;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox > label {
|
||||
display: block;
|
||||
padding-left: 20px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th ul.dropdown-menu > li > a.checkbox input[type="checkbox"] {
|
||||
position: absolute;
|
||||
margin-left: -20px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
table.footable > thead > tr.footable-filtering > th div.input-group {
|
||||
width: auto;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
table.footable > thead > tr.footable-filtering > th div.form-group+div.form-group {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
td.footable-sortable,
|
||||
th.footable-sortable {
|
||||
position: relative;
|
||||
padding-right: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
td.footable-sortable > span.fooicon,
|
||||
th.footable-sortable > span.fooicon {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 50%;
|
||||
margin-top: -7px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease-in;
|
||||
}
|
||||
td.footable-sortable:hover > span.fooicon,
|
||||
th.footable-sortable:hover > span.fooicon {
|
||||
opacity: 1;
|
||||
}
|
||||
td.footable-sortable.footable-asc > span.fooicon,
|
||||
th.footable-sortable.footable-asc > span.fooicon,
|
||||
td.footable-sortable.footable-desc > span.fooicon,
|
||||
th.footable-sortable.footable-desc > span.fooicon {
|
||||
opacity: 1;
|
||||
}
|
||||
table.footable > tfoot > tr.footable-paging > td > ul.pagination {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
table.footable > tfoot > tr.footable-paging > td > span.label {
|
||||
display: inline-block;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 4px 10px;
|
||||
}
|
||||
table.footable > tfoot > tr.footable-paging > td,
|
||||
table.footable-paging-center > tfoot > tr.footable-paging > td {
|
||||
text-align: center;
|
||||
}
|
||||
table.footable-paging-left > tfoot > tr.footable-paging > td {
|
||||
text-align: left;
|
||||
}
|
||||
table.footable-paging-right > tfoot > tr.footable-paging > td {
|
||||
text-align: right;
|
||||
}
|
||||
ul.pagination > li.footable-page {
|
||||
display: none;
|
||||
}
|
||||
ul.pagination > li.footable-page.visible {
|
||||
display: inline;
|
||||
}
|
File diff suppressed because one or more lines are too long
14
media/footable/dist/footable.all.min.js
vendored
14
media/footable/dist/footable.all.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
(function(t,e,undefined){function a(t,e){e=e?e:location.hash;var a=RegExp("&"+t+"(?:=([^&]*))?(?=&|$)","i");return(e=e.replace(/^\#/,"&").match(a))?e[1]===undefined?"":decodeURIComponent(e[1]):undefined}function i(e,a){var i=t(e.table).find("tbody").find("tr:not(.footable-row-detail, .footable-filtered)").length;t(e.table).data("status_num_total",i);var o=t(e.table).find("tbody").find("tr:not(.footable-row-detail)").filter(":visible").length;t(e.table).data("status_num_shown",o);var n=t(e.table).data("sorted"),r=t(e.table).find("th")[n],l=t(r).hasClass("footable-sorted-desc");if(t(e.table).data("status_descending",l),e.pageInfo){var s=e.pageInfo.currentPage;t(e.table).data("status_pagenum",s)}var d="",f=t(e.table).data("filter");t(f).length&&(d=t(f).val()),t(e.table).data("status_filter_val",d);var u,p,c;if("footable_row_expanded"==a.type&&(u=a.row,u&&(p=t(e.table).data("expanded_rows"),c=[],p&&(c=p.split(",")),c.push(u.rowIndex),t(e.table).data("expanded_rows",c.join(",")))),"footable_row_collapsed"==a.type&&(u=a.row)){p=t(e.table).data("expanded_rows"),c=[],p&&(c=p.split(","));var g=[];for(var b in c)if(c[b]==u.rowIndex){g=c.splice(b,1);break}t(e.table).data("expanded_rows",g.join(","))}}function o(){var e=this;e.name="Footable LucidBookmarkable",e.init=function(e){e.options.bookmarkable.enabled&&t(e.table).bind({footable_initialized:function(){var i=e.table.id,o=a(i+"_f"),n=a(i+"_p"),r=a(i+"_s"),l=a(i+"_d"),s=a(i+"_e");if(o){var d=t(e.table).data("filter");t(d).val(o),t(e.table).trigger("footable_filter",{filter:o})}if(n&&t(e.table).data("currentPage",n),r!==undefined){var f=t(e.table).data("footable-sort"),u=!0;"true"==l&&(u=!1),f.doSort(r,u)}else t(e.table).trigger("footable_setup_paging");if(s){var p=s.split(",");for(var c in p){var g=t(e.table.rows[p[c]]);g.find("> td:first").trigger("footable_toggle_row")}}e.lucid_bookmark_read=!0},"footable_page_filled footable_redrawn footable_filtered footable_sorted footable_row_expanded footable_row_collapsed":function(a){if(i(e,a),e.lucid_bookmark_read){var o=e.table.id,n=o+"_f",r=o+"_p",l=o+"_s",s=o+"_d",d=o+"_e",f=location.hash.replace(/^\#/,"&"),u=[n,r,l,s,d];for(var p in u){var c=RegExp("&"+u[p]+"=([^&]*)","g");f=f.replace(c,"")}var g={};g[n]=t(e.table).data("status_filter_val"),g[r]=t(e.table).data("status_pagenum"),g[l]=t(e.table).data("sorted"),g[s]=t(e.table).data("status_descending"),g[d]=t(e.table).data("expanded_rows");var b=[];for(var h in g)g[h]!==undefined&&b.push(h+"="+encodeURIComponent(g[h]));f.length&&b.push(f),location.hash=b.join("&")}}})}}if(e.footable===undefined||null===e.foobox)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var n={bookmarkable:{enabled:!1}};e.footable.plugins.register(o,n)})(jQuery,window);
|
1
media/footable/dist/footable.filter.min.js
vendored
1
media/footable/dist/footable.filter.min.js
vendored
@ -1 +0,0 @@
|
||||
(function(t,e,undefined){function a(){var e=this;e.name="Footable Filter",e.init=function(a){if(e.footable=a,a.options.filter.enabled===!0){if(t(a.table).data("filter")===!1)return;a.timers.register("filter"),t(a.table).unbind(".filtering").bind({"footable_initialized.filtering":function(){var i=t(a.table),o={input:i.data("filter")||a.options.filter.input,timeout:i.data("filter-timeout")||a.options.filter.timeout,minimum:i.data("filter-minimum")||a.options.filter.minimum,disableEnter:i.data("filter-disable-enter")||a.options.filter.disableEnter};o.disableEnter&&t(o.input).keypress(function(t){return window.event?13!==window.event.keyCode:13!==t.which}),i.bind("footable_clear_filter",function(){t(o.input).val(""),e.clearFilter()}),i.bind("footable_filter",function(t,a){e.filter(a.filter)}),t(o.input).keyup(function(i){a.timers.filter.stop(),27===i.which&&t(o.input).val(""),a.timers.filter.start(function(){var a=t(o.input).val()||"";e.filter(a)},o.timeout)})},"footable_redrawn.filtering":function(){var i=t(a.table),o=i.data("filter-string");o&&e.filter(o)}}).data("footable-filter",e)}},e.filter=function(a){var i=e.footable,o=t(i.table),n=o.data("filter-minimum")||i.options.filter.minimum,r=!a,l=i.raise("footable_filtering",{filter:a,clear:r});if(!(l&&l.result===!1||l.filter&&n>l.filter.length))if(l.clear)e.clearFilter();else{var d=l.filter.split(" ");o.find("> tbody > tr").hide().addClass("footable-filtered");var s=o.find("> tbody > tr:not(.footable-row-detail)");t.each(d,function(t,e){e&&e.length>0&&(o.data("current-filter",e),s=s.filter(i.options.filter.filterFunction))}),s.each(function(){e.showRow(this,i),t(this).removeClass("footable-filtered")}),o.data("filter-string",l.filter),i.raise("footable_filtered",{filter:l.filter,clear:!1})}},e.clearFilter=function(){var a=e.footable,i=t(a.table);i.find("> tbody > tr:not(.footable-row-detail)").removeClass("footable-filtered").each(function(){e.showRow(this,a)}),i.removeData("filter-string"),a.raise("footable_filtered",{clear:!0})},e.showRow=function(e,a){var i=t(e),o=i.next(),n=t(a.table);i.is(":visible")||(n.hasClass("breakpoint")&&i.hasClass("footable-detail-show")&&o.hasClass("footable-row-detail")?(i.add(o).show(),a.createOrUpdateDetailRow(e)):i.show())}}if(e.footable===undefined||null===e.footable)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={filter:{enabled:!0,input:".footable-filter",timeout:300,minimum:2,disableEnter:!1,filterFunction:function(){var e=t(this),a=e.parents("table:first"),i=a.data("current-filter").toUpperCase(),o=e.find("td").text();return a.data("filter-text-only")||e.find("td[data-value]").each(function(){o+=t(this).data("value")}),o.toUpperCase().indexOf(i)>=0}}};e.footable.plugins.register(a,i)})(jQuery,window);
|
1
media/footable/dist/footable.grid.min.js
vendored
1
media/footable/dist/footable.grid.min.js
vendored
File diff suppressed because one or more lines are too long
14
media/footable/dist/footable.min.js
vendored
14
media/footable/dist/footable.min.js
vendored
File diff suppressed because one or more lines are too long
1
media/footable/dist/footable.paginate.min.js
vendored
1
media/footable/dist/footable.paginate.min.js
vendored
File diff suppressed because one or more lines are too long
1
media/footable/dist/footable.sort.min.js
vendored
1
media/footable/dist/footable.sort.min.js
vendored
@ -1 +0,0 @@
|
||||
(function(t,e,undefined){function a(){var e=this;e.name="Footable Sortable",e.init=function(a){e.footable=a,a.options.sort===!0&&t(a.table).unbind(".sorting").bind({"footable_initialized.sorting":function(){var i,o,n=t(a.table),r=(n.find("> tbody"),a.options.classes.sort);if(n.data("sort")!==!1){n.find("> thead > tr:last-child > th, > thead > tr:last-child > td").each(function(){var e=t(this),i=a.columns[e.index()];i.sort.ignore===!0||e.hasClass(r.sortable)||(e.addClass(r.sortable),t("<span />").addClass(r.indicator).appendTo(e))}),n.find("> thead > tr:last-child > th."+r.sortable+", > thead > tr:last-child > td."+r.sortable).unbind("click.footable").bind("click.footable",function(a){a.preventDefault(),o=t(this);var i=!o.hasClass(r.sorted);return e.doSort(o.index(),i),!1});var l=!1;for(var s in a.columns)if(i=a.columns[s],i.sort.initial){var d="descending"!==i.sort.initial;e.doSort(i.index,d);break}l&&a.bindToggleSelectors()}},"footable_redrawn.sorting":function(){var i=t(a.table),o=a.options.classes.sort;i.data("sorted")>=0&&i.find("> thead > tr:last-child > th").each(function(a){var i=t(this);return i.hasClass(o.sorted)||i.hasClass(o.descending)?(e.doSort(a),undefined):undefined})},"footable_column_data.sorting":function(e){var a=t(e.column.th);e.column.data.sort=e.column.data.sort||{},e.column.data.sort.initial=a.data("sort-initial")||!1,e.column.data.sort.ignore=a.data("sort-ignore")||!1,e.column.data.sort.selector=a.data("sort-selector")||null;var i=a.data("sort-match")||0;i>=e.column.data.matches.length&&(i=0),e.column.data.sort.match=e.column.data.matches[i]}}).data("footable-sort",e)},e.doSort=function(a,i){var o=e.footable;if(t(o.table).data("sort")!==!1){var n=t(o.table),r=n.find("> tbody"),l=o.columns[a],s=n.find("> thead > tr:last-child > th:eq("+a+")"),d=o.options.classes.sort,f=o.options.events.sort;if(i=i===undefined?s.hasClass(d.sorted):"toggle"===i?!s.hasClass(d.sorted):i,l.sort.ignore===!0)return!0;var u=o.raise(f.sorting,{column:l,direction:i?"ASC":"DESC"});u&&u.result===!1||(n.data("sorted",l.index),n.find("> thead > tr:last-child > th, > thead > tr:last-child > td").not(s).removeClass(d.sorted+" "+d.descending),i===undefined&&(i=s.hasClass(d.sorted)),i?s.removeClass(d.descending).addClass(d.sorted):s.removeClass(d.sorted).addClass(d.descending),e.sort(o,r,l,i),o.bindToggleSelectors(),o.raise(f.sorted,{column:l,direction:i?"ASC":"DESC"}))}},e.rows=function(e,a,i){var o=[];return a.find("> tr").each(function(){var a=t(this),n=null;if(a.hasClass(e.options.classes.detail))return!0;a.next().hasClass(e.options.classes.detail)&&(n=a.next().get(0));var r={row:a,detail:n};return i!==undefined&&(r.value=e.parse(this.cells[i.sort.match],i)),o.push(r),!0}).detach(),o},e.sort=function(t,a,i,o){var n=e.rows(t,a,i),r=t.options.sorters[i.type]||t.options.sorters.alpha;n.sort(function(t,e){return o?r(t.value,e.value):r(e.value,t.value)});for(var l=0;n.length>l;l++)a.append(n[l].row),null!==n[l].detail&&a.append(n[l].detail)}}if(e.footable===undefined||null===e.footable)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={sort:!0,sorters:{alpha:function(t,e){return"string"==typeof t&&(t=t.toLowerCase()),"string"==typeof e&&(e=e.toLowerCase()),t===e?0:e>t?-1:1},numeric:function(t,e){return t-e}},classes:{sort:{sortable:"footable-sortable",sorted:"footable-sorted",descending:"footable-sorted-desc",indicator:"footable-sort-indicator"}},events:{sort:{sorting:"footable_sorting",sorted:"footable_sorted"}}};e.footable.plugins.register(a,i)})(jQuery,window);
|
1
media/footable/dist/footable.striping.min.js
vendored
1
media/footable/dist/footable.striping.min.js
vendored
@ -1 +0,0 @@
|
||||
(function(t,e,undefined){function a(){var e=this;e.name="Footable Striping",e.init=function(a){e.footable=a,t(a.table).unbind("striping").bind({"footable_initialized.striping footable_row_removed.striping footable_redrawn.striping footable_sorted.striping footable_filtered.striping":function(){t(this).data("striping")!==!1&&e.setupStriping(a)}})},e.setupStriping=function(e){var a=0;t(e.table).find("> tbody > tr:not(.footable-row-detail)").each(function(){var i=t(this);i.removeClass(e.options.classes.striping.even).removeClass(e.options.classes.striping.odd),0===a%2?i.addClass(e.options.classes.striping.even):i.addClass(e.options.classes.striping.odd),a++})}}if(e.footable===undefined||null===e.foobox)throw Error("Please check and make sure footable.js is included in the page and is loaded prior to this script.");var i={striping:{enabled:!0},classes:{striping:{odd:"footable-odd",even:"footable-even"}}};e.footable.plugins.register(a,i)})(jQuery,window);
|
1
media/footable/dist/index.html
vendored
1
media/footable/dist/index.html
vendored
@ -1 +0,0 @@
|
||||
<html><body bgcolor="#FFFFFF"></body></html>
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
<html><body bgcolor="#FFFFFF"></body></html>
|
@ -1,29 +0,0 @@
|
||||
{
|
||||
"curly": false,
|
||||
"eqeqeq": false,
|
||||
"forin": false,
|
||||
"indent": false,
|
||||
"newcap": false,
|
||||
"plusplus": false,
|
||||
"quotmark": false,
|
||||
"undef": false,
|
||||
"unused": false,
|
||||
"strict": false,
|
||||
"trailing": false,
|
||||
"maxparams": false,
|
||||
"maxdepth": false,
|
||||
"maxstatements": false,
|
||||
"maxcomplexity": false,
|
||||
"maxlen": false,
|
||||
|
||||
"eqnull": true,
|
||||
"loopfunc": true,
|
||||
"smarttabs": true,
|
||||
"sub": true,
|
||||
|
||||
"browser": true,
|
||||
"jquery": true,
|
||||
"node": true,
|
||||
|
||||
"white": false
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
(function ($, w, undefined) {
|
||||
if (w.footable === undefined || w.foobox === null)
|
||||
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
||||
|
||||
var defaults = {
|
||||
bookmarkable: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
|
||||
// see http://www.onlineaspect.com/2009/06/10/reading-get-variables-with-javascript/
|
||||
function $_HASH(q,s) {
|
||||
s = s ? s : location.hash;
|
||||
var re = new RegExp('&'+q+'(?:=([^&]*))?(?=&|$)','i');
|
||||
return (s=s.replace(/^\#/,'&').match(re)) ? (typeof s[1] == 'undefined' ? '' : decodeURIComponent(s[1])) : undefined;
|
||||
}
|
||||
|
||||
function addFootableStatusData(ft, event) {
|
||||
var tbl_total = $(ft.table).find("tbody").find("tr:not(.footable-row-detail, .footable-filtered)").length;
|
||||
$(ft.table).data("status_num_total", tbl_total);
|
||||
|
||||
var tbl_num = $(ft.table).find("tbody").find("tr:not(.footable-row-detail)").filter(":visible").length;
|
||||
$(ft.table).data("status_num_shown", tbl_num);
|
||||
|
||||
var sort_colnum = $(ft.table).data("sorted");
|
||||
var sort_col = $(ft.table).find("th")[sort_colnum];
|
||||
var descending = $(sort_col).hasClass("footable-sorted-desc");
|
||||
$(ft.table).data("status_descending", descending);
|
||||
|
||||
if (ft.pageInfo) {
|
||||
var pagenum = ft.pageInfo.currentPage;
|
||||
$(ft.table).data("status_pagenum", pagenum);
|
||||
}
|
||||
|
||||
var filter_val = '';
|
||||
var filter_field_id = $(ft.table).data('filter');
|
||||
if ( $(filter_field_id).length ) {
|
||||
filter_val = $(filter_field_id).val();
|
||||
}
|
||||
|
||||
$(ft.table).data("status_filter_val", filter_val);
|
||||
|
||||
// manage expanded or collapsed rows:
|
||||
var row, rowlist, expanded_rows;
|
||||
if (event.type == 'footable_row_expanded') {
|
||||
row = event.row;
|
||||
if (row) {
|
||||
rowlist = $(ft.table).data('expanded_rows');
|
||||
expanded_rows = [];
|
||||
if (rowlist) {
|
||||
expanded_rows = rowlist.split(',');
|
||||
}
|
||||
expanded_rows.push(row.rowIndex);
|
||||
$(ft.table).data('expanded_rows', expanded_rows.join(','));
|
||||
}
|
||||
}
|
||||
if (event.type == 'footable_row_collapsed') {
|
||||
row = event.row;
|
||||
if (row) {
|
||||
rowlist = $(ft.table).data('expanded_rows');
|
||||
expanded_rows = [];
|
||||
if (rowlist) {
|
||||
expanded_rows = rowlist.split(',');
|
||||
}
|
||||
var new_expanded_rows = [];
|
||||
for (var i in expanded_rows) {
|
||||
if (expanded_rows[i] == row.rowIndex) {
|
||||
new_expanded_rows = expanded_rows.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$(ft.table).data('expanded_rows', new_expanded_rows.join(','));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Bookmarkable() {
|
||||
var p = this;
|
||||
p.name = 'Footable LucidBookmarkable';
|
||||
p.init = function(ft) {
|
||||
if (ft.options.bookmarkable.enabled) {
|
||||
|
||||
$(ft.table).bind({
|
||||
'footable_initialized': function(){
|
||||
var tbl_id = ft.table.id;
|
||||
var q_filter = $_HASH(tbl_id + '_f');
|
||||
var q_page_num = $_HASH(tbl_id + '_p');
|
||||
var q_sorted = $_HASH(tbl_id + '_s');
|
||||
var q_desc = $_HASH(tbl_id + '_d');
|
||||
var q_expanded = $_HASH(tbl_id + '_e');
|
||||
|
||||
if (q_filter) {
|
||||
var filter_field_id = $(ft.table).data('filter');
|
||||
$(filter_field_id).val(q_filter);
|
||||
$(ft.table).trigger('footable_filter', {filter: q_filter});
|
||||
}
|
||||
if (q_page_num) {
|
||||
$(ft.table).data('currentPage', q_page_num);
|
||||
// we'll check for sort before triggering pagination, since
|
||||
// sorting triggers pagination.
|
||||
}
|
||||
if (typeof q_sorted !== 'undefined') {
|
||||
var footableSort = $(ft.table).data('footable-sort');
|
||||
var ascending = true;
|
||||
if (q_desc == 'true') {
|
||||
ascending = false;
|
||||
}
|
||||
footableSort.doSort(q_sorted, ascending);
|
||||
}
|
||||
else {
|
||||
$(ft.table).trigger('footable_setup_paging');
|
||||
}
|
||||
if (q_expanded) {
|
||||
var expanded_rows = q_expanded.split(',');
|
||||
for (var i in expanded_rows) {
|
||||
var row = $(ft.table.rows[expanded_rows[i]]);
|
||||
row.find('> td:first').trigger('footable_toggle_row');
|
||||
}
|
||||
}
|
||||
ft.lucid_bookmark_read = true;
|
||||
},
|
||||
'footable_page_filled footable_redrawn footable_filtered footable_sorted footable_row_expanded footable_row_collapsed': function(e) {
|
||||
addFootableStatusData(ft, e);
|
||||
|
||||
// update the URL hash
|
||||
// lucid_bookmark_read guards against running this logic before
|
||||
// the "first read" of the location bookmark hash.
|
||||
if (ft.lucid_bookmark_read) {
|
||||
var tbl_id = ft.table.id;
|
||||
var filter = tbl_id + '_f';
|
||||
var page_num = tbl_id + '_p';
|
||||
var sorted = tbl_id + '_s';
|
||||
var descending = tbl_id + '_d';
|
||||
var expanded = tbl_id + '_e';
|
||||
|
||||
var hash = location.hash.replace(/^\#/, '&');
|
||||
var hashkeys = [filter, page_num, sorted, descending, expanded];
|
||||
// trim existing elements out of the hash.
|
||||
for (var i in hashkeys) {
|
||||
var re = new RegExp('&' + hashkeys[i]+'=([^&]*)', 'g');
|
||||
hash = hash.replace(re, '');
|
||||
}
|
||||
|
||||
var foostate = {};
|
||||
foostate[filter] = $(ft.table).data('status_filter_val');
|
||||
foostate[page_num] = $(ft.table).data('status_pagenum');
|
||||
foostate[sorted] = $(ft.table).data('sorted');
|
||||
foostate[descending] = $(ft.table).data('status_descending');
|
||||
foostate[expanded] = $(ft.table).data('expanded_rows');
|
||||
|
||||
var pairs = [];
|
||||
for (var elt in foostate) {
|
||||
if (foostate[elt] !== undefined) {
|
||||
pairs.push(elt + '=' + encodeURIComponent(foostate[elt]));
|
||||
}
|
||||
}
|
||||
if (hash.length) {
|
||||
pairs.push(hash);
|
||||
}
|
||||
location.hash = pairs.join('&');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
w.footable.plugins.register(Bookmarkable, defaults);
|
||||
|
||||
})(jQuery, window);
|
3248
media/footable/js/footable.core.js
Normal file
3248
media/footable/js/footable.core.js
Normal file
File diff suppressed because it is too large
Load Diff
9
media/footable/js/footable.core.min.js
vendored
Normal file
9
media/footable/js/footable.core.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,144 +0,0 @@
|
||||
(function ($, w, undefined) {
|
||||
if (w.footable === undefined || w.footable === null)
|
||||
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
||||
|
||||
var defaults = {
|
||||
filter: {
|
||||
enabled: true,
|
||||
input: '.footable-filter',
|
||||
timeout: 300,
|
||||
minimum: 2,
|
||||
disableEnter: false,
|
||||
filterFunction: function(index) {
|
||||
var $t = $(this),
|
||||
$table = $t.parents('table:first'),
|
||||
filter = $table.data('current-filter').toUpperCase(),
|
||||
text = $t.find('td').text();
|
||||
if (!$table.data('filter-text-only')) {
|
||||
$t.find('td[data-value]').each(function () {
|
||||
text += $(this).data('value');
|
||||
});
|
||||
}
|
||||
return text.toUpperCase().indexOf(filter) >= 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function Filter() {
|
||||
var p = this;
|
||||
p.name = 'Footable Filter';
|
||||
p.init = function (ft) {
|
||||
p.footable = ft;
|
||||
if (ft.options.filter.enabled === true) {
|
||||
if ($(ft.table).data('filter') === false) return;
|
||||
ft.timers.register('filter');
|
||||
$(ft.table)
|
||||
.unbind('.filtering')
|
||||
.bind({
|
||||
'footable_initialized.filtering': function (e) {
|
||||
var $table = $(ft.table);
|
||||
var data = {
|
||||
'input': $table.data('filter') || ft.options.filter.input,
|
||||
'timeout': $table.data('filter-timeout') || ft.options.filter.timeout,
|
||||
'minimum': $table.data('filter-minimum') || ft.options.filter.minimum,
|
||||
'disableEnter': $table.data('filter-disable-enter') || ft.options.filter.disableEnter
|
||||
};
|
||||
if (data.disableEnter) {
|
||||
$(data.input).keypress(function (event) {
|
||||
if (window.event)
|
||||
return (window.event.keyCode !== 13);
|
||||
else
|
||||
return (event.which !== 13);
|
||||
});
|
||||
}
|
||||
$table.bind('footable_clear_filter', function () {
|
||||
$(data.input).val('');
|
||||
p.clearFilter();
|
||||
});
|
||||
$table.bind('footable_filter', function (event, args) {
|
||||
p.filter(args.filter);
|
||||
});
|
||||
$(data.input).keyup(function (eve) {
|
||||
ft.timers.filter.stop();
|
||||
if (eve.which === 27) {
|
||||
$(data.input).val('');
|
||||
}
|
||||
ft.timers.filter.start(function () {
|
||||
var val = $(data.input).val() || '';
|
||||
p.filter(val);
|
||||
}, data.timeout);
|
||||
});
|
||||
},
|
||||
'footable_redrawn.filtering': function (e) {
|
||||
var $table = $(ft.table),
|
||||
filter = $table.data('filter-string');
|
||||
if (filter) {
|
||||
p.filter(filter);
|
||||
}
|
||||
}
|
||||
})
|
||||
//save the filter object onto the table so we can access it later
|
||||
.data('footable-filter', p);
|
||||
}
|
||||
};
|
||||
|
||||
p.filter = function (filterString) {
|
||||
var ft = p.footable,
|
||||
$table = $(ft.table),
|
||||
minimum = $table.data('filter-minimum') || ft.options.filter.minimum,
|
||||
clear = !filterString;
|
||||
|
||||
//raise a pre-filter event so that we can cancel the filtering if needed
|
||||
var event = ft.raise('footable_filtering', { filter: filterString, clear: clear });
|
||||
if (event && event.result === false) return;
|
||||
if (event.filter && event.filter.length < minimum) {
|
||||
return; //if we do not have the minimum chars then do nothing
|
||||
}
|
||||
|
||||
if (event.clear) {
|
||||
p.clearFilter();
|
||||
} else {
|
||||
var filters = event.filter.split(' ');
|
||||
|
||||
$table.find('> tbody > tr').hide().addClass('footable-filtered');
|
||||
var rows = $table.find('> tbody > tr:not(.footable-row-detail)');
|
||||
$.each(filters, function (i, f) {
|
||||
if (f && f.length > 0) {
|
||||
$table.data('current-filter', f);
|
||||
rows = rows.filter(ft.options.filter.filterFunction);
|
||||
}
|
||||
});
|
||||
rows.each(function () {
|
||||
p.showRow(this, ft);
|
||||
$(this).removeClass('footable-filtered');
|
||||
});
|
||||
$table.data('filter-string', event.filter);
|
||||
ft.raise('footable_filtered', { filter: event.filter, clear: false });
|
||||
}
|
||||
};
|
||||
|
||||
p.clearFilter = function () {
|
||||
var ft = p.footable,
|
||||
$table = $(ft.table);
|
||||
|
||||
$table.find('> tbody > tr:not(.footable-row-detail)').removeClass('footable-filtered').each(function () {
|
||||
p.showRow(this, ft);
|
||||
});
|
||||
$table.removeData('filter-string');
|
||||
ft.raise('footable_filtered', { clear: true });
|
||||
};
|
||||
|
||||
p.showRow = function (row, ft) {
|
||||
var $row = $(row), $next = $row.next(), $table = $(ft.table);
|
||||
if ($row.is(':visible')) return; //already visible - do nothing
|
||||
if ($table.hasClass('breakpoint') && $row.hasClass('footable-detail-show') && $next.hasClass('footable-row-detail')) {
|
||||
$row.add($next).show();
|
||||
ft.createOrUpdateDetailRow(row);
|
||||
}
|
||||
else $row.show();
|
||||
};
|
||||
}
|
||||
|
||||
w.footable.plugins.register(Filter, defaults);
|
||||
|
||||
})(jQuery, window);
|
925
media/footable/js/footable.filtering.js
Normal file
925
media/footable/js/footable.filtering.js
Normal file
@ -0,0 +1,925 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
(function(F){
|
||||
F.Filter = F.Class.extend(/** @lends FooTable.Filter */{
|
||||
/**
|
||||
* The filter object contains the query to filter by and the columns to apply it to.
|
||||
* @constructs
|
||||
* @extends FooTable.Class
|
||||
* @param {string} name - The name for the filter.
|
||||
* @param {string} query - The query for the filter.
|
||||
* @param {Array.<FooTable.Column>} columns - The columns to apply the query to.
|
||||
* @param {string} [space="AND"] - How the query treats space chars.
|
||||
* @param {boolean} [connectors=true] - Whether or not to replace phrase connectors (+.-_) with spaces.
|
||||
* @returns {FooTable.Filter}
|
||||
*/
|
||||
construct: function(name, query, columns, space, connectors){
|
||||
/**
|
||||
* The name of the filter.
|
||||
* @instance
|
||||
* @type {string}
|
||||
*/
|
||||
this.name = name;
|
||||
/**
|
||||
* A string specifying how the filter treats space characters. Can be either "OR" or "AND".
|
||||
* @instance
|
||||
* @type {string}
|
||||
*/
|
||||
this.space = F.is.string(space) && (space == 'OR' || space == 'AND') ? space : 'AND';
|
||||
/**
|
||||
* Whether or not to replace phrase connectors (+.-_) with spaces before executing the query.
|
||||
* @instance
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.connectors = F.is.boolean(connectors) ? connectors : true;
|
||||
/**
|
||||
* The query for the filter.
|
||||
* @instance
|
||||
* @type {(string|FooTable.Query)}
|
||||
*/
|
||||
this.query = new F.Query(query, this.space, this.connectors);
|
||||
/**
|
||||
* The columns to apply the query to.
|
||||
* @instance
|
||||
* @type {Array.<FooTable.Column>}
|
||||
*/
|
||||
this.columns = columns;
|
||||
},
|
||||
/**
|
||||
* Checks if the current filter matches the supplied string.
|
||||
* If the current query property is a string it will be auto converted to a {@link FooTable.Query} object to perform the match.
|
||||
* @instance
|
||||
* @param {string} str - The string to check.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
match: function(str){
|
||||
if (!F.is.string(str)) return false;
|
||||
if (F.is.string(this.query)){
|
||||
this.query = new F.Query(this.query, this.space, this.connectors);
|
||||
}
|
||||
return this.query instanceof F.Query ? this.query.match(str) : false;
|
||||
},
|
||||
/**
|
||||
* Checks if the current filter matches the supplied {@link FooTable.Row}.
|
||||
* @instance
|
||||
* @param {FooTable.Row} row - The row to check.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
matchRow: function(row){
|
||||
var self = this, text = F.arr.map(row.cells, function(cell){
|
||||
return F.arr.contains(self.columns, cell.column) ? cell.filterValue : null;
|
||||
}).join(' ');
|
||||
return self.match(text);
|
||||
}
|
||||
});
|
||||
|
||||
})(FooTable);
|
||||
(function ($, F) {
|
||||
F.Filtering = F.Component.extend(/** @lends FooTable.Filtering */{
|
||||
/**
|
||||
* The filtering component adds a search input and column selector dropdown to the table allowing users to filter the using space delimited queries.
|
||||
* @constructs
|
||||
* @extends FooTable.Component
|
||||
* @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
|
||||
* @returns {FooTable.Filtering}
|
||||
*/
|
||||
construct: function (table) {
|
||||
// call the constructor of the base class
|
||||
this._super(table, table.o.filtering.enabled);
|
||||
|
||||
/* PUBLIC */
|
||||
/**
|
||||
* The filters to apply to the current {@link FooTable.Rows#array}.
|
||||
* @instance
|
||||
* @type {Array.<FooTable.Filter>}
|
||||
*/
|
||||
this.filters = table.o.filtering.filters;
|
||||
/**
|
||||
* The delay in milliseconds before the query is auto applied after a change.
|
||||
* @instance
|
||||
* @type {number}
|
||||
*/
|
||||
this.delay = table.o.filtering.delay;
|
||||
/**
|
||||
* The minimum number of characters allowed in the search input before it is auto applied.
|
||||
* @instance
|
||||
* @type {number}
|
||||
*/
|
||||
this.min = table.o.filtering.min;
|
||||
/**
|
||||
* Specifies how whitespace in a filter query is handled.
|
||||
* @instance
|
||||
* @type {string}
|
||||
*/
|
||||
this.space = table.o.filtering.space;
|
||||
/**
|
||||
* Whether or not to replace phrase connectors (+.-_) with spaces before executing the query.
|
||||
* @instance
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.connectors = table.o.filtering.connectors;
|
||||
/**
|
||||
* The placeholder text to display within the search $input.
|
||||
* @instance
|
||||
* @type {string}
|
||||
*/
|
||||
this.placeholder = table.o.filtering.placeholder;
|
||||
/**
|
||||
* The position of the $search input within the filtering rows cell.
|
||||
* @type {string}
|
||||
*/
|
||||
this.position = table.o.filtering.position;
|
||||
/**
|
||||
* The jQuery row object that contains all the filtering specific elements.
|
||||
* @instance
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$row = null;
|
||||
/**
|
||||
* The jQuery cell object that contains the search input and column selector.
|
||||
* @instance
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$cell = null;
|
||||
/**
|
||||
* The jQuery object of the column selector dropdown.
|
||||
* @instance
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$dropdown = null;
|
||||
/**
|
||||
* The jQuery object of the search input.
|
||||
* @instance
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$input = null;
|
||||
/**
|
||||
* The jQuery object of the search button.
|
||||
* @instance
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$button = null;
|
||||
|
||||
/* PRIVATE */
|
||||
/**
|
||||
* The timeout ID for the filter changed event.
|
||||
* @instance
|
||||
* @private
|
||||
* @type {?number}
|
||||
*/
|
||||
this._filterTimeout = null;
|
||||
},
|
||||
|
||||
/* PROTECTED */
|
||||
/**
|
||||
* Checks the supplied data and options for the filtering component.
|
||||
* @instance
|
||||
* @protected
|
||||
* @param {object} data - The jQuery data object from the parent table.
|
||||
* @fires FooTable.Filtering#"preinit.ft.filtering"
|
||||
*/
|
||||
preinit: function(data){
|
||||
var self = this;
|
||||
/**
|
||||
* The preinit.ft.filtering event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
|
||||
* Calling preventDefault on this event will disable the component.
|
||||
* @event FooTable.Filtering#"preinit.ft.filtering"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {object} data - The jQuery data object of the table raising the event.
|
||||
*/
|
||||
this.ft.raise('preinit.ft.filtering').then(function(){
|
||||
// first check if filtering is enabled via the class being applied
|
||||
if (self.ft.$el.hasClass('footable-filtering'))
|
||||
self.enabled = true;
|
||||
// then check if the data-filtering-enabled attribute has been set
|
||||
self.enabled = F.is.boolean(data.filtering)
|
||||
? data.filtering
|
||||
: self.enabled;
|
||||
|
||||
// if filtering is not enabled exit early as we don't need to do anything else
|
||||
if (!self.enabled) return;
|
||||
|
||||
self.space = F.is.string(data.filterSpace)
|
||||
? data.filterSpace
|
||||
: self.space;
|
||||
|
||||
self.min = F.is.number(data.filterMin)
|
||||
? data.filterMin
|
||||
: self.min;
|
||||
|
||||
self.connectors = F.is.number(data.filterConnectors)
|
||||
? data.filterConnectors
|
||||
: self.connectors;
|
||||
|
||||
self.delay = F.is.number(data.filterDelay)
|
||||
? data.filterDelay
|
||||
: self.delay;
|
||||
|
||||
self.placeholder = F.is.number(data.filterPlaceholder)
|
||||
? data.filterPlaceholder
|
||||
: self.placeholder;
|
||||
|
||||
self.filters = F.is.array(data.filterFilters)
|
||||
? self.ensure(data.filterFilters)
|
||||
: self.ensure(self.filters);
|
||||
|
||||
if (self.ft.$el.hasClass('footable-filtering-left'))
|
||||
self.position = 'left';
|
||||
if (self.ft.$el.hasClass('footable-filtering-center'))
|
||||
self.position = 'center';
|
||||
if (self.ft.$el.hasClass('footable-filtering-right'))
|
||||
self.position = 'right';
|
||||
|
||||
self.position = F.is.string(data.filterPosition)
|
||||
? data.filterPosition
|
||||
: self.position;
|
||||
},function(){
|
||||
self.enabled = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Initializes the filtering component for the plugin.
|
||||
* @instance
|
||||
* @protected
|
||||
* @fires FooTable.Filtering#"init.ft.filtering"
|
||||
*/
|
||||
init: function () {
|
||||
var self = this;
|
||||
/**
|
||||
* The init.ft.filtering event is raised before its UI is generated.
|
||||
* Calling preventDefault on this event will disable the component.
|
||||
* @event FooTable.Filtering#"init.ft.filtering"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
*/
|
||||
this.ft.raise('init.ft.filtering').then(function(){
|
||||
self.$create();
|
||||
}, function(){
|
||||
self.enabled = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Destroys the filtering component removing any UI from the table.
|
||||
* @instance
|
||||
* @protected
|
||||
* @fires FooTable.Filtering#"destroy.ft.filtering"
|
||||
*/
|
||||
destroy: function () {
|
||||
/**
|
||||
* The destroy.ft.filtering event is raised before its UI is removed.
|
||||
* Calling preventDefault on this event will prevent the component from being destroyed.
|
||||
* @event FooTable.Filtering#"destroy.ft.filtering"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
*/
|
||||
var self = this;
|
||||
this.ft.raise('destroy.ft.filtering').then(function(){
|
||||
self.ft.$el.removeClass('footable-filtering')
|
||||
.find('thead > tr.footable-filtering').remove();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Creates the filtering UI from the current options setting the various jQuery properties of this component.
|
||||
* @instance
|
||||
* @protected
|
||||
* @this FooTable.Filtering
|
||||
*/
|
||||
$create: function () {
|
||||
var self = this;
|
||||
// generate the cell that actually contains all the UI.
|
||||
var $form_grp = $('<div/>', {'class': 'form-group'})
|
||||
.append($('<label/>', {'class': 'sr-only', text: 'Search'})),
|
||||
$input_grp = $('<div/>', {'class': 'input-group'}).appendTo($form_grp),
|
||||
$input_grp_btn = $('<div/>', {'class': 'input-group-btn'}),
|
||||
$dropdown_toggle = $('<button/>', {type: 'button', 'class': 'btn btn-default dropdown-toggle'})
|
||||
.on('click', { self: self }, self._onDropdownToggleClicked)
|
||||
.append($('<span/>', {'class': 'caret'})),
|
||||
position;
|
||||
|
||||
switch (self.position){
|
||||
case 'left': position = 'footable-filtering-left'; break;
|
||||
case 'center': position = 'footable-filtering-center'; break;
|
||||
default: position = 'footable-filtering-right'; break;
|
||||
}
|
||||
self.ft.$el.addClass('footable-filtering').addClass(position);
|
||||
|
||||
// add it to a row and then populate it with the search input and column selector dropdown.
|
||||
self.$row = $('<tr/>', {'class': 'footable-filtering'}).prependTo(self.ft.$el.children('thead'));
|
||||
self.$cell = $('<th/>').attr('colspan', self.ft.columns.visibleColspan).appendTo(self.$row);
|
||||
self.$form = $('<form/>', {'class': 'form-inline'}).append($form_grp).appendTo(self.$cell);
|
||||
|
||||
self.$input = $('<input/>', {type: 'text', 'class': 'form-control', placeholder: self.placeholder});
|
||||
|
||||
self.$button = $('<button/>', {type: 'button', 'class': 'btn btn-primary'})
|
||||
.on('click', { self: self }, self._onSearchButtonClicked)
|
||||
.append($('<span/>', {'class': 'fooicon fooicon-search'}));
|
||||
|
||||
self.$dropdown = $('<ul/>', {'class': 'dropdown-menu dropdown-menu-right'}).append(
|
||||
F.arr.map(self.ft.columns.array, function (col) {
|
||||
return col.filterable && col.visible ? $('<li/>').append(
|
||||
$('<a/>', {'class': 'checkbox'}).append(
|
||||
$('<label/>', {text: col.title}).prepend(
|
||||
$('<input/>', {type: 'checkbox', checked: true}).data('__FooTableColumn__', col)
|
||||
)
|
||||
)
|
||||
) : null;
|
||||
})
|
||||
);
|
||||
|
||||
if (self.delay > 0){
|
||||
self.$input.on('keypress keyup', { self: self }, self._onSearchInputChanged);
|
||||
self.$dropdown.on('click', 'input[type="checkbox"]', {self: self}, self._onSearchColumnClicked);
|
||||
}
|
||||
|
||||
$input_grp_btn.append(self.$button, $dropdown_toggle, self.$dropdown);
|
||||
$input_grp.append(self.$input, $input_grp_btn);
|
||||
},
|
||||
/**
|
||||
* Performs the filtering of rows before they are appended to the page.
|
||||
* @instance
|
||||
* @protected
|
||||
*/
|
||||
predraw: function(){
|
||||
if (F.is.emptyArray(this.filters))
|
||||
return;
|
||||
|
||||
var self = this;
|
||||
self.ft.rows.array = $.grep(self.ft.rows.array, function(r){
|
||||
return r.filtered(self.filters);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* As the rows are drawn by the {@link FooTable.Rows#draw} method this simply updates the colspan for the UI.
|
||||
* @instance
|
||||
* @protected
|
||||
*/
|
||||
draw: function(){
|
||||
this.$cell.attr('colspan', this.ft.columns.visibleColspan);
|
||||
},
|
||||
|
||||
/* PUBLIC */
|
||||
/**
|
||||
* Adds or updates the filter using the supplied name, query and columns.
|
||||
* @param {string} name - The name for the filter.
|
||||
* @param {(string|FooTable.Query)} query - The query for the filter.
|
||||
* @param {(Array.<number>|Array.<string>|Array.<FooTable.Column>)} columns - The columns to apply the filter to.
|
||||
*/
|
||||
addFilter: function(name, query, columns){
|
||||
var f = F.arr.first(this.filters, function(f){ return f.name == name; });
|
||||
if (f instanceof F.Filter){
|
||||
f.name = name;
|
||||
f.query = query;
|
||||
f.columns = columns;
|
||||
} else {
|
||||
this.filters.push({name: name, query: query, columns: columns});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Removes the filter using the supplied name if it exists.
|
||||
* @param {string} name - The name of the filter to remove.
|
||||
*/
|
||||
removeFilter: function(name){
|
||||
F.arr.remove(this.filters, function(f){ return f.name == name; });
|
||||
},
|
||||
/**
|
||||
* Creates a new search filter from the supplied parameters and applies it to the rows. If no parameters are supplied the current search input value
|
||||
* and selected columns are used to create or update the search filter. If there is no search input value then the search filter is removed.
|
||||
* @instance
|
||||
* @param {string} [query] - The query to filter the rows by.
|
||||
* @param {(Array.<string>|Array.<number>|Array.<FooTable.Column>)} [columns] - The columns to apply the filter to in each row.
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Filtering#"before.ft.filtering"
|
||||
* @fires FooTable.Filtering#"after.ft.filtering"
|
||||
*/
|
||||
filter: function(query, columns){
|
||||
if (F.is.undef(query)){
|
||||
query = $.trim(this.$input.val() || '');
|
||||
} else {
|
||||
this.$input.val(query);
|
||||
}
|
||||
if (!F.is.emptyString(query)) {
|
||||
this.addFilter('search', query, columns);
|
||||
} else {
|
||||
this.removeFilter('search');
|
||||
}
|
||||
this.$button.children('.fooicon').removeClass('fooicon-search').addClass('fooicon-remove');
|
||||
return this._filter();
|
||||
},
|
||||
/**
|
||||
* Removes the current search filter.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Filtering#"before.ft.filtering"
|
||||
* @fires FooTable.Filtering#"after.ft.filtering"
|
||||
*/
|
||||
clear: function(){
|
||||
this.$button.children('.fooicon').removeClass('fooicon-remove').addClass('fooicon-search');
|
||||
this.$input.val(null);
|
||||
this.removeFilter('search');
|
||||
return this._filter();
|
||||
},
|
||||
/**
|
||||
* Gets an array of {@link FooTable.Column} to apply the search filter to. This also doubles as the default columns for filters which do not specify any columns.
|
||||
* @instance
|
||||
* @returns {Array.<FooTable.Column>}
|
||||
*/
|
||||
columns: function(){
|
||||
if (F.is.jq(this.$dropdown)){
|
||||
// if we have a dropdown containing the column names get the selected columns from there
|
||||
return this.$dropdown.find('input:checked').map(function(){
|
||||
return $(this).data('__FooTableColumn__');
|
||||
}).get();
|
||||
} else {
|
||||
// otherwise find all columns that are set to be filterable.
|
||||
return this.ft.columns.get(function(c){ return c.filterable; });
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Takes an array of plain objects containing the filter values or actual {@link FooTable.Filter} objects and ensures that an array of only {@link FooTable.Filter} is returned.
|
||||
* If supplied a plain object that object must contain a name, query and columns properties which are used to create a new {@link FooTable.Filter}.
|
||||
* @instance
|
||||
* @param {({name: string, query: (string|FooTable.Query), columns: (Array.<string>|Array.<number>|Array.<FooTable.Column>)}|Array.<FooTable.Filter>)} filters - The array of filters to check.
|
||||
* @returns {Array.<FooTable.Filter>}
|
||||
*/
|
||||
ensure: function(filters){
|
||||
var self = this, parsed = [], filterable = self.columns();
|
||||
if (!F.is.emptyArray(filters)){
|
||||
F.arr.each(filters, function(f){
|
||||
if (F.is.object(f) && (!F.is.emptyString(f.query) || f.query instanceof F.Query)) {
|
||||
f.name = F.is.emptyString(f.name) ? 'anon' : f.name;
|
||||
f.columns = F.is.emptyArray(f.columns) ? filterable : self.ft.columns.ensure(f.columns);
|
||||
parsed.push(f instanceof F.Filter ? f : new F.Filter(f.name, f.query, f.columns, self.space, self.connectors));
|
||||
}
|
||||
});
|
||||
}
|
||||
return parsed;
|
||||
},
|
||||
|
||||
/* PRIVATE */
|
||||
/**
|
||||
* Performs the required steps to handle filtering including the raising of the {@link FooTable.Filtering#"before.ft.filtering"} and {@link FooTable.Filtering#"after.ft.filtering"} events.
|
||||
* @instance
|
||||
* @private
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Filtering#"before.ft.filtering"
|
||||
* @fires FooTable.Filtering#"after.ft.filtering"
|
||||
*/
|
||||
_filter: function(){
|
||||
var self = this;
|
||||
self.filters = self.ensure(self.filters);
|
||||
/**
|
||||
* The before.ft.filtering event is raised before a filter is applied and allows listeners to modify the filter or cancel it completely by calling preventDefault on the jQuery.Event object.
|
||||
* @event FooTable.Filtering#"before.ft.filtering"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {Array.<FooTable.Filter>} filters - The filters that are about to be applied.
|
||||
*/
|
||||
return self.ft.raise('before.ft.filtering', [self.filters]).then(function(){
|
||||
self.filters = self.ensure(self.filters);
|
||||
return self.ft.draw().then(function(){
|
||||
/**
|
||||
* The after.ft.filtering event is raised after a filter has been applied.
|
||||
* @event FooTable.Filtering#"after.ft.filtering"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {FooTable.Filter} filter - The filters that were applied.
|
||||
*/
|
||||
self.ft.raise('after.ft.filtering', [self.filters]);
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Handles the change event for the {@link FooTable.Filtering#$input}.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {jQuery.Event} e - The event object for the event.
|
||||
*/
|
||||
_onSearchInputChanged: function (e) {
|
||||
var self = e.data.self;
|
||||
var alpha = e.type == 'keypress' && !F.is.emptyString(String.fromCharCode(e.charCode)),
|
||||
ctrl = e.type == 'keyup' && (e.which == 8 || e.which == 46); // backspace & delete
|
||||
|
||||
// if alphanumeric characters or specific control characters
|
||||
if(alpha || ctrl) {
|
||||
if (e.which == 13) e.preventDefault();
|
||||
if (self._filterTimeout != null) clearTimeout(self._filterTimeout);
|
||||
self._filterTimeout = setTimeout(function(){
|
||||
self._filterTimeout = null;
|
||||
self.filter();
|
||||
}, self.delay);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Handles the click event for the {@link FooTable.Filtering#$button}.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {jQuery.Event} e - The event object for the event.
|
||||
*/
|
||||
_onSearchButtonClicked: function (e) {
|
||||
e.preventDefault();
|
||||
var self = e.data.self;
|
||||
if (self._filterTimeout != null) clearTimeout(self._filterTimeout);
|
||||
var $icon = self.$button.children('.fooicon');
|
||||
if ($icon.hasClass('fooicon-remove')) self.clear();
|
||||
else self.filter();
|
||||
},
|
||||
/**
|
||||
* Handles the click event for the column checkboxes in the {@link FooTable.Filtering#$dropdown}.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {jQuery.Event} e - The event object for the event.
|
||||
*/
|
||||
_onSearchColumnClicked: function (e) {
|
||||
var self = e.data.self;
|
||||
if (self._filterTimeout != null) clearTimeout(self._filterTimeout);
|
||||
self._filterTimeout = setTimeout(function(){
|
||||
self._filterTimeout = null;
|
||||
var $icon = self.$button.children('.fooicon');
|
||||
if ($icon.hasClass('fooicon-remove')){
|
||||
$icon.removeClass('fooicon-remove').addClass('fooicon-search');
|
||||
self.filter();
|
||||
}
|
||||
}, self.delay);
|
||||
},
|
||||
/**
|
||||
* Handles the click event for the {@link FooTable.Filtering#$dropdown} toggle.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {jQuery.Event} e - The event object for the event.
|
||||
*/
|
||||
_onDropdownToggleClicked: function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var self = e.data.self;
|
||||
self.$dropdown.parent().toggleClass('open');
|
||||
if (self.$dropdown.parent().hasClass('open')) $(document).on('click.footable', { self: self }, self._onDocumentClicked);
|
||||
else $(document).off('click.footable', self._onDocumentClicked);
|
||||
},
|
||||
/**
|
||||
* Checks all click events when the dropdown is visible and closes the menu if the target is not the dropdown.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {jQuery.Event} e - The event object for the event.
|
||||
*/
|
||||
_onDocumentClicked: function(e){
|
||||
if ($(e.target).closest('.dropdown-menu').length == 0){
|
||||
e.preventDefault();
|
||||
var self = e.data.self;
|
||||
self.$dropdown.parent().removeClass('open');
|
||||
$(document).off('click.footable', self._onDocumentClicked);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
F.components.core.register('filtering', F.Filtering, 10);
|
||||
|
||||
})(jQuery, FooTable);
|
||||
(function(F){
|
||||
F.Query = F.Class.extend(/** @lends FooTable.Query */{
|
||||
/**
|
||||
* The query object is used to parse and test the filtering component's queries
|
||||
* @constructs
|
||||
* @extends FooTable.Class
|
||||
* @param {string} query - The string value of the query.
|
||||
* @param {string} [space="AND"] - How the query treats whitespace.
|
||||
* @param {boolean} [connectors=true] - Whether or not to replace phrase connectors (+.-_) with spaces.
|
||||
* @returns {FooTable.Query}
|
||||
*/
|
||||
construct: function(query, space, connectors){
|
||||
/* PRIVATE */
|
||||
/**
|
||||
* Holds the previous value of the query and is used internally in the {@link FooTable.Query#val} method.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this._original = null;
|
||||
/**
|
||||
* Holds the value for the query. Access to this variable is provided through the {@link FooTable.Query#val} method.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this._value = null;
|
||||
/* PUBLIC */
|
||||
/**
|
||||
* A string specifying how the query treats whitespace. Can be either "OR" or "AND".
|
||||
* @type {string}
|
||||
*/
|
||||
this.space = F.is.string(space) && (space == 'OR' || space == 'AND') ? space : 'AND';
|
||||
/**
|
||||
* Whether or not to replace phrase connectors (+.-_) with spaces before executing the query.
|
||||
* @instance
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.connectors = F.is.boolean(connectors) ? connectors : true;
|
||||
/**
|
||||
* The left side of the query if one exists. OR takes precedence over AND.
|
||||
* @type {FooTable.Query}
|
||||
* @example <caption>The below shows what is meant by the "left" side of a query</caption>
|
||||
* query = "Dave AND Mary" - "Dave" is the left side of the query.
|
||||
* query = "Dave AND Mary OR John" - "Dave and Mary" is the left side of the query.
|
||||
*/
|
||||
this.left = null;
|
||||
/**
|
||||
* The right side of the query if one exists. OR takes precedence over AND.
|
||||
* @type {FooTable.Query}
|
||||
* @example <caption>The below shows what is meant by the "right" side of a query</caption>
|
||||
* query = "Dave AND Mary" - "Mary" is the right side of the query.
|
||||
* query = "Dave AND Mary OR John" - "John" is the right side of the query.
|
||||
*/
|
||||
this.right = null;
|
||||
/**
|
||||
* The parsed parts of the query. This contains the information used to actually perform a match against a string.
|
||||
* @type {Array}
|
||||
*/
|
||||
this.parts = [];
|
||||
/**
|
||||
* The type of operand to apply to the results of the individual parts of the query.
|
||||
* @type {string}
|
||||
*/
|
||||
this.operator = null;
|
||||
this.val(query);
|
||||
},
|
||||
/**
|
||||
* Gets or sets the value for the query. During set the value is parsed setting all properties as required.
|
||||
* @param {string} [value] - If supplied the value to set for this query.
|
||||
* @returns {(string|undefined)}
|
||||
*/
|
||||
val: function(value){
|
||||
// get
|
||||
if (F.is.emptyString(value)) return this._value;
|
||||
|
||||
// set
|
||||
if (F.is.emptyString(this._original)) this._original = value;
|
||||
else if (this._original == value) return;
|
||||
|
||||
this._value = value;
|
||||
this._parse();
|
||||
},
|
||||
/**
|
||||
* Tests the supplied string against the query.
|
||||
* @param {string} str - The string to test.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
match: function(str){
|
||||
if (F.is.emptyString(this.operator) || this.operator === 'OR')
|
||||
return this._left(str, false) || this._match(str, false) || this._right(str, false);
|
||||
if (this.operator === 'AND')
|
||||
return this._left(str, true) && this._match(str, true) && this._right(str, true);
|
||||
},
|
||||
/**
|
||||
* Matches this queries parts array against the supplied string.
|
||||
* @param {string} str - The string to test.
|
||||
* @param {boolean} def - The default value to return based on the operand.
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
_match: function(str, def){
|
||||
var self = this, result = false;
|
||||
if (F.is.emptyArray(self.parts) && self.left instanceof F.Query) return def;
|
||||
if (F.is.emptyArray(self.parts)) return result;
|
||||
if (self.space === 'OR'){
|
||||
// with OR we give the str every part to test and if any match it is a success, we do exit early if a negated match occurs
|
||||
F.arr.each(self.parts, function(p){
|
||||
var match = F.str.contains(str, p.query, true);
|
||||
if (match && !p.negate) result = true;
|
||||
if (match && p.negate) {
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// otherwise with AND we check until the first failure and then exit
|
||||
result = true;
|
||||
F.arr.each(self.parts, function(p){
|
||||
var match = F.str.contains(str, p.query, true);
|
||||
if ((!match && !p.negate) || (match && p.negate)) result = false;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* Matches the left side of the query if one exists with the supplied string.
|
||||
* @param {string} str - The string to test.
|
||||
* @param {boolean} def - The default value to return based on the operand.
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
_left: function(str, def){
|
||||
return (this.left instanceof F.Query) ? this.left.match(str) : def;
|
||||
},
|
||||
/**
|
||||
* Matches the right side of the query if one exists with the supplied string.
|
||||
* @param {string} str - The string to test.
|
||||
* @param {boolean} def - The default value to return based on the operand.
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
_right: function(str, def){
|
||||
return (this.right instanceof F.Query) ? this.right.match(str) : def;
|
||||
},
|
||||
/**
|
||||
* Parses the private {@link FooTable.Query#_value} property and populates the object.
|
||||
* @private
|
||||
*/
|
||||
_parse: function(){
|
||||
if (F.is.emptyString(this._value)) return;
|
||||
// OR takes precedence so test for it first
|
||||
if (/\sOR\s/.test(this._value)){
|
||||
// we have an OR so split the value on the first occurrence of OR to get the left and right sides of the statement
|
||||
this.operator = 'OR';
|
||||
var or = this._value.split(/(?:\sOR\s)(.*)?/);
|
||||
this.left = new F.Query(or[0], this.space, this.connectors);
|
||||
this.right = new F.Query(or[1], this.space, this.connectors);
|
||||
} else if (/\sAND\s/.test(this._value)) {
|
||||
// there are no more OR's so start with AND
|
||||
this.operator = 'AND';
|
||||
var and = this._value.split(/(?:\sAND\s)(.*)?/);
|
||||
this.left = new F.Query(and[0], this.space, this.connectors);
|
||||
this.right = new F.Query(and[1], this.space, this.connectors);
|
||||
} else {
|
||||
// we have no more statements to parse so set the parts array by parsing each part of the remaining query
|
||||
var self = this;
|
||||
this.parts = F.arr.map(this._value.match(/(?:[^\s"]+|"[^"]*")+/g), function(str){
|
||||
return self._part(str);
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Parses a single part of a query into an object to use during matching.
|
||||
* @param {string} str - The string representation of the part.
|
||||
* @returns {{query: string, negate: boolean, phrase: boolean, exact: boolean}}
|
||||
* @private
|
||||
*/
|
||||
_part: function(str){
|
||||
var p = {
|
||||
query: str,
|
||||
negate: false,
|
||||
phrase: false,
|
||||
exact: false
|
||||
};
|
||||
// support for NEGATE operand - (minus sign). Remove this first so we can get onto phrase checking
|
||||
if (F.str.startsWith(p.query, '-')){
|
||||
p.query = F.str.from(p.query, '-');
|
||||
p.negate = true;
|
||||
}
|
||||
// support for PHRASES (exact matches)
|
||||
if (/^"(.*?)"$/.test(p.query)){ // if surrounded in quotes strip them and nothing else
|
||||
p.query = p.query.replace(/^"(.*?)"$/, '$1');
|
||||
p.phrase = true;
|
||||
p.exact = true;
|
||||
} else if (this.connectors && /(?:\w)+?([-_\+\.])(?:\w)+?/.test(p.query)) { // otherwise replace supported phrase connectors (-_+.) with spaces
|
||||
p.query = p.query.replace(/(?:\w)+?([-_\+\.])(?:\w)+?/g, function(match, p1){
|
||||
return match.replace(p1, ' ');
|
||||
});
|
||||
p.phrase = true;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
});
|
||||
|
||||
})(FooTable);
|
||||
(function(F){
|
||||
|
||||
/**
|
||||
* The value used by the filtering component during filter operations. Must be a string and can be set using the data-filter-value attribute on the cell itself.
|
||||
* If this is not supplied it is set to the result of the toString method called on the value for the cell. Added by the {@link FooTable.Filtering} component.
|
||||
* @type {string}
|
||||
* @default null
|
||||
*/
|
||||
F.Cell.prototype.filterValue = null;
|
||||
|
||||
// this is used to define the filtering specific properties on cell creation
|
||||
F.Cell.prototype.__filtering_define__ = function(valueOrElement){
|
||||
this.filterValue = this.column.filterValue.call(this.column, valueOrElement);
|
||||
};
|
||||
|
||||
// this is used to update the filterValue property whenever the cell value is changed
|
||||
F.Cell.prototype.__filtering_val__ = function(value){
|
||||
if (F.is.defined(value)){
|
||||
// set only
|
||||
this.filterValue = this.column.filterValue.call(this.column, value);
|
||||
}
|
||||
};
|
||||
|
||||
// overrides the public define method and replaces it with our own
|
||||
F.Cell.extend('define', function(valueOrElement){
|
||||
this._super(valueOrElement);
|
||||
this.__filtering_define__(valueOrElement);
|
||||
});
|
||||
// overrides the public val method and replaces it with our own
|
||||
F.Cell.extend('val', function(value){
|
||||
var val = this._super(value);
|
||||
this.__filtering_val__(value);
|
||||
return val;
|
||||
});
|
||||
})(FooTable);
|
||||
(function($, F){
|
||||
/**
|
||||
* Whether or not the column can be used during filtering. Added by the {@link FooTable.Filtering} component.
|
||||
* @type {boolean}
|
||||
* @default true
|
||||
*/
|
||||
F.Column.prototype.filterable = true;
|
||||
|
||||
/**
|
||||
* This is supplied either the cell value or jQuery object to parse. A string value must be returned from this method and will be used during filtering operations.
|
||||
* @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
|
||||
* @returns {string}
|
||||
* @this FooTable.Column
|
||||
*/
|
||||
F.Column.prototype.filterValue = function(valueOrElement){
|
||||
// if we have an element or a jQuery object use jQuery to get the value
|
||||
if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)) return $(valueOrElement).data('filterValue') || $(valueOrElement).text();
|
||||
// if options are supplied with the value
|
||||
if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
|
||||
if (F.is.string(valueOrElement.options.filterValue)) return valueOrElement.options.filterValue;
|
||||
if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
|
||||
}
|
||||
if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement+''; // use the native toString of the value
|
||||
return ''; // otherwise we have no value so return an empty string
|
||||
};
|
||||
|
||||
// this is used to define the filtering specific properties on column creation
|
||||
F.Column.prototype.__filtering_define__ = function(definition){
|
||||
this.filterable = F.is.boolean(definition.filterable) ? definition.filterable : this.filterable;
|
||||
};
|
||||
|
||||
// overrides the public define method and replaces it with our own
|
||||
F.Column.extend('define', function(definition){
|
||||
this._super(definition); // call the base so we don't have to redefine any previously set properties
|
||||
this.__filtering_define__(definition); // then call our own
|
||||
});
|
||||
})(jQuery, FooTable);
|
||||
(function(F){
|
||||
/**
|
||||
* An object containing the filtering options for the plugin. Added by the {@link FooTable.Filtering} component.
|
||||
* @type {object}
|
||||
* @prop {boolean} enabled=false - Whether or not to allow filtering on the table.
|
||||
* @prop {({name: string, query: (string|FooTable.Query), columns: (Array.<string>|Array.<number>|Array.<FooTable.Column>)}|Array.<FooTable.Filter>)} filters - The filters to apply to the current {@link FooTable.Rows#array}.
|
||||
* @prop {number} delay=1200 - The delay in milliseconds before the query is auto applied after a change (any value equal to or less than zero will disable this).
|
||||
* @prop {number} min=3 - The minimum number of characters allowed in the search input before it is auto applied.
|
||||
* @prop {string} space="AND" - Specifies how whitespace in a filter query is handled.
|
||||
* @prop {string} placeholder="Search" - The string used as the placeholder for the search input.
|
||||
* @prop {string} position="right" - The string used to specify the alignment of the search input.
|
||||
* @prop {string} connectors=true - Whether or not to replace phrase connectors (+.-_) with space before executing the query.
|
||||
*/
|
||||
F.Defaults.prototype.filtering = {
|
||||
enabled: false,
|
||||
filters: [],
|
||||
delay: 1200,
|
||||
min: 3,
|
||||
space: 'AND',
|
||||
placeholder: 'Search',
|
||||
position: 'right',
|
||||
connectors: true
|
||||
};
|
||||
})(FooTable);
|
||||
(function(F){
|
||||
/**
|
||||
* Checks if the row is filtered using the supplied filters.
|
||||
* @this FooTable.Row
|
||||
* @param {Array.<FooTable.Filter>} filters - The filters to apply.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
F.Row.prototype.filtered = function(filters){
|
||||
var result = true, self = this;
|
||||
F.arr.each(filters, function(f){
|
||||
if ((result = f.matchRow(self)) == false) return false;
|
||||
});
|
||||
return result;
|
||||
};
|
||||
})(FooTable);
|
||||
(function(F){
|
||||
/**
|
||||
* Filter the table using the supplied query and columns. Added by the {@link FooTable.Filtering} component.
|
||||
* @instance
|
||||
* @param {string} query - The query to filter the rows by.
|
||||
* @param {(Array.<string>|Array.<number>|Array.<FooTable.Column>)} [columns] - The columns to apply the filter to in each row.
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Filtering#before.ft.filtering
|
||||
* @fires FooTable.Filtering#after.ft.filtering
|
||||
* @see FooTable.Filtering#filter
|
||||
*/
|
||||
F.Table.prototype.applyFilter = function(query, columns){
|
||||
return this.use(F.Filtering).filter(query, columns);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the current filter from the table. Added by the {@link FooTable.Filtering} component.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Filtering#before.ft.filtering
|
||||
* @fires FooTable.Filtering#after.ft.filtering
|
||||
* @see FooTable.Filtering#clear
|
||||
*/
|
||||
F.Table.prototype.clearFilter = function(){
|
||||
return this.use(F.Filtering).clear();
|
||||
};
|
||||
})(FooTable);
|
8
media/footable/js/footable.filtering.min.js
vendored
Normal file
8
media/footable/js/footable.filtering.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,373 +0,0 @@
|
||||
(function($, w, undefined) {
|
||||
if (w.footable === undefined || w.foobox === null) throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
||||
var defaults = {
|
||||
grid: {
|
||||
enabled: true,
|
||||
data: null,
|
||||
template: null, //row html template, use for make a row.
|
||||
cols: null, //column define
|
||||
items: null, //data items
|
||||
url: null, //get data from url
|
||||
ajax: null, //paramater for $.ajax
|
||||
activeClass: 'active', //add to row selected
|
||||
multiSelect: false, //allow select multiple row
|
||||
showIndex: false, //show row index
|
||||
showCheckbox: false, //show checkbox for select
|
||||
showEmptyInfo: false, //when that is not data in table, show a info to notify user
|
||||
emptyInfo: '<p class="text-center text-warning">No Data</p>',
|
||||
pagination: {
|
||||
"page-size": 20,
|
||||
"pagination-class": "pagination pagination-centered"
|
||||
},
|
||||
indexFormatter: function(val, $td, index) {
|
||||
return index + 1;
|
||||
},
|
||||
checkboxFormatter: function(isTop) {
|
||||
return '<input type="checkbox" class="' + (isTop ? 'checkAll' : 'check') + '">';
|
||||
},
|
||||
events: {
|
||||
loaded: 'footable_grid_loaded',
|
||||
created: 'footable_grid_created',
|
||||
removed: 'footable_grid_removed',
|
||||
updated: 'footable_grid_updated'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function makeTh(col) {
|
||||
var $th = $('<th>' + col.title + '</th>');
|
||||
if ($.isPlainObject(col.data)) {
|
||||
$th.data(col.data);
|
||||
}
|
||||
if ($.isPlainObject(col.style)) {
|
||||
$th.css(col.style);
|
||||
}
|
||||
if (col.className) {
|
||||
$th.addClass(col.className);
|
||||
}
|
||||
return $th;
|
||||
}
|
||||
|
||||
function initThead($table, options) {
|
||||
var $thead = $table.find('thead');
|
||||
if ($thead.size() === 0) {
|
||||
$thead = $('<thead>').appendTo($table);
|
||||
}
|
||||
var $row = $('<tr>').appendTo($thead);
|
||||
for (var i = 0, len = options.cols.length; i < len; i++) {
|
||||
$row.append(makeTh(options.cols[i]));
|
||||
}
|
||||
}
|
||||
|
||||
function initTBody($table) {
|
||||
var $tbody = $table.find('tbody');
|
||||
if ($tbody.size() === 0) {
|
||||
$tbody = $('<tbody>').appendTo($table);
|
||||
}
|
||||
}
|
||||
|
||||
function initPagination($table, cols, options) {
|
||||
if (options) {
|
||||
$table.attr("data-page-size", options['page-size']);
|
||||
var $tfoot = $table.find('tfoot');
|
||||
if ($tfoot.size() === 0) {
|
||||
$tfoot = $('<tfoot class="hide-if-no-paging"></tfoot>').appendTo($table);
|
||||
}
|
||||
$tfoot.append('<tr><td colspan=' + cols.length + '></td></tr>');
|
||||
var $pagination = $("<div>").appendTo($tfoot.find("tr:last-child td"));
|
||||
$pagination.addClass(options['pagination-class']);
|
||||
}
|
||||
}
|
||||
|
||||
function setToggleColumn(cols) {
|
||||
var toggleColumn = cols[0];
|
||||
for (var i = 0, len = cols.length; i < len; i++) {
|
||||
var col = cols[i];
|
||||
if (col.data && (col.data.toggle === true || col.data.toggle === "true")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
toggleColumn.data = $.extend(toggleColumn.data, {
|
||||
toggle: true
|
||||
});
|
||||
}
|
||||
|
||||
function makeEmptyInfo($table, cols, emptyInfo) {
|
||||
if ($table.find("tr.emptyInfo").size() === 0) {
|
||||
$table.find('tbody').append('<tr class="emptyInfo"><td colspan="' + cols.length + '">' + emptyInfo + '</td></tr>');
|
||||
}
|
||||
}
|
||||
|
||||
function updateRowIndex($tbody, $newRow, detailClass, offset) {
|
||||
//update rows index
|
||||
$tbody.find('tr:not(.' + detailClass + ')').each(function() {
|
||||
var $row = $(this),
|
||||
index = $newRow.data('index'),
|
||||
oldIndex = parseInt($row.data('index'), 0),
|
||||
newIndex = oldIndex + offset;
|
||||
if (oldIndex >= index && this !== $newRow.get(0)) {
|
||||
$row.attr('data-index', newIndex).data('index', newIndex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function Grid() {
|
||||
var grid = this;
|
||||
grid.name = 'Footable Grid';
|
||||
grid.init = function(ft) {
|
||||
var toggleClass = ft.options.classes.toggle;
|
||||
var detailClass = ft.options.classes.detail;
|
||||
var options = ft.options.grid;
|
||||
if (!options.cols) return;
|
||||
grid.footable = ft;
|
||||
var $table = $(ft.table);
|
||||
$table.data('grid', grid);
|
||||
if ($.isPlainObject(options.data)) {
|
||||
$table.data(options.data);
|
||||
}
|
||||
grid._items = [];
|
||||
setToggleColumn(options.cols);
|
||||
if (options.showCheckbox) {
|
||||
options.multiSelect = true;
|
||||
options.cols.unshift({
|
||||
title: options.checkboxFormatter(true),
|
||||
name: '',
|
||||
data: {
|
||||
"sort-ignore": true
|
||||
},
|
||||
formatter: options.checkboxFormatter
|
||||
});
|
||||
}
|
||||
if (options.showIndex) {
|
||||
options.cols.unshift({
|
||||
title: '#',
|
||||
name: 'index',
|
||||
data: {
|
||||
"sort-ignore": true
|
||||
},
|
||||
formatter: options.indexFormatter
|
||||
});
|
||||
}
|
||||
initThead($table, options);
|
||||
initTBody($table);
|
||||
initPagination($table, options.cols, options.pagination);
|
||||
$table.off('.grid').on({
|
||||
'footable_initialized.grid': function(e) {
|
||||
if (options.url || options.ajax) {
|
||||
$.ajax(options.ajax || {
|
||||
url: options.url
|
||||
}).then(function(resp) {
|
||||
grid.newItem(resp);
|
||||
ft.raise(options.events.loaded);
|
||||
}, function(jqXHR) {
|
||||
throw 'load data from ' + (options.url || options.ajax.url) + ' fail';
|
||||
});
|
||||
} else {
|
||||
grid.newItem(options.items || []);
|
||||
ft.raise(options.events.loaded);
|
||||
}
|
||||
},
|
||||
'footable_sorted.grid footable_grid_created.grid footable_grid_removed.grid': function(event) {
|
||||
if (options.showIndex && grid.getItem().length > 0) {
|
||||
$table.find('tbody tr:not(.' + detailClass + ')').each(function(index) {
|
||||
var $td = $(this).find('td:first');
|
||||
$td.html(options.indexFormatter(null, $td, index));
|
||||
});
|
||||
}
|
||||
},
|
||||
'footable_redrawn.grid footable_row_removed.grid': function(event) {
|
||||
if (grid.getItem().length === 0 && options.showEmptyInfo) {
|
||||
makeEmptyInfo($table, options.cols, options.emptyInfo);
|
||||
}
|
||||
}
|
||||
}).on({
|
||||
'click.grid': function(event) {
|
||||
if ($(event.target).closest('td').find('>.' + toggleClass).size() > 0) {
|
||||
return true;
|
||||
}
|
||||
var $tr = $(event.currentTarget);
|
||||
if ($tr.hasClass(detailClass)) {
|
||||
return true;
|
||||
}
|
||||
if (!options.multiSelect && !$tr.hasClass(options.activeClass)) {
|
||||
$table.find('tbody tr.' + options.activeClass).removeClass(options.activeClass);
|
||||
}
|
||||
$tr.toggleClass(options.activeClass);
|
||||
if (options.showCheckbox) {
|
||||
$tr.find('input:checkbox.check').prop('checked', function(index, val) {
|
||||
if (event.target === this) {
|
||||
return val;
|
||||
}
|
||||
return !val;
|
||||
});
|
||||
}
|
||||
ft.toggleDetail($tr);
|
||||
}
|
||||
}, 'tbody tr').on('click.grid', 'thead input:checkbox.checkAll', function(event) {
|
||||
var checked = !! event.currentTarget.checked;
|
||||
if (checked) {
|
||||
$table.find('tbody tr').addClass(options.activeClass);
|
||||
} else {
|
||||
$table.find('tbody tr').removeClass(options.activeClass);
|
||||
}
|
||||
$table.find('tbody input:checkbox.check').prop('checked', checked);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* get selected rows index;
|
||||
*/
|
||||
grid.getSelected = function() {
|
||||
var options = grid.footable.options.grid,
|
||||
$selected = $(grid.footable.table).find('tbody>tr.' + options.activeClass);
|
||||
return $selected.map(function() {
|
||||
return $(this).data('index');
|
||||
});
|
||||
};
|
||||
/**
|
||||
* get row's data by index
|
||||
*/
|
||||
grid.getItem = function(index) {
|
||||
if (index !== undefined) {
|
||||
if ($.isArray(index)) {
|
||||
return $.map(index, function(item) {
|
||||
return grid._items[item];
|
||||
});
|
||||
}
|
||||
return grid._items[index];
|
||||
}
|
||||
return grid._items;
|
||||
};
|
||||
|
||||
function makeCell(col, value, index) {
|
||||
var $td = $('<td>');
|
||||
if (col.formatter) {
|
||||
$td.html(col.formatter(value, $td, index));
|
||||
} else {
|
||||
$td.html(value || '');
|
||||
}
|
||||
return $td;
|
||||
}
|
||||
grid._makeRow = function(item, index) {
|
||||
var options = grid.footable.options.grid;
|
||||
var $row;
|
||||
if ($.isFunction(options.template)) {
|
||||
$row = $(options.template($.extend({}, {
|
||||
__index: index
|
||||
}, item)));
|
||||
} else {
|
||||
$row = $('<tr>');
|
||||
for (var i = 0, len = options.cols.length; i < len; i++) {
|
||||
var col = options.cols[i];
|
||||
$row.append(makeCell(col, item[col.name] || '', index));
|
||||
}
|
||||
}
|
||||
$row.attr('data-index', index);
|
||||
return $row;
|
||||
};
|
||||
/**
|
||||
* create rows by js object
|
||||
*/
|
||||
grid.newItem = function(item, index, wait) {
|
||||
var $tbody = $(grid.footable.table).find('tbody');
|
||||
var detailClass = grid.footable.options.classes.detail;
|
||||
$tbody.find('tr.emptyInfo').remove();
|
||||
if ($.isArray(item)) {
|
||||
for (var atom;
|
||||
(atom = item.pop());) {
|
||||
grid.newItem(atom, index, true);
|
||||
}
|
||||
grid.footable.redraw();
|
||||
grid.footable.raise(grid.footable.options.grid.events.created, {
|
||||
item: item,
|
||||
index: index
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!$.isPlainObject(item)) {
|
||||
return;
|
||||
}
|
||||
var $tr, len = grid._items.length;
|
||||
if (index === undefined || index < 0 || index > len) {
|
||||
$tr = grid._makeRow(item, len++);
|
||||
grid._items.push(item);
|
||||
$tbody.append($tr);
|
||||
} else {
|
||||
$tr = grid._makeRow(item, index);
|
||||
if (index === 0) {
|
||||
grid._items.unshift(item);
|
||||
$tbody.prepend($tr);
|
||||
} else {
|
||||
var $before = $tbody.find('tr[data-index=' + (index - 1) + ']');
|
||||
grid._items.splice(index, 0, item);
|
||||
if ($before.data('detail_created') === true) {
|
||||
$before = $before.next();
|
||||
}
|
||||
$before.after($tr);
|
||||
}
|
||||
updateRowIndex($tbody, $tr, detailClass, 1);
|
||||
}
|
||||
if (!wait) {
|
||||
grid.footable.redraw();
|
||||
grid.footable.raise(grid.footable.options.grid.events.created, {
|
||||
item: item,
|
||||
index: index
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* update row by js object
|
||||
*/
|
||||
grid.setItem = function(item, index) {
|
||||
if (!$.isPlainObject(item)) {
|
||||
return;
|
||||
}
|
||||
var $tbody = $(grid.footable.table).find('tbody'),
|
||||
$newTr = grid._makeRow(item, index);
|
||||
$.extend(grid._items[index], item);
|
||||
var $tr = $tbody.find('tr').eq(index);
|
||||
$tr.html($newTr.html());
|
||||
grid.footable.redraw();
|
||||
grid.footable.raise(grid.footable.options.grid.events.updated, {
|
||||
item: item,
|
||||
index: index
|
||||
});
|
||||
};
|
||||
/**
|
||||
* remove rows by index
|
||||
*/
|
||||
grid.removeItem = function(index) {
|
||||
var $tbody = $(grid.footable.table).find('tbody');
|
||||
var detailClass = grid.footable.options.classes.detail;
|
||||
var result = [];
|
||||
if ($.isArray(index)) {
|
||||
for (var i;
|
||||
(i = index.pop());) {
|
||||
result.push(grid.removeItem(i));
|
||||
}
|
||||
grid.footable.raise(grid.footable.options.grid.events.removed, {
|
||||
item: result,
|
||||
index: index
|
||||
});
|
||||
return result;
|
||||
}
|
||||
if (index === undefined) {
|
||||
$tbody.find('tr').each(function() {
|
||||
result.push(grid._items.shift());
|
||||
grid.footable.removeRow(this);
|
||||
});
|
||||
} else {
|
||||
var $tr = $tbody.find('tr[data-index=' + index + ']');
|
||||
result = grid._items.splice(index, 1)[0];
|
||||
grid.footable.removeRow($tr);
|
||||
//update rows index
|
||||
updateRowIndex($tbody, $tr, detailClass, -1);
|
||||
}
|
||||
grid.footable.raise(grid.footable.options.grid.events.removed, {
|
||||
item: result,
|
||||
index: index
|
||||
});
|
||||
return result;
|
||||
};
|
||||
}
|
||||
w.footable.plugins.register(Grid, defaults);
|
||||
})(jQuery, window);
|
@ -1,824 +0,0 @@
|
||||
/*!
|
||||
* FooTable - Awesome Responsive Tables
|
||||
* Version : 2.0.3
|
||||
* http://fooplugins.com/plugins/footable-jquery/
|
||||
*
|
||||
* Requires jQuery - http://jquery.com/
|
||||
*
|
||||
* Copyright 2014 Steven Usher & Brad Vincent
|
||||
* Released under the MIT license
|
||||
* You are free to use FooTable in commercial projects as long as this copyright header is left intact.
|
||||
*
|
||||
* Date: 11 Nov 2014
|
||||
*/
|
||||
(function ($, w, undefined) {
|
||||
w.footable = {
|
||||
options: {
|
||||
delay: 100, // The number of millseconds to wait before triggering the react event
|
||||
breakpoints: { // The different screen resolution breakpoints
|
||||
phone: 480,
|
||||
tablet: 1024
|
||||
},
|
||||
parsers: { // The default parser to parse the value out of a cell (values are used in building up row detail)
|
||||
alpha: function (cell) {
|
||||
return $(cell).data('value') || $.trim($(cell).text());
|
||||
},
|
||||
numeric: function (cell) {
|
||||
var val = $(cell).data('value') || $(cell).text().replace(/[^0-9.\-]/g, '');
|
||||
val = parseFloat(val);
|
||||
if (isNaN(val)) val = 0;
|
||||
return val;
|
||||
}
|
||||
},
|
||||
addRowToggle: true,
|
||||
calculateWidthOverride: null,
|
||||
toggleSelector: ' > tbody > tr:not(.footable-row-detail)', //the selector to show/hide the detail row
|
||||
columnDataSelector: '> thead > tr:last-child > th, > thead > tr:last-child > td', //the selector used to find the column data in the thead
|
||||
detailSeparator: ':', //the separator character used when building up the detail row
|
||||
toggleHTMLElement: '<span />', // override this if you want to insert a click target rather than use a background image.
|
||||
createGroupedDetail: function (data) {
|
||||
var groups = { '_none': { 'name': null, 'data': [] } };
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var groupid = data[i].group;
|
||||
if (groupid !== null) {
|
||||
if (!(groupid in groups))
|
||||
groups[groupid] = { 'name': data[i].groupName || data[i].group, 'data': [] };
|
||||
|
||||
groups[groupid].data.push(data[i]);
|
||||
} else {
|
||||
groups._none.data.push(data[i]);
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
},
|
||||
createDetail: function (element, data, createGroupedDetail, separatorChar, classes) {
|
||||
/// <summary>This function is used by FooTable to generate the detail view seen when expanding a collapsed row.</summary>
|
||||
/// <param name="element">This is the div that contains all the detail row information, anything could be added to it.</param>
|
||||
/// <param name="data">
|
||||
/// This is an array of objects containing the cell information for the current row.
|
||||
/// These objects look like the below:
|
||||
/// obj = {
|
||||
/// 'name': String, // The name of the column
|
||||
/// 'value': Object, // The value parsed from the cell using the parsers. This could be a string, a number or whatever the parser outputs.
|
||||
/// 'display': String, // This is the actual HTML from the cell, so if you have images etc you want moved this is the one to use and is the default value used.
|
||||
/// 'group': String, // This is the identifier used in the data-group attribute of the column.
|
||||
/// 'groupName': String // This is the actual name of the group the column belongs to.
|
||||
/// }
|
||||
/// </param>
|
||||
/// <param name="createGroupedDetail">The grouping function to group the data</param>
|
||||
/// <param name="separatorChar">The separator charactor used</param>
|
||||
/// <param name="classes">The array of class names used to build up the detail row</param>
|
||||
|
||||
var groups = createGroupedDetail(data);
|
||||
for (var group in groups) {
|
||||
if (groups[group].data.length === 0) continue;
|
||||
if (group !== '_none') element.append('<div class="' + classes.detailInnerGroup + '">' + groups[group].name + '</div>');
|
||||
|
||||
for (var j = 0; j < groups[group].data.length; j++) {
|
||||
var separator = (groups[group].data[j].name) ? separatorChar : '';
|
||||
element.append($('<div></div>').addClass(classes.detailInnerRow).append($('<div></div>').addClass(classes.detailInnerName)
|
||||
.append(groups[group].data[j].name + separator)).append($('<div></div>').addClass(classes.detailInnerValue)
|
||||
.attr('data-bind-value', groups[group].data[j].bindName).append(groups[group].data[j].display)));
|
||||
}
|
||||
}
|
||||
},
|
||||
classes: {
|
||||
main: 'footable',
|
||||
loading: 'footable-loading',
|
||||
loaded: 'footable-loaded',
|
||||
toggle: 'footable-toggle',
|
||||
disabled: 'footable-disabled',
|
||||
detail: 'footable-row-detail',
|
||||
detailCell: 'footable-row-detail-cell',
|
||||
detailInner: 'footable-row-detail-inner',
|
||||
detailInnerRow: 'footable-row-detail-row',
|
||||
detailInnerGroup: 'footable-row-detail-group',
|
||||
detailInnerName: 'footable-row-detail-name',
|
||||
detailInnerValue: 'footable-row-detail-value',
|
||||
detailShow: 'footable-detail-show'
|
||||
},
|
||||
triggers: {
|
||||
initialize: 'footable_initialize', //trigger this event to force FooTable to reinitialize
|
||||
resize: 'footable_resize', //trigger this event to force FooTable to resize
|
||||
redraw: 'footable_redraw', //trigger this event to force FooTable to redraw
|
||||
toggleRow: 'footable_toggle_row', //trigger this event to force FooTable to toggle a row
|
||||
expandFirstRow: 'footable_expand_first_row', //trigger this event to force FooTable to expand the first row
|
||||
expandAll: 'footable_expand_all', //trigger this event to force FooTable to expand all rows
|
||||
collapseAll: 'footable_collapse_all' //trigger this event to force FooTable to collapse all rows
|
||||
},
|
||||
events: {
|
||||
alreadyInitialized: 'footable_already_initialized', //fires when the FooTable has already been initialized
|
||||
initializing: 'footable_initializing', //fires before FooTable starts initializing
|
||||
initialized: 'footable_initialized', //fires after FooTable has finished initializing
|
||||
resizing: 'footable_resizing', //fires before FooTable resizes
|
||||
resized: 'footable_resized', //fires after FooTable has resized
|
||||
redrawn: 'footable_redrawn', //fires after FooTable has redrawn
|
||||
breakpoint: 'footable_breakpoint', //fires inside the resize function, when a breakpoint is hit
|
||||
columnData: 'footable_column_data', //fires when setting up column data. Plugins should use this event to capture their own info about a column
|
||||
rowDetailUpdating: 'footable_row_detail_updating', //fires before a detail row is updated
|
||||
rowDetailUpdated: 'footable_row_detail_updated', //fires when a detail row is being updated
|
||||
rowCollapsed: 'footable_row_collapsed', //fires when a row is collapsed
|
||||
rowExpanded: 'footable_row_expanded', //fires when a row is expanded
|
||||
rowRemoved: 'footable_row_removed', //fires when a row is removed
|
||||
reset: 'footable_reset' //fires when FooTable is reset
|
||||
},
|
||||
debug: false, // Whether or not to log information to the console.
|
||||
log: null
|
||||
},
|
||||
|
||||
version: {
|
||||
major: 0, minor: 5,
|
||||
toString: function () {
|
||||
return w.footable.version.major + '.' + w.footable.version.minor;
|
||||
},
|
||||
parse: function (str) {
|
||||
var version = /(\d+)\.?(\d+)?\.?(\d+)?/.exec(str);
|
||||
return {
|
||||
major: parseInt(version[1], 10) || 0,
|
||||
minor: parseInt(version[2], 10) || 0,
|
||||
patch: parseInt(version[3], 10) || 0
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
plugins: {
|
||||
_validate: function (plugin) {
|
||||
///<summary>Simple validation of the <paramref name="plugin"/> to make sure any members called by FooTable actually exist.</summary>
|
||||
///<param name="plugin">The object defining the plugin, this should implement a string property called "name" and a function called "init".</param>
|
||||
|
||||
if (!$.isFunction(plugin)) {
|
||||
if (w.footable.options.debug === true) console.error('Validation failed, expected type "function", received type "{0}".', typeof plugin);
|
||||
return false;
|
||||
}
|
||||
var p = new plugin();
|
||||
if (typeof p['name'] !== 'string') {
|
||||
if (w.footable.options.debug === true) console.error('Validation failed, plugin does not implement a string property called "name".', p);
|
||||
return false;
|
||||
}
|
||||
if (!$.isFunction(p['init'])) {
|
||||
if (w.footable.options.debug === true) console.error('Validation failed, plugin "' + p['name'] + '" does not implement a function called "init".', p);
|
||||
return false;
|
||||
}
|
||||
if (w.footable.options.debug === true) console.log('Validation succeeded for plugin "' + p['name'] + '".', p);
|
||||
return true;
|
||||
},
|
||||
registered: [], // An array containing all registered plugins.
|
||||
register: function (plugin, options) {
|
||||
///<summary>Registers a <paramref name="plugin"/> and its default <paramref name="options"/> with FooTable.</summary>
|
||||
///<param name="plugin">The plugin that should implement a string property called "name" and a function called "init".</param>
|
||||
///<param name="options">The default options to merge with the FooTable's base options.</param>
|
||||
|
||||
if (w.footable.plugins._validate(plugin)) {
|
||||
w.footable.plugins.registered.push(plugin);
|
||||
if (typeof options === 'object') $.extend(true, w.footable.options, options);
|
||||
}
|
||||
},
|
||||
load: function(instance){
|
||||
var loaded = [], registered, i;
|
||||
for(i = 0; i < w.footable.plugins.registered.length; i++){
|
||||
try {
|
||||
registered = w.footable.plugins.registered[i];
|
||||
loaded.push(new registered(instance));
|
||||
} catch (err) {
|
||||
if (w.footable.options.debug === true) console.error(err);
|
||||
}
|
||||
}
|
||||
return loaded;
|
||||
},
|
||||
init: function (instance) {
|
||||
///<summary>Loops through all registered plugins and calls the "init" method supplying the current <paramref name="instance"/> of the FooTable as the first parameter.</summary>
|
||||
///<param name="instance">The current instance of the FooTable that the plugin is being initialized for.</param>
|
||||
|
||||
for (var i = 0; i < instance.plugins.length; i++) {
|
||||
try {
|
||||
instance.plugins[i]['init'](instance);
|
||||
} catch (err) {
|
||||
if (w.footable.options.debug === true) console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var instanceCount = 0;
|
||||
|
||||
$.fn.footable = function (options) {
|
||||
///<summary>The main constructor call to initialize the plugin using the supplied <paramref name="options"/>.</summary>
|
||||
///<param name="options">
|
||||
///<para>A JSON object containing user defined options for the plugin to use. Any options not supplied will have a default value assigned.</para>
|
||||
///<para>Check the documentation or the default options object above for more information on available options.</para>
|
||||
///</param>
|
||||
|
||||
options = options || {};
|
||||
var o = $.extend(true, {}, w.footable.options, options); //merge user and default options
|
||||
return this.each(function () {
|
||||
instanceCount++;
|
||||
var footable = new Footable(this, o, instanceCount);
|
||||
$(this).data('footable', footable);
|
||||
});
|
||||
};
|
||||
|
||||
//helper for using timeouts
|
||||
function Timer() {
|
||||
///<summary>Simple timer object created around a timeout.</summary>
|
||||
var t = this;
|
||||
t.id = null;
|
||||
t.busy = false;
|
||||
t.start = function (code, milliseconds) {
|
||||
///<summary>Starts the timer and waits the specified amount of <paramref name="milliseconds"/> before executing the supplied <paramref name="code"/>.</summary>
|
||||
///<param name="code">The code to execute once the timer runs out.</param>
|
||||
///<param name="milliseconds">The time in milliseconds to wait before executing the supplied <paramref name="code"/>.</param>
|
||||
|
||||
if (t.busy) {
|
||||
return;
|
||||
}
|
||||
t.stop();
|
||||
t.id = setTimeout(function () {
|
||||
code();
|
||||
t.id = null;
|
||||
t.busy = false;
|
||||
}, milliseconds);
|
||||
t.busy = true;
|
||||
};
|
||||
t.stop = function () {
|
||||
///<summary>Stops the timer if its runnning and resets it back to its starting state.</summary>
|
||||
|
||||
if (t.id !== null) {
|
||||
clearTimeout(t.id);
|
||||
t.id = null;
|
||||
t.busy = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function Footable(t, o, id) {
|
||||
///<summary>Inits a new instance of the plugin.</summary>
|
||||
///<param name="t">The main table element to apply this plugin to.</param>
|
||||
///<param name="o">The options supplied to the plugin. Check the defaults object to see all available options.</param>
|
||||
///<param name="id">The id to assign to this instance of the plugin.</param>
|
||||
|
||||
var ft = this;
|
||||
ft.id = id;
|
||||
ft.table = t;
|
||||
ft.options = o;
|
||||
ft.breakpoints = [];
|
||||
ft.breakpointNames = '';
|
||||
ft.columns = {};
|
||||
ft.plugins = w.footable.plugins.load(ft);
|
||||
|
||||
var opt = ft.options,
|
||||
cls = opt.classes,
|
||||
evt = opt.events,
|
||||
trg = opt.triggers,
|
||||
indexOffset = 0;
|
||||
|
||||
// This object simply houses all the timers used in the FooTable.
|
||||
ft.timers = {
|
||||
resize: new Timer(),
|
||||
register: function (name) {
|
||||
ft.timers[name] = new Timer();
|
||||
return ft.timers[name];
|
||||
}
|
||||
};
|
||||
|
||||
ft.init = function () {
|
||||
var $window = $(w), $table = $(ft.table);
|
||||
|
||||
w.footable.plugins.init(ft);
|
||||
|
||||
if ($table.hasClass(cls.loaded)) {
|
||||
//already loaded FooTable for the table, so don't init again
|
||||
ft.raise(evt.alreadyInitialized);
|
||||
return;
|
||||
}
|
||||
|
||||
//raise the initializing event
|
||||
ft.raise(evt.initializing);
|
||||
|
||||
$table.addClass(cls.loading);
|
||||
|
||||
// Get the column data once for the life time of the plugin
|
||||
$table.find(opt.columnDataSelector).each(function () {
|
||||
var data = ft.getColumnData(this);
|
||||
ft.columns[data.index] = data;
|
||||
});
|
||||
|
||||
// Create a nice friendly array to work with out of the breakpoints object.
|
||||
for (var name in opt.breakpoints) {
|
||||
ft.breakpoints.push({ 'name': name, 'width': opt.breakpoints[name] });
|
||||
ft.breakpointNames += (name + ' ');
|
||||
}
|
||||
|
||||
// Sort the breakpoints so the smallest is checked first
|
||||
ft.breakpoints.sort(function (a, b) {
|
||||
return a['width'] - b['width'];
|
||||
});
|
||||
|
||||
$table
|
||||
.unbind(trg.initialize)
|
||||
//bind to FooTable initialize trigger
|
||||
.bind(trg.initialize, function () {
|
||||
//remove previous "state" (to "force" a resize)
|
||||
$table.removeData('footable_info');
|
||||
$table.data('breakpoint', '');
|
||||
|
||||
//trigger the FooTable resize
|
||||
$table.trigger(trg.resize);
|
||||
|
||||
//remove the loading class
|
||||
$table.removeClass(cls.loading);
|
||||
|
||||
//add the FooTable and loaded class
|
||||
$table.addClass(cls.loaded).addClass(cls.main);
|
||||
|
||||
//raise the initialized event
|
||||
ft.raise(evt.initialized);
|
||||
})
|
||||
.unbind(trg.redraw)
|
||||
//bind to FooTable redraw trigger
|
||||
.bind(trg.redraw, function () {
|
||||
ft.redraw();
|
||||
})
|
||||
.unbind(trg.resize)
|
||||
//bind to FooTable resize trigger
|
||||
.bind(trg.resize, function () {
|
||||
ft.resize();
|
||||
})
|
||||
.unbind(trg.expandFirstRow)
|
||||
//bind to FooTable expandFirstRow trigger
|
||||
.bind(trg.expandFirstRow, function () {
|
||||
$table.find(opt.toggleSelector).first().not('.' + cls.detailShow).trigger(trg.toggleRow);
|
||||
})
|
||||
.unbind(trg.expandAll)
|
||||
//bind to FooTable expandFirstRow trigger
|
||||
.bind(trg.expandAll, function () {
|
||||
$table.find(opt.toggleSelector).not('.' + cls.detailShow).trigger(trg.toggleRow);
|
||||
})
|
||||
.unbind(trg.collapseAll)
|
||||
//bind to FooTable expandFirstRow trigger
|
||||
.bind(trg.collapseAll, function () {
|
||||
$table.find('.' + cls.detailShow).trigger(trg.toggleRow);
|
||||
});
|
||||
|
||||
//trigger a FooTable initialize
|
||||
$table.trigger(trg.initialize);
|
||||
|
||||
//bind to window resize
|
||||
$window
|
||||
.bind('resize.footable', function () {
|
||||
ft.timers.resize.stop();
|
||||
ft.timers.resize.start(function () {
|
||||
ft.raise(trg.resize);
|
||||
}, opt.delay);
|
||||
});
|
||||
};
|
||||
|
||||
ft.addRowToggle = function () {
|
||||
if (!opt.addRowToggle) return;
|
||||
|
||||
var $table = $(ft.table),
|
||||
hasToggleColumn = false;
|
||||
|
||||
//first remove all toggle spans
|
||||
$table.find('span.' + cls.toggle).remove();
|
||||
|
||||
for (var c in ft.columns) {
|
||||
var col = ft.columns[c];
|
||||
if (col.toggle) {
|
||||
hasToggleColumn = true;
|
||||
var selector = '> tbody > tr:not(.' + cls.detail + ',.' + cls.disabled + ') > td:nth-child(' + (parseInt(col.index, 10) + 1) + '),' +
|
||||
'> tbody > tr:not(.' + cls.detail + ',.' + cls.disabled + ') > th:nth-child(' + (parseInt(col.index, 10) + 1) + ')';
|
||||
$table.find(selector).not('.' + cls.detailCell).prepend($(opt.toggleHTMLElement).addClass(cls.toggle));
|
||||
return;
|
||||
}
|
||||
}
|
||||
//check if we have an toggle column. If not then add it to the first column just to be safe
|
||||
if (!hasToggleColumn) {
|
||||
$table
|
||||
.find('> tbody > tr:not(.' + cls.detail + ',.' + cls.disabled + ') > td:first-child')
|
||||
.add('> tbody > tr:not(.' + cls.detail + ',.' + cls.disabled + ') > th:first-child')
|
||||
.not('.' + cls.detailCell)
|
||||
.prepend($(opt.toggleHTMLElement).addClass(cls.toggle));
|
||||
}
|
||||
};
|
||||
|
||||
ft.setColumnClasses = function () {
|
||||
var $table = $(ft.table);
|
||||
for (var c in ft.columns) {
|
||||
var col = ft.columns[c];
|
||||
if (col.className !== null) {
|
||||
var selector = '', first = true;
|
||||
$.each(col.matches, function (m, match) { //support for colspans
|
||||
if (!first) selector += ', ';
|
||||
selector += '> tbody > tr:not(.' + cls.detail + ') > td:nth-child(' + (parseInt(match, 10) + 1) + ')';
|
||||
first = false;
|
||||
});
|
||||
//add the className to the cells specified by data-class="blah"
|
||||
$table.find(selector).not('.' + cls.detailCell).addClass(col.className);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//moved this out into it's own function so that it can be called from other add-ons
|
||||
ft.bindToggleSelectors = function () {
|
||||
var $table = $(ft.table);
|
||||
|
||||
if (!ft.hasAnyBreakpointColumn()) return;
|
||||
|
||||
$table.find(opt.toggleSelector).unbind(trg.toggleRow).bind(trg.toggleRow, function (e) {
|
||||
var $row = $(this).is('tr') ? $(this) : $(this).parents('tr:first');
|
||||
ft.toggleDetail($row);
|
||||
});
|
||||
|
||||
$table.find(opt.toggleSelector).unbind('click.footable').bind('click.footable', function (e) {
|
||||
if ($table.is('.breakpoint') && $(e.target).is('td,th,.'+ cls.toggle)) {
|
||||
$(this).trigger(trg.toggleRow);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ft.parse = function (cell, column) {
|
||||
var parser = opt.parsers[column.type] || opt.parsers.alpha;
|
||||
return parser(cell);
|
||||
};
|
||||
|
||||
ft.getColumnData = function (th) {
|
||||
var $th = $(th), hide = $th.data('hide'), index = $th.index();
|
||||
hide = hide || '';
|
||||
hide = jQuery.map(hide.split(','), function (a) {
|
||||
return jQuery.trim(a);
|
||||
});
|
||||
var data = {
|
||||
'index': index,
|
||||
'hide': { },
|
||||
'type': $th.data('type') || 'alpha',
|
||||
'name': $th.data('name') || $.trim($th.text()),
|
||||
'ignore': $th.data('ignore') || false,
|
||||
'toggle': $th.data('toggle') || false,
|
||||
'className': $th.data('class') || null,
|
||||
'matches': [],
|
||||
'names': { },
|
||||
'group': $th.data('group') || null,
|
||||
'groupName': null,
|
||||
'isEditable': $th.data('editable')
|
||||
};
|
||||
|
||||
if (data.group !== null) {
|
||||
var $group = $(ft.table).find('> thead > tr.footable-group-row > th[data-group="' + data.group + '"], > thead > tr.footable-group-row > td[data-group="' + data.group + '"]').first();
|
||||
data.groupName = ft.parse($group, { 'type': 'alpha' });
|
||||
}
|
||||
|
||||
var pcolspan = parseInt($th.prev().attr('colspan') || 0, 10);
|
||||
indexOffset += pcolspan > 1 ? pcolspan - 1 : 0;
|
||||
var colspan = parseInt($th.attr('colspan') || 0, 10), curindex = data.index + indexOffset;
|
||||
if (colspan > 1) {
|
||||
var names = $th.data('names');
|
||||
names = names || '';
|
||||
names = names.split(',');
|
||||
for (var i = 0; i < colspan; i++) {
|
||||
data.matches.push(i + curindex);
|
||||
if (i < names.length) data.names[i + curindex] = names[i];
|
||||
}
|
||||
} else {
|
||||
data.matches.push(curindex);
|
||||
}
|
||||
|
||||
data.hide['default'] = ($th.data('hide') === "all") || ($.inArray('default', hide) >= 0);
|
||||
|
||||
var hasBreakpoint = false;
|
||||
for (var name in opt.breakpoints) {
|
||||
data.hide[name] = ($th.data('hide') === "all") || ($.inArray(name, hide) >= 0);
|
||||
hasBreakpoint = hasBreakpoint || data.hide[name];
|
||||
}
|
||||
data.hasBreakpoint = hasBreakpoint;
|
||||
var e = ft.raise(evt.columnData, { 'column': { 'data': data, 'th': th } });
|
||||
return e.column.data;
|
||||
};
|
||||
|
||||
ft.getViewportWidth = function () {
|
||||
return window.innerWidth || (document.body ? document.body.offsetWidth : 0);
|
||||
};
|
||||
|
||||
ft.calculateWidth = function ($table, info) {
|
||||
if (jQuery.isFunction(opt.calculateWidthOverride)) {
|
||||
return opt.calculateWidthOverride($table, info);
|
||||
}
|
||||
if (info.viewportWidth < info.width) info.width = info.viewportWidth;
|
||||
if (info.parentWidth < info.width) info.width = info.parentWidth;
|
||||
return info;
|
||||
};
|
||||
|
||||
ft.hasBreakpointColumn = function (breakpoint) {
|
||||
for (var c in ft.columns) {
|
||||
if (ft.columns[c].hide[breakpoint]) {
|
||||
if (ft.columns[c].ignore) {
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
ft.hasAnyBreakpointColumn = function () {
|
||||
for (var c in ft.columns) {
|
||||
if (ft.columns[c].hasBreakpoint) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
ft.resize = function () {
|
||||
var $table = $(ft.table);
|
||||
|
||||
if (!$table.is(':visible')) {
|
||||
return;
|
||||
} //we only care about FooTables that are visible
|
||||
|
||||
if (!ft.hasAnyBreakpointColumn()) {
|
||||
$table.trigger(trg.redraw);
|
||||
return;
|
||||
} //we only care about FooTables that have breakpoints
|
||||
|
||||
var info = {
|
||||
'width': $table.width(), //the table width
|
||||
'viewportWidth': ft.getViewportWidth(), //the width of the viewport
|
||||
'parentWidth': $table.parent().width() //the width of the parent
|
||||
};
|
||||
|
||||
info = ft.calculateWidth($table, info);
|
||||
|
||||
var pinfo = $table.data('footable_info');
|
||||
$table.data('footable_info', info);
|
||||
ft.raise(evt.resizing, { 'old': pinfo, 'info': info });
|
||||
|
||||
// This (if) statement is here purely to make sure events aren't raised twice as mobile safari seems to do
|
||||
if (!pinfo || (pinfo && pinfo.width && pinfo.width !== info.width)) {
|
||||
|
||||
var current = null, breakpoint;
|
||||
for (var i = 0; i < ft.breakpoints.length; i++) {
|
||||
breakpoint = ft.breakpoints[i];
|
||||
if (breakpoint && breakpoint.width && info.width <= breakpoint.width) {
|
||||
current = breakpoint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var breakpointName = (current === null ? 'default' : current['name']),
|
||||
hasBreakpointFired = ft.hasBreakpointColumn(breakpointName),
|
||||
previousBreakpoint = $table.data('breakpoint');
|
||||
|
||||
$table
|
||||
.data('breakpoint', breakpointName)
|
||||
.removeClass('default breakpoint').removeClass(ft.breakpointNames)
|
||||
.addClass(breakpointName + (hasBreakpointFired ? ' breakpoint' : ''));
|
||||
|
||||
//only do something if the breakpoint has changed
|
||||
if (breakpointName !== previousBreakpoint) {
|
||||
//trigger a redraw
|
||||
$table.trigger(trg.redraw);
|
||||
//raise a breakpoint event
|
||||
ft.raise(evt.breakpoint, { 'breakpoint': breakpointName, 'info': info });
|
||||
}
|
||||
}
|
||||
|
||||
ft.raise(evt.resized, { 'old': pinfo, 'info': info });
|
||||
};
|
||||
|
||||
ft.redraw = function () {
|
||||
//add the toggler to each row
|
||||
ft.addRowToggle();
|
||||
|
||||
//bind the toggle selector click events
|
||||
ft.bindToggleSelectors();
|
||||
|
||||
//set any cell classes defined for the columns
|
||||
ft.setColumnClasses();
|
||||
|
||||
var $table = $(ft.table),
|
||||
breakpointName = $table.data('breakpoint'),
|
||||
hasBreakpointFired = ft.hasBreakpointColumn(breakpointName);
|
||||
|
||||
$table
|
||||
.find('> tbody > tr:not(.' + cls.detail + ')').data('detail_created', false).end()
|
||||
.find('> thead > tr:last-child > th')
|
||||
.each(function () {
|
||||
var data = ft.columns[$(this).index()], selector = '', first = true;
|
||||
$.each(data.matches, function (m, match) {
|
||||
if (!first) {
|
||||
selector += ', ';
|
||||
}
|
||||
var count = match + 1;
|
||||
selector += '> tbody > tr:not(.' + cls.detail + ') > td:nth-child(' + count + ')';
|
||||
selector += ', > tfoot > tr:not(.' + cls.detail + ') > td:nth-child(' + count + ')';
|
||||
selector += ', > colgroup > col:nth-child(' + count + ')';
|
||||
first = false;
|
||||
});
|
||||
|
||||
selector += ', > thead > tr[data-group-row="true"] > th[data-group="' + data.group + '"]';
|
||||
var $column = $table.find(selector).add(this);
|
||||
if (breakpointName !== '') {
|
||||
if (data.hide[breakpointName] === false) $column.addClass('footable-visible').show();
|
||||
else $column.removeClass('footable-visible').hide();
|
||||
}
|
||||
|
||||
if ($table.find('> thead > tr.footable-group-row').length === 1) {
|
||||
var $groupcols = $table.find('> thead > tr:last-child > th[data-group="' + data.group + '"]:visible, > thead > tr:last-child > th[data-group="' + data.group + '"]:visible'),
|
||||
$group = $table.find('> thead > tr.footable-group-row > th[data-group="' + data.group + '"], > thead > tr.footable-group-row > td[data-group="' + data.group + '"]'),
|
||||
groupspan = 0;
|
||||
|
||||
$.each($groupcols, function () {
|
||||
groupspan += parseInt($(this).attr('colspan') || 1, 10);
|
||||
});
|
||||
|
||||
if (groupspan > 0) $group.attr('colspan', groupspan).show();
|
||||
else $group.hide();
|
||||
}
|
||||
})
|
||||
.end()
|
||||
.find('> tbody > tr.' + cls.detailShow).each(function () {
|
||||
ft.createOrUpdateDetailRow(this);
|
||||
});
|
||||
|
||||
$table.find("[data-bind-name]").each(function () {
|
||||
ft.toggleInput(this);
|
||||
});
|
||||
|
||||
$table.find('> tbody > tr.' + cls.detailShow + ':visible').each(function () {
|
||||
var $next = $(this).next();
|
||||
if ($next.hasClass(cls.detail)) {
|
||||
if (!hasBreakpointFired) $next.hide();
|
||||
else $next.show();
|
||||
}
|
||||
});
|
||||
|
||||
// adding .footable-first-column and .footable-last-column to the first and last th and td of each row in order to allow
|
||||
// for styling if the first or last column is hidden (which won't work using :first-child or :last-child)
|
||||
$table.find('> thead > tr > th.footable-last-column, > tbody > tr > td.footable-last-column').removeClass('footable-last-column');
|
||||
$table.find('> thead > tr > th.footable-first-column, > tbody > tr > td.footable-first-column').removeClass('footable-first-column');
|
||||
$table.find('> thead > tr, > tbody > tr')
|
||||
.find('> th.footable-visible:last, > td.footable-visible:last')
|
||||
.addClass('footable-last-column')
|
||||
.end()
|
||||
.find('> th.footable-visible:first, > td.footable-visible:first')
|
||||
.addClass('footable-first-column');
|
||||
|
||||
ft.raise(evt.redrawn);
|
||||
};
|
||||
|
||||
ft.toggleDetail = function (row) {
|
||||
var $row = (row.jquery) ? row : $(row),
|
||||
$next = $row.next();
|
||||
|
||||
//check if the row is already expanded
|
||||
if ($row.hasClass(cls.detailShow)) {
|
||||
$row.removeClass(cls.detailShow);
|
||||
|
||||
//only hide the next row if it's a detail row
|
||||
if ($next.hasClass(cls.detail)) $next.hide();
|
||||
|
||||
ft.raise(evt.rowCollapsed, { 'row': $row[0] });
|
||||
|
||||
} else {
|
||||
ft.createOrUpdateDetailRow($row[0]);
|
||||
$row.addClass(cls.detailShow)
|
||||
.next().show();
|
||||
|
||||
ft.raise(evt.rowExpanded, { 'row': $row[0] });
|
||||
}
|
||||
};
|
||||
|
||||
ft.removeRow = function (row) {
|
||||
var $row = (row.jquery) ? row : $(row);
|
||||
if ($row.hasClass(cls.detail)) {
|
||||
$row = $row.prev();
|
||||
}
|
||||
var $next = $row.next();
|
||||
if ($row.data('detail_created') === true) {
|
||||
//remove the detail row
|
||||
$next.remove();
|
||||
}
|
||||
$row.remove();
|
||||
|
||||
//raise event
|
||||
ft.raise(evt.rowRemoved);
|
||||
};
|
||||
|
||||
ft.appendRow = function (row) {
|
||||
var $row = (row.jquery) ? row : $(row);
|
||||
$(ft.table).find('tbody').append($row);
|
||||
|
||||
//redraw the table
|
||||
ft.redraw();
|
||||
};
|
||||
|
||||
ft.getColumnFromTdIndex = function (index) {
|
||||
/// <summary>Returns the correct column data for the supplied index taking into account colspans.</summary>
|
||||
/// <param name="index">The index to retrieve the column data for.</param>
|
||||
/// <returns type="json">A JSON object containing the column data for the supplied index.</returns>
|
||||
var result = null;
|
||||
for (var column in ft.columns) {
|
||||
if ($.inArray(index, ft.columns[column].matches) >= 0) {
|
||||
result = ft.columns[column];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
ft.createOrUpdateDetailRow = function (actualRow) {
|
||||
var $row = $(actualRow), $next = $row.next(), $detail, values = [];
|
||||
if ($row.data('detail_created') === true) return true;
|
||||
|
||||
if ($row.is(':hidden')) return false; //if the row is hidden for some reason (perhaps filtered) then get out of here
|
||||
ft.raise(evt.rowDetailUpdating, { 'row': $row, 'detail': $next });
|
||||
$row.find('> td:hidden').each(function () {
|
||||
var index = $(this).index(), column = ft.getColumnFromTdIndex(index), name = column.name;
|
||||
if (column.ignore === true) return true;
|
||||
|
||||
if (index in column.names) name = column.names[index];
|
||||
|
||||
var bindName = $(this).attr("data-bind-name");
|
||||
if (bindName != null && $(this).is(':empty')) {
|
||||
var bindValue = $('.' + cls.detailInnerValue + '[' + 'data-bind-value="' + bindName + '"]');
|
||||
$(this).html($(bindValue).contents().detach());
|
||||
}
|
||||
var display;
|
||||
if (column.isEditable !== false && (column.isEditable || $(this).find(":input").length > 0)) {
|
||||
if(bindName == null) {
|
||||
bindName = "bind-" + $.now() + "-" + index;
|
||||
$(this).attr("data-bind-name", bindName);
|
||||
}
|
||||
display = $(this).contents().detach();
|
||||
}
|
||||
if (!display) display = $(this).contents().clone(true, true);
|
||||
values.push({ 'name': name, 'value': ft.parse(this, column), 'display': display, 'group': column.group, 'groupName': column.groupName, 'bindName': bindName });
|
||||
return true;
|
||||
});
|
||||
if (values.length === 0) return false; //return if we don't have any data to show
|
||||
var colspan = $row.find('> td:visible').length;
|
||||
var exists = $next.hasClass(cls.detail);
|
||||
if (!exists) { // Create
|
||||
$next = $('<tr class="' + cls.detail + '"><td class="' + cls.detailCell + '"><div class="' + cls.detailInner + '"></div></td></tr>');
|
||||
$row.after($next);
|
||||
}
|
||||
$next.find('> td:first').attr('colspan', colspan);
|
||||
$detail = $next.find('.' + cls.detailInner).empty();
|
||||
opt.createDetail($detail, values, opt.createGroupedDetail, opt.detailSeparator, cls);
|
||||
$row.data('detail_created', true);
|
||||
ft.raise(evt.rowDetailUpdated, { 'row': $row, 'detail': $next });
|
||||
return !exists;
|
||||
};
|
||||
|
||||
ft.raise = function (eventName, args) {
|
||||
|
||||
if (ft.options.debug === true && $.isFunction(ft.options.log)) ft.options.log(eventName, 'event');
|
||||
|
||||
args = args || { };
|
||||
var def = { 'ft': ft };
|
||||
$.extend(true, def, args);
|
||||
var e = $.Event(eventName, def);
|
||||
if (!e.ft) {
|
||||
$.extend(true, e, def);
|
||||
} //pre jQuery 1.6 which did not allow data to be passed to event object constructor
|
||||
$(ft.table).trigger(e);
|
||||
return e;
|
||||
};
|
||||
|
||||
//reset the state of FooTable
|
||||
ft.reset = function() {
|
||||
var $table = $(ft.table);
|
||||
$table.removeData('footable_info')
|
||||
.data('breakpoint', '')
|
||||
.removeClass(cls.loading)
|
||||
.removeClass(cls.loaded);
|
||||
|
||||
$table.find(opt.toggleSelector).unbind(trg.toggleRow).unbind('click.footable');
|
||||
|
||||
$table.find('> tbody > tr').removeClass(cls.detailShow);
|
||||
|
||||
$table.find('> tbody > tr.' + cls.detail).remove();
|
||||
|
||||
ft.raise(evt.reset);
|
||||
};
|
||||
|
||||
//Switch between row-detail and detail-show.
|
||||
ft.toggleInput = function (column) {
|
||||
var bindName = $(column).attr("data-bind-name");
|
||||
if(bindName != null) {
|
||||
var bindValue = $('.' + cls.detailInnerValue + '[' + 'data-bind-value="' + bindName + '"]');
|
||||
if(bindValue != null) {
|
||||
if($(column).is(":visible")) {
|
||||
if(!$(bindValue).is(':empty')) $(column).html($(bindValue).contents().detach());
|
||||
} else if(!$(column).is(':empty')) {
|
||||
$(bindValue).html($(column).contents().detach());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ft.init();
|
||||
return ft;
|
||||
}
|
||||
})(jQuery, window);
|
@ -1,429 +0,0 @@
|
||||
/**
|
||||
* Footable Memory
|
||||
*
|
||||
* Version 1.1.0
|
||||
*
|
||||
* Requires browser support for localStorage. Fallback to cookies using
|
||||
* jQuery Cookie (https://github.com/carhartl/jquery-cookie)
|
||||
*
|
||||
* Stores table state in a cookie and reloads state when page is refreshed.
|
||||
*
|
||||
* Supports common FooTable features:
|
||||
* - Pagination
|
||||
* - Sorting
|
||||
* - Filtering
|
||||
* - Expansion
|
||||
*
|
||||
* Written to be compatible with multiple FooTables per page and with
|
||||
* JavaScript libraries like AngularJS and Ember that use hash based URLs.
|
||||
*
|
||||
* Disabled by default, to enable add the following section to the footable
|
||||
* options:
|
||||
*
|
||||
* $('#table').footable({
|
||||
* memory: {
|
||||
* enabled: true
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* Based on FooTable Plugin Bookmarkable by Amy Farrell (https://github.com/akf)
|
||||
*
|
||||
* Created by Chris Laskey (https://github.com/chrislaskey)
|
||||
*/
|
||||
|
||||
(function ($, w, undefined) {
|
||||
|
||||
if (w.footable === undefined || w.foobox === null) {
|
||||
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
||||
}
|
||||
|
||||
var defaults = {
|
||||
memory: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
|
||||
var storage;
|
||||
|
||||
var storage_engines = {};
|
||||
|
||||
storage_engines.local_storage = (function($){
|
||||
|
||||
'use strict';
|
||||
|
||||
var path_page = function(){
|
||||
return location.pathname;
|
||||
};
|
||||
|
||||
var path_subpage = function(){
|
||||
return location.hash || 'root';
|
||||
};
|
||||
|
||||
var storage_key = function(index){
|
||||
return path_page() + '/' + path_subpage() + '/index-' + index;
|
||||
};
|
||||
|
||||
var get = function(index){
|
||||
var key = storage_key(index),
|
||||
as_string = localStorage.getItem(key);
|
||||
|
||||
return as_string ? JSON.parse(as_string) : {};
|
||||
};
|
||||
|
||||
var set = function(index, item){
|
||||
var key = storage_key(index),
|
||||
as_string = JSON.stringify(item);
|
||||
|
||||
localStorage.setItem(key, as_string);
|
||||
};
|
||||
|
||||
return {
|
||||
get: function(index){
|
||||
return get(index);
|
||||
},
|
||||
set: function(index, item){
|
||||
set(index, item);
|
||||
}
|
||||
};
|
||||
|
||||
})($);
|
||||
|
||||
storage_engines.cookie = (function($){
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Stores footable bookmarkable data in a cookie
|
||||
*
|
||||
* By default will store each page in its own cookie.
|
||||
* Supports multiple FooTables per page.
|
||||
* Supports JS frameworks that use hashmap URLs (AngularJS, Ember, etc).
|
||||
*
|
||||
* For example take an example application:
|
||||
*
|
||||
* http://example.com/application-data (2 FooTables on this page)
|
||||
* http://example.com/application-data/#/details (1 FooTable on this page)
|
||||
* http://example.com/other-data (1 FooTable on this page)
|
||||
*
|
||||
* Would be stored like this:
|
||||
*
|
||||
* cookie['/application-data'] = {
|
||||
* '/': {
|
||||
* 1: {
|
||||
* key1: value1,
|
||||
* key2: value2
|
||||
* },
|
||||
* 2: {
|
||||
* key1: value1,
|
||||
* key2: value2
|
||||
* }
|
||||
* },
|
||||
* '#/details': {
|
||||
* 1: {
|
||||
* key1: value1,
|
||||
* key2: value2
|
||||
* }
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* cookie['/other-data'] = {
|
||||
* '/': {
|
||||
* 1: {
|
||||
* key1: value1,
|
||||
* key2: value2
|
||||
* },
|
||||
* }
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
if( $.cookie ){
|
||||
$.cookie.json = true;
|
||||
}
|
||||
|
||||
var days_to_keep_data = 7;
|
||||
|
||||
var path_page = function(){
|
||||
return location.pathname;
|
||||
};
|
||||
|
||||
var path_subpage = function(){
|
||||
return location.hash || '/';
|
||||
};
|
||||
|
||||
var get_data = function(){
|
||||
var page = path_page(),
|
||||
data = $.cookie(page);
|
||||
|
||||
return data || {};
|
||||
};
|
||||
|
||||
var get_table = function(index){
|
||||
var subpage = path_subpage(),
|
||||
data = get_data();
|
||||
|
||||
if( data[subpage] && data[subpage][index] ){
|
||||
return data[subpage][index];
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
var set = function(index, item){
|
||||
var page = path_page(),
|
||||
subpage = path_subpage(),
|
||||
data = get_data(),
|
||||
options;
|
||||
|
||||
if( !data[subpage] ){
|
||||
data[subpage] = {};
|
||||
}
|
||||
|
||||
data[subpage][index] = item;
|
||||
|
||||
options = {
|
||||
path: page,
|
||||
expires: days_to_keep_data
|
||||
};
|
||||
|
||||
$.cookie(page, data, options);
|
||||
};
|
||||
|
||||
return {
|
||||
get: function(index){
|
||||
return get_table(index);
|
||||
},
|
||||
set: function(index, item){
|
||||
set(index, item);
|
||||
}
|
||||
};
|
||||
|
||||
})($);
|
||||
|
||||
var set_storage_engine = (function(){
|
||||
var test = 'footable-memory-plugin-storage-test';
|
||||
|
||||
try {
|
||||
localStorage.setItem(test, test);
|
||||
localStorage.removeItem(test);
|
||||
storage = storage_engines.local_storage;
|
||||
} catch(e) {
|
||||
try {
|
||||
$.cookie(test, test);
|
||||
storage = storage_engines.cookie;
|
||||
} catch(e) {
|
||||
throw new Error('FooTable Memory requires either localStorage or cookie support via jQuery $.cookie plugin (https://github.com/carhartl/jquery-cookie)');
|
||||
}
|
||||
}
|
||||
})($);
|
||||
|
||||
var state = (function($){
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Gets and sets current table state
|
||||
*/
|
||||
|
||||
var vars = {};
|
||||
|
||||
var get = {};
|
||||
|
||||
var set = {};
|
||||
|
||||
set.vars = function(ft){
|
||||
vars.ft = ft;
|
||||
vars.table = $(ft.table);
|
||||
};
|
||||
|
||||
get.descending = function(){
|
||||
var descending = false;
|
||||
$.each(vars.table.find('th'), function(index){
|
||||
if( $(this).hasClass('footable-sorted-desc') ){
|
||||
descending = true;
|
||||
}
|
||||
});
|
||||
return descending;
|
||||
};
|
||||
|
||||
get.expanded = function(){
|
||||
var indexes = [];
|
||||
$.each(vars.ft.table.rows, function(index, value){
|
||||
if( $(this).hasClass('footable-detail-show') ){
|
||||
indexes.push(index);
|
||||
}
|
||||
});
|
||||
return indexes;
|
||||
};
|
||||
|
||||
set.expanded = function(data){
|
||||
if( data.expanded ){
|
||||
$.each(data.expanded, function(index, value){
|
||||
// var row = $(vars.ft.table.rows[value]);
|
||||
// row.find('> td:first').trigger('footable_toggle_row');
|
||||
|
||||
// Trying to execute the lines above, but the expanded row
|
||||
// shows raw AngularJS template (with {{ values }}) instead
|
||||
// of the fully rendered result.
|
||||
//
|
||||
// Best guess is some things happen after
|
||||
// 'footable_initialized' event and row expanding can not
|
||||
// occur until after those fire.
|
||||
//
|
||||
// A hack to get around this is to wait an interval before
|
||||
// executing the intended commands. Wrapped in an
|
||||
// immediately executing function to ensure ft is the
|
||||
// current value.
|
||||
|
||||
(function(ft){
|
||||
setTimeout(function(){
|
||||
var row = $(ft.table.rows[value]);
|
||||
row.find('> td:first').trigger('footable_toggle_row');
|
||||
}, 150);
|
||||
})(vars.ft);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
get.filter = function(){
|
||||
return vars.table.data('filter') ? $(vars.table.data('filter')).val() : '';
|
||||
};
|
||||
|
||||
set.filter = function(data){
|
||||
if( data.filter ){
|
||||
$(vars.table.data('filter'))
|
||||
.val(data.filter)
|
||||
.trigger('keyup');
|
||||
}
|
||||
};
|
||||
|
||||
get.page = function(){
|
||||
return vars.ft.pageInfo && vars.ft.pageInfo.currentPage !== undefined ? vars.ft.pageInfo.currentPage : 0;
|
||||
};
|
||||
|
||||
set.page = function(data){
|
||||
if( data.page ){
|
||||
vars.table.data('currentPage', data.page);
|
||||
// Delay triggering table until sort is updated, since both effect
|
||||
// pagination.
|
||||
}
|
||||
};
|
||||
|
||||
get.shown = function(){
|
||||
return vars.table
|
||||
.find('tbody')
|
||||
.find('tr:not(.footable-row-detail)')
|
||||
.filter(':visible').length;
|
||||
};
|
||||
|
||||
get.sorted = function(){
|
||||
if( vars.table.data('sorted') !== undefined ){
|
||||
return vars.table.data('sorted');
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
set.sorted = function(data){
|
||||
if( data.sorted >= 0 ) {
|
||||
// vars.table.data('footable-sort').doSort(data.sorted, !data.descending);
|
||||
|
||||
// Trying to execute the line above, but only sort icon on the
|
||||
// <th> element gets set. The rows themselves do not get sorted.
|
||||
//
|
||||
// Best guess is some things happen after 'footable_initialized' event
|
||||
// and sorting can not occur until after those fire.
|
||||
//
|
||||
// A hack to get around this is to wait an interval before executing
|
||||
// the intended commands. Wrapped in an immediately executing
|
||||
// function to ensure ft is the current value.
|
||||
|
||||
(function(ft){
|
||||
setTimeout(function(){
|
||||
$(ft.table).data('footable-sort').doSort(data.sorted, !data.descending);
|
||||
}, 150);
|
||||
})(vars.ft);
|
||||
} else {
|
||||
vars.table.trigger('footable_setup_paging');
|
||||
}
|
||||
};
|
||||
|
||||
get.total = function(){
|
||||
return vars.table
|
||||
.find('tbody')
|
||||
.find('tr:not(.footable-row-detail, .footable-filtered)').length;
|
||||
};
|
||||
|
||||
var get_state = function(){
|
||||
return {
|
||||
descending: get.descending(),
|
||||
expanded: get.expanded(),
|
||||
filter: get.filter(),
|
||||
page: get.page(),
|
||||
shown: get.shown(),
|
||||
sorted: get.sorted(),
|
||||
total: get.total()
|
||||
};
|
||||
};
|
||||
|
||||
var set_state = function(data){
|
||||
set.filter(data);
|
||||
set.page(data);
|
||||
set.sorted(data);
|
||||
set.expanded(data);
|
||||
};
|
||||
|
||||
return {
|
||||
get: function(ft){
|
||||
set.vars(ft);
|
||||
return get_state();
|
||||
},
|
||||
set: function(ft, data){
|
||||
set.vars(ft);
|
||||
return set_state(data);
|
||||
}
|
||||
};
|
||||
|
||||
})($);
|
||||
|
||||
var is_enabled = function(ft){
|
||||
return ft.options.memory.enabled;
|
||||
};
|
||||
|
||||
var update = function(ft, event) {
|
||||
var index = ft.id,
|
||||
data = state.get(ft);
|
||||
|
||||
storage.set(index, data);
|
||||
};
|
||||
|
||||
var load = function(ft){
|
||||
var index = ft.id,
|
||||
data = storage.get(index);
|
||||
|
||||
state.set(ft, data);
|
||||
ft.memory_plugin_loaded = true;
|
||||
};
|
||||
|
||||
function Memory() {
|
||||
var p = this;
|
||||
p.name = 'Footable Memory';
|
||||
p.init = function(ft) {
|
||||
if (is_enabled(ft)) {
|
||||
$(ft.table).bind({
|
||||
'footable_initialized': function(){
|
||||
load(ft);
|
||||
},
|
||||
'footable_page_filled footable_redrawn footable_filtered footable_sorted footable_row_expanded footable_row_collapsed': function(e) {
|
||||
if (ft.memory_plugin_loaded) {
|
||||
update(ft, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
w.footable.plugins.register(Memory, defaults);
|
||||
|
||||
})(jQuery, window);
|
9
media/footable/js/footable.min.js
vendored
Normal file
9
media/footable/js/footable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,242 +0,0 @@
|
||||
(function ($, w, undefined) {
|
||||
if (w.footable === undefined || w.footable === null)
|
||||
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
||||
|
||||
var defaults = {
|
||||
paginate: true,
|
||||
pageSize: 10,
|
||||
pageNavigation: '.pagination',
|
||||
firstText: '«',
|
||||
previousText: '‹',
|
||||
nextText: '›',
|
||||
lastText: '»',
|
||||
limitNavigation: 0,
|
||||
limitPreviousText: '...',
|
||||
limitNextText: '...'
|
||||
};
|
||||
|
||||
function pageInfo(ft) {
|
||||
var $table = $(ft.table), data = $table.data();
|
||||
this.pageNavigation = data.pageNavigation || ft.options.pageNavigation;
|
||||
this.pageSize = data.pageSize || ft.options.pageSize;
|
||||
this.firstText = data.firstText || ft.options.firstText;
|
||||
this.previousText = data.previousText || ft.options.previousText;
|
||||
this.nextText = data.nextText || ft.options.nextText;
|
||||
this.lastText = data.lastText || ft.options.lastText;
|
||||
this.limitNavigation = parseInt(data.limitNavigation || ft.options.limitNavigation || defaults.limitNavigation, 10);
|
||||
this.limitPreviousText = data.limitPreviousText || ft.options.limitPreviousText;
|
||||
this.limitNextText = data.limitNextText || ft.options.limitNextText;
|
||||
this.limit = this.limitNavigation > 0;
|
||||
this.currentPage = data.currentPage || 0;
|
||||
this.pages = [];
|
||||
this.control = false;
|
||||
}
|
||||
|
||||
function Paginate() {
|
||||
var p = this;
|
||||
p.name = 'Footable Paginate';
|
||||
|
||||
p.init = function (ft) {
|
||||
if (ft.options.paginate === true) {
|
||||
if ($(ft.table).data('page') === false) return;
|
||||
p.footable = ft;
|
||||
$(ft.table)
|
||||
.unbind('.paging')
|
||||
.bind({
|
||||
'footable_initialized.paging footable_row_removed.paging footable_redrawn.paging footable_sorted.paging footable_filtered.paging': function () {
|
||||
p.setupPaging();
|
||||
}
|
||||
})
|
||||
//save the filter object onto the table so we can access it later
|
||||
.data('footable-paging', p);
|
||||
}
|
||||
};
|
||||
|
||||
p.setupPaging = function () {
|
||||
var ft = p.footable,
|
||||
$tbody = $(ft.table).find('> tbody');
|
||||
|
||||
ft.pageInfo = new pageInfo(ft);
|
||||
|
||||
p.createPages(ft, $tbody);
|
||||
p.createNavigation(ft, $tbody);
|
||||
p.fillPage(ft, $tbody, ft.pageInfo.currentPage);
|
||||
};
|
||||
|
||||
p.createPages = function (ft, tbody) {
|
||||
var pages = 1;
|
||||
var info = ft.pageInfo;
|
||||
var pageCount = pages * info.pageSize;
|
||||
var page = [];
|
||||
var lastPage = [];
|
||||
info.pages = [];
|
||||
var rows = tbody.find('> tr:not(.footable-filtered,.footable-row-detail)');
|
||||
rows.each(function (i, row) {
|
||||
page.push(row);
|
||||
if (i === pageCount - 1) {
|
||||
info.pages.push(page);
|
||||
pages++;
|
||||
pageCount = pages * info.pageSize;
|
||||
page = [];
|
||||
} else if (i >= rows.length - (rows.length % info.pageSize)) {
|
||||
lastPage.push(row);
|
||||
}
|
||||
});
|
||||
if (lastPage.length > 0) info.pages.push(lastPage);
|
||||
if (info.currentPage >= info.pages.length) info.currentPage = info.pages.length - 1;
|
||||
if (info.currentPage < 0) info.currentPage = 0;
|
||||
if (info.pages.length === 1) {
|
||||
//we only have a single page
|
||||
$(ft.table).addClass('no-paging');
|
||||
} else {
|
||||
$(ft.table).removeClass('no-paging');
|
||||
}
|
||||
};
|
||||
|
||||
p.createNavigation = function (ft, tbody) {
|
||||
var $nav = $(ft.table).find(ft.pageInfo.pageNavigation);
|
||||
//if we cannot find the navigation control within the table, then try find it outside
|
||||
if ($nav.length === 0) {
|
||||
$nav = $(ft.pageInfo.pageNavigation);
|
||||
//if the navigation control is inside another table, then get out
|
||||
if ($nav.parents('table:first').length > 0 && $nav.parents('table:first') !== $(ft.table)) return;
|
||||
//if we found more than one navigation control, write error to console
|
||||
if ($nav.length > 1 && ft.options.debug === true) console.error('More than one pagination control was found!');
|
||||
}
|
||||
//if we still cannot find the control, then don't do anything
|
||||
if ($nav.length === 0) return;
|
||||
//if the nav is not a UL, then find or create a UL
|
||||
if (!$nav.is('ul')) {
|
||||
if ($nav.find('ul:first').length === 0) {
|
||||
$nav.append('<ul />');
|
||||
}
|
||||
$nav = $nav.find('ul');
|
||||
}
|
||||
$nav.find('li').remove();
|
||||
var info = ft.pageInfo;
|
||||
info.control = $nav;
|
||||
if (info.pages.length > 0) {
|
||||
$nav.append('<li class="footable-page-arrow"><a data-page="first" href="#first">' + ft.pageInfo.firstText + '</a>');
|
||||
$nav.append('<li class="footable-page-arrow"><a data-page="prev" href="#prev">' + ft.pageInfo.previousText + '</a></li>');
|
||||
if (info.limit){
|
||||
$nav.append('<li class="footable-page-arrow"><a data-page="limit-prev" href="#limit-prev">' + ft.pageInfo.limitPreviousText + '</a></li>');
|
||||
}
|
||||
if (!info.limit){
|
||||
$.each(info.pages, function (i, page) {
|
||||
if (page.length > 0) {
|
||||
$nav.append('<li class="footable-page"><a data-page="' + i + '" href="#">' + (i + 1) + '</a></li>');
|
||||
}
|
||||
});
|
||||
}
|
||||
if (info.limit){
|
||||
$nav.append('<li class="footable-page-arrow"><a data-page="limit-next" href="#limit-next">' + ft.pageInfo.limitNextText + '</a></li>');
|
||||
p.createLimited($nav, info, 0);
|
||||
}
|
||||
$nav.append('<li class="footable-page-arrow"><a data-page="next" href="#next">' + ft.pageInfo.nextText + '</a></li>');
|
||||
$nav.append('<li class="footable-page-arrow"><a data-page="last" href="#last">' + ft.pageInfo.lastText + '</a></li>');
|
||||
}
|
||||
$nav.off('click', 'a[data-page]').on('click', 'a[data-page]', function (e) {
|
||||
e.preventDefault();
|
||||
var page = $(this).data('page');
|
||||
var newPage = info.currentPage;
|
||||
if (page === 'first') {
|
||||
newPage = 0;
|
||||
} else if (page === 'prev') {
|
||||
if (newPage > 0) newPage--;
|
||||
} else if (page === 'next') {
|
||||
if (newPage < info.pages.length - 1) newPage++;
|
||||
} else if (page === 'last') {
|
||||
newPage = info.pages.length - 1;
|
||||
} else if (page === 'limit-prev') {
|
||||
newPage = -1;
|
||||
var first = $nav.find('.footable-page:first a').data('page');
|
||||
p.createLimited($nav, info, first - info.limitNavigation);
|
||||
p.setPagingClasses($nav, info.currentPage, info.pages.length);
|
||||
} else if (page === 'limit-next') {
|
||||
newPage = -1;
|
||||
var last = $nav.find('.footable-page:last a').data('page');
|
||||
p.createLimited($nav, info, last + 1);
|
||||
p.setPagingClasses($nav, info.currentPage, info.pages.length);
|
||||
} else {
|
||||
newPage = page;
|
||||
}
|
||||
if (newPage >= 0){
|
||||
if (info.limit && info.currentPage != newPage){
|
||||
var start = newPage;
|
||||
while (start % info.limitNavigation !== 0){ start -= 1; }
|
||||
p.createLimited($nav, info, start);
|
||||
}
|
||||
p.paginate(ft, newPage);
|
||||
}
|
||||
});
|
||||
p.setPagingClasses($nav, info.currentPage, info.pages.length);
|
||||
};
|
||||
|
||||
p.createLimited = function(nav, info, start){
|
||||
start = start || 0;
|
||||
nav.find('li.footable-page').remove();
|
||||
var i, page,
|
||||
$prev = nav.find('li.footable-page-arrow > a[data-page="limit-prev"]').parent(),
|
||||
$next = nav.find('li.footable-page-arrow > a[data-page="limit-next"]').parent();
|
||||
for (i = info.pages.length - 1; i >=0 ; i--){
|
||||
page = info.pages[i];
|
||||
if (i >= start && i < start + info.limitNavigation && page.length > 0) {
|
||||
$prev.after('<li class="footable-page"><a data-page="' + i + '" href="#">' + (i + 1) + '</a></li>');
|
||||
}
|
||||
}
|
||||
if (start === 0){ $prev.hide(); }
|
||||
else { $prev.show(); }
|
||||
if (start + info.limitNavigation >= info.pages.length){ $next.hide(); }
|
||||
else { $next.show(); }
|
||||
};
|
||||
|
||||
p.paginate = function (ft, newPage) {
|
||||
var info = ft.pageInfo;
|
||||
if (info.currentPage !== newPage) {
|
||||
var $tbody = $(ft.table).find('> tbody');
|
||||
|
||||
//raise a pre-pagin event so that we can cancel the paging if needed
|
||||
var event = ft.raise('footable_paging', { page: newPage, size: info.pageSize });
|
||||
if (event && event.result === false) return;
|
||||
|
||||
p.fillPage(ft, $tbody, newPage);
|
||||
info.control.find('li').removeClass('active disabled');
|
||||
p.setPagingClasses(info.control, info.currentPage, info.pages.length);
|
||||
}
|
||||
};
|
||||
|
||||
p.setPagingClasses = function (nav, currentPage, pageCount) {
|
||||
nav.find('li.footable-page > a[data-page=' + currentPage + ']').parent().addClass('active');
|
||||
if (currentPage >= pageCount - 1) {
|
||||
nav.find('li.footable-page-arrow > a[data-page="next"]').parent().addClass('disabled');
|
||||
nav.find('li.footable-page-arrow > a[data-page="last"]').parent().addClass('disabled');
|
||||
}
|
||||
if (currentPage < 1) {
|
||||
nav.find('li.footable-page-arrow > a[data-page="first"]').parent().addClass('disabled');
|
||||
nav.find('li.footable-page-arrow > a[data-page="prev"]').parent().addClass('disabled');
|
||||
}
|
||||
};
|
||||
|
||||
p.fillPage = function (ft, tbody, pageNumber) {
|
||||
ft.pageInfo.currentPage = pageNumber;
|
||||
$(ft.table).data('currentPage', pageNumber);
|
||||
tbody.find('> tr').hide();
|
||||
$(ft.pageInfo.pages[pageNumber]).each(function () {
|
||||
p.showRow(this, ft);
|
||||
});
|
||||
ft.raise('footable_page_filled');
|
||||
};
|
||||
|
||||
p.showRow = function (row, ft) {
|
||||
var $row = $(row), $next = $row.next(), $table = $(ft.table);
|
||||
if ($table.hasClass('breakpoint') && $row.hasClass('footable-detail-show') && $next.hasClass('footable-row-detail')) {
|
||||
$row.add($next).show();
|
||||
ft.createOrUpdateDetailRow(row);
|
||||
}
|
||||
else $row.show();
|
||||
};
|
||||
}
|
||||
|
||||
w.footable.plugins.register(Paginate, defaults);
|
||||
|
||||
})(jQuery, window);
|
710
media/footable/js/footable.paging.js
Normal file
710
media/footable/js/footable.paging.js
Normal file
@ -0,0 +1,710 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
(function($, F){
|
||||
|
||||
F.Pager = F.Class.extend(/** @lends FooTable.Pager */{
|
||||
/**
|
||||
* The pager object contains the page number and direction to page to.
|
||||
* @constructs
|
||||
* @extends FooTable.Class
|
||||
* @param {number} total - The total number of pages available.
|
||||
* @param {number} current - The current page number.
|
||||
* @param {number} size - The number of rows per page.
|
||||
* @param {number} page - The page number to goto.
|
||||
* @param {boolean} forward - A boolean indicating the direction of paging, TRUE = forward, FALSE = back.
|
||||
* @returns {FooTable.Pager}
|
||||
*/
|
||||
construct: function(total, current, size, page, forward){
|
||||
/**
|
||||
* The total number of pages available.
|
||||
* @type {number}
|
||||
*/
|
||||
this.total = total;
|
||||
/**
|
||||
* The current page number.
|
||||
* @type {number}
|
||||
*/
|
||||
this.current = current;
|
||||
/**
|
||||
* The number of rows per page.
|
||||
* @type {number}
|
||||
*/
|
||||
this.size = size;
|
||||
/**
|
||||
* The page number to goto.
|
||||
* @type {number}
|
||||
*/
|
||||
this.page = page;
|
||||
/**
|
||||
* A boolean indicating the direction of paging, TRUE = forward, FALSE = back.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.forward = forward;
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery, FooTable);
|
||||
(function($, F){
|
||||
F.Paging = F.Component.extend(/** @lends FooTable.Paging */{
|
||||
/**
|
||||
* The paging component adds a pagination control to the table allowing users to navigate table rows via pages.
|
||||
* @constructs
|
||||
* @extends FooTable.Component
|
||||
* @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
|
||||
* @returns {FooTable.Filtering}
|
||||
*/
|
||||
construct: function(table){
|
||||
// call the base constructor
|
||||
this._super(table, table.o.paging.enabled);
|
||||
|
||||
/* PROTECTED */
|
||||
/**
|
||||
* An object containing the strings used by the paging buttons.
|
||||
* @type {{ first: string, prev: string, next: string, last: string }}
|
||||
*/
|
||||
this.strings = table.o.paging.strings;
|
||||
|
||||
/* PUBLIC */
|
||||
/**
|
||||
* The current page number to display.
|
||||
* @instance
|
||||
* @type {number}
|
||||
*/
|
||||
this.current = table.o.paging.current;
|
||||
/**
|
||||
* The number of rows to display per page.
|
||||
* @instance
|
||||
* @type {number}
|
||||
*/
|
||||
this.size = table.o.paging.size;
|
||||
/**
|
||||
* The maximum number of page links to display at once.
|
||||
* @type {number}
|
||||
*/
|
||||
this.limit = table.o.paging.limit;
|
||||
/**
|
||||
* The position of the pagination control within the paging rows cell.
|
||||
* @type {string}
|
||||
*/
|
||||
this.position = table.o.paging.position;
|
||||
/**
|
||||
* The format string used to generate the text displayed under the pagination control.
|
||||
* @type {string}
|
||||
*/
|
||||
this.countFormat = table.o.paging.countFormat;
|
||||
/**
|
||||
* The total number of pages.
|
||||
* @instance
|
||||
* @type {number}
|
||||
*/
|
||||
this.total = -1;
|
||||
/**
|
||||
* The jQuery row object that contains all the paging specific elements.
|
||||
* @instance
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$row = null;
|
||||
/**
|
||||
* The jQuery cell object that contains the pagination control and total count.
|
||||
* @instance
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$cell = null;
|
||||
/**
|
||||
* The jQuery object that contains the links for the pagination control.
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$pagination = null;
|
||||
/**
|
||||
* The jQuery object that contains the row count.
|
||||
* @type {jQuery}
|
||||
*/
|
||||
this.$count = null;
|
||||
|
||||
/* PRIVATE */
|
||||
/**
|
||||
* A number indicating the previous page displayed.
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this._previous = 1;
|
||||
|
||||
/**
|
||||
* Used to hold the number of rows in the {@link FooTable.Rows#array} before paging is applied.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this._total = 0;
|
||||
},
|
||||
|
||||
/* PROTECTED */
|
||||
/**
|
||||
* Checks the supplied data and options for the paging component.
|
||||
* @instance
|
||||
* @protected
|
||||
* @param {object} data - The jQuery data object from the parent table.
|
||||
* @fires FooTable.Paging#"preinit.ft.paging"
|
||||
*/
|
||||
preinit: function(data){
|
||||
var self = this;
|
||||
/**
|
||||
* The preinit.ft.paging event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
|
||||
* Calling preventDefault on this event will disable the component.
|
||||
* @event FooTable.Paging#"preinit.ft.paging"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {object} data - The jQuery data object of the table raising the event.
|
||||
*/
|
||||
this.ft.raise('preinit.ft.paging', [data]).then(function(){
|
||||
if (self.ft.$el.hasClass('footable-paging'))
|
||||
self.enabled = true;
|
||||
self.enabled = F.is.boolean(data.paging)
|
||||
? data.paging
|
||||
: self.enabled;
|
||||
|
||||
if (!self.enabled) return;
|
||||
|
||||
self.size = F.is.number(data.pagingSize)
|
||||
? data.pagingSize
|
||||
: self.size;
|
||||
|
||||
self.current = F.is.number(data.pagingCurrent)
|
||||
? data.pagingCurrent
|
||||
: self.current;
|
||||
|
||||
self.limit = F.is.number(data.pagingLimit)
|
||||
? data.pagingLimit
|
||||
: self.limit;
|
||||
|
||||
if (self.ft.$el.hasClass('footable-paging-left'))
|
||||
self.position = 'left';
|
||||
if (self.ft.$el.hasClass('footable-paging-center'))
|
||||
self.position = 'center';
|
||||
if (self.ft.$el.hasClass('footable-paging-right'))
|
||||
self.position = 'right';
|
||||
|
||||
self.position = F.is.string(data.pagingPosition)
|
||||
? data.pagingPosition
|
||||
: self.position;
|
||||
|
||||
self.countFormat = F.is.string(data.pagingCountFormat)
|
||||
? data.pagingCountFormat
|
||||
: self.countFormat;
|
||||
|
||||
self.total = Math.ceil(self.ft.rows.array.length / self.size);
|
||||
self._total = self.total;
|
||||
}, function(){
|
||||
self.enabled = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Initializes the paging component for the plugin using the supplied table and options.
|
||||
* @instance
|
||||
* @protected
|
||||
* @fires FooTable.Paging#"init.ft.paging"
|
||||
*/
|
||||
init: function(){
|
||||
/**
|
||||
* The init.ft.paging event is raised before its UI is generated.
|
||||
* Calling preventDefault on this event will disable the component.
|
||||
* @event FooTable.Paging#"init.ft.paging"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
*/
|
||||
var self = this;
|
||||
this.ft.raise('init.ft.paging').then(function(){
|
||||
self.$create();
|
||||
}, function(){
|
||||
self.enabled = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Destroys the paging component removing any UI generated from the table.
|
||||
* @instance
|
||||
* @protected
|
||||
* @fires FooTable.Paging#"destroy.ft.paging"
|
||||
*/
|
||||
destroy: function () {
|
||||
/**
|
||||
* The destroy.ft.paging event is raised before its UI is removed.
|
||||
* Calling preventDefault on this event will prevent the component from being destroyed.
|
||||
* @event FooTable.Paging#"destroy.ft.paging"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
*/
|
||||
var self = this;
|
||||
this.ft.raise('destroy.ft.paging').then(function(){
|
||||
self.ft.$el.removeClass('footable-paging')
|
||||
.find('tfoot > tr.footable-paging').remove();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Performs the actual paging against the {@link FooTable.Rows#current} array removing all rows that are not on the current visible page.
|
||||
* @instance
|
||||
* @protected
|
||||
*/
|
||||
predraw: function(){
|
||||
this.total = Math.ceil(this.ft.rows.array.length / this.size);
|
||||
this.current = this.current > this.total ? this.total : (this.current < 1 ? 1 : this.current);
|
||||
this._total = this.ft.rows.array.length;
|
||||
if (this.ft.rows.array.length > this.size)
|
||||
this.ft.rows.array = this.ft.rows.array.splice((this.current - 1) * this.size, this.size);
|
||||
},
|
||||
/**
|
||||
* Updates the paging UI setting the state of the pagination control.
|
||||
* @instance
|
||||
* @protected
|
||||
*/
|
||||
draw: function(){
|
||||
this.$cell.attr('colspan', this.ft.columns.visibleColspan);
|
||||
this._setVisible(this.current, this.current > this._previous);
|
||||
this._setNavigation(true);
|
||||
},
|
||||
/**
|
||||
* Creates the paging UI from the current options setting the various jQuery properties of this component.
|
||||
* @instance
|
||||
* @protected
|
||||
*/
|
||||
$create: function(){
|
||||
var self = this,
|
||||
multiple = self.total > 1,
|
||||
link = function(attr, html, klass){
|
||||
return $('<li/>', {
|
||||
'class': klass
|
||||
}).attr('data-page', attr)
|
||||
.append($('<a/>', {
|
||||
'class': 'footable-page-link',
|
||||
href: '#'
|
||||
}).data('page', attr).html(html));
|
||||
},
|
||||
position;
|
||||
|
||||
if (!multiple) return;
|
||||
|
||||
switch (self.position){
|
||||
case 'left': position = 'footable-paging-left'; break;
|
||||
case 'right': position = 'footable-paging-right'; break;
|
||||
default: position = 'footable-paging-center'; break;
|
||||
}
|
||||
self.ft.$el.addClass('footable-paging').addClass(position);
|
||||
self.$cell = $('<td/>').attr('colspan', self.ft.columns.visibleColspan);
|
||||
var $tfoot = self.ft.$el.children('tfoot');
|
||||
if ($tfoot.length == 0){
|
||||
$tfoot = $('<tfoot/>');
|
||||
self.ft.$el.append($tfoot);
|
||||
}
|
||||
self.$row = $('<tr/>', { 'class': 'footable-paging' }).append(self.$cell).appendTo($tfoot);
|
||||
self.$pagination = $('<ul/>', { 'class': 'pagination' }).on('click.footable', 'a.footable-page-link', { self: self }, self._onPageClicked);
|
||||
self.$count = $('<span/>', { 'class': 'label label-default' });
|
||||
|
||||
self.$pagination.empty();
|
||||
if (multiple) {
|
||||
self.$pagination.append(link('first', self.strings.first, 'footable-page-nav'));
|
||||
self.$pagination.append(link('prev', self.strings.prev, 'footable-page-nav'));
|
||||
if (self.limit > 0 && self.limit < self.total){
|
||||
self.$pagination.append(link('prev-limit', self.strings.prevPages, 'footable-page-nav'));
|
||||
}
|
||||
}
|
||||
for (var i = 0, $li; i < self.total; i++){
|
||||
$li = link(i + 1, i + 1, 'footable-page');
|
||||
self.$pagination.append($li);
|
||||
}
|
||||
if (multiple){
|
||||
if (self.limit > 0 && self.limit < self.total){
|
||||
self.$pagination.append(link('next-limit', self.strings.nextPages, 'footable-page-nav'));
|
||||
}
|
||||
self.$pagination.append(link('next', self.strings.next, 'footable-page-nav'));
|
||||
self.$pagination.append(link('last', self.strings.last, 'footable-page-nav'));
|
||||
}
|
||||
|
||||
self.$cell.append(self.$pagination, $('<div/>', {'class': 'divider'}), self.$count);
|
||||
self._total = self.total;
|
||||
},
|
||||
|
||||
/* PUBLIC */
|
||||
/**
|
||||
* Pages to the first page.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#"before.ft.paging"
|
||||
* @fires FooTable.Paging#"after.ft.paging"
|
||||
*/
|
||||
first: function(){
|
||||
return this._set(1);
|
||||
},
|
||||
/**
|
||||
* Pages to the previous page.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#"before.ft.paging"
|
||||
* @fires FooTable.Paging#"after.ft.paging"
|
||||
*/
|
||||
prev: function(){
|
||||
return this._set(this.current - 1 > 0 ? this.current - 1 : 1);
|
||||
},
|
||||
/**
|
||||
* Pages to the next page.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#"before.ft.paging"
|
||||
* @fires FooTable.Paging#"after.ft.paging"
|
||||
*/
|
||||
next: function(){
|
||||
return this._set(this.current + 1 < this.total ? this.current + 1 : this.total);
|
||||
},
|
||||
/**
|
||||
* Pages to the last page.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#"before.ft.paging"
|
||||
* @fires FooTable.Paging#"after.ft.paging"
|
||||
*/
|
||||
last: function(){
|
||||
return this._set(this.total);
|
||||
},
|
||||
/**
|
||||
* Pages to the specified page.
|
||||
* @instance
|
||||
* @param {number} page - The page number to go to.
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#"before.ft.paging"
|
||||
* @fires FooTable.Paging#"after.ft.paging"
|
||||
*/
|
||||
goto: function(page){
|
||||
return this._set(page > this.total ? this.total : (page < 1 ? 1 : page));
|
||||
},
|
||||
/**
|
||||
* Shows the previous X number of pages in the pagination control where X is the value set by the {@link FooTable.Defaults#paging} - limit option value.
|
||||
* @instance
|
||||
*/
|
||||
prevPages: function(){
|
||||
var page = this.$pagination.children('li.footable-page.visible:first').data('page') - 1;
|
||||
this._setVisible(page, true);
|
||||
this._setNavigation(false);
|
||||
},
|
||||
/**
|
||||
* Shows the next X number of pages in the pagination control where X is the value set by the {@link FooTable.Defaults#paging} - limit option value.
|
||||
* @instance
|
||||
*/
|
||||
nextPages: function(){
|
||||
var page = this.$pagination.children('li.footable-page.visible:last').data('page') + 1;
|
||||
this._setVisible(page, false);
|
||||
this._setNavigation(false);
|
||||
},
|
||||
/**
|
||||
* Gets or sets the current page size
|
||||
* @instance
|
||||
* @param {number} [value] - The new page size to use.
|
||||
* @returns {(number|undefined)}
|
||||
*/
|
||||
pageSize: function(value){
|
||||
if (!F.is.number(value)){
|
||||
return this.size;
|
||||
}
|
||||
this.size = value;
|
||||
this.total = Math.ceil(this.ft.rows.all.length / this.size);
|
||||
if (F.is.jq(this.$row)) this.$row.remove();
|
||||
this.$create();
|
||||
this.ft.draw();
|
||||
},
|
||||
|
||||
/* PRIVATE */
|
||||
/**
|
||||
* Performs the required steps to handle paging including the raising of the {@link FooTable.Paging#"before.ft.paging"} and {@link FooTable.Paging#"after.ft.paging"} events.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {number} page - The page to set.
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#"before.ft.paging"
|
||||
* @fires FooTable.Paging#"after.ft.paging"
|
||||
*/
|
||||
_set: function(page){
|
||||
var self = this,
|
||||
pager = new F.Pager(self.total, self.current, self.size, page, page > self.current);
|
||||
/**
|
||||
* The before.ft.paging event is raised before a sort is applied and allows listeners to modify the pager or cancel it completely by calling preventDefault on the jQuery.Event object.
|
||||
* @event FooTable.Paging#"before.ft.paging"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {FooTable.Pager} pager - The pager that is about to be applied.
|
||||
*/
|
||||
return self.ft.raise('before.ft.paging', [pager]).then(function(){
|
||||
pager.page = pager.page > pager.total ? pager.total : pager.page;
|
||||
pager.page = pager.page < 1 ? 1 : pager.page;
|
||||
if (self.current == page) return $.when();
|
||||
self._previous = self.current;
|
||||
self.current = pager.page;
|
||||
return self.ft.draw().then(function(){
|
||||
/**
|
||||
* The after.ft.paging event is raised after a pager has been applied.
|
||||
* @event FooTable.Paging#"after.ft.paging"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {FooTable.Pager} pager - The pager that has been applied.
|
||||
*/
|
||||
self.ft.raise('after.ft.paging', [pager]);
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Sets the state for the navigation links of the pagination control and optionally sets the active class state on the current page link.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {boolean} active - Whether or not to set the active class state on the individual page links.
|
||||
*/
|
||||
_setNavigation: function(active){
|
||||
if (this.current == 1) {
|
||||
this.$pagination.children('li[data-page="first"],li[data-page="prev"]').addClass('disabled');
|
||||
} else {
|
||||
this.$pagination.children('li[data-page="first"],li[data-page="prev"]').removeClass('disabled');
|
||||
}
|
||||
|
||||
if (this.current == this.total) {
|
||||
this.$pagination.children('li[data-page="next"],li[data-page="last"]').addClass('disabled');
|
||||
} else {
|
||||
this.$pagination.children('li[data-page="next"],li[data-page="last"]').removeClass('disabled');
|
||||
}
|
||||
|
||||
if ((this.$pagination.children('li.footable-page.visible:first').data('page') || 1) == 1) {
|
||||
this.$pagination.children('li[data-page="prev-limit"]').addClass('disabled');
|
||||
} else {
|
||||
this.$pagination.children('li[data-page="prev-limit"]').removeClass('disabled');
|
||||
}
|
||||
|
||||
if ((this.$pagination.children('li.footable-page.visible:last').data('page') || this.limit) == this.total) {
|
||||
this.$pagination.children('li[data-page="next-limit"]').addClass('disabled');
|
||||
} else {
|
||||
this.$pagination.children('li[data-page="next-limit"]').removeClass('disabled');
|
||||
}
|
||||
|
||||
if (this.limit > 0 && this.total < this.limit){
|
||||
this.$pagination.children('li[data-page="prev-limit"],li[data-page="next-limit"]').hide();
|
||||
} else {
|
||||
this.$pagination.children('li[data-page="prev-limit"],li[data-page="next-limit"]').show();
|
||||
}
|
||||
|
||||
if (active){
|
||||
this.$pagination.children('li.footable-page').removeClass('active').filter('li[data-page="' + this.current + '"]').addClass('active');
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Sets the visible page using the supplied parameters.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {number} page - The page to make visible.
|
||||
* @param {boolean} right - If set to true the supplied page will be the right most visible pagination link.
|
||||
*/
|
||||
_setVisible: function(page, right){
|
||||
if (this.limit > 0 && this.total > this.limit){
|
||||
if (!this.$pagination.children('li.footable-page[data-page="'+page+'"]').hasClass('visible')){
|
||||
var start = 0, end = 0;
|
||||
if (right == true){
|
||||
end = page > this.total ? this.total : page;
|
||||
start = end - this.limit;
|
||||
} else {
|
||||
start = page < 1 ? 0 : page - 1;
|
||||
end = start + this.limit;
|
||||
}
|
||||
if (start < 0){
|
||||
start = 0;
|
||||
end = this.limit > this.total ? this.total : this.limit;
|
||||
}
|
||||
if (end > this.total){
|
||||
end = this.total;
|
||||
start = this.total - this.limit < 0 ? 0 : this.total - this.limit;
|
||||
}
|
||||
this.$pagination.children('li.footable-page').removeClass('visible').slice(start, end).addClass('visible');
|
||||
}
|
||||
} else {
|
||||
this.$pagination.children('li.footable-page').removeClass('visible').slice(0, this.total).addClass('visible');
|
||||
}
|
||||
var first = (this.size * (page - 1)) + 1,
|
||||
last = this.size * page;
|
||||
if (this.ft.rows.array.length == 0){
|
||||
first = 0;
|
||||
last = 0;
|
||||
} else {
|
||||
last = last > this._total ? this._total : last;
|
||||
}
|
||||
this._setCount(page, this.total, first, last, this._total);
|
||||
},
|
||||
/**
|
||||
* Uses the countFormat option to generate the text using the supplied parameters.
|
||||
* @param {number} currentPage - The current page.
|
||||
* @param {number} totalPages - The total number of pages.
|
||||
* @param {number} pageFirst - The first row number of the current page.
|
||||
* @param {number} pageLast - The last row number of the current page.
|
||||
* @param {number} totalRows - The total number of rows.
|
||||
* @private
|
||||
*/
|
||||
_setCount: function(currentPage, totalPages, pageFirst, pageLast, totalRows){
|
||||
this.$count.text(this.countFormat.replace(/\{CP}/g, currentPage)
|
||||
.replace(/\{TP}/g, totalPages)
|
||||
.replace(/\{PF}/g, pageFirst)
|
||||
.replace(/\{PL}/g, pageLast)
|
||||
.replace(/\{TR}/g, totalRows));
|
||||
},
|
||||
/**
|
||||
* Handles the click event for all links in the pagination control.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {jQuery.Event} e - The event object for the event.
|
||||
*/
|
||||
_onPageClicked: function(e){
|
||||
e.preventDefault();
|
||||
if ($(e.target).closest('li').is('.active,.disabled')) return;
|
||||
|
||||
var self = e.data.self, page = $(this).data('page');
|
||||
switch(page){
|
||||
case 'first': self.first();
|
||||
return;
|
||||
case 'prev': self.prev();
|
||||
return;
|
||||
case 'next': self.next();
|
||||
return;
|
||||
case 'last': self.last();
|
||||
return;
|
||||
case 'prev-limit': self.prevPages();
|
||||
return;
|
||||
case 'next-limit': self.nextPages();
|
||||
return;
|
||||
default: self._set(page);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
F.components.core.register('paging', F.Paging, 0);
|
||||
|
||||
})(jQuery, FooTable);
|
||||
(function(F){
|
||||
/**
|
||||
* An object containing the paging options for the plugin. Added by the {@link FooTable.Paging} component.
|
||||
* @type {object}
|
||||
* @prop {boolean} enabled=false - Whether or not to allow paging on the table.
|
||||
* @prop {string} countFormat="{CP} of {TP}" - A string format used to generate the page count text.
|
||||
* @prop {number} current=1 - The page number to display.
|
||||
* @prop {number} limit=5 - The maximum number of page links to display at once.
|
||||
* @prop {string} position="center" - The string used to specify the alignment of the pagination control.
|
||||
* @prop {number} size=10 - The number of rows displayed per page.
|
||||
* @prop {object} strings - An object containing the strings used by the paging buttons.
|
||||
* @prop {string} strings.first="«" - The string used for the 'first' button.
|
||||
* @prop {string} strings.prev="‹" - The string used for the 'previous' button.
|
||||
* @prop {string} strings.next="›" - The string used for the 'next' button.
|
||||
* @prop {string} strings.last="»" - The string used for the 'last' button.
|
||||
* @prop {string} strings.prevPages="..." - The string used for the 'previous X pages' button.
|
||||
* @prop {string} strings.nextPages="..." - The string used for the 'next X pages' button.
|
||||
*/
|
||||
F.Defaults.prototype.paging = {
|
||||
enabled: false,
|
||||
countFormat: '{CP} of {TP}',
|
||||
current: 1,
|
||||
limit: 5,
|
||||
position: 'center',
|
||||
size: 10,
|
||||
strings: {
|
||||
first: '«',
|
||||
prev: '‹',
|
||||
next: '›',
|
||||
last: '»',
|
||||
prevPages: '...',
|
||||
nextPages: '...'
|
||||
}
|
||||
};
|
||||
})(FooTable);
|
||||
(function(F){
|
||||
/**
|
||||
* Navigates to the specified page number. Added by the {@link FooTable.Paging} component.
|
||||
* @instance
|
||||
* @param {number} num - The page number to go to.
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#paging_changing
|
||||
* @fires FooTable.Paging#paging_changed
|
||||
* @see FooTable.Paging#goto
|
||||
*/
|
||||
F.Table.prototype.gotoPage = function(num){
|
||||
return this.use(F.Paging).goto(num);
|
||||
};
|
||||
|
||||
/**
|
||||
* Navigates to the next page. Added by the {@link FooTable.Paging} component.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#paging_changing
|
||||
* @fires FooTable.Paging#paging_changed
|
||||
* @see FooTable.Paging#next
|
||||
*/
|
||||
F.Table.prototype.nextPage = function(){
|
||||
return this.use(F.Paging).next();
|
||||
};
|
||||
|
||||
/**
|
||||
* Navigates to the previous page. Added by the {@link FooTable.Paging} component.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#paging_changing
|
||||
* @fires FooTable.Paging#paging_changed
|
||||
* @see FooTable.Paging#prev
|
||||
*/
|
||||
F.Table.prototype.prevPage = function(){
|
||||
return this.use(F.Paging).prev();
|
||||
};
|
||||
|
||||
/**
|
||||
* Navigates to the first page. Added by the {@link FooTable.Paging} component.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#paging_changing
|
||||
* @fires FooTable.Paging#paging_changed
|
||||
* @see FooTable.Paging#first
|
||||
*/
|
||||
F.Table.prototype.firstPage = function(){
|
||||
return this.use(F.Paging).first();
|
||||
};
|
||||
|
||||
/**
|
||||
* Navigates to the last page. Added by the {@link FooTable.Paging} component.
|
||||
* @instance
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Paging#paging_changing
|
||||
* @fires FooTable.Paging#paging_changed
|
||||
* @see FooTable.Paging#last
|
||||
*/
|
||||
F.Table.prototype.lastPage = function(){
|
||||
return this.use(F.Paging).last();
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the next X number of pages in the pagination control where X is the value set by the {@link FooTable.Defaults#paging} - limit.size option value. Added by the {@link FooTable.Paging} component.
|
||||
* @instance
|
||||
* @see FooTable.Paging#nextPages
|
||||
*/
|
||||
F.Table.prototype.nextPages = function(){
|
||||
return this.use(F.Paging).nextPages();
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the previous X number of pages in the pagination control where X is the value set by the {@link FooTable.Defaults#paging} - limit.size option value. Added by the {@link FooTable.Paging} component.
|
||||
* @instance
|
||||
* @see FooTable.Paging#prevPages
|
||||
*/
|
||||
F.Table.prototype.prevPages = function(){
|
||||
return this.use(F.Paging).prevPages();
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets or sets the current page size
|
||||
* @instance
|
||||
* @param {number} [value] - The new page size to use.
|
||||
* @returns {(number|undefined)}
|
||||
* @see FooTable.Paging#pageSize
|
||||
*/
|
||||
F.Table.prototype.pageSize = function(value){
|
||||
return this.use(F.Paging).pageSize(value);
|
||||
};
|
||||
})(FooTable);
|
8
media/footable/js/footable.paging.min.js
vendored
Normal file
8
media/footable/js/footable.paging.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,44 +0,0 @@
|
||||
(function ($, w, undefined) {
|
||||
if (w.footable === undefined || w.foobox === null)
|
||||
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
||||
|
||||
var defaults = {
|
||||
/*
|
||||
Plugin options here, example:
|
||||
|
||||
var defaults = {
|
||||
myPlugin: {
|
||||
enabled: true
|
||||
}
|
||||
};
|
||||
|
||||
This would allow you to access this option using ft.options.myPlugin.enabled
|
||||
*/
|
||||
};
|
||||
|
||||
function MyPlugin() {
|
||||
var p = this;
|
||||
p.name = 'Footable MyPlugin';
|
||||
p.init = function(ft) {
|
||||
$(ft.table).bind({
|
||||
/*
|
||||
Bind to relevant events here to modify/add functionality to Footable, example:
|
||||
|
||||
$(ft.table).bind({
|
||||
'footable_initialized': function(e){
|
||||
if (e.ft.options.myPlugin.enabled === true){
|
||||
alert('Hello World');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
This would listen for the 'footable_initialized' event and when called check if the plugin is enabled
|
||||
and if it is alert 'Hello World' to the user.
|
||||
*/
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
w.footable.plugins.register(MyPlugin, defaults);
|
||||
|
||||
})(jQuery, window);
|
@ -1,190 +0,0 @@
|
||||
(function ($, w, undefined) {
|
||||
if (w.footable === undefined || w.footable === null)
|
||||
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
||||
|
||||
var defaults = {
|
||||
sort: true,
|
||||
sorters: {
|
||||
alpha: function (a, b) {
|
||||
if (typeof(a) === 'string') { a = a.toLowerCase(); }
|
||||
if (typeof(b) === 'string') { b = b.toLowerCase(); }
|
||||
if (a === b) return 0;
|
||||
if (a < b) return -1;
|
||||
return 1;
|
||||
},
|
||||
numeric: function (a, b) {
|
||||
return a - b;
|
||||
}
|
||||
},
|
||||
classes: {
|
||||
sort: {
|
||||
sortable: 'footable-sortable',
|
||||
sorted: 'footable-sorted',
|
||||
descending: 'footable-sorted-desc',
|
||||
indicator: 'footable-sort-indicator'
|
||||
}
|
||||
},
|
||||
events: {
|
||||
sort: {
|
||||
sorting: 'footable_sorting',
|
||||
sorted: 'footable_sorted'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function Sort() {
|
||||
var p = this;
|
||||
p.name = 'Footable Sortable';
|
||||
p.init = function (ft) {
|
||||
p.footable = ft;
|
||||
if (ft.options.sort === true) {
|
||||
$(ft.table)
|
||||
.unbind('.sorting')
|
||||
.bind({
|
||||
'footable_initialized.sorting': function (e) {
|
||||
var $table = $(ft.table),
|
||||
$tbody = $table.find('> tbody'),
|
||||
cls = ft.options.classes.sort,
|
||||
column, $th;
|
||||
|
||||
if ($table.data('sort') === false) return;
|
||||
|
||||
$table.find('> thead > tr:last-child > th, > thead > tr:last-child > td').each(function (ec) {
|
||||
var $th = $(this), column = ft.columns[$th.index()];
|
||||
if (column.sort.ignore !== true && !$th.hasClass(cls.sortable)) {
|
||||
$th.addClass(cls.sortable);
|
||||
$('<span />').addClass(cls.indicator).appendTo($th);
|
||||
}
|
||||
});
|
||||
|
||||
$table.find('> thead > tr:last-child > th.' + cls.sortable + ', > thead > tr:last-child > td.' + cls.sortable).unbind('click.footable').bind('click.footable', function (ec) {
|
||||
ec.preventDefault();
|
||||
$th = $(this);
|
||||
var ascending = !$th.hasClass(cls.sorted);
|
||||
p.doSort($th.index(), ascending);
|
||||
return false;
|
||||
});
|
||||
|
||||
var didSomeSorting = false;
|
||||
for (var c in ft.columns) {
|
||||
column = ft.columns[c];
|
||||
if (column.sort.initial) {
|
||||
var ascending = (column.sort.initial !== 'descending');
|
||||
p.doSort(column.index, ascending);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (didSomeSorting) {
|
||||
ft.bindToggleSelectors();
|
||||
}
|
||||
},
|
||||
'footable_redrawn.sorting': function(e) {
|
||||
var $table = $(ft.table),
|
||||
cls = ft.options.classes.sort;
|
||||
if ($table.data('sorted') >= 0) {
|
||||
$table.find('> thead > tr:last-child > th').each(function(i){
|
||||
var $th = $(this);
|
||||
if ($th.hasClass(cls.sorted) || $th.hasClass(cls.descending)) {
|
||||
p.doSort(i);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
'footable_column_data.sorting': function (e) {
|
||||
var $th = $(e.column.th);
|
||||
e.column.data.sort = e.column.data.sort || {};
|
||||
e.column.data.sort.initial = $th.data('sort-initial') || false;
|
||||
e.column.data.sort.ignore = $th.data('sort-ignore') || false;
|
||||
e.column.data.sort.selector = $th.data('sort-selector') || null;
|
||||
|
||||
var match = $th.data('sort-match') || 0;
|
||||
if (match >= e.column.data.matches.length) match = 0;
|
||||
e.column.data.sort.match = e.column.data.matches[match];
|
||||
}
|
||||
})
|
||||
//save the sort object onto the table so we can access it later
|
||||
.data('footable-sort', p);
|
||||
}
|
||||
};
|
||||
|
||||
p.doSort = function(columnIndex, ascending) {
|
||||
var ft = p.footable;
|
||||
if ($(ft.table).data('sort') === false) return;
|
||||
|
||||
var $table = $(ft.table),
|
||||
$tbody = $table.find('> tbody'),
|
||||
column = ft.columns[columnIndex],
|
||||
$th = $table.find('> thead > tr:last-child > th:eq(' + columnIndex + ')'),
|
||||
cls = ft.options.classes.sort,
|
||||
evt = ft.options.events.sort;
|
||||
|
||||
ascending = (ascending === undefined) ? $th.hasClass(cls.sorted) :
|
||||
(ascending === 'toggle') ? !$th.hasClass(cls.sorted) : ascending;
|
||||
|
||||
if (column.sort.ignore === true) return true;
|
||||
|
||||
//raise a pre-sorting event so that we can cancel the sorting if needed
|
||||
var event = ft.raise(evt.sorting, { column: column, direction: ascending ? 'ASC' : 'DESC' });
|
||||
if (event && event.result === false) return;
|
||||
|
||||
$table.data('sorted', column.index);
|
||||
|
||||
$table.find('> thead > tr:last-child > th, > thead > tr:last-child > td').not($th).removeClass(cls.sorted + ' ' + cls.descending);
|
||||
|
||||
if (ascending === undefined) {
|
||||
ascending = $th.hasClass(cls.sorted);
|
||||
}
|
||||
|
||||
if (ascending) {
|
||||
$th.removeClass(cls.descending).addClass(cls.sorted);
|
||||
} else {
|
||||
$th.removeClass(cls.sorted).addClass(cls.descending);
|
||||
}
|
||||
|
||||
p.sort(ft, $tbody, column, ascending);
|
||||
|
||||
ft.bindToggleSelectors();
|
||||
ft.raise(evt.sorted, { column: column, direction: ascending ? 'ASC' : 'DESC' });
|
||||
};
|
||||
|
||||
p.rows = function (ft, tbody, column) {
|
||||
var rows = [];
|
||||
tbody.find('> tr').each(function () {
|
||||
var $row = $(this), $next = null;
|
||||
if ($row.hasClass(ft.options.classes.detail)) return true;
|
||||
if ($row.next().hasClass(ft.options.classes.detail)) {
|
||||
$next = $row.next().get(0);
|
||||
}
|
||||
var row = { 'row': $row, 'detail': $next };
|
||||
if (column !== undefined) {
|
||||
row.value = ft.parse(this.cells[column.sort.match], column);
|
||||
}
|
||||
rows.push(row);
|
||||
return true;
|
||||
}).detach();
|
||||
return rows;
|
||||
};
|
||||
|
||||
p.sort = function (ft, tbody, column, ascending) {
|
||||
var rows = p.rows(ft, tbody, column);
|
||||
var sorter = ft.options.sorters[column.type] || ft.options.sorters.alpha;
|
||||
rows.sort(function (a, b) {
|
||||
if (ascending) {
|
||||
return sorter(a.value, b.value);
|
||||
} else {
|
||||
return sorter(b.value, a.value);
|
||||
}
|
||||
});
|
||||
for (var j = 0; j < rows.length; j++) {
|
||||
tbody.append(rows[j].row);
|
||||
if (rows[j].detail !== null) {
|
||||
tbody.append(rows[j].detail);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
w.footable.plugins.register(Sort, defaults);
|
||||
|
||||
})(jQuery, window);
|
435
media/footable/js/footable.sorting.js
Normal file
435
media/footable/js/footable.sorting.js
Normal file
@ -0,0 +1,435 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
(function($, F){
|
||||
|
||||
F.Sorter = F.Class.extend(/** @lends FooTable.Sorter */{
|
||||
/**
|
||||
* The sorter object contains the column and direction to sort by.
|
||||
* @constructs
|
||||
* @extends FooTable.Class
|
||||
* @param {FooTable.Column} column - The column to sort.
|
||||
* @param {string} direction - The direction to sort by.
|
||||
* @returns {FooTable.Sorter}
|
||||
*/
|
||||
construct: function(column, direction){
|
||||
/**
|
||||
* The column to sort.
|
||||
* @type {FooTable.Column}
|
||||
*/
|
||||
this.column = column;
|
||||
/**
|
||||
* The direction to sort by.
|
||||
* @type {string}
|
||||
*/
|
||||
this.direction = direction;
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery, FooTable);
|
||||
(function ($, F) {
|
||||
F.Sorting = F.Component.extend(/** @lends FooTable.Sorting */{
|
||||
/**
|
||||
* The sorting component adds a small sort button to specified column headers allowing users to sort those columns in the table.
|
||||
* @constructs
|
||||
* @extends FooTable.Component
|
||||
* @param {FooTable.Table} table - The parent {@link FooTable.Table} object for the component.
|
||||
* @returns {FooTable.Sorting}
|
||||
*/
|
||||
construct: function (table) {
|
||||
// call the constructor of the base class
|
||||
this._super(table, table.o.sorting.enabled);
|
||||
|
||||
/* PROTECTED */
|
||||
/**
|
||||
* This provides a shortcut to the {@link FooTable.Table#options}.[sorting]{@link FooTable.Defaults#sorting} object.
|
||||
* @instance
|
||||
* @protected
|
||||
* @type {object}
|
||||
*/
|
||||
this.o = table.o.sorting;
|
||||
/**
|
||||
* The current sorted column.
|
||||
* @instance
|
||||
* @type {FooTable.Column}
|
||||
*/
|
||||
this.column = null;
|
||||
|
||||
/* PRIVATE */
|
||||
/**
|
||||
* Sets a flag indicating whether or not the sorting has changed. When set to true the {@link FooTable.Sorting#sorting_changing} and {@link FooTable.Sorting#sorting_changed} events
|
||||
* will be raised during the drawing operation.
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this._changed = false;
|
||||
},
|
||||
|
||||
/* PROTECTED */
|
||||
/**
|
||||
* Checks the supplied data and options for the sorting component.
|
||||
* @instance
|
||||
* @protected
|
||||
* @param {object} data - The jQuery data object from the parent table.
|
||||
* @fires FooTable.Sorting#"preinit.ft.sorting"
|
||||
* @this FooTable.Sorting
|
||||
*/
|
||||
preinit: function(data){
|
||||
var self = this;
|
||||
/**
|
||||
* The preinit.ft.sorting event is raised before the UI is created and provides the tables jQuery data object for additional options parsing.
|
||||
* Calling preventDefault on this event will disable the component.
|
||||
* @event FooTable.Sorting#"preinit.ft.sorting"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {object} data - The jQuery data object of the table raising the event.
|
||||
*/
|
||||
this.ft.raise('preinit.ft.sorting', [data]).then(function(){
|
||||
if (self.ft.$el.hasClass('footable-sorting'))
|
||||
self.enabled = true;
|
||||
self.enabled = F.is.boolean(data.sorting)
|
||||
? data.sorting
|
||||
: self.enabled;
|
||||
if (!self.enabled) return;
|
||||
self.column = F.arr.first(self.ft.columns.array, function(col){ return col.sorted; });
|
||||
}, function(){
|
||||
self.enabled = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Initializes the sorting component for the plugin using the supplied table and options.
|
||||
* @instance
|
||||
* @protected
|
||||
* @fires FooTable.Sorting#"init.ft.sorting"
|
||||
* @this FooTable.Sorting
|
||||
*/
|
||||
init: function () {
|
||||
/**
|
||||
* The init.ft.sorting event is raised before its UI is generated.
|
||||
* Calling preventDefault on this event will disable the component.
|
||||
* @event FooTable.Sorting#"init.ft.sorting"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
*/
|
||||
var self = this;
|
||||
this.ft.raise('init.ft.sorting').then(function(){
|
||||
F.arr.each(self.ft.columns.array, function(col){
|
||||
if (col.sortable){
|
||||
col.$el.addClass('footable-sortable').append($('<span/>', {'class': 'fooicon fooicon-sort'}));
|
||||
}
|
||||
});
|
||||
self.ft.$el.on('click.footable', '.footable-sortable', { self: self }, self._onSortClicked);
|
||||
}, function(){
|
||||
self.enabled = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Destroys the sorting component removing any UI generated from the table.
|
||||
* @instance
|
||||
* @protected
|
||||
* @fires FooTable.Sorting#"destroy.ft.sorting"
|
||||
*/
|
||||
destroy: function () {
|
||||
/**
|
||||
* The destroy.ft.sorting event is raised before its UI is removed.
|
||||
* Calling preventDefault on this event will prevent the component from being destroyed.
|
||||
* @event FooTable.Sorting#"destroy.ft.sorting"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
*/
|
||||
var self = this;
|
||||
this.ft.raise('destroy.ft.paging').then(function(){
|
||||
self.ft.$el.off('click.footable', '.footable-sortable', self._onSortClicked);
|
||||
self.ft.$el.children('thead').children('tr.footable-header')
|
||||
.children('.footable-sortable').removeClass('footable-sortable')
|
||||
.find('span.fooicon').remove();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Performs the actual sorting against the {@link FooTable.Rows#current} array.
|
||||
* @instance
|
||||
* @protected
|
||||
*/
|
||||
predraw: function () {
|
||||
if (!this.column) return;
|
||||
var self = this, col = self.column;
|
||||
//self.ft.rows.array.sort(function (a, b) {
|
||||
// return col.direction == 'ASC'
|
||||
// ? col.sorter(a.cells[col.index].value, b.cells[col.index].value)
|
||||
// : col.sorter(b.cells[col.index].value, a.cells[col.index].value);
|
||||
//});
|
||||
self.ft.rows.array.sort(function (a, b) {
|
||||
return col.direction == 'ASC'
|
||||
? col.sorter(a.cells[col.index].sortValue, b.cells[col.index].sortValue)
|
||||
: col.sorter(b.cells[col.index].sortValue, a.cells[col.index].sortValue);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Updates the sorting UI setting the state of the sort buttons.
|
||||
* @instance
|
||||
* @protected
|
||||
*/
|
||||
draw: function () {
|
||||
if (!this.column) return;
|
||||
var self = this,
|
||||
$sortable = self.ft.$el.find('thead > tr > .footable-sortable'),
|
||||
$active = self.column.$el;
|
||||
|
||||
$sortable.removeClass('footable-asc footable-desc').children('.fooicon').removeClass('fooicon-sort fooicon-sort-asc fooicon-sort-desc');
|
||||
$sortable.not($active).children('.fooicon').addClass('fooicon-sort');
|
||||
$active.addClass(self.column.direction == 'ASC' ? 'footable-asc' : 'footable-desc')
|
||||
.children('.fooicon').addClass(self.column.direction == 'ASC' ? 'fooicon-sort-asc' : 'fooicon-sort-desc');
|
||||
},
|
||||
|
||||
/* PUBLIC */
|
||||
/**
|
||||
* Sets the sorting options and calls the {@link FooTable.Table#draw} method to perform the actual sorting.
|
||||
* @instance
|
||||
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
|
||||
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Sorting#"before.ft.sorting"
|
||||
* @fires FooTable.Sorting#"after.ft.sorting"
|
||||
*/
|
||||
sort: function(column, direction){
|
||||
return this._sort(column, direction);
|
||||
},
|
||||
|
||||
/* PRIVATE */
|
||||
/**
|
||||
* Performs the required steps to handle sorting including the raising of the {@link FooTable.Sorting#"before.ft.sorting"} and {@link FooTable.Sorting#"after.ft.sorting"} events.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
|
||||
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Sorting#"before.ft.sorting"
|
||||
* @fires FooTable.Sorting#"after.ft.sorting"
|
||||
*/
|
||||
_sort: function(column, direction){
|
||||
var self = this;
|
||||
var sorter = new F.Sorter(self.ft.columns.get(column), F.Sorting.dir(direction));
|
||||
/**
|
||||
* The before.ft.sorting event is raised before a sort is applied and allows listeners to modify the sorter or cancel it completely by calling preventDefault on the jQuery.Event object.
|
||||
* @event FooTable.Sorting#"before.ft.sorting"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {FooTable.Sorter} sorter - The sorter that is about to be applied.
|
||||
*/
|
||||
return self.ft.raise('before.ft.sorting', [sorter]).then(function(){
|
||||
F.arr.each(self.ft.columns.array, function(col){
|
||||
if (col != self.column) col.direction = null;
|
||||
});
|
||||
self.column = self.ft.columns.get(sorter.column);
|
||||
if (self.column) self.column.direction = F.Sorting.dir(sorter.direction);
|
||||
return self.ft.draw().then(function(){
|
||||
/**
|
||||
* The after.ft.sorting event is raised after a sorter has been applied.
|
||||
* @event FooTable.Sorting#"after.ft.sorting"
|
||||
* @param {jQuery.Event} e - The jQuery.Event object for the event.
|
||||
* @param {FooTable.Table} ft - The instance of the plugin raising the event.
|
||||
* @param {FooTable.Sorter} sorter - The sorter that has been applied.
|
||||
*/
|
||||
self.ft.raise('after.ft.sorting', [sorter]);
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Handles the sort button clicked event.
|
||||
* @instance
|
||||
* @private
|
||||
* @param {jQuery.Event} e - The event object for the event.
|
||||
*/
|
||||
_onSortClicked: function (e) {
|
||||
e.preventDefault();
|
||||
var self = e.data.self, $header = $(this).closest('th,td'),
|
||||
direction = $header.is('.footable-asc, .footable-desc')
|
||||
? ($header.hasClass('footable-desc') ? 'ASC' : 'DESC')
|
||||
: 'ASC';
|
||||
self._sort($header.index(), direction);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks the supplied string is a valid direction and if not returns ASC as default.
|
||||
* @static
|
||||
* @protected
|
||||
* @param {string} str - The string to check.
|
||||
*/
|
||||
F.Sorting.dir = function(str){
|
||||
return F.is.string(str) && (str == 'ASC' || str == 'DESC') ? str : 'ASC';
|
||||
};
|
||||
|
||||
F.components.core.register('sorting', F.Sorting, 5);
|
||||
|
||||
})(jQuery, FooTable);
|
||||
(function(F){
|
||||
|
||||
/**
|
||||
* The value used by the sorting component during sort operations. Can be set using the data-sort-value attribute on the cell itself.
|
||||
* If this is not supplied it is set to the result of the toString method called on the value for the cell. Added by the {@link FooTable.Sorting} component.
|
||||
* @type {string}
|
||||
* @default null
|
||||
*/
|
||||
F.Cell.prototype.sortValue = null;
|
||||
|
||||
// this is used to define the sorting specific properties on cell creation
|
||||
F.Cell.prototype.__sorting_define__ = function(valueOrElement){
|
||||
this.sortValue = this.column.sortValue.call(this.column, valueOrElement);
|
||||
};
|
||||
|
||||
// this is used to update the sortValue property whenever the cell value is changed
|
||||
F.Cell.prototype.__sorting_val__ = function(value){
|
||||
if (F.is.defined(value)){
|
||||
// set only
|
||||
this.sortValue = this.column.sortValue.call(this.column, value);
|
||||
}
|
||||
};
|
||||
|
||||
// overrides the public define method and replaces it with our own
|
||||
F.Cell.extend('define', function(valueOrElement){
|
||||
this._super(valueOrElement);
|
||||
this.__sorting_define__(valueOrElement);
|
||||
});
|
||||
// overrides the public val method and replaces it with our own
|
||||
F.Cell.extend('val', function(value){
|
||||
var val = this._super(value);
|
||||
this.__sorting_val__(value);
|
||||
return val;
|
||||
});
|
||||
})(FooTable);
|
||||
(function($, F){
|
||||
/**
|
||||
* The direction to sort if the {@link FooTable.Column#sorted} property is set to true. Can be "ASC", "DESC" or NULL. Added by the {@link FooTable.Sorting} component.
|
||||
* @type {string}
|
||||
* @default null
|
||||
*/
|
||||
F.Column.prototype.direction = null;
|
||||
/**
|
||||
* Whether or not the column can be sorted. Added by the {@link FooTable.Sorting} component.
|
||||
* @type {boolean}
|
||||
* @default true
|
||||
*/
|
||||
F.Column.prototype.sortable = true;
|
||||
/**
|
||||
* Whether or not the column is sorted. Added by the {@link FooTable.Sorting} component.
|
||||
* @type {boolean}
|
||||
* @default false
|
||||
*/
|
||||
F.Column.prototype.sorted = false;
|
||||
|
||||
/**
|
||||
* This is supplied two values from the column for a comparison to be made and the result returned. Added by the {@link FooTable.Sorting} component.
|
||||
* @param {*} a - The first value to be compared.
|
||||
* @param {*} b - The second value to compare to the first.
|
||||
* @returns {number}
|
||||
* @example <caption>This example shows using pseudo code what a sort function would look like.</caption>
|
||||
* "sorter": function(a, b){
|
||||
* if (a is less than b by some ordering criterion) {
|
||||
* return -1;
|
||||
* }
|
||||
* if (a is greater than b by the ordering criterion) {
|
||||
* return 1;
|
||||
* }
|
||||
* // a must be equal to b
|
||||
* return 0;
|
||||
* }
|
||||
*/
|
||||
F.Column.prototype.sorter = function(a, b){
|
||||
if (typeof a === 'string') a = a.toLowerCase();
|
||||
if (typeof b === 'string') b = b.toLowerCase();
|
||||
if (a === b) return 0;
|
||||
if (a < b) return -1;
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is supplied either the cell value or jQuery object to parse. A value must be returned from this method and will be used during sorting operations.
|
||||
* @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
|
||||
* @returns {*}
|
||||
* @this FooTable.Column
|
||||
*/
|
||||
F.Column.prototype.sortValue = function(valueOrElement){
|
||||
// if we have an element or a jQuery object use jQuery to get the value
|
||||
if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)) return $(valueOrElement).data('sortValue') || this.parser(valueOrElement);
|
||||
// if options are supplied with the value
|
||||
if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
|
||||
if (F.is.string(valueOrElement.options.sortValue)) return valueOrElement.options.sortValue;
|
||||
if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
|
||||
}
|
||||
if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement;
|
||||
return null;
|
||||
};
|
||||
|
||||
// this is used to define the sorting specific properties on column creation
|
||||
F.Column.prototype.__sorting_define__ = function(definition){
|
||||
this.sorter = F.checkFnValue(this, definition.sorter, this.sorter);
|
||||
this.direction = F.is.type(definition.direction, 'string') ? F.Sorting.dir(definition.direction) : null;
|
||||
this.sortable = F.is.boolean(definition.sortable) ? definition.sortable : true;
|
||||
this.sorted = F.is.boolean(definition.sorted) ? definition.sorted : false;
|
||||
};
|
||||
|
||||
// overrides the public define method and replaces it with our own
|
||||
F.Column.extend('define', function(definition){
|
||||
this._super(definition);
|
||||
this.__sorting_define__(definition);
|
||||
});
|
||||
|
||||
})(jQuery, FooTable);
|
||||
(function(F){
|
||||
/**
|
||||
* An object containing the sorting options for the plugin. Added by the {@link FooTable.Sorting} component.
|
||||
* @type {object}
|
||||
* @prop {boolean} enabled=false - Whether or not to allow sorting on the table.
|
||||
*/
|
||||
F.Defaults.prototype.sorting = {
|
||||
enabled: false
|
||||
};
|
||||
})(FooTable);
|
||||
(function($, F){
|
||||
|
||||
F.HTMLColumn.extend('__sorting_define__', function(definition){
|
||||
this._super(definition);
|
||||
this.sortUse = F.is.string(definition.sortUse) && $.inArray(definition.sortUse, ['html','text']) !== -1 ? definition.sortUse : 'html';
|
||||
});
|
||||
|
||||
/**
|
||||
* This is supplied either the cell value or jQuery object to parse. A value must be returned from this method and will be used during sorting operations.
|
||||
* @param {(*|jQuery)} valueOrElement - The value or jQuery cell object.
|
||||
* @returns {*}
|
||||
* @this FooTable.HTMLColumn
|
||||
*/
|
||||
F.HTMLColumn.prototype.sortValue = function(valueOrElement){
|
||||
// if we have an element or a jQuery object use jQuery to get the data value or pass it off to the parser
|
||||
if (F.is.element(valueOrElement) || F.is.jq(valueOrElement)){
|
||||
return $(valueOrElement).data('sortValue') || $.trim($(valueOrElement)[this.sortUse]());
|
||||
}
|
||||
// if options are supplied with the value
|
||||
if (F.is.hash(valueOrElement) && F.is.hash(valueOrElement.options)){
|
||||
if (F.is.string(valueOrElement.options.sortValue)) return valueOrElement.options.sortValue;
|
||||
if (F.is.defined(valueOrElement.value)) valueOrElement = valueOrElement.value;
|
||||
}
|
||||
if (F.is.defined(valueOrElement) && valueOrElement != null) return valueOrElement;
|
||||
return null;
|
||||
};
|
||||
|
||||
})(jQuery, FooTable);
|
||||
(function(F){
|
||||
/**
|
||||
* Sort the table using the specified column and direction. Added by the {@link FooTable.Sorting} component.
|
||||
* @instance
|
||||
* @param {(string|number|FooTable.Column)} column - The column name, index or the actual {@link FooTable.Column} object to sort by.
|
||||
* @param {string} [direction="ASC"] - The direction to sort by, either ASC or DESC.
|
||||
* @returns {jQuery.Promise}
|
||||
* @fires FooTable.Sorting#"change.ft.sorting"
|
||||
* @fires FooTable.Sorting#"changed.ft.sorting"
|
||||
* @see FooTable.Sorting#sort
|
||||
*/
|
||||
F.Table.prototype.sort = function(column, direction){
|
||||
return this.use(F.Sorting).sort(column, direction);
|
||||
};
|
||||
})(FooTable);
|
8
media/footable/js/footable.sorting.min.js
vendored
Normal file
8
media/footable/js/footable.sorting.min.js
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
/*
|
||||
* FooTable v3 - FooTable is a jQuery plugin that aims to make HTML tables on smaller devices look awesome.
|
||||
* @version 3.0.6
|
||||
* @link http://fooplugins.com
|
||||
* @copyright Steven Usher & Brad Vincent 2015
|
||||
* @license Released under the GPLv3 license.
|
||||
*/
|
||||
!function(a,b){b.Sorter=b.Class.extend({construct:function(a,b){this.column=a,this.direction=b}})}(jQuery,FooTable),function(a,b){b.Sorting=b.Component.extend({construct:function(a){this._super(a,a.o.sorting.enabled),this.o=a.o.sorting,this.column=null,this._changed=!1},preinit:function(a){var c=this;this.ft.raise("preinit.ft.sorting",[a]).then(function(){c.ft.$el.hasClass("footable-sorting")&&(c.enabled=!0),c.enabled=b.is["boolean"](a.sorting)?a.sorting:c.enabled,c.enabled&&(c.column=b.arr.first(c.ft.columns.array,function(a){return a.sorted}))},function(){c.enabled=!1})},init:function(){var c=this;this.ft.raise("init.ft.sorting").then(function(){b.arr.each(c.ft.columns.array,function(b){b.sortable&&b.$el.addClass("footable-sortable").append(a("<span/>",{"class":"fooicon fooicon-sort"}))}),c.ft.$el.on("click.footable",".footable-sortable",{self:c},c._onSortClicked)},function(){c.enabled=!1})},destroy:function(){var a=this;this.ft.raise("destroy.ft.paging").then(function(){a.ft.$el.off("click.footable",".footable-sortable",a._onSortClicked),a.ft.$el.children("thead").children("tr.footable-header").children(".footable-sortable").removeClass("footable-sortable").find("span.fooicon").remove()})},predraw:function(){if(this.column){var a=this,b=a.column;a.ft.rows.array.sort(function(a,c){return"ASC"==b.direction?b.sorter(a.cells[b.index].sortValue,c.cells[b.index].sortValue):b.sorter(c.cells[b.index].sortValue,a.cells[b.index].sortValue)})}},draw:function(){if(this.column){var a=this,b=a.ft.$el.find("thead > tr > .footable-sortable"),c=a.column.$el;b.removeClass("footable-asc footable-desc").children(".fooicon").removeClass("fooicon-sort fooicon-sort-asc fooicon-sort-desc"),b.not(c).children(".fooicon").addClass("fooicon-sort"),c.addClass("ASC"==a.column.direction?"footable-asc":"footable-desc").children(".fooicon").addClass("ASC"==a.column.direction?"fooicon-sort-asc":"fooicon-sort-desc")}},sort:function(a,b){return this._sort(a,b)},_sort:function(a,c){var d=this,e=new b.Sorter(d.ft.columns.get(a),b.Sorting.dir(c));return d.ft.raise("before.ft.sorting",[e]).then(function(){return b.arr.each(d.ft.columns.array,function(a){a!=d.column&&(a.direction=null)}),d.column=d.ft.columns.get(e.column),d.column&&(d.column.direction=b.Sorting.dir(e.direction)),d.ft.draw().then(function(){d.ft.raise("after.ft.sorting",[e])})})},_onSortClicked:function(b){b.preventDefault();var c=b.data.self,d=a(this).closest("th,td"),e=d.is(".footable-asc, .footable-desc")?d.hasClass("footable-desc")?"ASC":"DESC":"ASC";c._sort(d.index(),e)}}),b.Sorting.dir=function(a){return!b.is.string(a)||"ASC"!=a&&"DESC"!=a?"ASC":a},b.components.core.register("sorting",b.Sorting,5)}(jQuery,FooTable),function(a){a.Cell.prototype.sortValue=null,a.Cell.prototype.__sorting_define__=function(a){this.sortValue=this.column.sortValue.call(this.column,a)},a.Cell.prototype.__sorting_val__=function(b){a.is.defined(b)&&(this.sortValue=this.column.sortValue.call(this.column,b))},a.Cell.extend("define",function(a){this._super(a),this.__sorting_define__(a)}),a.Cell.extend("val",function(a){var b=this._super(a);return this.__sorting_val__(a),b})}(FooTable),function(a,b){b.Column.prototype.direction=null,b.Column.prototype.sortable=!0,b.Column.prototype.sorted=!1,b.Column.prototype.sorter=function(a,b){return"string"==typeof a&&(a=a.toLowerCase()),"string"==typeof b&&(b=b.toLowerCase()),a===b?0:b>a?-1:1},b.Column.prototype.sortValue=function(c){if(b.is.element(c)||b.is.jq(c))return a(c).data("sortValue")||this.parser(c);if(b.is.hash(c)&&b.is.hash(c.options)){if(b.is.string(c.options.sortValue))return c.options.sortValue;b.is.defined(c.value)&&(c=c.value)}return b.is.defined(c)&&null!=c?c:null},b.Column.prototype.__sorting_define__=function(a){this.sorter=b.checkFnValue(this,a.sorter,this.sorter),this.direction=b.is.type(a.direction,"string")?b.Sorting.dir(a.direction):null,this.sortable=b.is["boolean"](a.sortable)?a.sortable:!0,this.sorted=b.is["boolean"](a.sorted)?a.sorted:!1},b.Column.extend("define",function(a){this._super(a),this.__sorting_define__(a)})}(jQuery,FooTable),function(a){a.Defaults.prototype.sorting={enabled:!1}}(FooTable),function(a,b){b.HTMLColumn.extend("__sorting_define__",function(c){this._super(c),this.sortUse=b.is.string(c.sortUse)&&-1!==a.inArray(c.sortUse,["html","text"])?c.sortUse:"html"}),b.HTMLColumn.prototype.sortValue=function(c){if(b.is.element(c)||b.is.jq(c))return a(c).data("sortValue")||a.trim(a(c)[this.sortUse]());if(b.is.hash(c)&&b.is.hash(c.options)){if(b.is.string(c.options.sortValue))return c.options.sortValue;b.is.defined(c.value)&&(c=c.value)}return b.is.defined(c)&&null!=c?c:null}}(jQuery,FooTable),function(a){a.Table.prototype.sort=function(b,c){return this.use(a.Sorting).sort(b,c)}}(FooTable);
|
@ -1,57 +0,0 @@
|
||||
(function ($, w, undefined) {
|
||||
if (w.footable === undefined || w.foobox === null)
|
||||
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
||||
|
||||
var defaults = {
|
||||
striping: {
|
||||
enabled: true
|
||||
},
|
||||
classes: {
|
||||
striping: {
|
||||
odd: 'footable-odd',
|
||||
even: 'footable-even'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function Striping() {
|
||||
var p = this;
|
||||
p.name = 'Footable Striping';
|
||||
p.init = function (ft) {
|
||||
p.footable = ft;
|
||||
$(ft.table)
|
||||
.unbind('striping')
|
||||
.bind({
|
||||
'footable_initialized.striping footable_row_removed.striping footable_redrawn.striping footable_sorted.striping footable_filtered.striping': function () {
|
||||
|
||||
if ($(this).data('striping') === false) return;
|
||||
|
||||
p.setupStriping(ft);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
p.setupStriping = function (ft) {
|
||||
|
||||
var rowIndex = 0;
|
||||
$(ft.table).find('> tbody > tr:not(.footable-row-detail)').each(function () {
|
||||
|
||||
var $row = $(this);
|
||||
|
||||
//Clean off old classes
|
||||
$row.removeClass(ft.options.classes.striping.even).removeClass(ft.options.classes.striping.odd);
|
||||
|
||||
if (rowIndex % 2 === 0) {
|
||||
$row.addClass(ft.options.classes.striping.even);
|
||||
} else {
|
||||
$row.addClass(ft.options.classes.striping.odd);
|
||||
}
|
||||
|
||||
rowIndex++;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
w.footable.plugins.register(Striping, defaults);
|
||||
|
||||
})(jQuery, window);
|
Reference in New Issue
Block a user