footable-on-rails 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/FooTable-On-Rails.gemspec +23 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/lib/footable-on-rails.rb +12 -0
- data/lib/footable-on-rails/engine.rb +6 -0
- data/lib/footable-on-rails/railtie.rb +5 -0
- data/lib/footable-on-rails/version.rb +5 -0
- data/vendor/assets/images/footable-on-rails/minus.png +0 -0
- data/vendor/assets/images/footable-on-rails/plus.png +0 -0
- data/vendor/assets/javascripts/footable-on-rails/footable.js +784 -0
- data/vendor/assets/javascripts/footable-on-rails/index.js +2 -0
- data/vendor/assets/javascripts/footable-on-rails/plugins/footable.filter.js +144 -0
- data/vendor/assets/javascripts/footable-on-rails/plugins/footable.paginate.js +241 -0
- data/vendor/assets/javascripts/footable-on-rails/plugins/footable.sort.js +190 -0
- data/vendor/assets/javascripts/footable-on-rails/plugins/footable.striping.js +57 -0
- data/vendor/assets/stylesheets/footable-on-rails/fonts/footable.eot +0 -0
- data/vendor/assets/stylesheets/footable-on-rails/fonts/footable.svg +78 -0
- data/vendor/assets/stylesheets/footable-on-rails/fonts/footable.ttf +0 -0
- data/vendor/assets/stylesheets/footable-on-rails/fonts/footable.woff +0 -0
- data/vendor/assets/stylesheets/footable-on-rails/footable.core.css +178 -0
- data/vendor/assets/stylesheets/footable-on-rails/footable.core.min.css +1 -0
- data/vendor/assets/stylesheets/footable-on-rails/footable.metro.css +152 -0
- data/vendor/assets/stylesheets/footable-on-rails/footable.metro.min.css +1 -0
- data/vendor/assets/stylesheets/footable-on-rails/footable.standalone.css +181 -0
- data/vendor/assets/stylesheets/footable-on-rails/footable.standalone.min.css +1 -0
- data/vendor/assets/stylesheets/footable-on-rails/index.css +9 -0
- metadata +101 -0
@@ -0,0 +1,144 @@
|
|
1
|
+
(function ($, w, undefined) {
|
2
|
+
if (w.footable === undefined || w.footable === null)
|
3
|
+
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
4
|
+
|
5
|
+
var defaults = {
|
6
|
+
filter: {
|
7
|
+
enabled: true,
|
8
|
+
input: '.footable-filter',
|
9
|
+
timeout: 300,
|
10
|
+
minimum: 2,
|
11
|
+
disableEnter: false,
|
12
|
+
filterFunction: function(index) {
|
13
|
+
var $t = $(this),
|
14
|
+
$table = $t.parents('table:first'),
|
15
|
+
filter = $table.data('current-filter').toUpperCase(),
|
16
|
+
text = $t.find('td').text();
|
17
|
+
if (!$table.data('filter-text-only')) {
|
18
|
+
$t.find('td[data-value]').each(function () {
|
19
|
+
text += $(this).data('value');
|
20
|
+
});
|
21
|
+
}
|
22
|
+
return text.toUpperCase().indexOf(filter) >= 0;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
};
|
26
|
+
|
27
|
+
function Filter() {
|
28
|
+
var p = this;
|
29
|
+
p.name = 'Footable Filter';
|
30
|
+
p.init = function (ft) {
|
31
|
+
p.footable = ft;
|
32
|
+
if (ft.options.filter.enabled === true) {
|
33
|
+
if ($(ft.table).data('filter') === false) return;
|
34
|
+
ft.timers.register('filter');
|
35
|
+
$(ft.table)
|
36
|
+
.unbind('.filtering')
|
37
|
+
.bind({
|
38
|
+
'footable_initialized.filtering': function (e) {
|
39
|
+
var $table = $(ft.table);
|
40
|
+
var data = {
|
41
|
+
'input': $table.data('filter') || ft.options.filter.input,
|
42
|
+
'timeout': $table.data('filter-timeout') || ft.options.filter.timeout,
|
43
|
+
'minimum': $table.data('filter-minimum') || ft.options.filter.minimum,
|
44
|
+
'disableEnter': $table.data('filter-disable-enter') || ft.options.filter.disableEnter
|
45
|
+
};
|
46
|
+
if (data.disableEnter) {
|
47
|
+
$(data.input).keypress(function (event) {
|
48
|
+
if (window.event)
|
49
|
+
return (window.event.keyCode !== 13);
|
50
|
+
else
|
51
|
+
return (event.which !== 13);
|
52
|
+
});
|
53
|
+
}
|
54
|
+
$table.bind('footable_clear_filter', function () {
|
55
|
+
$(data.input).val('');
|
56
|
+
p.clearFilter();
|
57
|
+
});
|
58
|
+
$table.bind('footable_filter', function (event, args) {
|
59
|
+
p.filter(args.filter);
|
60
|
+
});
|
61
|
+
$(data.input).keyup(function (eve) {
|
62
|
+
ft.timers.filter.stop();
|
63
|
+
if (eve.which === 27) {
|
64
|
+
$(data.input).val('');
|
65
|
+
}
|
66
|
+
ft.timers.filter.start(function () {
|
67
|
+
var val = $(data.input).val() || '';
|
68
|
+
p.filter(val);
|
69
|
+
}, data.timeout);
|
70
|
+
});
|
71
|
+
},
|
72
|
+
'footable_redrawn.filtering': function (e) {
|
73
|
+
var $table = $(ft.table),
|
74
|
+
filter = $table.data('filter-string');
|
75
|
+
if (filter) {
|
76
|
+
p.filter(filter);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
})
|
80
|
+
//save the filter object onto the table so we can access it later
|
81
|
+
.data('footable-filter', p);
|
82
|
+
}
|
83
|
+
};
|
84
|
+
|
85
|
+
p.filter = function (filterString) {
|
86
|
+
var ft = p.footable,
|
87
|
+
$table = $(ft.table),
|
88
|
+
minimum = $table.data('filter-minimum') || ft.options.filter.minimum,
|
89
|
+
clear = !filterString;
|
90
|
+
|
91
|
+
//raise a pre-filter event so that we can cancel the filtering if needed
|
92
|
+
var event = ft.raise('footable_filtering', { filter: filterString, clear: clear });
|
93
|
+
if (event && event.result === false) return;
|
94
|
+
if (event.filter && event.filter.length < minimum) {
|
95
|
+
return; //if we do not have the minimum chars then do nothing
|
96
|
+
}
|
97
|
+
|
98
|
+
if (event.clear) {
|
99
|
+
p.clearFilter();
|
100
|
+
} else {
|
101
|
+
var filters = event.filter.split(' ');
|
102
|
+
|
103
|
+
$table.find('> tbody > tr').hide().addClass('footable-filtered');
|
104
|
+
var rows = $table.find('> tbody > tr:not(.footable-row-detail)');
|
105
|
+
$.each(filters, function (i, f) {
|
106
|
+
if (f && f.length > 0) {
|
107
|
+
$table.data('current-filter', f);
|
108
|
+
rows = rows.filter(ft.options.filter.filterFunction);
|
109
|
+
}
|
110
|
+
});
|
111
|
+
rows.each(function () {
|
112
|
+
p.showRow(this, ft);
|
113
|
+
$(this).removeClass('footable-filtered');
|
114
|
+
});
|
115
|
+
$table.data('filter-string', event.filter);
|
116
|
+
ft.raise('footable_filtered', { filter: event.filter, clear: false });
|
117
|
+
}
|
118
|
+
};
|
119
|
+
|
120
|
+
p.clearFilter = function () {
|
121
|
+
var ft = p.footable,
|
122
|
+
$table = $(ft.table);
|
123
|
+
|
124
|
+
$table.find('> tbody > tr:not(.footable-row-detail)').removeClass('footable-filtered').each(function () {
|
125
|
+
p.showRow(this, ft);
|
126
|
+
});
|
127
|
+
$table.removeData('filter-string');
|
128
|
+
ft.raise('footable_filtered', { clear: true });
|
129
|
+
};
|
130
|
+
|
131
|
+
p.showRow = function (row, ft) {
|
132
|
+
var $row = $(row), $next = $row.next(), $table = $(ft.table);
|
133
|
+
if ($row.is(':visible')) return; //already visible - do nothing
|
134
|
+
if ($table.hasClass('breakpoint') && $row.hasClass('footable-detail-show') && $next.hasClass('footable-row-detail')) {
|
135
|
+
$row.add($next).show();
|
136
|
+
ft.createOrUpdateDetailRow(row);
|
137
|
+
}
|
138
|
+
else $row.show();
|
139
|
+
};
|
140
|
+
}
|
141
|
+
|
142
|
+
w.footable.plugins.register(Filter, defaults);
|
143
|
+
|
144
|
+
})(jQuery, window);
|
@@ -0,0 +1,241 @@
|
|
1
|
+
(function ($, w, undefined) {
|
2
|
+
if (w.footable === undefined || w.footable === null)
|
3
|
+
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
4
|
+
|
5
|
+
var defaults = {
|
6
|
+
paginate: true,
|
7
|
+
pageSize: 10,
|
8
|
+
pageNavigation: '.pagination',
|
9
|
+
firstText: '«',
|
10
|
+
previousText: '‹',
|
11
|
+
nextText: '›',
|
12
|
+
lastText: '»',
|
13
|
+
limitNavigation: 0,
|
14
|
+
limitPreviousText: '...',
|
15
|
+
limitNextText: '...'
|
16
|
+
};
|
17
|
+
|
18
|
+
function pageInfo(ft) {
|
19
|
+
var $table = $(ft.table), data = $table.data();
|
20
|
+
this.pageNavigation = data.pageNavigation || ft.options.pageNavigation;
|
21
|
+
this.pageSize = data.pageSize || ft.options.pageSize;
|
22
|
+
this.firstText = data.firstText || ft.options.firstText;
|
23
|
+
this.previousText = data.previousText || ft.options.previousText;
|
24
|
+
this.nextText = data.nextText || ft.options.nextText;
|
25
|
+
this.lastText = data.lastText || ft.options.lastText;
|
26
|
+
this.limitNavigation = parseInt(data.limitNavigation || ft.options.limitNavigation || defaults.limitNavigation, 10);
|
27
|
+
this.limitPreviousText = data.limitPreviousText || ft.options.limitPreviousText;
|
28
|
+
this.limitNextText = data.limitNextText || ft.options.limitNextText;
|
29
|
+
this.limit = this.limitNavigation > 0;
|
30
|
+
this.currentPage = data.currentPage || 0;
|
31
|
+
this.pages = [];
|
32
|
+
this.control = false;
|
33
|
+
}
|
34
|
+
|
35
|
+
function Paginate() {
|
36
|
+
var p = this;
|
37
|
+
p.name = 'Footable Paginate';
|
38
|
+
|
39
|
+
p.init = function (ft) {
|
40
|
+
if (ft.options.paginate === true) {
|
41
|
+
if ($(ft.table).data('page') === false) return;
|
42
|
+
p.footable = ft;
|
43
|
+
$(ft.table)
|
44
|
+
.unbind('.paging')
|
45
|
+
.bind({
|
46
|
+
'footable_initialized.paging footable_row_removed.paging footable_redrawn.paging footable_sorted.paging footable_filtered.paging': function () {
|
47
|
+
p.setupPaging();
|
48
|
+
}
|
49
|
+
})
|
50
|
+
//save the filter object onto the table so we can access it later
|
51
|
+
.data('footable-paging', p);
|
52
|
+
}
|
53
|
+
};
|
54
|
+
|
55
|
+
p.setupPaging = function () {
|
56
|
+
var ft = p.footable,
|
57
|
+
$tbody = $(ft.table).find('> tbody');
|
58
|
+
|
59
|
+
ft.pageInfo = new pageInfo(ft);
|
60
|
+
|
61
|
+
p.createPages(ft, $tbody);
|
62
|
+
p.createNavigation(ft, $tbody);
|
63
|
+
p.fillPage(ft, $tbody, ft.pageInfo.currentPage);
|
64
|
+
};
|
65
|
+
|
66
|
+
p.createPages = function (ft, tbody) {
|
67
|
+
var pages = 1;
|
68
|
+
var info = ft.pageInfo;
|
69
|
+
var pageCount = pages * info.pageSize;
|
70
|
+
var page = [];
|
71
|
+
var lastPage = [];
|
72
|
+
info.pages = [];
|
73
|
+
var rows = tbody.find('> tr:not(.footable-filtered,.footable-row-detail)');
|
74
|
+
rows.each(function (i, row) {
|
75
|
+
page.push(row);
|
76
|
+
if (i === pageCount - 1) {
|
77
|
+
info.pages.push(page);
|
78
|
+
pages++;
|
79
|
+
pageCount = pages * info.pageSize;
|
80
|
+
page = [];
|
81
|
+
} else if (i >= rows.length - (rows.length % info.pageSize)) {
|
82
|
+
lastPage.push(row);
|
83
|
+
}
|
84
|
+
});
|
85
|
+
if (lastPage.length > 0) info.pages.push(lastPage);
|
86
|
+
if (info.currentPage >= info.pages.length) info.currentPage = info.pages.length - 1;
|
87
|
+
if (info.currentPage < 0) info.currentPage = 0;
|
88
|
+
if (info.pages.length === 1) {
|
89
|
+
//we only have a single page
|
90
|
+
$(ft.table).addClass('no-paging');
|
91
|
+
} else {
|
92
|
+
$(ft.table).removeClass('no-paging');
|
93
|
+
}
|
94
|
+
};
|
95
|
+
|
96
|
+
p.createNavigation = function (ft, tbody) {
|
97
|
+
var $nav = $(ft.table).find(ft.pageInfo.pageNavigation);
|
98
|
+
//if we cannot find the navigation control within the table, then try find it outside
|
99
|
+
if ($nav.length === 0) {
|
100
|
+
$nav = $(ft.pageInfo.pageNavigation);
|
101
|
+
//if the navigation control is inside another table, then get out
|
102
|
+
if ($nav.parents('table:first').length > 0 && $nav.parents('table:first') !== $(ft.table)) return;
|
103
|
+
//if we found more than one navigation control, write error to console
|
104
|
+
if ($nav.length > 1 && ft.options.debug === true) console.error('More than one pagination control was found!');
|
105
|
+
}
|
106
|
+
//if we still cannot find the control, then don't do anything
|
107
|
+
if ($nav.length === 0) return;
|
108
|
+
//if the nav is not a UL, then find or create a UL
|
109
|
+
if (!$nav.is('ul')) {
|
110
|
+
if ($nav.find('ul:first').length === 0) {
|
111
|
+
$nav.append('<ul />');
|
112
|
+
}
|
113
|
+
$nav = $nav.find('ul');
|
114
|
+
}
|
115
|
+
$nav.find('li').remove();
|
116
|
+
var info = ft.pageInfo;
|
117
|
+
info.control = $nav;
|
118
|
+
if (info.pages.length > 0) {
|
119
|
+
$nav.append('<li class="footable-page-arrow"><a data-page="first" href="#first">' + ft.pageInfo.firstText + '</a>');
|
120
|
+
$nav.append('<li class="footable-page-arrow"><a data-page="prev" href="#prev">' + ft.pageInfo.previousText + '</a></li>');
|
121
|
+
if (info.limit){
|
122
|
+
$nav.append('<li class="footable-page-arrow"><a data-page="limit-prev" href="#limit-prev">' + ft.pageInfo.limitPreviousText + '</a></li>');
|
123
|
+
}
|
124
|
+
if (!info.limit){
|
125
|
+
$.each(info.pages, function (i, page) {
|
126
|
+
if (page.length > 0) {
|
127
|
+
$nav.append('<li class="footable-page"><a data-page="' + i + '" href="#">' + (i + 1) + '</a></li>');
|
128
|
+
}
|
129
|
+
});
|
130
|
+
}
|
131
|
+
if (info.limit){
|
132
|
+
$nav.append('<li class="footable-page-arrow"><a data-page="limit-next" href="#limit-next">' + ft.pageInfo.limitNextText + '</a></li>');
|
133
|
+
p.createLimited($nav, info, 0);
|
134
|
+
}
|
135
|
+
$nav.append('<li class="footable-page-arrow"><a data-page="next" href="#next">' + ft.pageInfo.nextText + '</a></li>');
|
136
|
+
$nav.append('<li class="footable-page-arrow"><a data-page="last" href="#last">' + ft.pageInfo.lastText + '</a></li>');
|
137
|
+
}
|
138
|
+
$nav.off('click', 'a[data-page]').on('click', 'a[data-page]', function (e) {
|
139
|
+
e.preventDefault();
|
140
|
+
var page = $(this).data('page');
|
141
|
+
var newPage = info.currentPage;
|
142
|
+
if (page === 'first') {
|
143
|
+
newPage = 0;
|
144
|
+
} else if (page === 'prev') {
|
145
|
+
if (newPage > 0) newPage--;
|
146
|
+
} else if (page === 'next') {
|
147
|
+
if (newPage < info.pages.length - 1) newPage++;
|
148
|
+
} else if (page === 'last') {
|
149
|
+
newPage = info.pages.length - 1;
|
150
|
+
} else if (page === 'limit-prev') {
|
151
|
+
newPage = -1;
|
152
|
+
var first = $nav.find('.footable-page:first a').data('page');
|
153
|
+
p.createLimited($nav, info, first - info.limitNavigation);
|
154
|
+
p.setPagingClasses($nav, info.currentPage, info.pages.length);
|
155
|
+
} else if (page === 'limit-next') {
|
156
|
+
newPage = -1;
|
157
|
+
var last = $nav.find('.footable-page:last a').data('page');
|
158
|
+
p.createLimited($nav, info, last + 1);
|
159
|
+
p.setPagingClasses($nav, info.currentPage, info.pages.length);
|
160
|
+
} else {
|
161
|
+
newPage = page;
|
162
|
+
}
|
163
|
+
if (newPage >= 0){
|
164
|
+
if (info.limit && info.currentPage != newPage){
|
165
|
+
var start = newPage;
|
166
|
+
while (start % info.limitNavigation !== 0){ start -= 1; }
|
167
|
+
p.createLimited($nav, info, start);
|
168
|
+
}
|
169
|
+
p.paginate(ft, newPage);
|
170
|
+
}
|
171
|
+
});
|
172
|
+
p.setPagingClasses($nav, info.currentPage, info.pages.length);
|
173
|
+
};
|
174
|
+
|
175
|
+
p.createLimited = function(nav, info, start){
|
176
|
+
start = start || 0;
|
177
|
+
nav.find('li.footable-page').remove();
|
178
|
+
var i, page,
|
179
|
+
$prev = nav.find('li.footable-page-arrow > a[data-page="limit-prev"]').parent(),
|
180
|
+
$next = nav.find('li.footable-page-arrow > a[data-page="limit-next"]').parent();
|
181
|
+
for (i = info.pages.length - 1; i >=0 ; i--){
|
182
|
+
page = info.pages[i];
|
183
|
+
if (i >= start && i < start + info.limitNavigation && page.length > 0) {
|
184
|
+
$prev.after('<li class="footable-page"><a data-page="' + i + '" href="#">' + (i + 1) + '</a></li>');
|
185
|
+
}
|
186
|
+
}
|
187
|
+
if (start === 0){ $prev.hide(); }
|
188
|
+
else { $prev.show(); }
|
189
|
+
if (start + info.limitNavigation >= info.pages.length){ $next.hide(); }
|
190
|
+
else { $next.show(); }
|
191
|
+
};
|
192
|
+
|
193
|
+
p.paginate = function (ft, newPage) {
|
194
|
+
var info = ft.pageInfo;
|
195
|
+
if (info.currentPage !== newPage) {
|
196
|
+
var $tbody = $(ft.table).find('> tbody');
|
197
|
+
|
198
|
+
//raise a pre-pagin event so that we can cancel the paging if needed
|
199
|
+
var event = ft.raise('footable_paging', { page: newPage, size: info.pageSize });
|
200
|
+
if (event && event.result === false) return;
|
201
|
+
|
202
|
+
p.fillPage(ft, $tbody, newPage);
|
203
|
+
info.control.find('li').removeClass('active disabled');
|
204
|
+
p.setPagingClasses(info.control, info.currentPage, info.pages.length);
|
205
|
+
}
|
206
|
+
};
|
207
|
+
|
208
|
+
p.setPagingClasses = function (nav, currentPage, pageCount) {
|
209
|
+
nav.find('li.footable-page > a[data-page=' + currentPage + ']').parent().addClass('active');
|
210
|
+
if (currentPage >= pageCount - 1) {
|
211
|
+
nav.find('li.footable-page-arrow > a[data-page="next"]').parent().addClass('disabled');
|
212
|
+
nav.find('li.footable-page-arrow > a[data-page="last"]').parent().addClass('disabled');
|
213
|
+
}
|
214
|
+
if (currentPage < 1) {
|
215
|
+
nav.find('li.footable-page-arrow > a[data-page="first"]').parent().addClass('disabled');
|
216
|
+
nav.find('li.footable-page-arrow > a[data-page="prev"]').parent().addClass('disabled');
|
217
|
+
}
|
218
|
+
};
|
219
|
+
|
220
|
+
p.fillPage = function (ft, tbody, pageNumber) {
|
221
|
+
ft.pageInfo.currentPage = pageNumber;
|
222
|
+
$(ft.table).data('currentPage', pageNumber);
|
223
|
+
tbody.find('> tr').hide();
|
224
|
+
$(ft.pageInfo.pages[pageNumber]).each(function () {
|
225
|
+
p.showRow(this, ft);
|
226
|
+
});
|
227
|
+
};
|
228
|
+
|
229
|
+
p.showRow = function (row, ft) {
|
230
|
+
var $row = $(row), $next = $row.next(), $table = $(ft.table);
|
231
|
+
if ($table.hasClass('breakpoint') && $row.hasClass('footable-detail-show') && $next.hasClass('footable-row-detail')) {
|
232
|
+
$row.add($next).show();
|
233
|
+
ft.createOrUpdateDetailRow(row);
|
234
|
+
}
|
235
|
+
else $row.show();
|
236
|
+
};
|
237
|
+
}
|
238
|
+
|
239
|
+
w.footable.plugins.register(Paginate, defaults);
|
240
|
+
|
241
|
+
})(jQuery, window);
|
@@ -0,0 +1,190 @@
|
|
1
|
+
(function ($, w, undefined) {
|
2
|
+
if (w.footable === undefined || w.footable === null)
|
3
|
+
throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');
|
4
|
+
|
5
|
+
var defaults = {
|
6
|
+
sort: true,
|
7
|
+
sorters: {
|
8
|
+
alpha: function (a, b) {
|
9
|
+
if (typeof(a) === 'string') { a = a.toLowerCase(); }
|
10
|
+
if (typeof(b) === 'string') { b = b.toLowerCase(); }
|
11
|
+
if (a === b) return 0;
|
12
|
+
if (a < b) return -1;
|
13
|
+
return 1;
|
14
|
+
},
|
15
|
+
numeric: function (a, b) {
|
16
|
+
return a - b;
|
17
|
+
}
|
18
|
+
},
|
19
|
+
classes: {
|
20
|
+
sort: {
|
21
|
+
sortable: 'footable-sortable',
|
22
|
+
sorted: 'footable-sorted',
|
23
|
+
descending: 'footable-sorted-desc',
|
24
|
+
indicator: 'footable-sort-indicator'
|
25
|
+
}
|
26
|
+
},
|
27
|
+
events: {
|
28
|
+
sort: {
|
29
|
+
sorting: 'footable_sorting',
|
30
|
+
sorted: 'footable_sorted'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
};
|
34
|
+
|
35
|
+
function Sort() {
|
36
|
+
var p = this;
|
37
|
+
p.name = 'Footable Sortable';
|
38
|
+
p.init = function (ft) {
|
39
|
+
p.footable = ft;
|
40
|
+
if (ft.options.sort === true) {
|
41
|
+
$(ft.table)
|
42
|
+
.unbind('.sorting')
|
43
|
+
.bind({
|
44
|
+
'footable_initialized.sorting': function (e) {
|
45
|
+
var $table = $(ft.table),
|
46
|
+
$tbody = $table.find('> tbody'),
|
47
|
+
cls = ft.options.classes.sort,
|
48
|
+
column, $th;
|
49
|
+
|
50
|
+
if ($table.data('sort') === false) return;
|
51
|
+
|
52
|
+
$table.find('> thead > tr:last-child > th, > thead > tr:last-child > td').each(function (ec) {
|
53
|
+
$th = $(this), column = ft.columns[$th.index()];
|
54
|
+
if (column.sort.ignore !== true && !$th.hasClass(cls.sortable)) {
|
55
|
+
$th.addClass(cls.sortable);
|
56
|
+
$('<span />').addClass(cls.indicator).appendTo($th);
|
57
|
+
}
|
58
|
+
});
|
59
|
+
|
60
|
+
$table.find('> thead > tr:last-child > th.' + cls.sortable + ', > thead > tr:last-child > td.' + cls.sortable).unbind('click.footable').bind('click.footable', function (ec) {
|
61
|
+
ec.preventDefault();
|
62
|
+
$th = $(this);
|
63
|
+
var ascending = !$th.hasClass(cls.sorted);
|
64
|
+
p.doSort($th.index(), ascending);
|
65
|
+
return false;
|
66
|
+
});
|
67
|
+
|
68
|
+
var didSomeSorting = false;
|
69
|
+
for (var c in ft.columns) {
|
70
|
+
column = ft.columns[c];
|
71
|
+
if (column.sort.initial) {
|
72
|
+
var ascending = (column.sort.initial !== 'descending');
|
73
|
+
p.doSort(column.index, ascending);
|
74
|
+
break;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
if (didSomeSorting) {
|
78
|
+
ft.bindToggleSelectors();
|
79
|
+
}
|
80
|
+
},
|
81
|
+
'footable_redrawn.sorting': function(e) {
|
82
|
+
var $table = $(ft.table),
|
83
|
+
cls = ft.options.classes.sort;
|
84
|
+
if ($table.data('sorted') >= 0) {
|
85
|
+
$table.find('> thead > tr:last-child > th').each(function(i){
|
86
|
+
var $th = $(this);
|
87
|
+
if ($th.hasClass(cls.sorted) || $th.hasClass(cls.descending)) {
|
88
|
+
p.doSort(i);
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
});
|
92
|
+
}
|
93
|
+
},
|
94
|
+
'footable_column_data.sorting': function (e) {
|
95
|
+
var $th = $(e.column.th);
|
96
|
+
e.column.data.sort = e.column.data.sort || {};
|
97
|
+
e.column.data.sort.initial = $th.data('sort-initial') || false;
|
98
|
+
e.column.data.sort.ignore = $th.data('sort-ignore') || false;
|
99
|
+
e.column.data.sort.selector = $th.data('sort-selector') || null;
|
100
|
+
|
101
|
+
var match = $th.data('sort-match') || 0;
|
102
|
+
if (match >= e.column.data.matches.length) match = 0;
|
103
|
+
e.column.data.sort.match = e.column.data.matches[match];
|
104
|
+
}
|
105
|
+
})
|
106
|
+
//save the sort object onto the table so we can access it later
|
107
|
+
.data('footable-sort', p);
|
108
|
+
}
|
109
|
+
};
|
110
|
+
|
111
|
+
p.doSort = function(columnIndex, ascending) {
|
112
|
+
var ft = p.footable;
|
113
|
+
if ($(ft.table).data('sort') === false) return;
|
114
|
+
|
115
|
+
var $table = $(ft.table),
|
116
|
+
$tbody = $table.find('> tbody'),
|
117
|
+
column = ft.columns[columnIndex],
|
118
|
+
$th = $table.find('> thead > tr:last-child > th:eq(' + columnIndex + ')'),
|
119
|
+
cls = ft.options.classes.sort,
|
120
|
+
evt = ft.options.events.sort;
|
121
|
+
|
122
|
+
ascending = (ascending === undefined) ? $th.hasClass(cls.sorted) :
|
123
|
+
(ascending === 'toggle') ? !$th.hasClass(cls.sorted) : ascending;
|
124
|
+
|
125
|
+
if (column.sort.ignore === true) return true;
|
126
|
+
|
127
|
+
//raise a pre-sorting event so that we can cancel the sorting if needed
|
128
|
+
var event = ft.raise(evt.sorting, { column: column, direction: ascending ? 'ASC' : 'DESC' });
|
129
|
+
if (event && event.result === false) return;
|
130
|
+
|
131
|
+
$table.data('sorted', column.index);
|
132
|
+
|
133
|
+
$table.find('> thead > tr:last-child > th, > thead > tr:last-child > td').not($th).removeClass(cls.sorted + ' ' + cls.descending);
|
134
|
+
|
135
|
+
if (ascending === undefined) {
|
136
|
+
ascending = $th.hasClass(cls.sorted);
|
137
|
+
}
|
138
|
+
|
139
|
+
if (ascending) {
|
140
|
+
$th.removeClass(cls.descending).addClass(cls.sorted);
|
141
|
+
} else {
|
142
|
+
$th.removeClass(cls.sorted).addClass(cls.descending);
|
143
|
+
}
|
144
|
+
|
145
|
+
p.sort(ft, $tbody, column, ascending);
|
146
|
+
|
147
|
+
ft.bindToggleSelectors();
|
148
|
+
ft.raise(evt.sorted, { column: column, direction: ascending ? 'ASC' : 'DESC' });
|
149
|
+
};
|
150
|
+
|
151
|
+
p.rows = function (ft, tbody, column) {
|
152
|
+
var rows = [];
|
153
|
+
tbody.find('> tr').each(function () {
|
154
|
+
var $row = $(this), $next = null;
|
155
|
+
if ($row.hasClass(ft.options.classes.detail)) return true;
|
156
|
+
if ($row.next().hasClass(ft.options.classes.detail)) {
|
157
|
+
$next = $row.next().get(0);
|
158
|
+
}
|
159
|
+
var row = { 'row': $row, 'detail': $next };
|
160
|
+
if (column !== undefined) {
|
161
|
+
row.value = ft.parse(this.cells[column.sort.match], column);
|
162
|
+
}
|
163
|
+
rows.push(row);
|
164
|
+
return true;
|
165
|
+
}).detach();
|
166
|
+
return rows;
|
167
|
+
};
|
168
|
+
|
169
|
+
p.sort = function (ft, tbody, column, ascending) {
|
170
|
+
var rows = p.rows(ft, tbody, column);
|
171
|
+
var sorter = ft.options.sorters[column.type] || ft.options.sorters.alpha;
|
172
|
+
rows.sort(function (a, b) {
|
173
|
+
if (ascending) {
|
174
|
+
return sorter(a.value, b.value);
|
175
|
+
} else {
|
176
|
+
return sorter(b.value, a.value);
|
177
|
+
}
|
178
|
+
});
|
179
|
+
for (var j = 0; j < rows.length; j++) {
|
180
|
+
tbody.append(rows[j].row);
|
181
|
+
if (rows[j].detail !== null) {
|
182
|
+
tbody.append(rows[j].detail);
|
183
|
+
}
|
184
|
+
}
|
185
|
+
};
|
186
|
+
}
|
187
|
+
|
188
|
+
w.footable.plugins.register(Sort, defaults);
|
189
|
+
|
190
|
+
})(jQuery, window);
|