Changed over to V3 of footable, fixed icon display in the repeatable icon selections.

This commit is contained in:
2016-05-07 02:12:30 +01:00
parent e21980bbea
commit c9150e930d
416 changed files with 8121 additions and 3991 deletions

View File

@ -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.

View 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/>.

View File

@ -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="&#xf000;" d="M0,480L 512 -32L0 -32 z" horiz-adv-x="0" />
<glyph unicode="&#xe000;" 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="&#xe001;" 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="&#xe002;" 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="&#xe003;" 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="&#xe004;" 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="&#xe005;" 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="&#xe006;" 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="&#xe007;" 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="&#xe008;" 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="&#xe009;" 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="&#xe00a;" 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="&#xe00b;" 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="&#xe00c;" 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="&#xe00d;" 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="&#xe00e;" d="M0,160L 96,64L 256,224L 416,64L 512,160L 256.001,416 z" />
<glyph unicode="&#xe00f;" d="M 512,288L 416,384L 256,224L 96,384L0,288L 256,32.001 z" />
<glyph unicode="&#xe010;" d="M 320-32L 416,64L 256,224L 416,384L 320,480L 64,224 z" />
<glyph unicode="&#xe011;" d="M 192,480L 96,384L 256,224L 96,64L 192-32L 448,224 z" />
<glyph unicode="&#xe012;" 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="&#xe013;" 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="&#xe014;" 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="&#xe015;" 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="&#xe016;" d="M 256,480L 32-32L 256,64L 480-32 z" />
<glyph unicode="&#xe017;" d="M 256-32L 480,480L 256,384L 32,480 z" />
<glyph unicode="&#xe018;" d="M0,224L 512,0L 416,224L 512,448 z" />
<glyph unicode="&#xe019;" d="M 512,224L0,448L 96,224L0,0 z" />
<glyph unicode="&#xe01a;" 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="&#xe01b;" 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="&#xe01c;" 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="&#xe01d;" 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="&#xe01e;" 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="&#xe01f;" 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="&#xe020;" 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="&#xe021;" 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="&#xe022;" 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="&#x20;" horiz-adv-x="256" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1 +0,0 @@
<html><body bgcolor="#FFFFFF"></body></html>

View 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;
}

File diff suppressed because one or more lines are too long

View 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";
}

View File

@ -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;
}

View File

@ -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}

View 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";
}

View 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;
}
}

View 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}}

View File

@ -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;
}

View File

@ -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}

View 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;
}

View 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}

View 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;
}

View 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}

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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);

View File

@ -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);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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);

View File

@ -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);

View File

@ -1 +0,0 @@
<html><body bgcolor="#FFFFFF"></body></html>

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -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
}

View File

@ -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);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -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);

View 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);

File diff suppressed because one or more lines are too long

View File

@ -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);

View File

@ -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);

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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: '&laquo;',
previousText: '&lsaquo;',
nextText: '&rsaquo;',
lastText: '&raquo;',
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);

View 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="&laquo;" - The string used for the 'first' button.
* @prop {string} strings.prev="&lsaquo;" - The string used for the 'previous' button.
* @prop {string} strings.next="&rsaquo;" - The string used for the 'next' button.
* @prop {string} strings.last="&raquo;" - 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: '&laquo;',
prev: '&lsaquo;',
next: '&rsaquo;',
last: '&raquo;',
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);

File diff suppressed because one or more lines are too long

View File

@ -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);

View File

@ -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);

View 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);

View 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);

View File

@ -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);