├── jquery.fulltable.eot ├── jquery.fulltable.ttf ├── jquery.fulltable.woff ├── jquery.fulltable.woff2 ├── resources ├── jquery.fulltable.ttf ├── save.svg ├── edit.svg ├── remove.svg ├── add.svg ├── discard.svg ├── down_arrow.svg ├── left_arrow.svg ├── right_arrow.svg ├── up_arrow.svg └── jquery.fulltable.sfd ├── LICENSE ├── README.md ├── jquery.fulltable.svg ├── jquery.fulltable.css ├── jquery.fulltable.html └── jquery.fulltable.js /jquery.fulltable.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseluisballesterosdelval/jquery-fulltable/HEAD/jquery.fulltable.eot -------------------------------------------------------------------------------- /jquery.fulltable.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseluisballesterosdelval/jquery-fulltable/HEAD/jquery.fulltable.ttf -------------------------------------------------------------------------------- /jquery.fulltable.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseluisballesterosdelval/jquery-fulltable/HEAD/jquery.fulltable.woff -------------------------------------------------------------------------------- /jquery.fulltable.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseluisballesterosdelval/jquery-fulltable/HEAD/jquery.fulltable.woff2 -------------------------------------------------------------------------------- /resources/jquery.fulltable.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joseluisballesterosdelval/jquery-fulltable/HEAD/resources/jquery.fulltable.ttf -------------------------------------------------------------------------------- /resources/save.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 joseluisballesterosdelval 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /resources/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /resources/remove.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jquery-fulltable 2 | 3 | This plugin defines a function of JQuery API called FullTable, which enables both initializate and operate any table, rendering, in addition, all the DOMs needed to be controlled by user. 4 | 5 | ## Installation 6 | 7 | This requires jQuery 1.7.2+. Really, it has not been tested yet for older versions. Once the javascript code and stylesheet has been included in the page, and so as to initializate any table as FullTable, and supposing that this table can be queried by "#fulltable-test" selector, it is only needed to invoke: 8 | 9 | $("#fulltable-test").FullTable(); 10 | 11 | It should be noted that all class names and data keys used by this plugin starts by "fulltable-", so is highly recommended to avoid this kind of names in the environment where the plugin is running. 12 | 13 | :warning: **Pending of completion** 14 | 15 | ## How to Contribute 16 | 17 | Contributors are welcome! And we need your contributions to keep the project moving forward. You can [report bugs](https://github.com/joseluisballesterosdelval/jquery-fulltable/issues), improve the documentation, or [contribute code](https://github.com/joseluisballesterosdelval/jquery-fulltable/pulls). 18 | 19 | :warning: **Found an issue?** File it on [issue tracker](https://github.com/joseluisballesterosdelval/jquery-fulltable/issues). 20 | 21 | **Have a solution?** Send a [Pull Request](https://github.com/joseluisballesterosdelval/jquery-fulltable/pulls). 22 | 23 | **And don't forget to test and document your code.** 24 | 25 | 26 | -------------------------------------------------------------------------------- /resources/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /resources/discard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /resources/down_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 56 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /resources/left_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 56 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /resources/right_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 56 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /resources/up_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 56 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /jquery.fulltable.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /jquery.fulltable.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'jquery.fulltable'; 3 | src: url('jquery.fulltable.eot'); 4 | src: url('jquery.fulltable.eot?#iefix') format('embedded-opentype'), 5 | url('jquery.fulltable.woff2') format('woff2'), 6 | url('jquery.fulltable.woff') format('woff'), 7 | url('jquery.fulltable.ttf') format('truetype'), 8 | url('jquery.fulltable.svg#jquery.fulltable') format('svg'); 9 | font-weight: normal; 10 | font-style: normal; 11 | } 12 | table.fulltable thead th { 13 | vertical-align: top; 14 | } 15 | table.fulltable span.fulltable-filter { 16 | position: relative; 17 | display: inline-block; 18 | overflow: hidden; 19 | box-sizing: border-box; 20 | padding: 0; 21 | } 22 | table.fulltable input, table.fulltable select { 23 | position:relative; 24 | 25 | width:100%!important; 26 | 27 | font-family: tahoma, arial, helvetica; 28 | font-size: 9pt; 29 | 30 | clear: both; 31 | float: left; 32 | margin: 6pt 0 !important; 33 | } 34 | table.fulltable input.checkbox { 35 | width: 13px!important; 36 | height: 13px!important; 37 | } 38 | table.fulltable th.fulltable-selection-control { 39 | width: 30px; 40 | } 41 | /*table.fulltable tr.fulltable-editing td.fulltable-selection-control input.checkbox { 42 | display:none; 43 | }*/ 44 | table.fulltable th.fulltable-selection-control, table.fulltable td.fulltable-selection-control { 45 | padding: 0 1em; 46 | width: 30px; 47 | } 48 | table.fulltable.fulltable-editable th.fulltable-edition-control { 49 | width: 70px; 50 | } 51 | table.fulltable.fulltable-editable th.fulltable-edition-control, table.fulltable.fulltable-editable td.fulltable-edition-control { 52 | padding: 0 1em; 53 | } 54 | table.fulltable.fulltable-editable input.invalid, table.fulltable.fulltable-editable select.invalid { 55 | border: solid 1px #FF3333; 56 | background-color:#FFEEEE; 57 | } 58 | table.fulltable thead th a.fulltable-sort { 59 | font-family: 'jquery.fulltable'; 60 | font-size: 9px; 61 | position: relative; 62 | left: 6px; 63 | top: 0px; 64 | display: inline-block; 65 | width: 9px; 66 | height: 9px; 67 | cursor: pointer; 68 | } 69 | table.fulltable thead th.fulltable-asc a.fulltable-sort-desc { 70 | display:none!important; 71 | } 72 | table.fulltable thead th.fulltable-desc a.fulltable-sort-asc { 73 | display:none!important; 74 | } 75 | table.fulltable.fulltable-editable td.fulltable-edition-control { 76 | white-space:nowrap; 77 | } 78 | table.fulltable.fulltable-editable td.fulltable-edition-control a { 79 | font-family:'jquery.fulltable'; 80 | font-size:16px; 81 | position:relative; 82 | display: inline-block; 83 | width:16px; 84 | height:16px; 85 | top:1px; 86 | line-height:16px; 87 | margin:0.5em; 88 | cursor:pointer; 89 | text-align:center; 90 | } 91 | table.fulltable.fulltable-editable td.fulltable-edition-control a.fulltable-create { 92 | display:none; 93 | } 94 | table.fulltable.fulltable-editable tr.fulltable-creating td.fulltable-edition-control a.fulltable-create { 95 | display:inline-block!important; 96 | } 97 | table.fulltable.fulltable-editable tr.fulltable-creating td.fulltable-edition-control a.fulltable-save { 98 | display:none!important; 99 | } 100 | table.fulltable.fulltable-editable tr.fulltable-editing td.fulltable-edition-control a.fulltable-edit, table.fulltable.fulltable-editable tr.fulltable-editing td.fulltable-edition-control a.fulltable-remove { 101 | display:none; 102 | } 103 | table.fulltable.fulltable-editable tr td.fulltable-edition-control a.fulltable-save, table.fulltable.fulltable-editable tr td.fulltable-edition-control a.fulltable-discard { 104 | display:none; 105 | } 106 | table.fulltable.fulltable-editable tr.fulltable-editing td.fulltable-edition-control a.fulltable-save, table.fulltable.fulltable-editable tr.fulltable-editing td.fulltable-edition-control a.fulltable-discard { 107 | display:inline-block; 108 | } -------------------------------------------------------------------------------- /jquery.fulltable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | jQuery FullTable Plugin Demonstration 4 | 5 | 6 | 7 | 8 | 49 | 50 | 139 | 140 | 141 | + Add row 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 |
First nameLast nameGenderAgeHeightDescription
JohnSmithxy231.72Famous explorer
PeterPanxy101.60Flyer boy who does not grow
MaryStevensonxx351.69Unknown woman
159 | > Get value 160 | 161 | -------------------------------------------------------------------------------- /resources/jquery.fulltable.sfd: -------------------------------------------------------------------------------- 1 | SplineFontDB: 3.0 2 | FontName: Untitled1 3 | FullName: Untitled1 4 | FamilyName: Untitled1 5 | Weight: Regular 6 | Copyright: Copyright (c) 2017, José Luis Ballesteros del Val,,, 7 | UComments: "2017-9-19: Created with FontForge (http://fontforge.org)" 8 | Version: 001.000 9 | ItalicAngle: 0 10 | UnderlinePosition: -100 11 | UnderlineWidth: 50 12 | Ascent: 800 13 | Descent: 200 14 | InvalidEm: 0 15 | LayerCount: 2 16 | Layer: 0 0 "Atr+AOEA-s" 1 17 | Layer: 1 0 "Fore" 0 18 | XUID: [1021 853 1694048007 10364579] 19 | StyleMap: 0x0000 20 | FSType: 0 21 | OS2Version: 0 22 | OS2_WeightWidthSlopeOnly: 0 23 | OS2_UseTypoMetrics: 1 24 | CreationTime: 1505799132 25 | ModificationTime: 1507531202 26 | OS2TypoAscent: 0 27 | OS2TypoAOffset: 1 28 | OS2TypoDescent: 0 29 | OS2TypoDOffset: 1 30 | OS2TypoLinegap: 90 31 | OS2WinAscent: 0 32 | OS2WinAOffset: 1 33 | OS2WinDescent: 0 34 | OS2WinDOffset: 1 35 | HheadAscent: 0 36 | HheadAOffset: 1 37 | HheadDescent: 0 38 | HheadDOffset: 1 39 | DEI: 91125 40 | Encoding: ISO8859-1 41 | UnicodeInterp: none 42 | NameList: AGL For New Fonts 43 | DisplaySize: -48 44 | AntiAlias: 1 45 | FitToEm: 0 46 | WinInfo: 0 26 10 47 | BeginChars: 256 9 48 | 49 | StartChar: A 50 | Encoding: 65 65 0 51 | Width: 1000 52 | VWidth: 0 53 | LayerCount: 2 54 | Fore 55 | SplineSet 56 | 1000 -35.0771484375 m 5 57 | 500 -35.1318359375 l 5 58 | 0 -35.185546875 l 5 59 | 249.952148438 397.853515625 l 5 60 | 499.905273438 830.893554688 l 5 61 | 749.952148438 397.908203125 l 5 62 | 1000 -35.0771484375 l 5 63 | EndSplineSet 64 | EndChar 65 | 66 | StartChar: B 67 | Encoding: 66 66 1 68 | Width: 1000 69 | VWidth: 0 70 | Flags: W 71 | LayerCount: 2 72 | Fore 73 | SplineSet 74 | 67.068359375 -102.146484375 m 5 75 | 67.013671875 397.853515625 l 5 76 | 66.9609375 897.853515625 l 5 77 | 500 647.90234375 l 5 78 | 933.0390625 397.94921875 l 5 79 | 500.0546875 147.90234375 l 5 80 | 67.068359375 -102.146484375 l 5 81 | EndSplineSet 82 | EndChar 83 | 84 | StartChar: C 85 | Encoding: 67 67 2 86 | Width: 1000 87 | VWidth: 0 88 | Flags: W 89 | LayerCount: 2 90 | Fore 91 | SplineSet 92 | 0 830.78515625 m 5 93 | 500 830.83984375 l 5 94 | 1000 830.893554688 l 5 95 | 750.047851562 397.854492188 l 5 96 | 500.094726562 -35.185546875 l 5 97 | 250.047851562 397.799804688 l 5 98 | 0 830.78515625 l 5 99 | EndSplineSet 100 | EndChar 101 | 102 | StartChar: D 103 | Encoding: 68 68 3 104 | Width: 1000 105 | VWidth: 0 106 | Flags: W 107 | LayerCount: 2 108 | Fore 109 | SplineSet 110 | 932.931640625 897.853515625 m 5 111 | 932.986328125 397.853515625 l 5 112 | 933.0390625 -102.146484375 l 5 113 | 500 147.806640625 l 5 114 | 66.9609375 397.759765625 l 5 115 | 499.9453125 647.806640625 l 5 116 | 932.931640625 897.853515625 l 5 117 | EndSplineSet 118 | EndChar 119 | 120 | StartChar: E 121 | Encoding: 69 69 4 122 | Width: 1000 123 | VWidth: 0 124 | LayerCount: 2 125 | Fore 126 | SplineSet 127 | 621.825195312 685.489257812 m 5 128 | 825.247070312 482.069335938 l 5 129 | 310.328125 -32.849609375 l 5 130 | 107.021484375 170.571289062 l 5 131 | 621.825195312 685.489257812 l 5 132 | 979.60546875 734.549804688 m 6 133 | 1006.79785156 707.357421875 1006.79785156 663.50390625 979.60546875 636.309570312 c 6 134 | 878.2421875 534.946289062 l 5 135 | 674.819335938 738.369140625 l 5 136 | 761.71875 825.268554688 l 6 137 | 796.897460938 860.328125 853.827148438 860.328125 888.88671875 825.268554688 c 6 138 | 979.60546875 734.549804688 l 6 139 | 0.56640625 -115.353515625 m 6 140 | 51.9423828125 115.490234375 l 5 141 | 255.25 -87.9306640625 l 5 142 | 28.5693359375 -142.891601562 l 6 143 | 11.9072265625 -146.943359375 -3.1357421875 -132.014648438 0.56640625 -115.353515625 c 6 144 | EndSplineSet 145 | EndChar 146 | 147 | StartChar: F 148 | Encoding: 70 70 5 149 | Width: 1000 150 | VWidth: 0 151 | LayerCount: 2 152 | Fore 153 | SplineSet 154 | 632.5625 593 m 5 155 | 720.9375 504.5625 l 5 156 | 588.375976562 372 l 5 157 | 720.9375 239.4375 l 5 158 | 632.5625 151.0625 l 5 159 | 500 283.624023438 l 5 160 | 367.4375 151.0625 l 5 161 | 279.063476562 239.4375 l 5 162 | 411.625976562 372 l 5 163 | 279 504.5625 l 5 164 | 367.4375 593 l 5 165 | 500 460.374023438 l 5 166 | 632.5625 593 l 5 167 | 853.5625 725.5625 m 4 168 | 1048.8125 530.3125 1048.8125 213.686523438 853.5625 18.4375 c 4 169 | 658.3125 -176.8125 341.6875 -176.8125 146.4375 18.4375 c 4 170 | -48.8125 213.6875 -48.8125 530.3125 146.4375 725.5625 c 4 171 | 341.6875 920.8125 658.3125 920.8125 853.5625 725.5625 c 4 172 | 765.1875 106.8125 m 4 173 | 911.624023438 253.3125 911.624023438 490.6875 765.1875 637.124023438 c 4 174 | 618.75 783.5625 381.313476562 783.5625 234.875976562 637.124023438 c 4 175 | 88.4375 490.6875 88.4375 253.25 234.875976562 106.8125 c 4 176 | 381.3125 -39.6240234375 618.75 -39.6240234375 765.1875 106.8125 c 4 177 | EndSplineSet 178 | EndChar 179 | 180 | StartChar: G 181 | Encoding: 71 71 6 182 | Width: 1000 183 | VWidth: 0 184 | HStem: -146 621.253<225.886 766.758> 185 | VStem: 0 225.886<475.253 835.183> 539.101 145.096<548.959 854> 766.758 233.242<475.253 641.575> 186 | LayerCount: 2 187 | Fore 188 | SplineSet 189 | 68.1201171875 -146 m 6 190 | 30.517578125 -146 0 -115.482421875 0 -77.8798828125 c 6 191 | 0 146.916015625 l 5 192 | 0 785.879882812 l 6 193 | 0 823.482421875 30.517578125 854 68.1201171875 854 c 6 194 | 225.885742188 854 l 5 195 | 225.885742188 475.252929688 l 5 196 | 766.7578125 475.252929688 l 5 197 | 766.7578125 854 l 5 198 | 767.030273438 854 l 5 199 | 970.02734375 651.002929688 l 6 200 | 989.237304688 631.928710938 1000 605.907226562 1000 578.795898438 c 6 201 | 1000 -77.8798828125 l 6 202 | 1000 -115.482421875 969.482421875 -146 931.879882812 -146 c 6 203 | 68.1201171875 -146 l 6 204 | 539.100585938 548.958984375 m 5 205 | 539.100585938 854 l 5 206 | 684.196289062 854 l 5 207 | 684.196289062 548.958984375 l 5 208 | 539.100585938 548.958984375 l 5 209 | EndSplineSet 210 | EndChar 211 | 212 | StartChar: H 213 | Encoding: 72 72 7 214 | Width: 837 215 | VWidth: 0 216 | HStem: -63.1943 147.91<320.356 541.906> 676.384 147.906<319.754 541.906> 217 | VStem: 727.343 147.906<271.044 490.059> 218 | LayerCount: 2 219 | Fore 220 | SplineSet 221 | 840.015625 552.7265625 m 0 222 | 863.504882812 498.026367188 875.250976562 440.654296875 875.249023438 380.551757812 c 0 223 | 875.249023438 320.470703125 863.510742188 263.067382812 840.012695312 208.369140625 c 0 224 | 816.514648438 153.669921875 784.931640625 106.4921875 745.255859375 66.8076171875 c 0 225 | 705.571289062 27.1396484375 658.399414062 -4.4580078125 603.694335938 -27.9482421875 c 0 226 | 548.99609375 -51.439453125 491.609375 -63.1943359375 431.514648438 -63.1943359375 c 0 227 | 365.262695312 -63.1943359375 302.27734375 -49.2236328125 242.571289062 -21.2998046875 c 0 228 | 182.865234375 6.619140625 132.024414062 46.0048828125 90.0322265625 96.8525390625 c 0 229 | 87.3388671875 100.704101562 86.08203125 105.032226562 86.2724609375 109.859375 c 0 230 | 86.466796875 114.666015625 88.1044921875 118.608398438 91.181640625 121.704101562 c 2 231 | 170.33984375 201.4453125 l 2 232 | 174.19140625 204.908203125 179.0078125 206.637695312 184.788085938 206.637695312 c 0 233 | 190.953125 205.86328125 195.383789062 203.548828125 198.078125 199.69921875 c 0 234 | 226.19921875 163.088867188 260.673828125 134.778320312 301.500976562 114.754882812 c 0 235 | 342.334960938 94.7314453125 385.670898438 84.7158203125 431.51171875 84.7158203125 c 0 236 | 471.567382812 84.7158203125 509.8046875 92.515625 546.20703125 108.112304688 c 0 237 | 582.602539062 123.709960938 614.091796875 144.805664062 640.674804688 171.385742188 c 0 238 | 667.254882812 197.96875 688.344726562 229.452148438 703.948242188 265.854492188 c 0 239 | 719.540039062 302.25390625 727.342773438 340.479492188 727.342773438 380.545898438 c 0 240 | 727.342773438 420.615234375 719.537109375 458.83984375 703.948242188 495.2421875 c 0 241 | 688.344726562 531.647460938 667.254882812 563.134765625 640.674804688 589.709960938 c 0 242 | 614.091796875 616.290039062 582.614257812 637.379882812 546.20703125 652.983398438 c 0 243 | 509.8046875 668.577148438 471.567382812 676.383789062 431.51171875 676.383789062 c 0 244 | 393.759765625 676.383789062 357.553710938 669.541015625 322.884765625 655.866210938 c 0 245 | 288.216796875 642.190429688 257.405273438 622.642578125 230.432617188 597.217773438 c 1 246 | 309.592773438 517.485351562 l 2 247 | 321.537109375 505.922851562 324.23046875 492.63671875 317.685546875 477.614257812 c 0 248 | 311.13671875 462.205078125 299.774414062 454.500976562 283.592773438 454.500976562 c 2 249 | 24.7373046875 454.500976562 l 2 250 | 14.7236328125 454.500976562 6.0556640625 458.162109375 -1.267578125 465.482421875 c 0 251 | -8.587890625 472.799804688 -12.2490234375 481.467773438 -12.2490234375 491.481445312 c 2 252 | -12.2490234375 750.336914062 l 2 253 | -12.2490234375 766.512695312 -4.5439453125 777.880859375 10.8662109375 784.4375 c 0 254 | 25.8955078125 790.98046875 39.1787109375 788.287109375 50.7373046875 776.344726562 c 2 255 | 125.859375 701.798828125 l 1 256 | 167.078125 740.708007812 214.168945312 770.84765625 267.129882812 792.2265625 c 0 257 | 320.102539062 813.610351562 374.89453125 824.290039062 431.514648438 824.290039062 c 0 258 | 491.609375 824.290039062 548.99609375 812.547851562 603.694335938 789.045898438 c 0 259 | 658.399414062 765.543945312 705.584960938 733.9609375 745.263671875 694.288085938 c 0 260 | 784.93359375 654.618164062 816.522460938 607.430664062 840.015625 552.7265625 c 0 261 | EndSplineSet 262 | EndChar 263 | 264 | StartChar: I 265 | Encoding: 73 73 8 266 | Width: 1000 267 | VWidth: 0 268 | HStem: -105 21G<422.343 577.646> 258.64 272.718<20.5084 363.631 636.359 979.49> 875 20G<422.347 577.645> 269 | VStem: 363.631 272.729<-84.5081 258.64 531.36 874.493> 270 | LayerCount: 2 271 | Fore 272 | SplineSet 273 | 980.115234375 511.474609375 m 4 274 | 993.37890625 498.22265625 999.994140625 482.125976562 999.998046875 463.1796875 c 6 275 | 999.998046875 326.8125 l 6 276 | 999.998046875 307.862304688 993.369140625 291.772460938 980.11328125 278.525390625 c 4 277 | 966.859375 265.26171875 950.76171875 258.639648438 931.810546875 258.639648438 c 6 278 | 636.359375 258.639648438 l 5 279 | 636.359375 -36.830078125 l 6 280 | 636.359375 -55.7626953125 629.736328125 -71.8701171875 616.47265625 -85.1318359375 c 4 281 | 603.212890625 -98.3779296875 587.119140625 -105 568.171875 -105 c 6 282 | 431.810546875 -105 l 6 283 | 412.875 -105 396.775390625 -98.3779296875 383.517578125 -85.1318359375 c 4 284 | 370.2578125 -71.8779296875 363.630859375 -55.7626953125 363.630859375 -36.830078125 c 6 285 | 363.630859375 258.639648438 l 5 286 | 68.17578125 258.639648438 l 6 287 | 49.244140625 258.639648438 33.140625 265.26171875 19.8828125 278.525390625 c 4 288 | 6.623046875 291.772460938 0.001953125 307.862304688 0.001953125 326.8125 c 6 289 | 0.001953125 463.1796875 l 6 290 | 0.001953125 482.125976562 6.625 498.212890625 19.884765625 511.471679688 c 4 291 | 33.14453125 524.73046875 49.24609375 531.357421875 68.1796875 531.357421875 c 6 292 | 363.6328125 531.357421875 l 5 293 | 363.6328125 826.822265625 l 6 294 | 363.6328125 845.755859375 370.259765625 861.857421875 383.51953125 875.116210938 c 4 295 | 396.779296875 888.375976562 412.87890625 895 431.814453125 895 c 6 296 | 568.1640625 895 l 6 297 | 587.125 895 603.21484375 888.368164062 616.470703125 875.119140625 c 4 298 | 629.724609375 861.860351562 636.357421875 845.7578125 636.357421875 826.825195312 c 6 299 | 636.357421875 531.360351562 l 5 300 | 931.814453125 531.360351562 l 6 301 | 950.74609375 531.360351562 966.853515625 524.733398438 980.115234375 511.474609375 c 4 302 | EndSplineSet 303 | EndChar 304 | EndChars 305 | EndSplineFont 306 | -------------------------------------------------------------------------------- /jquery.fulltable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description Inline editor for HTML tables compatible with Bootstrap 3 | * @version 1.0.0 4 | * @author José Luis Ballesteros del Val 5 | */ 6 | 7 | if (typeof jQuery === 'undefined') { 8 | throw new Error('FullTable requires jQuery library.'); 9 | } 10 | 11 | if (typeof Array.isArray != "function") { 12 | Array.isArray = function(obj) { 13 | if (typeof obj != "object") return false; 14 | if (typeof obj.length == "undefined") return false; 15 | for (var i in obj) { 16 | if (!obj.hasOwnProperty(i)) continue; 17 | if (isNaN(i)) return false; 18 | } 19 | return true; 20 | }; 21 | } 22 | 23 | (function($) { 24 | 'use strict'; 25 | 26 | $.fn.FullTable = function() { 27 | 28 | if (!this.is('table')) { 29 | return this; 30 | } 31 | 32 | var table = $(this); 33 | 34 | table.getKeys = function() { 35 | if ($(table).data('fulltable-keys') == null) $(table).data('fulltable-keys', []); 36 | return $(table).data('fulltable-keys'); 37 | }; 38 | table.setKeys = function(val) { 39 | $(table).data('fulltable-keys', val); 40 | }; 41 | 42 | table.getRows = function() { 43 | if ($(table).data('fulltable-rows') == null) $(table).data('fulltable-rows', []); 44 | return $(table).data('fulltable-rows'); 45 | }; 46 | table.setRows = function(val) { 47 | $(table).data('fulltable-rows', val); 48 | }; 49 | 50 | table.getSorting = function() { 51 | if ($(table).data('fulltable-sorting') == null) $(table).data('fulltable-sorting', []); 52 | return $(table).data('fulltable-sorting'); 53 | }; 54 | table.setSorting = function(val) { 55 | $(table).data('fulltable-sorting', val); 56 | }; 57 | 58 | table.getEvents = function() { 59 | if ($(table).data('fulltable-events') == null) $(table).data('fulltable-events', {}); 60 | return $(table).data('fulltable-events'); 61 | }; 62 | table.setEvents = function(val) { 63 | $(table).data('fulltable-events', val); 64 | }; 65 | 66 | var types = { 67 | "integer":["integer", "number"], 68 | "decimal":["decimal", "float", "double"], 69 | "string":["string", "literal"] 70 | }; 71 | 72 | var on = function() { 73 | return methods['on'].apply(this, arguments); 74 | }; 75 | 76 | var clean = function() { 77 | return methods['clean'].apply(this, arguments); 78 | }; 79 | 80 | var changeSettings = function() { 81 | return methods['changeSettings'].apply(this, arguments); 82 | }; 83 | 84 | var drawHeader = function() { 85 | return methods['drawHeader'].apply(this, arguments); 86 | }; 87 | 88 | var drawBody = function() { 89 | return methods['drawBody'].apply(this, arguments); 90 | }; 91 | 92 | var draw = function() { 93 | return methods['draw'].apply(this, arguments); 94 | }; 95 | 96 | var filter = function() { 97 | return methods['filter'].apply(this, arguments); 98 | }; 99 | 100 | var order = function() { 101 | return methods['order'].apply(this, arguments); 102 | }; 103 | 104 | var validateRow = function() { 105 | return methods['validateRow'].apply(this, arguments); 106 | }; 107 | 108 | var addRow = function() { 109 | return methods['addRow'].apply(this, arguments); 110 | }; 111 | 112 | var editRow = function() { 113 | return methods['editRow'].apply(this, arguments); 114 | }; 115 | 116 | var removeRow = function() { 117 | return methods['removeRow'].apply(this, arguments); 118 | }; 119 | 120 | var saveRow = function() { 121 | return methods['saveRow'].apply(this, arguments); 122 | }; 123 | 124 | var discardRow = function() { 125 | return methods['discardRow'].apply(this, arguments); 126 | }; 127 | 128 | var checkRow = function() { 129 | return methods['checkRow'].apply(this, arguments); 130 | }; 131 | 132 | var addSortItem = function(fieldName, fieldSort) { 133 | var removing_indexes = []; 134 | for (var index in table.getSorting()) { 135 | if (!table.getSorting().hasOwnProperty(index)) continue; 136 | var sortingItem = table.getSorting()[index]; 137 | if (sortingItem.name == fieldName) { 138 | removing_indexes.push(index); 139 | } 140 | } 141 | removing_indexes = removing_indexes.reverse(); 142 | for (var index in removing_indexes) { 143 | if (!removing_indexes.hasOwnProperty(index)) continue; 144 | index = removing_indexes[index]; 145 | table.getSorting().splice(index, 1); 146 | } 147 | table.getSorting().push({ 148 | name: fieldName, 149 | sort: fieldSort 150 | }); 151 | } 152 | 153 | var getHeaderFromDom = function() { 154 | // Init headers and field names. 155 | $(table).find("thead th").each(function(th_index, th) { 156 | var fieldName = $(th).attr("fulltable-field-name"); 157 | if (fieldName == null) { 158 | fieldName = (new Date()).getTime()+""+(Math.floor(Math.random()*1e8)); 159 | $(th).attr("fulltable-field-name", fieldName); 160 | } 161 | table.getKeys()[th_index] = fieldName; 162 | }); 163 | }; 164 | 165 | var drawRow = function(data, tr) { 166 | if (typeof data != "object") data = null; 167 | if (tr == null) { 168 | tr = $(""); 169 | for (var key in table.getKeys()) { 170 | if (!table.getKeys().hasOwnProperty(key)) continue; 171 | key = table.getKeys()[key]; 172 | var td = $(""); 173 | $(td).attr("fulltable-field-name", key); 174 | $(tr).append($(td)); 175 | } 176 | } 177 | var row = {}; 178 | $(tr).children("td").each(function(td_index, td) { 179 | var key = table.getKeys()[td_index]; 180 | if (key != null) $(td).attr("fulltable-field-name", key); 181 | var value; 182 | if (data == null) { 183 | value = $(td).html(); 184 | } else { 185 | value = data[key]; 186 | } 187 | var text = value; 188 | var fieldData = options.fields[key]; 189 | if (fieldData == null) fieldData = {}; 190 | // TODO: Here must be validation of input type: select, checkbox, if (fieldData.options == "boolean") 191 | if (fieldData.options != null) { 192 | text = ""; 193 | var found = false; 194 | for (var option in fieldData.options) { 195 | if (!fieldData.options.hasOwnProperty(option)) continue; 196 | option = fieldData.options[option]; 197 | if (option.value == value) { 198 | text = option.title; 199 | found = true; 200 | break; 201 | } 202 | } 203 | if (!found) value = null; 204 | } 205 | row[key] = value; 206 | $(td).html(text); 207 | }); 208 | row["__dom"] = $(tr); 209 | row["__filtered"] = false; 210 | addSelectionControl(row, "body"); 211 | addEditionControl(row, "body"); 212 | return row; 213 | }; 214 | 215 | var getBodyFromDom = function() { 216 | $(table).find("tbody tr").each(function(tr_index, tr) { 217 | table.getRows()[tr_index] = drawRow(null, tr); 218 | }); 219 | }; 220 | 221 | var addEditionControl = function(row, type) { 222 | if (!options.editable) return; 223 | if (typeof row != "object") return; 224 | var tr = row["__dom"]; 225 | if (!$(tr).is("tr")) return; 226 | if ($(tr).find(".fulltable-edition-control").length > 0) return; 227 | var edition_control = null; 228 | if ($(tr).parent().is("thead") || type == "head") { 229 | edition_control = $("", { 230 | 'class':"fulltable-edition-control" 231 | }); 232 | } 233 | if ($(tr).parent().is("tbody") || type == "body") { 234 | edition_control = $("", { 235 | 'class':"fulltable-edition-control" 236 | }); 237 | edition_control.append($("", { 238 | 'class':"fulltable-edit", 239 | 'text':"E" 240 | }).click(function() { 241 | editRow(row); 242 | })); 243 | edition_control.append($("", { 244 | 'class':"fulltable-remove", 245 | 'text':"F" 246 | }).click(function() { 247 | removeRow(row); 248 | })); 249 | edition_control.append($("", { 250 | 'class':"fulltable-save", 251 | 'text':"G" 252 | }).click(function() { 253 | saveRow(row); 254 | })); 255 | edition_control.append($("", { 256 | 'class':"fulltable-create", 257 | 'text':"I" 258 | }).click(function() { 259 | saveRow(row); 260 | })); 261 | edition_control.append($("", { 262 | 'class':"fulltable-discard", 263 | 'text':"H" 264 | }).click(function() { 265 | discardRow(row); 266 | })); 267 | } 268 | $(tr).append($(edition_control)); 269 | }; 270 | 271 | var addSelectionControl = function(row, type) { 272 | if (!options.selectable) return; 273 | if (typeof row != "object") return; 274 | var tr = row["__dom"]; 275 | if (!$(tr).is("tr")) return; 276 | if ($(tr).find(".fulltable-selection-control").length > 0) return; 277 | var selection_control = null; 278 | if ($(tr).parent().is("thead") || type == "head") { 279 | selection_control = $("", { 280 | 'class':"fulltable-selection-control" 281 | }); 282 | } 283 | if ($(tr).parent().is("tbody") || type == "body") { 284 | selection_control = $("", { 285 | 'class':"fulltable-selection-control" 286 | }); 287 | selection_control.append($("", { 288 | 'type':"checkbox", 289 | 'class':"checkbox", 290 | 'value':row["__selected"] 291 | }).change(function() { 292 | checkRow(row); 293 | })); 294 | } 295 | $(tr).prepend($(selection_control)); 296 | }; 297 | 298 | var showRowForm = function(row) { 299 | for (var fieldName in row) { 300 | if (!row.hasOwnProperty(fieldName)) continue; 301 | if (fieldName.indexOf("__") == 0) continue; 302 | var value = row[fieldName]; 303 | if (value == "") value = null; 304 | var td = $(row["__dom"]).find("td[fulltable-field-name='" + fieldName + "']"); 305 | $(td).empty(); 306 | var fieldData = options.fields[fieldName]; 307 | if (fieldData == null) fieldData = {}; 308 | var input; 309 | // TODO: Here must be validation of input type: select, checkbox, if (fieldData.options == "boolean") 310 | if (fieldData.options != null) { 311 | input = $("", { 332 | 'type':"text", 333 | 'placeholder':fieldData.placeholder, 334 | 'disabled':fieldData.disabled 335 | }); 336 | } 337 | if (value != null) $(input).val(value); 338 | $(input).change(function(event) { 339 | $(event.target).removeClass("invalid"); 340 | }); 341 | $(input).keyup(function(event) { 342 | $(event.target).removeClass("invalid"); 343 | }); 344 | $(td).append($(input)); 345 | } 346 | $(row["__dom"]).addClass("fulltable-editing"); 347 | }; 348 | 349 | var methods = { 350 | 'on':function(eventName, eventHandler) { 351 | if (typeof eventName != "string" || typeof eventHandler != "function") return; 352 | if (eventName != "on" && methods[eventName] != null) { 353 | table.getEvents()[eventName] = function() { 354 | eventHandler.apply(this, arguments); 355 | }; 356 | } 357 | }, 358 | 'clean':function() { 359 | $(table).find(".fulltable-edition-control, .fulltable-sort, .fulltable-filter").remove(); 360 | $(table).removeClass(function (index, className) { 361 | return (className.match("/(^|\s)fulltable-\S+/g") || []).join(' '); 362 | }); 363 | $(table).find("*").removeClass(function (index, className) { 364 | return (className.match("/(^|\s)fultablle-\S+/g") || []).join(' '); 365 | }); 366 | var dataKeys = ["fulltable-creating", "fulltable-editing"]; 367 | for (var dataKey in dataKeys) { 368 | if (!dataKeys.hasOwnProperty(dataKey)) continue; 369 | $(table).removeData(dataKey); 370 | $(table).find("*").removeData(dataKey); 371 | } 372 | $(table).removeData('fulltable'); 373 | if (typeof table.getEvents().clean == "function") table.getEvents().clean(); 374 | }, 375 | 'changeSettings':function(newOptionsPart) { 376 | if (typeof newOptionsPart != "object") return this; 377 | for (var key in options) { 378 | if (!options.hasOwnProperty(key)) continue; 379 | if (newOptionsPart[key] == null) continue; 380 | if (key == "fields") { 381 | var fields = options["fields"] 382 | var newFields = newOptionsPart["fields"]; 383 | if (typeof newFields != "object") continue; 384 | for (var newFieldName in newFields) { 385 | if (!newFields.hasOwnProperty(newFieldName)) continue; 386 | var newField = newFields[newFieldName]; 387 | if (fields[newFieldName] == null) { 388 | fields[newFieldName] = newField; 389 | continue; 390 | } 391 | for (var key in newField) { 392 | if (!newField.hasOwnProperty(key)) continue; 393 | fields[newFieldName][key] = newFields[newFieldName][key]; 394 | } 395 | } 396 | continue; 397 | } 398 | options[key] = newOptionsPart[key]; 399 | } 400 | draw(); 401 | if (typeof table.getEvents().changeSettings == "function") table.getEvents().changeSettings(newOptionsPart, options); 402 | return this; 403 | }, 404 | 'draw':function() { 405 | drawHeader(); 406 | drawBody(); 407 | return this; 408 | }, 409 | 'drawHeader':function() { 410 | // Drawing of header 411 | $(table).find("thead th:not(.fulltable-edition-control):not(.fulltable-selection-control)").each(function(th_index, th) { 412 | var fieldName = $(th).attr("fulltable-field-name"); 413 | var apply_order = function(reverse) { 414 | var fieldSort = 0; 415 | if ($(th).hasClass("fulltable-asc")) { 416 | fieldSort = 1; 417 | } else if ($(th).hasClass("fulltable-desc")) { 418 | fieldSort = -1; 419 | } 420 | if (reverse) fieldSort = -fieldSort; 421 | addSortItem(fieldName, fieldSort); 422 | }; 423 | apply_order(false); 424 | 425 | // Insertion of ordenation button. 426 | $(th).children("a.fulltable-sort").remove(); 427 | if (options.orderable) { 428 | var fieldData = options.fields[fieldName]; 429 | if (fieldData == null) fieldData = {}; 430 | if (fieldData.orderable == null || fieldData.orderable == true) { 431 | var sortElement = $("").addClass("fulltable-sort").addClass("fulltable-sort-asc").html("A"); 432 | $(sortElement).click(function(event) { 433 | apply_order(true); 434 | order(); 435 | }); 436 | $(th).append(sortElement); 437 | var sortElement = $("").addClass("fulltable-sort").addClass("fulltable-sort-desc").html("C"); 438 | $(sortElement).click(function(event) { 439 | apply_order(true); 440 | order(); 441 | }); 442 | $(th).append(sortElement); 443 | } 444 | } 445 | // Insertion of filtering fields. 446 | $(th).children("span.fulltable-filter, input.fulltable-filter, select.fulltable-filter").remove(); 447 | if (options.filterable) { 448 | var fieldData = options.fields[fieldName]; 449 | if (fieldData == null) fieldData = {}; 450 | if (fieldData.filterable == null || fieldData.filterable == true) { 451 | var filterFieldElement; 452 | // TODO: Here must be validation of input type: select, checkbox, if (fieldData.options == "boolean") 453 | if (fieldData.options != null) { 454 | filterFieldElement = $("", { 474 | 'class':"fulltable-filter", 475 | 'type':"text" 476 | }); 477 | } 478 | var filterSpanWrapper = $("", { 479 | 'class':"fulltable-filter" 480 | }); 481 | $(th).append(filterSpanWrapper); 482 | $(filterSpanWrapper).append(filterFieldElement); 483 | } 484 | } 485 | }).removeClass("fulltable-asc").removeClass("fulltable-desc").addClass("fulltable-asc"); 486 | 487 | $(table).find("input, select").change(function(event) { 488 | filter(); 489 | }); 490 | $(table).find("input, select").keyup(function(event) { 491 | filter(); 492 | }); 493 | 494 | var pseudoRow = {"__dom":$(table).find("thead tr")}; 495 | 496 | // Appending of header for edition controls 497 | addEditionControl(pseudoRow, "head"); 498 | addSelectionControl(pseudoRow, "head"); 499 | if (typeof table.getEvents().drawHeader == "function") table.getEvents().drawHeader(pseudoRow); 500 | return this; 501 | }, 502 | 'drawBody':function() { 503 | $(table).find("tbody tr").detach(); 504 | for (var row in table.getRows()) { 505 | if (!table.getRows().hasOwnProperty(row)) continue; 506 | row = table.getRows()[row]; 507 | if ((row["__filtered"] && !row["__creating"]) || row["__removed"]) continue; 508 | row["__invalidOptionRemoved"] = false; 509 | for (var fieldName in row) { 510 | if (!row.hasOwnProperty(fieldName)) continue; 511 | $(row["__dom"]).find("td[fulltable-field-name='" + fieldName + "']").empty(); 512 | if (row["__creating"] || $(row["__dom"]).data("fulltable-editing")) continue; 513 | var value = row[fieldName]; 514 | var text = value; 515 | var fieldData = options.fields[fieldName]; 516 | if (fieldData == null) fieldData = {}; 517 | if (fieldData.options != null) { 518 | // TODO: Here must be validation of input type: select, checkbox, if (fieldData.options == "boolean") 519 | var found = false; 520 | if (value == null) { 521 | if (!fieldData.mandatory) found = true; 522 | } else { 523 | for (var option in fieldData.options) { 524 | if (!fieldData.options.hasOwnProperty(option)) continue; 525 | option = fieldData.options[option]; 526 | if (option.value == value) { 527 | found = true; 528 | text = option.title; 529 | break; 530 | } 531 | } 532 | } 533 | row["__invalidOptionRemoved"] = row["__invalidOptionRemoved"] || !found; // If option is not in option list, this restriction must be activated. 534 | } else { 535 | row["__invalidOptionRemoved"] = row["__invalidOptionRemoved"] || false; // If options has been removed from field settings, this restriction must be also removed. 536 | } 537 | if (value == null) text = ""; 538 | $(row["__dom"]).find("td[fulltable-field-name='" + fieldName + "']").html(text); 539 | if (row["__invalidOptionRemoved"]) break; 540 | } 541 | if (row["__invalidOptionRemoved"] && !row["__creating"]) continue; 542 | if ($(row["__dom"]).data("fulltable-editing")) { 543 | showRowForm(row); 544 | } 545 | $(table).find("tbody").append(row["__dom"]); 546 | } 547 | if (typeof table.getEvents().drawBody == "function") table.getEvents().drawBody(table.getRows()); 548 | return this; 549 | }, 550 | 'filter':function() { 551 | for (var row in table.getRows()) { 552 | if (!table.getRows().hasOwnProperty(row)) continue; 553 | row = table.getRows()[row]; 554 | if (row["__removed"] == true) { 555 | $(row["__dom"]).remove(); 556 | continue; 557 | } 558 | row["__filtered"] = false; 559 | $(table).find("tbody").append($(row["__dom"])); 560 | } 561 | $(table).find("thead th input.fulltable-filter, thead th select.fulltable-filter").each(function (i, e) { 562 | var filtering_value = $(e).val(); 563 | var fieldName = $(e).parents("th").first().attr("fulltable-field-name"); 564 | for (var row in table.getRows()) { 565 | if (!table.getRows().hasOwnProperty(row)) continue; 566 | row = table.getRows()[row]; 567 | var filtered_value = row[fieldName]; 568 | var filtered = false; 569 | if ($(row["__dom"]).data("fulltable-editing")) continue; 570 | var fieldData = options.fields[fieldName]; 571 | if (fieldData == null) fieldData = {}; 572 | // TODO: Here must be validation of input type: select, checkbox, if (fieldData.options == "boolean") 573 | if (fieldData.options != null) { 574 | filtered = (filtering_value != null && filtering_value != '' && filtered_value != filtering_value); 575 | } else { 576 | if (filtered_value == null) filtered_value = ''; 577 | filtered = (filtering_value != null && filtering_value != '' && filtered_value.toUpperCase().indexOf(filtering_value.toUpperCase()) < 0); 578 | } 579 | if (filtered) { 580 | $(row["__dom"]).detach(); 581 | row["__filtered"] = true; 582 | } 583 | } 584 | }); 585 | if (typeof table.getEvents().filter == "function") table.getEvents().filter(); 586 | order(); 587 | return this; 588 | }, 589 | 'order':function(sorting) { 590 | var fields = table.getSorting(); 591 | if (Array.isArray(sorting)) { 592 | sorting = sorting.reverse(); 593 | for (var sortingItem in sorting) { 594 | if (!sorting.hasOwnProperty(sortingItem)) continue; 595 | sortingItem = sorting[sortingItem]; 596 | if (sortingItem.name != null && typeof(sortingItem.sort) == "number") { 597 | addSortItem(sortingItem.name, sortingItem.sort); 598 | } 599 | } 600 | } 601 | var compareFunction = function(field, order) { 602 | if (order == null) order = 1; 603 | var result = function (a, b) { 604 | if (a["__creating"] == true) return 1; 605 | if (b["__creating"] == true) return -1; 606 | if (a == null || b == null) return 0; 607 | var fieldData = options.fields[field]; 608 | if (fieldData == null) fieldData = {}; 609 | // TODO: Here must be validation of input type: select, checkbox, if (fieldData.options == "boolean") 610 | if (fieldData.options != null) { 611 | var foundA = false, foundB = false; 612 | for (var option in fieldData.options) { 613 | if (!fieldData.options.hasOwnProperty(option)) continue; 614 | option = fieldData.options[option]; 615 | if (!foundA && option["value"] == a[field]) { 616 | a = option["title"]; 617 | foundA = true; 618 | } 619 | if (!foundB && option["value"] == b[field]) { 620 | b = option["title"]; 621 | foundB = true; 622 | } 623 | if (foundA && foundB) break; 624 | } 625 | } else { 626 | a = a[field]; 627 | b = b[field]; 628 | } 629 | if (typeof a == "string") a = a.toUpperCase(); 630 | if (typeof b == "string") b = b.toUpperCase(); 631 | if (a == null || b == null) return 0; 632 | if (!isNaN(a) && !isNaN(b)) { 633 | a = Number(a); 634 | b = Number(b); 635 | return order*(a - b); 636 | } else { 637 | if (a < b) 638 | return order*(-1); 639 | else if (a == b) 640 | return 0; 641 | else 642 | return order*(1); 643 | } 644 | }; 645 | return result; 646 | }; 647 | if (!Array.isArray(fields) || fields.length == 0) return this; 648 | for (var field in fields) { 649 | if (!fields.hasOwnProperty(field)) continue; 650 | field = fields[field]; 651 | table.setRows(table.getRows().sort(compareFunction(field.name, field.sort))); 652 | var head = $(table).find("thead th[fulltable-field-name='" + field.name + "']"); // TODO: Improve saving header in all rows by reference. 653 | $(head).removeClass("fulltable-asc").removeClass("fulltable-desc"); 654 | if (field.sort >= 0) $(head).addClass("fulltable-asc"); 655 | else $(head).addClass("fulltable-desc"); 656 | } 657 | drawBody(); 658 | if (typeof table.getEvents().order == "function") table.getEvents().order(); 659 | return this; 660 | }, 661 | 'validateRow':function(row, writeRow) { 662 | if (typeof row != "object") return this; 663 | var error = false; 664 | var errors = []; 665 | var values = {}; 666 | var texts = {}; 667 | row["__validated_texts"] = texts; 668 | row["__validated_values"] = values; 669 | for (var fieldName in row) { 670 | if (!row.hasOwnProperty(fieldName)) continue; 671 | var fieldError = false; 672 | if (fieldName.indexOf("__") == 0) continue; 673 | var fieldData = options.fields[fieldName] || {}; 674 | var td = $(row["__dom"]).find("td[fulltable-field-name='" + fieldName + "']"); 675 | var value = null; 676 | var text = null; 677 | if ($(td).find("input").length > 0) { 678 | value = $(td).find("input").val(); 679 | text = value; 680 | } else if ($(td).find("select").length > 0) { 681 | value = $(td).find("select").val(); 682 | } else { 683 | text = $(td).html(); 684 | } 685 | // TODO: Here must be validation of input type: select, checkbox, if (fieldData.options == "boolean") 686 | if (fieldData.options != null) { 687 | var found = false; 688 | for (var option in fieldData.options) { 689 | if (!fieldData.options.hasOwnProperty(option)) continue; 690 | option = fieldData.options[option]; 691 | if (option["value"] == value) { 692 | text = option["title"]; 693 | found = true; 694 | break; 695 | } else { 696 | if (text = "") text = null; 697 | if (option["value"] == text) { 698 | value = option["value"]; 699 | text = option["title"]; 700 | found = true; 701 | break; 702 | } 703 | } 704 | } 705 | if (!found) { 706 | value = null; 707 | } 708 | } 709 | if (value == "") value = null; 710 | 711 | // Validations: 712 | if (value == null && fieldData.mandatory) { 713 | fieldError = true; 714 | if (fieldData.errors != null && fieldData.errors.mandatory != null) { 715 | errors.push(fieldData.errors.mandatory); 716 | } 717 | } 718 | if (value != null && fieldData.type != null) { 719 | var type = null; 720 | for (var typeEntry in types) { 721 | if (!types.hasOwnProperty(typeEntry)) continue; 722 | var typeNames = types[typeEntry]; 723 | if (typeNames.indexOf(fieldData.type) >= 0) { 724 | type = typeEntry; 725 | break; 726 | } 727 | } 728 | switch (type) { 729 | case "decimal": 730 | if (isNaN(value)) { 731 | fieldError = true; 732 | if (fieldData.errors != null && fieldData.errors.type != null) { 733 | errors.push(fieldData.errors.type); 734 | value = null; 735 | } 736 | break; 737 | } 738 | value = Number(value); 739 | break; 740 | case "integer": 741 | if (isNaN(value)) { 742 | fieldError = true; 743 | if (fieldData.errors != null && fieldData.errors.type != null) { 744 | errors.push(fieldData.errors.type); 745 | value = null; 746 | } 747 | break; 748 | } 749 | value = Number(value); 750 | if (Math.floor(value) != value) { 751 | fieldError = true; 752 | if (fieldData.errors != null && fieldData.errors.type != null) { 753 | errors.push(fieldData.errors.type); 754 | value = null; 755 | } 756 | break; 757 | } 758 | break; 759 | case "string": 760 | default: 761 | 762 | break; 763 | } 764 | } 765 | if (value != null && typeof fieldData.validator == "function") { 766 | if (!(fieldData.validator(value, row, table.getRows(), table) === true)) { 767 | fieldError = true; 768 | if (fieldData.errors != null && fieldData.errors.validator != null) { 769 | errors.push(fieldData.errors.validator); 770 | value = null; 771 | } 772 | } 773 | } 774 | 775 | if (value == null) text = ""; 776 | values[fieldName] = value; 777 | texts[fieldName] = text; 778 | 779 | if (writeRow == null) writeRow = false; 780 | if (writeRow) { 781 | for (var fieldName in values) { 782 | if (!values.hasOwnProperty(fieldName)) continue; 783 | if ($(td).find("input, select").length > 0) { 784 | $(td).find("input, select").val(value); 785 | } else { 786 | $(td).empty(); 787 | $(td).html(text); 788 | } 789 | } 790 | } 791 | if (fieldError) { 792 | $(td).find("input, select").addClass("invalid"); 793 | error = true; 794 | } 795 | } 796 | if (error) { 797 | if (typeof table.getEvents().error == "function") table.getEvents().error(errors); 798 | } 799 | return !error; 800 | }, 801 | 'addRow':function() { 802 | if (!options.editable) return this; 803 | if ($(table).data("fulltable-creating")) return this; 804 | $(table).data("fulltable-creating", true); 805 | var row = {}; 806 | var row_index = table.getRows().length; 807 | table.getRows()[row_index] = row; 808 | row["__creating"] = true; 809 | row["__dom"] = $(""); 810 | row["__filtering"] = false; 811 | row["__invalidOptionRemoved"] = false; 812 | for (var fieldName in table.getKeys()) { 813 | if (!table.getKeys().hasOwnProperty(fieldName)) continue; 814 | fieldName = table.getKeys()[fieldName]; 815 | var td = $("", { 816 | 'fulltable-field-name': fieldName 817 | }); 818 | $(row["__dom"]).append($(td)); 819 | row[fieldName] = ""; 820 | } 821 | $(table).children("tbody").append($(row["__dom"])); 822 | addEditionControl(row, "body"); 823 | addSelectionControl(row, "body"); 824 | $(row["__dom"]).find("td.fulltable-selection-control input[type='checkbox']").prop("disabled", true); 825 | $(row["__dom"]).data("fulltable-editing", true); 826 | showRowForm(row); 827 | $(row["__dom"]).addClass("fulltable-creating"); 828 | if (typeof table.getEvents().addRow == "function") table.getEvents().addRow(row); 829 | return this; 830 | }, 831 | 'editRow':function(row) { 832 | if (!options.editable) return this; 833 | if (typeof row != "object") return this; 834 | $(row["__dom"]).data("fulltable-editing", true); 835 | showRowForm(row); 836 | if (typeof table.getEvents().editRow == "function") table.getEvents().editRow(row); 837 | if (options.alwaysCreating === true) addRow(); // Here this invocation should not be needed, but it cannot cause problems because method idenpontency. 838 | return this; 839 | }, 840 | 'removeRow':function(row) { 841 | if (!options.editable) return this; 842 | if (typeof row != "object") return this; 843 | row["__removed"] = true; 844 | $(row["__dom"]).detach(); 845 | for (var fieldName in row) { 846 | if (!row.hasOwnProperty(fieldName)) continue; 847 | if (fieldName.indexOf("__") == 0) continue; 848 | var value = row[fieldName]; 849 | var td = $(row["__dom"]).find("td[fulltable-field-name='" + fieldName + "']"); 850 | $(td).empty(); 851 | var input = $("", { 852 | 'type':"text", 853 | 'value':value 854 | }); 855 | $(td).append($(input)); 856 | } 857 | if (typeof table.getEvents().removeRow == "function") table.getEvents().removeRow(row); 858 | if (options.alwaysCreating === true) addRow(); 859 | return this; 860 | }, 861 | 'saveRow':function(row) { 862 | if (!options.editable) return this; 863 | if (typeof row != "object") return this; 864 | if (!validateRow(row)) return this; 865 | $(row["__dom"]).removeClass("fulltable-editing"); 866 | $(row["__dom"]).data("fulltable-editing", false); 867 | if (row["__creating"]) { 868 | $(table).data("fulltable-creating", false); 869 | $(row["__dom"]).removeClass("fulltable-creating"); 870 | $(row["__dom"]).find("td.fulltable-selection-control input[type='checkbox']").prop("disabled", false); 871 | row["__creating"] = false; 872 | } 873 | for (var fieldName in row) { 874 | if (!row.hasOwnProperty(fieldName)) continue; 875 | if (fieldName.indexOf("__") == 0) continue; 876 | var td = $(row["__dom"]).find("td[fulltable-field-name='" + fieldName + "']"); 877 | $(td).empty(); 878 | $(td).html(row["__validated_texts"][fieldName]); 879 | row[fieldName] = row["__validated_values"][fieldName]; 880 | } 881 | if (typeof table.getEvents().saveRow == "function") table.getEvents().saveRow(row); 882 | if (options.alwaysCreating === true) addRow(); 883 | return this; 884 | }, 885 | 'discardRow': function(row) { 886 | if (!options.editable) return this; 887 | if (typeof row != "object") return this; 888 | $(row["__dom"]).data("fulltable-editing", false); 889 | $(row["__dom"]).removeClass("fulltable-editing"); 890 | if (row["__creating"]) { 891 | $(table).data("fulltable-creating", false); 892 | row["__creating"] = false; 893 | row["__removed"] = true; 894 | $(row["__dom"]).detach(); 895 | } else { 896 | for (var fieldName in row) { 897 | if (!row.hasOwnProperty(fieldName)) continue; 898 | if (fieldName.indexOf("__") == 0) continue; 899 | var value = row[fieldName]; 900 | var text = value; 901 | if (text == null) text = ""; 902 | var fieldData = options.fields[fieldName] || {}; 903 | // TODO: Here must be validation of input type: select, checkbox, if (fieldData.options == "boolean") 904 | if (fieldData.options != null) { 905 | text = ""; 906 | for (var option in fieldData.options) { 907 | if (!fieldData.options.hasOwnProperty(option)) continue; 908 | option = fieldData.options[option]; 909 | if (option["value"] == value) { 910 | text = option["title"]; 911 | break; 912 | } 913 | } 914 | } 915 | var td = $(row["__dom"]).find("td[fulltable-field-name='" + fieldName + "']"); 916 | $(td).empty(); 917 | $(td).html(text); 918 | } 919 | } 920 | if (typeof table.getEvents().discardRow == "function") table.getEvents().discardRow(row); 921 | if (options.alwaysCreating === true) addRow(); 922 | return this; 923 | }, 924 | 'checkRow': function(row) { 925 | if (row["__selected"] == null) row["__selected"] = false; 926 | row["__selected"] = !row["__selected"]; 927 | if (typeof table.getEvents().checkRow == "function") table.getEvents().checkRow(row); 928 | }, 929 | 'getData':function(selected) { 930 | var result = []; 931 | for (var row in table.getRows()) { 932 | if (!table.getRows().hasOwnProperty(row)) continue; 933 | row = table.getRows()[row]; 934 | if (row["__selected"] == null) row["__selected"] = false; 935 | if (selected === false && row["__selected"] == true) continue; 936 | if (selected === true && row["__selected"] == false) continue; 937 | var resultRow = {}; 938 | if (row["__creating"] === true) continue; 939 | if (row["__removed"] === true || row["__invalidOptionRemoved"] === true) continue; 940 | result.push(resultRow); 941 | for (var fieldName in row) { 942 | if (!row.hasOwnProperty(fieldName)) continue; 943 | if (fieldName.indexOf("__") == 0) continue; 944 | var value = row[fieldName]; 945 | resultRow[fieldName] = value; 946 | } 947 | } 948 | if (typeof table.getEvents().getData == "function") table.getEvents().getData(); 949 | return result; 950 | }, 951 | 'setData':function(data) { 952 | if (!Array.isArray(data)) { 953 | return this; 954 | } 955 | var oldData = table.getRows().splice(0, table.getRows().length); 956 | var newData = data; 957 | for (var rowData in data) { 958 | if (!data.hasOwnProperty(rowData)) continue; 959 | rowData = data[rowData]; 960 | var row = drawRow(rowData, null); 961 | if (!validateRow(row)) continue; 962 | table.getRows().push(row); 963 | } 964 | drawBody(); 965 | if (typeof table.getEvents().setData == "function") table.getEvents().setData(oldData, newData); 966 | return this; 967 | }, 968 | 'error': function() { 969 | return this; 970 | } 971 | }; 972 | 973 | // DEPRECATED: Compatibility, uncomment if needed 974 | /* 975 | methods['create'] = methods['addRow']; 976 | methods['edit'] = methods['editRow']; 977 | methods['remove'] = methods['removeRow']; 978 | methods['save'] = methods['saveRow']; 979 | methods['discard'] = methods['discardRow']; 980 | methods['getValue'] = methods['getData']; 981 | */ 982 | 983 | var defaults = { 984 | "editable":true, 985 | "filterable":true, 986 | "orderable":true, 987 | "selectable":false, 988 | "fields":{}, 989 | "on":{ 990 | "update":function() { 991 | 992 | } 993 | } 994 | }; 995 | 996 | var options = $(table).data('options'); 997 | 998 | var method = null; 999 | var methodArguments = null; 1000 | 1001 | if (typeof arguments[0] == "string") { 1002 | if ($(table).data('fulltable') != true) return; 1003 | if (options == null) return this; 1004 | method = methods[arguments[0]]; 1005 | methodArguments = Array.prototype.slice.call(arguments, 1); 1006 | if (typeof method != "function") return this; 1007 | return method.apply(this, methodArguments); 1008 | } 1009 | 1010 | if (options == null) { 1011 | if (typeof arguments[0] == "object") { 1012 | options = arguments[0]; 1013 | options = $.extend(true, defaults, options); 1014 | } else { 1015 | options = defaults; 1016 | } 1017 | $(table).data('options', options); 1018 | } 1019 | 1020 | $(table).data('fulltable', true); 1021 | $(table).addClass("fulltable"); 1022 | if (options.editable) { 1023 | $(table).addClass("fulltable-editable"); 1024 | } 1025 | 1026 | getHeaderFromDom(); 1027 | drawHeader(); 1028 | getBodyFromDom(); 1029 | drawBody(); 1030 | if (options.alwaysCreating === true) addRow(); 1031 | filter(); 1032 | 1033 | return this; 1034 | }; 1035 | }(jQuery)); --------------------------------------------------------------------------------