corrade-nucleus-nucleons – Blame information for rev 20

Subversion Repositories:
Rev:
Rev Author Line No. Line
20 office 1 /**
2 * @author: Dennis Hernández
3 * @webSite: http://djhvscf.github.io/Blog
4 * @version: v2.1.1
5 */
6  
7 (function ($) {
8  
9 'use strict';
10  
11 var sprintf = $.fn.bootstrapTable.utils.sprintf,
12 objectKeys = $.fn.bootstrapTable.utils.objectKeys;
13  
14 var getOptionsFromSelectControl = function (selectControl) {
15 return selectControl.get(selectControl.length - 1).options;
16 };
17  
18 var hideUnusedSelectOptions = function (selectControl, uniqueValues) {
19 var options = getOptionsFromSelectControl(selectControl);
20  
21 for (var i = 0; i < options.length; i++) {
22 if (options[i].value !== "") {
23 if (!uniqueValues.hasOwnProperty(options[i].value)) {
24 selectControl.find(sprintf("option[value='%s']", options[i].value)).hide();
25 } else {
26 selectControl.find(sprintf("option[value='%s']", options[i].value)).show();
27 }
28 }
29 }
30 };
31  
32 var addOptionToSelectControl = function (selectControl, value, text) {
33 value = $.trim(value);
34 selectControl = $(selectControl.get(selectControl.length - 1));
35 if (!existOptionInSelectControl(selectControl, value)) {
36 selectControl.append($("<option></option>")
37 .attr("value", value)
38 .text($('<div />').html(text).text()));
39 }
40 };
41  
42 var sortSelectControl = function (selectControl) {
43 var $opts = selectControl.find('option:gt(0)');
44 $opts.sort(function (a, b) {
45 a = $(a).text().toLowerCase();
46 b = $(b).text().toLowerCase();
47 if ($.isNumeric(a) && $.isNumeric(b)) {
48 // Convert numerical values from string to float.
49 a = parseFloat(a);
50 b = parseFloat(b);
51 }
52 return a > b ? 1 : a < b ? -1 : 0;
53 });
54  
55 selectControl.find('option:gt(0)').remove();
56 selectControl.append($opts);
57 };
58  
59 var existOptionInSelectControl = function (selectControl, value) {
60 var options = getOptionsFromSelectControl(selectControl);
61 for (var i = 0; i < options.length; i++) {
62 if (options[i].value === value.toString()) {
63 //The value is not valid to add
64 return true;
65 }
66 }
67  
68 //If we get here, the value is valid to add
69 return false;
70 };
71  
72 var fixHeaderCSS = function (that) {
73 that.$tableHeader.css('height', '77px');
74 };
75  
76 var getCurrentHeader = function (that) {
77 var header = that.$header;
78 if (that.options.height) {
79 header = that.$tableHeader;
80 }
81  
82 return header;
83 };
84  
85 var getCurrentSearchControls = function (that) {
86 var searchControls = 'select, input';
87 if (that.options.height) {
88 searchControls = 'table select, table input';
89 }
90  
91 return searchControls;
92 };
93  
94 var getCursorPosition = function(el) {
95 if ($.fn.bootstrapTable.utils.isIEBrowser()) {
96 if ($(el).is('input')) {
97 var pos = 0;
98 if ('selectionStart' in el) {
99 pos = el.selectionStart;
100 } else if ('selection' in document) {
101 el.focus();
102 var Sel = document.selection.createRange();
103 var SelLength = document.selection.createRange().text.length;
104 Sel.moveStart('character', -el.value.length);
105 pos = Sel.text.length - SelLength;
106 }
107 return pos;
108 } else {
109 return -1;
110 }
111 } else {
112 return -1;
113 }
114 };
115  
116 var setCursorPosition = function (el, index) {
117 if ($.fn.bootstrapTable.utils.isIEBrowser()) {
118 if(el.setSelectionRange !== undefined) {
119 el.setSelectionRange(index, index);
120 } else {
121 $(el).val(el.value);
122 }
123 }
124 };
125  
126 var copyValues = function (that) {
127 var header = getCurrentHeader(that),
128 searchControls = getCurrentSearchControls(that);
129  
130 that.options.valuesFilterControl = [];
131  
132 header.find(searchControls).each(function () {
133 that.options.valuesFilterControl.push(
134 {
135 field: $(this).closest('[data-field]').data('field'),
136 value: $(this).val(),
137 position: getCursorPosition($(this).get(0))
138 });
139 });
140 };
141  
142 var setValues = function(that) {
143 var field = null,
144 result = [],
145 header = getCurrentHeader(that),
146 searchControls = getCurrentSearchControls(that);
147  
148 if (that.options.valuesFilterControl.length > 0) {
149 header.find(searchControls).each(function (index, ele) {
150 field = $(this).closest('[data-field]').data('field');
151 result = $.grep(that.options.valuesFilterControl, function (valueObj) {
152 return valueObj.field === field;
153 });
154  
155 if (result.length > 0) {
156 $(this).val(result[0].value);
157 setCursorPosition($(this).get(0), result[0].position);
158 }
159 });
160 }
161 };
162  
163 var collectBootstrapCookies = function cookiesRegex() {
164 var cookies = [],
165 foundCookies = document.cookie.match(/(?:bs.table.)(\w*)/g);
166  
167 if (foundCookies) {
168 $.each(foundCookies, function (i, cookie) {
169 if (/./.test(cookie)) {
170 cookie = cookie.split(".").pop();
171 }
172  
173 if ($.inArray(cookie, cookies) === -1) {
174 cookies.push(cookie);
175 }
176 });
177 return cookies;
178 }
179 };
180  
181 var initFilterSelectControls = function (that) {
182 var data = that.data,
183 itemsPerPage = that.pageTo < that.options.data.length ? that.options.data.length : that.pageTo,
184  
185 isColumnSearchableViaSelect = function (column) {
186 return column.filterControl && column.filterControl.toLowerCase() === 'select' && column.searchable;
187 },
188  
189 isFilterDataNotGiven = function (column) {
190 return column.filterData === undefined || column.filterData.toLowerCase() === 'column';
191 },
192  
193 hasSelectControlElement = function (selectControl) {
194 return selectControl && selectControl.length > 0;
195 };
196  
197 var z = that.options.pagination ?
198 (that.options.sidePagination === 'server' ? that.pageTo : that.options.totalRows) :
199 that.pageTo;
200  
201 $.each(that.header.fields, function (j, field) {
202 var column = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, field)],
203 selectControl = $('.bootstrap-table-filter-control-' + escapeID(column.field));
204  
205 if (isColumnSearchableViaSelect(column) && isFilterDataNotGiven(column) && hasSelectControlElement(selectControl)) {
206 if (selectControl.get(selectControl.length - 1).options.length === 0) {
207 //Added the default option
208 addOptionToSelectControl(selectControl, '', '');
209 }
210  
211 var uniqueValues = {};
212 for (var i = 0; i < z; i++) {
213 //Added a new value
214 var fieldValue = data[i][field],
215 formattedValue = $.fn.bootstrapTable.utils.calculateObjectValue(that.header, that.header.formatters[j], [fieldValue, data[i], i], fieldValue);
216  
217 uniqueValues[formattedValue] = fieldValue;
218 }
219  
220 for (var key in uniqueValues) {
221 addOptionToSelectControl(selectControl, uniqueValues[key], key);
222 }
223  
224 sortSelectControl(selectControl);
225  
226 if (that.options.hideUnusedSelectOptions) {
227 hideUnusedSelectOptions(selectControl, uniqueValues);
228 }
229 }
230 });
231 };
232  
233 var escapeID = function(id) {
234 return String(id).replace( /(:|\.|\[|\]|,)/g, "\\$1" );
235 };
236  
237 var createControls = function (that, header) {
238 var addedFilterControl = false,
239 isVisible,
240 html,
241 timeoutId = 0;
242  
243 $.each(that.columns, function (i, column) {
244 isVisible = 'hidden';
245 html = [];
246  
247 if (!column.visible) {
248 return;
249 }
250  
251 if (!column.filterControl) {
252 html.push('<div class="no-filter-control"></div>');
253 } else {
254 html.push('<div class="filter-control">');
255  
256 var nameControl = column.filterControl.toLowerCase();
257 if (column.searchable && that.options.filterTemplate[nameControl]) {
258 addedFilterControl = true;
259 isVisible = 'visible';
260 html.push(that.options.filterTemplate[nameControl](that, column.field, isVisible, column.filterControlPlaceholder));
261 }
262 }
263  
264 $.each(header.children().children(), function (i, tr) {
265 tr = $(tr);
266 if (tr.data('field') === column.field) {
267 tr.find('.fht-cell').append(html.join(''));
268 return false;
269 }
270 });
271  
272 if (column.filterData !== undefined && column.filterData.toLowerCase() !== 'column') {
273 var filterDataType = getFilterDataMethod(filterDataMethods, column.filterData.substring(0, column.filterData.indexOf(':')));
274 var filterDataSource, selectControl;
275  
276 if (filterDataType !== null) {
277 filterDataSource = column.filterData.substring(column.filterData.indexOf(':') + 1, column.filterData.length);
278 selectControl = $('.bootstrap-table-filter-control-' + escapeID(column.field));
279  
280 addOptionToSelectControl(selectControl, '', '');
281 filterDataType(filterDataSource, selectControl);
282 } else {
283 throw new SyntaxError('Error. You should use any of these allowed filter data methods: var, json, url.' + ' Use like this: var: {key: "value"}');
284 }
285  
286 var variableValues, key;
287 switch (filterDataType) {
288 case 'url':
289 $.ajax({
290 url: filterDataSource,
291 dataType: 'json',
292 success: function (data) {
293 for (var key in data) {
294 addOptionToSelectControl(selectControl, key, data[key]);
295 }
296 sortSelectControl(selectControl);
297 }
298 });
299 break;
300 case 'var':
301 variableValues = window[filterDataSource];
302 for (key in variableValues) {
303 addOptionToSelectControl(selectControl, key, variableValues[key]);
304 }
305 sortSelectControl(selectControl);
306 break;
307 case 'jso':
308 variableValues = JSON.parse(filterDataSource);
309 for (key in variableValues) {
310 addOptionToSelectControl(selectControl, key, variableValues[key]);
311 }
312 sortSelectControl(selectControl);
313 break;
314 }
315 }
316 });
317  
318 if (addedFilterControl) {
319 header.off('keyup', 'input').on('keyup', 'input', function (event) {
320 clearTimeout(timeoutId);
321 timeoutId = setTimeout(function () {
322 that.onColumnSearch(event);
323 }, that.options.searchTimeOut);
324 });
325  
326 header.off('change', 'select').on('change', 'select', function (event) {
327 clearTimeout(timeoutId);
328 timeoutId = setTimeout(function () {
329 that.onColumnSearch(event);
330 }, that.options.searchTimeOut);
331 });
332  
333 header.off('mouseup', 'input').on('mouseup', 'input', function (event) {
334 var $input = $(this),
335 oldValue = $input.val();
336  
337 if (oldValue === "") {
338 return;
339 }
340  
341 setTimeout(function(){
342 var newValue = $input.val();
343  
344 if (newValue === "") {
345 clearTimeout(timeoutId);
346 timeoutId = setTimeout(function () {
347 that.onColumnSearch(event);
348 }, that.options.searchTimeOut);
349 }
350 }, 1);
351 });
352  
353 if (header.find('.date-filter-control').length > 0) {
354 $.each(that.columns, function (i, column) {
355 if (column.filterControl !== undefined && column.filterControl.toLowerCase() === 'datepicker') {
356 header.find('.date-filter-control.bootstrap-table-filter-control-' + column.field).datepicker(column.filterDatepickerOptions)
357 .on('changeDate', function (e) {
358 $(sprintf(".%s", e.currentTarget.classList.toString().split(" ").join("."))).val(e.currentTarget.value);
359 //Fired the keyup event
360 $(e.currentTarget).keyup();
361 });
362 }
363 });
364 }
365 } else {
366 header.find('.filterControl').hide();
367 }
368 };
369  
370 var getDirectionOfSelectOptions = function (alignment) {
371 alignment = alignment === undefined ? 'left' : alignment.toLowerCase();
372  
373 switch (alignment) {
374 case 'left':
375 return 'ltr';
376 case 'right':
377 return 'rtl';
378 case 'auto':
379 return 'auto';
380 default:
381 return 'ltr';
382 }
383 };
384  
385 var filterDataMethods =
386 {
387 'var': function (filterDataSource, selectControl) {
388 var variableValues = window[filterDataSource];
389 for (var key in variableValues) {
390 addOptionToSelectControl(selectControl, key, variableValues[key]);
391 }
392 sortSelectControl(selectControl);
393 },
394 'url': function (filterDataSource, selectControl) {
395 $.ajax({
396 url: filterDataSource,
397 dataType: 'json',
398 success: function (data) {
399 for (var key in data) {
400 addOptionToSelectControl(selectControl, key, data[key]);
401 }
402 sortSelectControl(selectControl);
403 }
404 });
405 },
406 'json':function (filterDataSource, selectControl) {
407 var variableValues = JSON.parse(filterDataSource);
408 for (var key in variableValues) {
409 addOptionToSelectControl(selectControl, key, variableValues[key]);
410 }
411 sortSelectControl(selectControl);
412 }
413 };
414  
415 var getFilterDataMethod = function (objFilterDataMethod, searchTerm) {
416 var keys = Object.keys(objFilterDataMethod);
417 for (var i = 0; i < keys.length; i++) {
418 if (keys[i] === searchTerm) {
419 return objFilterDataMethod[searchTerm];
420 }
421 }
422 return null;
423 };
424  
425 $.extend($.fn.bootstrapTable.defaults, {
426 filterControl: false,
427 onColumnSearch: function (field, text) {
428 return false;
429 },
430 filterShowClear: false,
431 alignmentSelectControlOptions: undefined,
432 filterTemplate: {
433 input: function (that, field, isVisible, placeholder) {
434 return sprintf('<input type="text" class="form-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s" placeholder="%s">', field, isVisible, placeholder);
435 },
436 select: function (that, field, isVisible) {
437 return sprintf('<select class="form-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s" dir="%s"></select>',
438 field, isVisible, getDirectionOfSelectOptions(that.options.alignmentSelectControlOptions));
439 },
440 datepicker: function (that, field, isVisible) {
441 return sprintf('<input type="text" class="form-control date-filter-control bootstrap-table-filter-control-%s" style="width: 100%; visibility: %s">', field, isVisible);
442 }
443 },
444 //internal variables
445 valuesFilterControl: []
446 });
447  
448 $.extend($.fn.bootstrapTable.COLUMN_DEFAULTS, {
449 filterControl: undefined,
450 filterData: undefined,
451 filterDatepickerOptions: undefined,
452 filterStrictSearch: false,
453 filterStartsWithSearch: false,
454 filterControlPlaceholder: ""
455 });
456  
457 $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
458 'column-search.bs.table': 'onColumnSearch'
459 });
460  
461 $.extend($.fn.bootstrapTable.defaults.icons, {
462 clear: 'glyphicon-trash icon-clear'
463 });
464  
465 $.extend($.fn.bootstrapTable.locales, {
466 formatClearFilters: function () {
467 return 'Clear Filters';
468 }
469 });
470 $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
471  
472 var BootstrapTable = $.fn.bootstrapTable.Constructor,
473 _init = BootstrapTable.prototype.init,
474 _initToolbar = BootstrapTable.prototype.initToolbar,
475 _initHeader = BootstrapTable.prototype.initHeader,
476 _initBody = BootstrapTable.prototype.initBody,
477 _initSearch = BootstrapTable.prototype.initSearch;
478  
479 BootstrapTable.prototype.init = function () {
480 //Make sure that the filterControl option is set
481 if (this.options.filterControl) {
482 var that = this;
483  
484 // Compatibility: IE < 9 and old browsers
485 if (!Object.keys) {
486 objectKeys();
487 }
488  
489 //Make sure that the internal variables are set correctly
490 this.options.valuesFilterControl = [];
491  
492 this.$el.on('reset-view.bs.table', function () {
493 //Create controls on $tableHeader if the height is set
494 if (!that.options.height) {
495 return;
496 }
497  
498 //Avoid recreate the controls
499 if (that.$tableHeader.find('select').length > 0 || that.$tableHeader.find('input').length > 0) {
500 return;
501 }
502  
503 createControls(that, that.$tableHeader);
504 }).on('post-header.bs.table', function () {
505 setValues(that);
506 }).on('post-body.bs.table', function () {
507 if (that.options.height) {
508 fixHeaderCSS(that);
509 }
510 }).on('column-switch.bs.table', function() {
511 setValues(that);
512 });
513 }
514 _init.apply(this, Array.prototype.slice.apply(arguments));
515 };
516  
517 BootstrapTable.prototype.initToolbar = function () {
518 this.showToolbar = this.options.filterControl && this.options.filterShowClear;
519  
520 _initToolbar.apply(this, Array.prototype.slice.apply(arguments));
521  
522 if (this.options.filterControl && this.options.filterShowClear) {
523 var $btnGroup = this.$toolbar.find('>.btn-group'),
524 $btnClear = $btnGroup.find('.filter-show-clear');
525  
526 if (!$btnClear.length) {
527 $btnClear = $([
528 '<button class="btn btn-default filter-show-clear" ',
529 sprintf('type="button" title="%s">', this.options.formatClearFilters()),
530 sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.clear),
531 '</button>'
532 ].join('')).appendTo($btnGroup);
533  
534 $btnClear.off('click').on('click', $.proxy(this.clearFilterControl, this));
535 }
536 }
537 };
538  
539 BootstrapTable.prototype.initHeader = function () {
540 _initHeader.apply(this, Array.prototype.slice.apply(arguments));
541  
542 if (!this.options.filterControl) {
543 return;
544 }
545 createControls(this, this.$header);
546 };
547  
548 BootstrapTable.prototype.initBody = function () {
549 _initBody.apply(this, Array.prototype.slice.apply(arguments));
550  
551 initFilterSelectControls(this);
552 };
553  
554 BootstrapTable.prototype.initSearch = function () {
555 _initSearch.apply(this, Array.prototype.slice.apply(arguments));
556  
557 if (this.options.sidePagination === 'server') {
558 return;
559 }
560  
561 var that = this;
562 var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;
563  
564 //Check partial column filter
565 this.data = fp ? $.grep(this.data, function (item, i) {
566 for (var key in fp) {
567 var thisColumn = that.columns[$.fn.bootstrapTable.utils.getFieldIndex(that.columns, key)];
568 var fval = fp[key].toLowerCase();
569 var value = item[key];
570  
571 // Fix #142: search use formated data
572 if (thisColumn && thisColumn.searchFormatter) {
573 value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header,
574 that.header.formatters[$.inArray(key, that.header.fields)],
575 [value, item, i], value);
576 }
577  
578 if (thisColumn.filterStrictSearch) {
579 if (!($.inArray(key, that.header.fields) !== -1 &&
580 (typeof value === 'string' || typeof value === 'number') &&
581 value.toString().toLowerCase() === fval.toString().toLowerCase())) {
582 return false;
583 }
584 } else if (thisColumn.filterStartsWithSearch) {
585 if (!($.inArray(key, that.header.fields) !== -1 &&
586 (typeof value === 'string' || typeof value === 'number') &&
587 (value + '').toLowerCase().indexOf(fval) === 0)) {
588 return false;
589 }
590 } else {
591 if (!($.inArray(key, that.header.fields) !== -1 &&
592 (typeof value === 'string' || typeof value === 'number') &&
593 (value + '').toLowerCase().indexOf(fval) !== -1)) {
594 return false;
595 }
596 }
597 }
598 return true;
599 }) : this.data;
600 };
601  
602 BootstrapTable.prototype.initColumnSearch = function(filterColumnsDefaults) {
603 copyValues(this);
604  
605 if (filterColumnsDefaults) {
606 this.filterColumnsPartial = filterColumnsDefaults;
607 this.updatePagination();
608  
609 for (var filter in filterColumnsDefaults) {
610 this.trigger('column-search', filter, filterColumnsDefaults[filter]);
611 }
612 }
613 };
614  
615 BootstrapTable.prototype.onColumnSearch = function (event) {
616 if ($.inArray(event.keyCode, [37, 38, 39, 40]) > -1) {
617 return;
618 }
619  
620 copyValues(this);
621 var text = $.trim($(event.currentTarget).val());
622 var $field = $(event.currentTarget).closest('[data-field]').data('field');
623  
624 if ($.isEmptyObject(this.filterColumnsPartial)) {
625 this.filterColumnsPartial = {};
626 }
627 if (text) {
628 this.filterColumnsPartial[$field] = text;
629 } else {
630 delete this.filterColumnsPartial[$field];
631 }
632  
633 // if the searchText is the same as the previously selected column value,
634 // bootstrapTable will not try searching again (even though the selected column
635 // may be different from the previous search). As a work around
636 // we're manually appending some text to bootrap's searchText field
637 // to guarantee that it will perform a search again when we call this.onSearch(event)
638 this.searchText += "randomText";
639  
640 this.options.pageNumber = 1;
641 this.onSearch(event);
642 this.trigger('column-search', $field, text);
643 };
644  
645 BootstrapTable.prototype.clearFilterControl = function () {
646 if (this.options.filterControl && this.options.filterShowClear) {
647 var that = this,
648 cookies = collectBootstrapCookies(),
649 header = getCurrentHeader(that),
650 table = header.closest('table'),
651 controls = header.find(getCurrentSearchControls(that)),
652 search = that.$toolbar.find('.search input'),
653 timeoutId = 0;
654  
655 $.each(that.options.valuesFilterControl, function (i, item) {
656 item.value = '';
657 });
658  
659 setValues(that);
660  
661 // Clear each type of filter if it exists.
662 // Requires the body to reload each time a type of filter is found because we never know
663 // which ones are going to be present.
664 if (controls.length > 0) {
665 this.filterColumnsPartial = {};
666 $(controls[0]).trigger(controls[0].tagName === 'INPUT' ? 'keyup' : 'change');
667 } else {
668 return;
669 }
670  
671 if (search.length > 0) {
672 that.resetSearch();
673 }
674  
675 // use the default sort order if it exists. do nothing if it does not
676 if (that.options.sortName !== table.data('sortName') || that.options.sortOrder !== table.data('sortOrder')) {
677 var sorter = header.find(sprintf('[data-field="%s"]', $(controls[0]).closest('table').data('sortName')));
678 if (sorter.length > 0) {
679 that.onSort(table.data('sortName'), table.data('sortName'));
680 $(sorter).find('.sortable').trigger('click');
681 }
682 }
683  
684 // clear cookies once the filters are clean
685 clearTimeout(timeoutId);
686 timeoutId = setTimeout(function () {
687 if (cookies && cookies.length > 0) {
688 $.each(cookies, function (i, item) {
689 if (that.deleteCookie !== undefined) {
690 that.deleteCookie(item);
691 }
692 });
693 }
694 }, that.options.searchTimeOut);
695 }
696 };
697 })(jQuery);