Gallery Bank: WordPress Photo Gallery Plugin - Version 4.0.10

Version Description

  • TWEAK: PL Uploader updated to 2.3.1
  • TWEAK: jQUery Datatables updated to 1.10.15
  • TWEAK: jQUery Filtree updated to 2.1.5
  • TWEAK: jQUery Clip Board updated to 1.7.1
  • FIX: Footer File Bugs
Download this release

Release Info

Developer contact-banker
Plugin Icon 128x128 Gallery Bank: WordPress Photo Gallery Plugin
Version 4.0.10
Comparing to
See all releases

Code changes from version 4.0.9 to 4.0.10

assets/global/plugins/clipboard/clipboard.js CHANGED
@@ -1,5 +1,5 @@
1
  /*!
2
- * clipboard.js v1.6.1
3
  * https://zenorocha.github.io/clipboard.js
4
  *
5
  * Licensed MIT © Zeno Rocha
@@ -16,7 +16,7 @@ var proto = Element.prototype;
16
  proto.msMatchesSelector ||
17
  proto.oMatchesSelector ||
18
  proto.webkitMatchesSelector;
19
- }
20
 
21
  /**
22
  * Finds the closest parent that matches a selector.
@@ -27,13 +27,16 @@ var proto = Element.prototype;
27
  */
28
  function closest (element, selector) {
29
  while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
30
- if (element.matches(selector)) return element;
31
- element = element.parentNode;
32
- }
 
 
 
33
  }
34
 
35
  module.exports = closest;
36
- }, {}], 2:[function(require, module, exports){
37
  var closest = require('./closest');
38
  /**
39
  * Delegates event to a selector.
@@ -85,7 +88,7 @@ exports.node = function(value) {
85
  return value !== undefined
86
  && value instanceof HTMLElement
87
  && value.nodeType === 1;
88
- };
89
  /**
90
  * Check if argument is a list of HTML elements.
91
  *
@@ -119,7 +122,7 @@ return value !== undefined
119
  var type = Object.prototype.toString.call(value);
120
  return type === '[object Function]';
121
  };
122
- }, {}], 4:[function(require, module, exports){
123
  var is = require('./is');
124
  var delegate = require('delegate');
125
  /**
@@ -218,25 +221,25 @@ var selectedText;
218
  if (element.nodeName === 'SELECT') {
219
  element.focus();
220
  selectedText = element.value;
221
- }
222
  else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
223
  var isReadOnly = element.hasAttribute('readonly');
224
  if (!isReadOnly) {
225
  element.setAttribute('readonly', '');
226
- }
227
 
228
  element.select();
229
  element.setSelectionRange(0, element.value.length);
230
  if (!isReadOnly) {
231
  element.removeAttribute('readonly');
232
- }
233
 
234
  selectedText = element.value;
235
- }
236
  else {
237
  if (element.hasAttribute('contenteditable')) {
238
  element.focus();
239
- }
240
 
241
  var selection = window.getSelection();
242
  var range = document.createRange();
@@ -244,13 +247,13 @@ var selection = window.getSelection();
244
  selection.removeAllRanges();
245
  selection.addRange(range);
246
  selectedText = selection.toString();
247
- }
248
 
249
  return selectedText;
250
- }
251
 
252
  module.exports = select;
253
- }, {}], 6:[function(require, module, exports){
254
  function E () {
255
  // Keep this empty so it's easier to inherit from
256
  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
@@ -262,9 +265,9 @@ var e = this.e || (this.e = {});
262
  (e[name] || (e[name] = [])).push({
263
  fn: callback,
264
  ctx: ctx
265
- });
266
  return this;
267
- },
268
  once: function (name, callback, ctx) {
269
  var self = this;
270
  function listener () {
@@ -307,19 +310,19 @@ fn: callback,
307
  }
308
  };
309
  module.exports = E;
310
- }, {}], 7:[function(require, module, exports){
311
  (function (global, factory) {
312
  if (typeof define === "function" && define.amd) {
313
  define(['module', 'select'], factory);
314
- } else if (typeof exports !== "undefined") {
315
  factory(module, require('select'));
316
- } else {
317
  var mod = {
318
  exports: {}
319
  };
320
  factory(mod, global.select);
321
  global.clipboardAction = mod.exports;
322
- }
323
  })(this, function (module, _select) {
324
  'use strict';
325
  var _select2 = _interopRequireDefault(_select);
@@ -331,9 +334,9 @@ exports: {}
331
 
332
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
333
  return typeof obj;
334
- } : function (obj) {
335
  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
336
- };
337
  function _classCallCheck(instance, Constructor) {
338
  if (!(instance instanceof Constructor)) {
339
  throw new TypeError("Cannot call a class as a function");
@@ -348,15 +351,15 @@ var descriptor = props[i];
348
  descriptor.configurable = true;
349
  if ("value" in descriptor) descriptor.writable = true;
350
  Object.defineProperty(target, descriptor.key, descriptor);
351
- }
352
  }
353
 
354
  return function (Constructor, protoProps, staticProps) {
355
  if (protoProps) defineProperties(Constructor.prototype, protoProps);
356
  if (staticProps) defineProperties(Constructor, staticProps);
357
  return Constructor;
358
- };
359
- }();
360
  var ClipboardAction = function () {
361
  /**
362
  * @param {Object} options
@@ -378,6 +381,7 @@ if (protoProps) defineProperties(Constructor.prototype, protoProps);
378
  value: function resolveOptions() {
379
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
380
  this.action = options.action;
 
381
  this.emitter = options.emitter;
382
  this.target = options.target;
383
  this.text = options.text;
@@ -402,7 +406,7 @@ if (protoProps) defineProperties(Constructor.prototype, protoProps);
402
  this.fakeHandlerCallback = function () {
403
  return _this.removeFake();
404
  };
405
- this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true;
406
  this.fakeElem = document.createElement('textarea');
407
  // Prevent zooming on iOS
408
  this.fakeElem.style.fontSize = '12pt';
@@ -418,7 +422,7 @@ if (protoProps) defineProperties(Constructor.prototype, protoProps);
418
  this.fakeElem.style.top = yPosition + 'px';
419
  this.fakeElem.setAttribute('readonly', '');
420
  this.fakeElem.value = this.text;
421
- document.body.appendChild(this.fakeElem);
422
  this.selectedText = (0, _select2.default)(this.fakeElem);
423
  this.copyText();
424
  }
@@ -426,13 +430,13 @@ if (protoProps) defineProperties(Constructor.prototype, protoProps);
426
  key: 'removeFake',
427
  value: function removeFake() {
428
  if (this.fakeHandler) {
429
- document.body.removeEventListener('click', this.fakeHandlerCallback);
430
  this.fakeHandler = null;
431
  this.fakeHandlerCallback = null;
432
  }
433
 
434
  if (this.fakeElem) {
435
- document.body.removeChild(this.fakeElem);
436
  this.fakeElem = null;
437
  }
438
  }
@@ -467,8 +471,8 @@ if (protoProps) defineProperties(Constructor.prototype, protoProps);
467
  }, {
468
  key: 'clearSelection',
469
  value: function clearSelection() {
470
- if (this.target) {
471
- this.target.blur();
472
  }
473
 
474
  window.getSelection().removeAllRanges();
@@ -516,20 +520,20 @@ if (protoProps) defineProperties(Constructor.prototype, protoProps);
516
  return ClipboardAction;
517
  }();
518
  module.exports = ClipboardAction;
519
- });
520
- }, {"select":5}], 8:[function(require, module, exports){
521
  (function (global, factory) {
522
  if (typeof define === "function" && define.amd) {
523
  define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory);
524
- } else if (typeof exports !== "undefined") {
525
  factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener'));
526
- } else {
527
  var mod = {
528
  exports: {}
529
  };
530
  factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener);
531
  global.clipboard = mod.exports;
532
- }
533
  })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) {
534
  'use strict';
535
  var _clipboardAction2 = _interopRequireDefault(_clipboardAction);
@@ -541,11 +545,16 @@ exports: {}
541
  };
542
  }
543
 
544
- function _classCallCheck(instance, Constructor) {
545
- if (!(instance instanceof Constructor)) {
546
- throw new TypeError("Cannot call a class as a function");
547
- }
548
- }
 
 
 
 
 
549
 
550
  var _createClass = function () {
551
  function defineProperties(target, props) {
@@ -555,15 +564,15 @@ var descriptor = props[i];
555
  descriptor.configurable = true;
556
  if ("value" in descriptor) descriptor.writable = true;
557
  Object.defineProperty(target, descriptor.key, descriptor);
558
- }
559
  }
560
 
561
  return function (Constructor, protoProps, staticProps) {
562
  if (protoProps) defineProperties(Constructor.prototype, protoProps);
563
  if (staticProps) defineProperties(Constructor, staticProps);
564
  return Constructor;
565
- };
566
- }();
567
  function _possibleConstructorReturn(self, call) {
568
  if (!self) {
569
  throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
@@ -575,7 +584,7 @@ if (protoProps) defineProperties(Constructor.prototype, protoProps);
575
  function _inherits(subClass, superClass) {
576
  if (typeof superClass !== "function" && superClass !== null) {
577
  throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
578
- }
579
 
580
  subClass.prototype = Object.create(superClass && superClass.prototype, {
581
  constructor: {
@@ -583,10 +592,10 @@ value: subClass,
583
  enumerable: false,
584
  writable: true,
585
  configurable: true
586
- }
587
  });
588
  if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
589
- }
590
 
591
  var Clipboard = function (_Emitter) {
592
  _inherits(Clipboard, _Emitter);
@@ -616,6 +625,7 @@ _inherits(Clipboard, _Emitter);
616
  this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
617
  this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
618
  this.text = typeof options.text === 'function' ? options.text : this.defaultText;
 
619
  }
620
  }, {
621
  key: 'listenClick',
@@ -637,6 +647,7 @@ _inherits(Clipboard, _Emitter);
637
  action: this.action(trigger),
638
  target: this.target(trigger),
639
  text: this.text(trigger),
 
640
  trigger: trigger,
641
  emitter: this
642
  });
@@ -698,5 +709,5 @@ _inherits(Clipboard, _Emitter);
698
 
699
  module.exports = Clipboard;
700
  });
701
- }, {"./clipboard-action":7, "good-listener":4, "tiny-emitter":6}]}, {}, [8])(8)
702
- });
1
  /*!
2
+ * clipboard.js v1.7.1
3
  * https://zenorocha.github.io/clipboard.js
4
  *
5
  * Licensed MIT © Zeno Rocha
16
  proto.msMatchesSelector ||
17
  proto.oMatchesSelector ||
18
  proto.webkitMatchesSelector;
19
+ }
20
 
21
  /**
22
  * Finds the closest parent that matches a selector.
27
  */
28
  function closest (element, selector) {
29
  while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
30
+ if (typeof element.matches === 'function' &&
31
+ element.matches(selector)) {
32
+ return element;
33
+ }
34
+ element = element.parentNode;
35
+ }
36
  }
37
 
38
  module.exports = closest;
39
+ }, {}], 2:[function(require, module, exports){
40
  var closest = require('./closest');
41
  /**
42
  * Delegates event to a selector.
88
  return value !== undefined
89
  && value instanceof HTMLElement
90
  && value.nodeType === 1;
91
+ };
92
  /**
93
  * Check if argument is a list of HTML elements.
94
  *
122
  var type = Object.prototype.toString.call(value);
123
  return type === '[object Function]';
124
  };
125
+ }, {}], 4:[function(require, module, exports){
126
  var is = require('./is');
127
  var delegate = require('delegate');
128
  /**
221
  if (element.nodeName === 'SELECT') {
222
  element.focus();
223
  selectedText = element.value;
224
+ }
225
  else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
226
  var isReadOnly = element.hasAttribute('readonly');
227
  if (!isReadOnly) {
228
  element.setAttribute('readonly', '');
229
+ }
230
 
231
  element.select();
232
  element.setSelectionRange(0, element.value.length);
233
  if (!isReadOnly) {
234
  element.removeAttribute('readonly');
235
+ }
236
 
237
  selectedText = element.value;
238
+ }
239
  else {
240
  if (element.hasAttribute('contenteditable')) {
241
  element.focus();
242
+ }
243
 
244
  var selection = window.getSelection();
245
  var range = document.createRange();
247
  selection.removeAllRanges();
248
  selection.addRange(range);
249
  selectedText = selection.toString();
250
+ }
251
 
252
  return selectedText;
253
+ }
254
 
255
  module.exports = select;
256
+ }, {}], 6:[function(require, module, exports){
257
  function E () {
258
  // Keep this empty so it's easier to inherit from
259
  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
265
  (e[name] || (e[name] = [])).push({
266
  fn: callback,
267
  ctx: ctx
268
+ });
269
  return this;
270
+ },
271
  once: function (name, callback, ctx) {
272
  var self = this;
273
  function listener () {
310
  }
311
  };
312
  module.exports = E;
313
+ }, {}], 7:[function(require, module, exports){
314
  (function (global, factory) {
315
  if (typeof define === "function" && define.amd) {
316
  define(['module', 'select'], factory);
317
+ } else if (typeof exports !== "undefined") {
318
  factory(module, require('select'));
319
+ } else {
320
  var mod = {
321
  exports: {}
322
  };
323
  factory(mod, global.select);
324
  global.clipboardAction = mod.exports;
325
+ }
326
  })(this, function (module, _select) {
327
  'use strict';
328
  var _select2 = _interopRequireDefault(_select);
334
 
335
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
336
  return typeof obj;
337
+ } : function (obj) {
338
  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
339
+ };
340
  function _classCallCheck(instance, Constructor) {
341
  if (!(instance instanceof Constructor)) {
342
  throw new TypeError("Cannot call a class as a function");
351
  descriptor.configurable = true;
352
  if ("value" in descriptor) descriptor.writable = true;
353
  Object.defineProperty(target, descriptor.key, descriptor);
354
+ }
355
  }
356
 
357
  return function (Constructor, protoProps, staticProps) {
358
  if (protoProps) defineProperties(Constructor.prototype, protoProps);
359
  if (staticProps) defineProperties(Constructor, staticProps);
360
  return Constructor;
361
+ };
362
+ }();
363
  var ClipboardAction = function () {
364
  /**
365
  * @param {Object} options
381
  value: function resolveOptions() {
382
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
383
  this.action = options.action;
384
+ this.container = options.container;
385
  this.emitter = options.emitter;
386
  this.target = options.target;
387
  this.text = options.text;
406
  this.fakeHandlerCallback = function () {
407
  return _this.removeFake();
408
  };
409
+ this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;
410
  this.fakeElem = document.createElement('textarea');
411
  // Prevent zooming on iOS
412
  this.fakeElem.style.fontSize = '12pt';
422
  this.fakeElem.style.top = yPosition + 'px';
423
  this.fakeElem.setAttribute('readonly', '');
424
  this.fakeElem.value = this.text;
425
+ this.container.appendChild(this.fakeElem);
426
  this.selectedText = (0, _select2.default)(this.fakeElem);
427
  this.copyText();
428
  }
430
  key: 'removeFake',
431
  value: function removeFake() {
432
  if (this.fakeHandler) {
433
+ this.container.removeEventListener('click', this.fakeHandlerCallback);
434
  this.fakeHandler = null;
435
  this.fakeHandlerCallback = null;
436
  }
437
 
438
  if (this.fakeElem) {
439
+ this.container.removeChild(this.fakeElem);
440
  this.fakeElem = null;
441
  }
442
  }
471
  }, {
472
  key: 'clearSelection',
473
  value: function clearSelection() {
474
+ if (this.trigger) {
475
+ this.trigger.focus();
476
  }
477
 
478
  window.getSelection().removeAllRanges();
520
  return ClipboardAction;
521
  }();
522
  module.exports = ClipboardAction;
523
+ });
524
+ }, {"select":5}], 8:[function(require, module, exports){
525
  (function (global, factory) {
526
  if (typeof define === "function" && define.amd) {
527
  define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory);
528
+ } else if (typeof exports !== "undefined") {
529
  factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener'));
530
+ } else {
531
  var mod = {
532
  exports: {}
533
  };
534
  factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener);
535
  global.clipboard = mod.exports;
536
+ }
537
  })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) {
538
  'use strict';
539
  var _clipboardAction2 = _interopRequireDefault(_clipboardAction);
545
  };
546
  }
547
 
548
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
549
+ return typeof obj;
550
+ } : function (obj) {
551
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
552
+ };
553
+ function _classCallCheck(instance, Constructor) {
554
+ if (!(instance instanceof Constructor)) {
555
+ throw new TypeError("Cannot call a class as a function");
556
+ }
557
+ }
558
 
559
  var _createClass = function () {
560
  function defineProperties(target, props) {
564
  descriptor.configurable = true;
565
  if ("value" in descriptor) descriptor.writable = true;
566
  Object.defineProperty(target, descriptor.key, descriptor);
567
+ }
568
  }
569
 
570
  return function (Constructor, protoProps, staticProps) {
571
  if (protoProps) defineProperties(Constructor.prototype, protoProps);
572
  if (staticProps) defineProperties(Constructor, staticProps);
573
  return Constructor;
574
+ };
575
+ }();
576
  function _possibleConstructorReturn(self, call) {
577
  if (!self) {
578
  throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
584
  function _inherits(subClass, superClass) {
585
  if (typeof superClass !== "function" && superClass !== null) {
586
  throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
587
+ }
588
 
589
  subClass.prototype = Object.create(superClass && superClass.prototype, {
590
  constructor: {
592
  enumerable: false,
593
  writable: true,
594
  configurable: true
595
+ }
596
  });
597
  if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
598
+ }
599
 
600
  var Clipboard = function (_Emitter) {
601
  _inherits(Clipboard, _Emitter);
625
  this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
626
  this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
627
  this.text = typeof options.text === 'function' ? options.text : this.defaultText;
628
+ this.container = _typeof(options.container) === 'object' ? options.container : document.body;
629
  }
630
  }, {
631
  key: 'listenClick',
647
  action: this.action(trigger),
648
  target: this.target(trigger),
649
  text: this.text(trigger),
650
+ container: this.container,
651
  trigger: trigger,
652
  emitter: this
653
  });
709
 
710
  module.exports = Clipboard;
711
  });
712
+ }, {"./clipboard-action":7, "good-listener":4, "tiny-emitter":6}]}, {}, [8])(8)
713
+ });
assets/global/plugins/datatables/media/js/jquery.datatables.js CHANGED
@@ -1,6 +1,29 @@
1
- /*! DataTables 1.10.12
 
2
  */
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  (function (factory) {
5
  "use strict";
6
 
@@ -34,25 +57,195 @@
34
  (function ($, window, document, undefined) {
35
  "use strict";
36
 
37
- var DataTable = function (options) {
38
-
39
- this.$ = function (sSelector, oOpts) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  return this.api(true).$(sSelector, oOpts);
41
  };
42
 
43
- this._ = function (sSelector, oOpts) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  return this.api(true).rows(sSelector, oOpts).data();
45
  };
46
 
47
- this.api = function (traditional) {
 
 
 
 
 
 
 
 
 
 
 
48
  return traditional ?
49
  new _Api(
50
- _fnSettingsFromNode(this[_ext.iApiIndex])
51
  ) :
52
  new _Api(this);
53
  };
54
 
55
- this.fnAddData = function (data, redraw) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  var api = this.api(true);
57
 
58
  /* Check if we want to add multiple rows or not */
@@ -67,7 +260,30 @@
67
  return rows.flatten().toArray();
68
  };
69
 
70
- this.fnAdjustColumnSizing = function (bRedraw) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  var api = this.api(true).columns.adjust();
72
  var settings = api.settings()[0];
73
  var scroll = settings.oScroll;
@@ -80,7 +296,23 @@
80
  }
81
  };
82
 
83
- this.fnClearTable = function (bRedraw) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  var api = this.api(true).clear();
85
 
86
  if (bRedraw === undefined || bRedraw) {
@@ -88,15 +320,61 @@
88
  }
89
  };
90
 
91
- this.fnClose = function (nTr) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  this.api(true).row(nTr).child.hide();
93
  };
94
 
95
- this.fnDeleteRow = function (target, callback, redraw) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  var api = this.api(true);
97
  var rows = api.rows(target);
98
  var settings = rows.settings()[0];
99
- var data = settings.aoData[rows[0][0]];
100
 
101
  rows.remove();
102
 
@@ -111,17 +389,70 @@
111
  return data;
112
  };
113
 
114
- this.fnDestroy = function (remove) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  this.api(true).destroy(remove);
116
  };
117
 
118
- this.fnDraw = function (complete) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  // Note that this isn't an exact match to the old call to _fnDraw - it takes
120
  // into account the new data, but can hold position.
121
  this.api(true).draw(complete);
122
  };
123
 
124
- this.fnFilter = function (sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  var api = this.api(true);
126
 
127
  if (iColumn === null || iColumn === undefined) {
@@ -133,7 +464,46 @@
133
  api.draw();
134
  };
135
 
136
- this.fnGetData = function (src, col) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  var api = this.api(true);
138
 
139
  if (src !== undefined) {
@@ -147,7 +517,27 @@
147
  return api.data().toArray();
148
  };
149
 
150
- this.fnGetNodes = function (iRow) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  var api = this.api(true);
152
 
153
  return iRow !== undefined ?
@@ -155,7 +545,37 @@
155
  api.rows().nodes().flatten().toArray();
156
  };
157
 
158
- this.fnGetPosition = function (node) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  var api = this.api(true);
160
  var nodeName = node.nodeName.toUpperCase();
161
 
@@ -173,11 +593,68 @@
173
  return null;
174
  };
175
 
176
- this.fnIsOpen = function (nTr) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  return this.api(true).row(nTr).child.isShown();
178
  };
179
 
180
- this.fnOpen = function (nTr, mHtml, sClass) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  return this.api(true)
182
  .row(nTr)
183
  .child(mHtml, sClass)
@@ -185,7 +662,25 @@
185
  .child()[0];
186
  };
187
 
188
- this.fnPageChange = function (mAction, bRedraw) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  var api = this.api(true).page(mAction);
190
 
191
  if (bRedraw === undefined || bRedraw) {
@@ -193,7 +688,25 @@
193
  }
194
  };
195
 
196
- this.fnSetColumnVis = function (iCol, bShow, bRedraw) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  var api = this.api(true).column(iCol).visible(bShow);
198
 
199
  if (bRedraw === undefined || bRedraw) {
@@ -201,19 +714,96 @@
201
  }
202
  };
203
 
204
- this.fnSettings = function () {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  return _fnSettingsFromNode(this[_ext.iApiIndex]);
206
  };
207
 
208
- this.fnSort = function (aaSort) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  this.api(true).order(aaSort).draw();
210
  };
211
 
212
- this.fnSortListener = function (nNode, iColumn, fnCallback) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  this.api(true).order.listener(nNode, iColumn, fnCallback);
214
  };
215
 
216
- this.fnUpdate = function (mData, mRow, iColumn, bRedraw, bAction) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  var api = this.api(true);
218
 
219
  if (iColumn === undefined || iColumn === null) {
@@ -232,8 +822,27 @@
232
  return 0;
233
  };
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  this.fnVersionCheck = _ext.fnVersionCheck;
236
 
 
237
  var _that = this;
238
  var emptyInit = options === undefined;
239
  var len = this.length;
@@ -260,15 +869,16 @@
260
  options;
261
 
262
  /*global oInit,_that,emptyInit*/
263
- var i = 0,
264
- iLen, j, jLen, k, kLen;
265
  var sId = this.getAttribute('id');
266
  var bInitHandedOff = false;
267
  var defaults = DataTable.defaults;
268
  var $this = $(this);
269
 
 
270
  /* Sanity check */
271
- if (this.nodeName.toLowerCase() != 'table') {
 
272
  _fnLog(null, 0, 'Non-table node initialisation (' + this.nodeName + ')', 2);
273
  return;
274
  }
@@ -284,35 +894,49 @@
284
  /* Setting up the initialisation object */
285
  _fnCamelToHungarian(defaults, $.extend(oInit, $this.data()));
286
 
 
 
287
  /* Check to see if we are re-initialising a table */
288
  var allSettings = DataTable.settings;
289
- for (i = 0, iLen = allSettings.length; i < iLen; i++) {
 
290
  var s = allSettings[i];
291
 
292
  /* Base check on table node */
293
- if (s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this)) {
 
294
  var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
295
  var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
296
 
297
- if (emptyInit || bRetrieve) {
 
298
  return s.oInstance;
299
- } else if (bDestroy) {
 
300
  s.oInstance.fnDestroy();
301
  break;
302
- } else {
 
303
  _fnLog(s, 0, 'Cannot reinitialise DataTable', 3);
304
  return;
305
  }
306
  }
307
 
308
- if (s.sTableId == this.id) {
 
 
 
 
 
 
309
  allSettings.splice(i, 1);
310
  break;
311
  }
312
  }
313
 
314
  /* Ensure the table has an ID - required for accessibility */
315
- if (sId === null || sId === "") {
 
316
  sId = "DataTables_Table_" + (DataTable.ext._unique++);
317
  this.id = sId;
318
  }
@@ -336,18 +960,23 @@
336
  // Backwards compatibility, before we apply all the defaults
337
  _fnCompatOpts(oInit);
338
 
339
- if (oInit.oLanguage) {
 
340
  _fnLanguageCompat(oInit.oLanguage);
341
  }
342
 
343
  // If the length menu is given, but the init display length is not, use the length menu
344
- if (oInit.aLengthMenu && !oInit.iDisplayLength) {
 
345
  oInit.iDisplayLength = $.isArray(oInit.aLengthMenu[0]) ?
346
  oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
347
  }
348
 
 
 
349
  oInit = _fnExtend($.extend(true, {}, defaults), oInit);
350
 
 
351
  // Map the initialisation options onto the settings object
352
  _fnMap(oSettings.oFeatures, oInit, [
353
  "bPaginate",
@@ -382,7 +1011,8 @@
382
  "fnStateSaveCallback",
383
  "renderer",
384
  "searchDelay",
385
- "rowId", ["iCookieDuration", "iStateDuration"], // backwards compat
 
386
  ["oSearch", "oPreviousSearch"],
387
  ["aoSearchCols", "aoPreSearchCols"],
388
  ["iDisplayLength", "_iDisplayLength"],
@@ -417,11 +1047,16 @@
417
  var oClasses = oSettings.oClasses;
418
 
419
  // @todo Remove in 1.11
420
- if (oInit.bJQueryUI) {
421
-
 
 
 
422
  $.extend(oClasses, DataTable.ext.oJUIClasses, oInit.oClasses);
423
 
424
- if (oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip") {
 
 
425
  oSettings.sDom = '<"H"lfr>t<"F"ip>';
426
  }
427
 
@@ -430,18 +1065,22 @@
430
  } else if ($.isPlainObject(oSettings.renderer) && !oSettings.renderer.header) {
431
  oSettings.renderer.header = 'jqueryui';
432
  }
433
- } else {
 
434
  $.extend(oClasses, DataTable.ext.classes, oInit.oClasses);
435
  }
436
  $this.addClass(oClasses.sTable);
437
 
438
- if (oSettings.iInitDisplayStart === undefined) {
 
 
439
  /* Display start point, taking into account the save saving */
440
  oSettings.iInitDisplayStart = oInit.iDisplayStart;
441
  oSettings._iDisplayStart = oInit.iDisplayStart;
442
  }
443
 
444
- if (oInit.iDeferLoading !== null) {
 
445
  oSettings.bDeferLoading = true;
446
  var tmp = $.isArray(oInit.iDeferLoading);
447
  oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
@@ -452,7 +1091,12 @@
452
  var oLanguage = oSettings.oLanguage;
453
  $.extend(true, oLanguage, oInit.oLanguage);
454
 
455
- if (oLanguage.sUrl !== "") {
 
 
 
 
 
456
  $.ajax({
457
  dataType: 'json',
458
  url: oLanguage.sUrl,
@@ -469,13 +1113,19 @@
469
  });
470
  bInitHandedOff = true;
471
  }
472
- if (oInit.asStripeClasses === null) {
 
 
 
 
 
473
  oSettings.asStripeClasses = [
474
  oClasses.sStripeOdd,
475
  oClasses.sStripeEven
476
  ];
477
  }
478
 
 
479
  var stripeClasses = oSettings.asStripeClasses;
480
  var rowOne = $this.children('tbody').find('tr').eq(0);
481
  if ($.inArray(true, $.map(stripeClasses, function (el, i) {
@@ -485,31 +1135,46 @@
485
  oSettings.asDestroyStripes = stripeClasses.slice();
486
  }
487
 
 
 
 
 
488
  var anThs = [];
489
  var aoColumnsInit;
490
  var nThead = this.getElementsByTagName('thead');
491
- if (nThead.length !== 0) {
 
492
  _fnDetectHeader(oSettings.aoHeader, nThead[0]);
493
  anThs = _fnGetUniqueThs(oSettings);
494
  }
495
 
496
- if (oInit.aoColumns === null) {
 
 
497
  aoColumnsInit = [];
498
- for (i = 0, iLen = anThs.length; i < iLen; i++) {
 
499
  aoColumnsInit.push(null);
500
  }
501
- } else {
 
502
  aoColumnsInit = oInit.aoColumns;
503
  }
504
 
505
- for (i = 0, iLen = aoColumnsInit.length; i < iLen; i++) {
 
 
506
  _fnAddColumn(oSettings, anThs ? anThs[i] : null);
507
  }
508
 
 
509
  _fnApplyColumnDefs(oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
510
  _fnColumnOptions(oSettings, iCol, oDef);
511
  });
512
 
 
 
 
513
  if (rowOne.length) {
514
  var a = function (cell, name) {
515
  return cell.getAttribute('data-' + name) !== null ? name : null;
@@ -537,89 +1202,144 @@
537
  }
538
 
539
  var features = oSettings.oFeatures;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
 
541
- if (oInit.bStateSave) {
542
- features.bStateSave = true;
543
- _fnLoadState(oSettings, oInit);
544
- _fnCallbackReg(oSettings, 'aoDrawCallback', _fnSaveState, 'state_save');
545
- }
546
 
547
- if (oInit.aaSorting === undefined) {
548
- var sorting = oSettings.aaSorting;
549
- for (i = 0, iLen = sorting.length; i < iLen; i++) {
550
- sorting[i][1] = oSettings.aoColumns[i].asSorting[0];
551
- }
552
- }
553
 
554
- _fnSortingClasses(oSettings);
 
 
 
 
 
 
 
 
555
 
556
- if (features.bSort) {
557
  _fnCallbackReg(oSettings, 'aoDrawCallback', function () {
558
- if (oSettings.bSorted) {
559
- var aSort = _fnSortFlatten(oSettings);
560
- var sortedColumns = {};
 
561
 
562
- $.each(aSort, function (i, val) {
563
- sortedColumns[val.src] = val.dir;
564
- });
565
 
566
- _fnCallbackFire(oSettings, null, 'order', [oSettings, aSort, sortedColumns]);
567
- _fnSortAria(oSettings);
568
- }
 
 
 
 
 
569
  });
570
- }
571
 
572
- _fnCallbackReg(oSettings, 'aoDrawCallback', function () {
573
- if (oSettings.bSorted || _fnDataSource(oSettings) === 'ssp' || features.bDeferRender) {
574
- _fnSortingClasses(oSettings);
575
  }
576
- }, 'sc');
577
-
578
- var captions = $this.children('caption').each(function () {
579
- this._captionSide = $this.css('caption-side');
580
- });
581
 
582
- var thead = $this.children('thead');
583
- if (thead.length === 0) {
584
- thead = $('<thead/>').appendTo(this);
585
- }
586
- oSettings.nTHead = thead[0];
587
 
588
- var tbody = $this.children('tbody');
589
- if (tbody.length === 0) {
590
- tbody = $('<tbody/>').appendTo(this);
591
- }
592
- oSettings.nTBody = tbody[0];
 
593
 
594
- var tfoot = $this.children('tfoot');
595
- if (tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "")) {
596
- tfoot = $('<tfoot/>').appendTo(this);
597
- }
 
 
598
 
599
- if (tfoot.length === 0 || tfoot.children().length === 0) {
600
- $this.addClass(oClasses.sNoFooter);
601
- } else if (tfoot.length > 0) {
602
- oSettings.nTFoot = tfoot[0];
603
- _fnDetectHeader(oSettings.aoFooter, oSettings.nTFoot);
604
- }
605
- if (oInit.aaData) {
606
- for (i = 0; i < oInit.aaData.length; i++) {
607
- _fnAddData(oSettings, oInit.aaData[i]);
 
 
608
  }
609
- } else if (oSettings.bDeferLoading || _fnDataSource(oSettings) == 'dom') {
610
- _fnAddTr(oSettings, $(oSettings.nTBody).children('tr'));
611
- }
612
 
613
- oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
614
- oSettings.bInitialised = true;
 
 
 
 
 
 
 
 
 
 
 
615
 
616
- if (bInitHandedOff === false) {
617
- _fnInitialise(oSettings);
 
 
 
 
 
 
618
  }
 
619
  });
620
  _that = null;
621
  return this;
622
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
  var _ext; // DataTable.ext
624
  var _Api; // DataTable.Api
625
  var _api_register; // DataTable.Api.register
@@ -628,34 +1348,56 @@
628
  var _re_dic = {};
629
  var _re_new_lines = /[\r\n]/g;
630
  var _re_html = /<.*?>/g;
631
- var _re_date_start = /^[\w\+\-]/;
632
- var _re_date_end = /[\w\+\-]$/;
633
 
 
 
 
 
 
634
  var _re_escape_regex = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-'].join('|\\') + ')', 'g');
635
 
 
 
 
 
 
 
 
 
 
 
636
  var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
 
 
637
  var _empty = function (d) {
638
  return !d || d === true || d === '-' ? true : false;
639
  };
640
 
 
641
  var _intVal = function (s) {
642
  var integer = parseInt(s, 10);
643
  return !isNaN(integer) && isFinite(s) ? integer : null;
644
  };
645
 
 
 
646
  var _numToDecimal = function (num, decimalPoint) {
647
  // Cache created regular expressions for speed as this function is called often
648
- if (!_re_dic[decimalPoint]) {
649
- _re_dic[decimalPoint] = new RegExp(_fnEscapeRegex(decimalPoint), 'g');
650
  }
651
  return typeof num === 'string' && decimalPoint !== '.' ?
652
- num.replace(/\./g, '').replace(_re_dic[decimalPoint], '.') :
653
  num;
654
  };
655
 
 
656
  var _isNumber = function (d, decimalPoint, formatted) {
657
  var strType = typeof d === 'string';
658
 
 
 
 
659
  if (_empty(d)) {
660
  return true;
661
  }
@@ -671,10 +1413,13 @@
671
  return !isNaN(parseFloat(d)) && isFinite(d);
672
  };
673
 
 
 
674
  var _isHtml = function (d) {
675
  return _empty(d) || typeof d === 'string';
676
  };
677
 
 
678
  var _htmlNumeric = function (d, decimalPoint, formatted) {
679
  if (_empty(d)) {
680
  return true;
@@ -688,21 +1433,23 @@
688
  null;
689
  };
690
 
 
691
  var _pluck = function (a, prop, prop2) {
692
  var out = [];
693
- var i = 0,
694
- ien = a.length;
695
 
 
 
696
  if (prop2 !== undefined) {
697
  for (; i < ien; i++) {
698
- if (a[i] && a[i][prop]) {
699
- out.push(a[i][prop][prop2]);
700
  }
701
  }
702
  } else {
703
  for (; i < ien; i++) {
704
  if (a[i]) {
705
- out.push(a[i][prop]);
706
  }
707
  }
708
  }
@@ -710,25 +1457,34 @@
710
  return out;
711
  };
712
 
713
- var _pluck_order = function (a, order, prop, prop2) {
 
 
 
 
714
  var out = [];
715
- var i = 0,
716
- ien = order.length;
 
 
717
  if (prop2 !== undefined) {
718
  for (; i < ien; i++) {
719
- if (a[order[i]][prop]) {
720
- out.push(a[order[i]][prop][prop2]);
721
  }
722
  }
723
  } else {
724
  for (; i < ien; i++) {
725
- out.push(a[order[i]][prop]);
726
  }
727
  }
728
 
729
  return out;
730
  };
731
- var _range = function (len, start) {
 
 
 
732
  var out = [];
733
  var end;
734
 
@@ -747,7 +1503,9 @@
747
  return out;
748
  };
749
 
750
- var _removeEmpty = function (a) {
 
 
751
  var out = [];
752
 
753
  for (var i = 0, ien = a.length; i < ien; i++) {
@@ -759,12 +1517,58 @@
759
  return out;
760
  };
761
 
 
762
  var _stripHtml = function (d) {
763
  return d.replace(_re_html, '');
764
  };
765
 
766
- var _unique = function (src) {
767
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
768
  var
769
  out = [],
770
  val,
@@ -787,8 +1591,26 @@
787
  return out;
788
  };
789
 
790
- DataTable.util = {
791
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
792
  throttle: function (fn, freq) {
793
  var
794
  frequency = freq !== undefined ? freq : 200,
@@ -815,12 +1637,28 @@
815
  };
816
  },
817
 
 
 
 
 
 
 
818
  escapeRegex: function (val) {
819
  return val.replace(_re_escape_regex, '\\$1');
820
  }
821
  };
822
 
823
- function _fnHungarianMap(o) {
 
 
 
 
 
 
 
 
 
 
824
  var
825
  hungarian = 'a aa ai ao as b fn i m o s ',
826
  match,
@@ -830,11 +1668,13 @@
830
  $.each(o, function (key, val) {
831
  match = key.match(/^([^A-Z]+?)([A-Z])/);
832
 
833
- if (match && hungarian.indexOf(match[1] + ' ') !== -1) {
 
834
  newKey = key.replace(match[0], match[2].toLowerCase());
835
- map[newKey] = key;
836
 
837
- if (match[1] === 'o') {
 
838
  _fnHungarianMap(o[key]);
839
  }
840
  }
@@ -843,7 +1683,20 @@
843
  o._hungarianMap = map;
844
  }
845
 
846
- function _fnCamelToHungarian(src, user, force) {
 
 
 
 
 
 
 
 
 
 
 
 
 
847
  if (!src._hungarianMap) {
848
  _fnHungarianMap(src);
849
  }
@@ -851,39 +1704,57 @@
851
  var hungarianKey;
852
 
853
  $.each(user, function (key, val) {
854
- hungarianKey = src._hungarianMap[key];
855
 
856
- if (hungarianKey !== undefined && (force || user[hungarianKey] === undefined)) {
 
857
  // For objects, we need to buzz down into the object to copy parameters
858
- if (hungarianKey.charAt(0) === 'o') {
 
859
  // Copy the camelCase options over to the hungarian
860
- if (!user[hungarianKey]) {
861
- user[hungarianKey] = {};
862
  }
863
  $.extend(true, user[hungarianKey], user[key]);
864
 
865
  _fnCamelToHungarian(src[hungarianKey], user[hungarianKey], force);
866
  } else {
867
- user[hungarianKey] = user[key];
868
  }
869
  }
870
  });
871
  }
872
 
873
- function _fnLanguageCompat(lang) {
 
 
 
 
 
 
 
 
 
874
  var defaults = DataTable.defaults.oLanguage;
875
  var zeroRecords = lang.sZeroRecords;
876
 
 
 
 
877
  if (!lang.sEmptyTable && zeroRecords &&
878
- defaults.sEmptyTable === "No data available in table") {
 
879
  _fnMap(lang, lang, 'sZeroRecords', 'sEmptyTable');
880
  }
881
 
 
882
  if (!lang.sLoadingRecords && zeroRecords &&
883
- defaults.sLoadingRecords === "Loading...") {
 
884
  _fnMap(lang, lang, 'sZeroRecords', 'sLoadingRecords');
885
  }
886
 
 
887
  if (lang.sInfoThousands) {
888
  lang.sThousands = lang.sInfoThousands;
889
  }
@@ -894,13 +1765,28 @@
894
  }
895
  }
896
 
 
 
 
 
 
 
 
897
  var _fnCompatMap = function (o, knew, old) {
898
- if (o[knew] !== undefined) {
899
- o[old] = o[knew];
900
  }
901
  };
902
 
903
- function _fnCompatOpts(init) {
 
 
 
 
 
 
 
 
904
  _fnCompatMap(init, 'ordering', 'bSort');
905
  _fnCompatMap(init, 'orderMulti', 'bSortMulti');
906
  _fnCompatMap(init, 'orderClasses', 'bSortClasses');
@@ -912,6 +1798,7 @@
912
  _fnCompatMap(init, 'pageLength', 'iDisplayLength');
913
  _fnCompatMap(init, 'searching', 'bFilter');
914
 
 
915
  if (typeof init.sScrollX === 'boolean') {
916
  init.sScrollX = init.sScrollX ? '100%' : '';
917
  }
@@ -919,6 +1806,8 @@
919
  init.scrollX = init.scrollX ? '100%' : '';
920
  }
921
 
 
 
922
  var searchCols = init.aoSearchCols;
923
 
924
  if (searchCols) {
@@ -930,29 +1819,48 @@
930
  }
931
  }
932
 
933
- function _fnCompatCols(init) {
 
 
 
 
 
 
 
 
934
  _fnCompatMap(init, 'orderable', 'bSortable');
935
  _fnCompatMap(init, 'orderData', 'aDataSort');
936
  _fnCompatMap(init, 'orderSequence', 'asSorting');
937
  _fnCompatMap(init, 'orderDataType', 'sortDataType');
938
 
 
939
  var dataSort = init.aDataSort;
940
- if (dataSort && !$.isArray(dataSort)) {
941
  init.aDataSort = [dataSort];
942
  }
943
  }
944
 
945
- function _fnBrowserDetect(settings) {
946
 
 
 
 
 
 
 
 
 
 
 
947
  if (!DataTable.__browser) {
948
  var browser = {};
949
  DataTable.__browser = browser;
950
 
 
951
  var n = $('<div/>')
952
  .css({
953
  position: 'fixed',
954
  top: 0,
955
- left: 0,
956
  height: 1,
957
  width: 1,
958
  overflow: 'hidden'
@@ -979,12 +1887,29 @@
979
  var outer = n.children();
980
  var inner = outer.children();
981
 
 
 
 
 
 
 
 
 
 
 
 
982
  browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
983
 
 
 
 
984
  browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
985
 
 
 
986
  browser.bScrollbarLeft = Math.round(inner.offset().left) !== 1;
987
 
 
988
  browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
989
 
990
  n.remove();
@@ -994,7 +1919,15 @@
994
  settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
995
  }
996
 
997
- function _fnReduce(that, fn, init, start, end, inc) {
 
 
 
 
 
 
 
 
998
  var
999
  i = start,
1000
  value,
@@ -1021,7 +1954,14 @@
1021
  return value;
1022
  }
1023
 
1024
- function _fnAddColumn(oSettings, nTh) {
 
 
 
 
 
 
 
1025
  // Add column to aoColumns array
1026
  var oDefaults = DataTable.defaults.column;
1027
  var iCol = oSettings.aoColumns.length;
@@ -1034,48 +1974,84 @@
1034
  });
1035
  oSettings.aoColumns.push(oCol);
1036
 
 
 
 
1037
  var searchCols = oSettings.aoPreSearchCols;
1038
- searchCols[iCol] = $.extend({}, DataTable.models.oSearch, searchCols[iCol]);
1039
 
 
1040
  _fnColumnOptions(oSettings, iCol, $(nTh).data());
1041
  }
1042
 
1043
- function _fnColumnOptions(oSettings, iCol, oOptions) {
1044
- var oCol = oSettings.aoColumns[iCol];
 
 
 
 
 
 
 
 
 
1045
  var oClasses = oSettings.oClasses;
1046
  var th = $(oCol.nTh);
1047
 
 
 
1048
  if (!oCol.sWidthOrig) {
1049
  // Width attribute
1050
  oCol.sWidthOrig = th.attr('width') || null;
 
 
1051
  var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
1052
  if (t) {
1053
  oCol.sWidthOrig = t[1];
1054
  }
1055
  }
1056
- if (oOptions !== undefined && oOptions !== null) {
1057
 
 
 
 
 
1058
  _fnCompatCols(oOptions);
1059
 
1060
  // Map camel case parameters to their Hungarian counterparts
1061
  _fnCamelToHungarian(DataTable.defaults.column, oOptions);
1062
- if (oOptions.mDataProp !== undefined && !oOptions.mData) {
 
 
 
1063
  oOptions.mData = oOptions.mDataProp;
1064
  }
1065
- if (oOptions.sType) {
 
 
1066
  oCol._sManualType = oOptions.sType;
1067
  }
1068
- if (oOptions.className && !oOptions.sClass) {
 
 
 
 
1069
  oOptions.sClass = oOptions.className;
1070
  }
1071
 
1072
  $.extend(oCol, oOptions);
1073
  _fnMap(oCol, oOptions, "sWidth", "sWidthOrig");
1074
- if (oOptions.iDataSort !== undefined) {
 
 
 
 
 
1075
  oCol.aDataSort = [oOptions.iDataSort];
1076
  }
1077
  _fnMap(oCol, oOptions, "aDataSort");
1078
  }
 
 
1079
  var mDataSrc = oCol.mData;
1080
  var mData = _fnGetObjectDataFn(mDataSrc);
1081
  var mRender = oCol.mRender ? _fnGetObjectDataFn(oCol.mRender) : null;
@@ -1099,52 +2075,82 @@
1099
  return _fnSetObjectDataFn(mDataSrc)(rowData, val, meta);
1100
  };
1101
 
 
 
1102
  if (typeof mDataSrc !== 'number') {
1103
  oSettings._rowReadObject = true;
1104
  }
1105
 
1106
- if (!oSettings.oFeatures.bSort) {
 
 
1107
  oCol.bSortable = false;
1108
  th.addClass(oClasses.sSortableNone); // Have to add class here as order event isn't called
1109
  }
1110
 
 
1111
  var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
1112
  var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
1113
- if (!oCol.bSortable || (!bAsc && !bDesc)) {
 
1114
  oCol.sSortingClass = oClasses.sSortableNone;
1115
  oCol.sSortingClassJUI = "";
1116
- } else if (bAsc && !bDesc) {
 
1117
  oCol.sSortingClass = oClasses.sSortableAsc;
1118
  oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
1119
- } else if (!bAsc && bDesc) {
 
1120
  oCol.sSortingClass = oClasses.sSortableDesc;
1121
  oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
1122
- } else {
 
1123
  oCol.sSortingClass = oClasses.sSortable;
1124
  oCol.sSortingClassJUI = oClasses.sSortJUI;
1125
  }
1126
  }
1127
 
1128
- function _fnAdjustColumnSizing(settings) {
 
 
 
 
 
 
 
 
1129
  /* Not interested in doing column width calculation if auto-width is disabled */
1130
- if (settings.oFeatures.bAutoWidth !== false) {
 
1131
  var columns = settings.aoColumns;
1132
 
1133
  _fnCalculateColumnWidths(settings);
1134
- for (var i = 0, iLen = columns.length; i < iLen; i++) {
 
1135
  columns[i].nTh.style.width = columns[i].sWidth;
1136
  }
1137
  }
1138
 
1139
  var scroll = settings.oScroll;
1140
- if (scroll.sY !== '' || scroll.sX !== '') {
 
1141
  _fnScrollDraw(settings);
1142
  }
1143
 
1144
  _fnCallbackFire(settings, null, 'column-sizing', [settings]);
1145
  }
1146
 
1147
- function _fnVisibleToColumnIndex(oSettings, iMatch) {
 
 
 
 
 
 
 
 
 
 
1148
  var aiVis = _fnGetColumns(oSettings, 'bVisible');
1149
 
1150
  return typeof aiVis[iMatch] === 'number' ?
@@ -1152,14 +2158,32 @@
1152
  null;
1153
  }
1154
 
1155
- function _fnColumnIndexToVisible(oSettings, iMatch) {
 
 
 
 
 
 
 
 
 
 
1156
  var aiVis = _fnGetColumns(oSettings, 'bVisible');
1157
  var iPos = $.inArray(iMatch, aiVis);
1158
 
1159
  return iPos !== -1 ? iPos : null;
1160
  }
1161
 
1162
- function _fnVisbleColumns(oSettings) {
 
 
 
 
 
 
 
 
1163
  var vis = 0;
1164
 
1165
  // No reduce in IE8, use a loop for now
@@ -1172,7 +2196,17 @@
1172
  return vis;
1173
  }
1174
 
1175
- function _fnGetColumns(oSettings, sParam) {
 
 
 
 
 
 
 
 
 
 
1176
  var a = [];
1177
 
1178
  $.map(oSettings.aoColumns, function (val, i) {
@@ -1184,14 +2218,21 @@
1184
  return a;
1185
  }
1186
 
1187
- function _fnColumnTypes(settings) {
 
 
 
 
 
 
 
1188
  var columns = settings.aoColumns;
1189
  var data = settings.aoData;
1190
  var types = DataTable.ext.type.detect;
1191
  var i, ien, j, jen, k, ken;
1192
  var col, cell, detectedType, cache;
1193
 
1194
- // For each column, spin over the
1195
  for (i = 0, ien = columns.length; i < ien; i++) {
1196
  col = columns[i];
1197
  cache = [];
@@ -1201,25 +2242,39 @@
1201
  } else if (!col.sType) {
1202
  for (j = 0, jen = types.length; j < jen; j++) {
1203
  for (k = 0, ken = data.length; k < ken; k++) {
1204
-
 
1205
  if (cache[k] === undefined) {
1206
  cache[k] = _fnGetCellData(settings, k, i, 'type');
1207
  }
1208
 
1209
  detectedType = types[j](cache[k], settings);
1210
 
 
 
 
 
 
1211
  if (!detectedType && j !== types.length - 1) {
1212
  break;
1213
  }
 
 
 
1214
  if (detectedType === 'html') {
1215
  break;
1216
  }
1217
  }
 
 
 
1218
  if (detectedType) {
1219
  col.sType = detectedType;
1220
  break;
1221
  }
1222
  }
 
 
1223
  if (!col.sType) {
1224
  col.sType = 'string';
1225
  }
@@ -1227,37 +2282,65 @@
1227
  }
1228
  }
1229
 
1230
- function _fnApplyColumnDefs(oSettings, aoColDefs, aoCols, fn) {
 
 
 
 
 
 
 
 
 
 
 
 
 
1231
  var i, iLen, j, jLen, k, kLen, def;
1232
  var columns = oSettings.aoColumns;
1233
 
1234
- if (aoColDefs) {
1235
-
1236
- for (i = aoColDefs.length - 1; i >= 0; i--) {
 
 
 
1237
  def = aoColDefs[i];
 
 
1238
  var aTargets = def.targets !== undefined ?
1239
  def.targets :
1240
  def.aTargets;
1241
 
1242
- if (!$.isArray(aTargets)) {
 
1243
  aTargets = [aTargets];
1244
  }
1245
 
1246
- for (j = 0, jLen = aTargets.length; j < jLen; j++) {
1247
- if (typeof aTargets[j] === 'number' && aTargets[j] >= 0) {
 
 
1248
  /* Add columns that we don't yet know about */
1249
- while (columns.length <= aTargets[j]) {
 
1250
  _fnAddColumn(oSettings);
1251
  }
 
 
1252
  fn(aTargets[j], def);
1253
- } else if (typeof aTargets[j] === 'number' && aTargets[j] < 0) {
 
1254
  /* Negative integer, right to left column counting */
1255
  fn(columns.length + aTargets[j], def);
1256
- } else if (typeof aTargets[j] === 'string') {
 
1257
  /* Class name matching on TH element */
1258
- for (k = 0, kLen = columns.length; k < kLen; k++) {
 
1259
  if (aTargets[j] == "_all" ||
1260
- $(columns[k].nTh).hasClass(aTargets[j])) {
 
1261
  fn(k, def);
1262
  }
1263
  }
@@ -1266,14 +2349,31 @@
1266
  }
1267
  }
1268
 
1269
- if (aoCols) {
1270
- for (i = 0, iLen = aoCols.length; i < iLen; i++) {
 
 
 
1271
  fn(i, aoCols[i]);
1272
  }
1273
  }
1274
  }
1275
 
1276
- function _fnAddData(oSettings, aDataIn, nTr, anTds) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1277
  /* Create the object for storing information about this new row */
1278
  var iRow = oSettings.aoData.length;
1279
  var oData = $.extend(true, {}, DataTable.models.oRow, {
@@ -1284,29 +2384,49 @@
1284
  oData._aData = aDataIn;
1285
  oSettings.aoData.push(oData);
1286
 
 
1287
  var nTd, sThisType;
1288
  var columns = oSettings.aoColumns;
1289
 
1290
- for (var i = 0, iLen = columns.length; i < iLen; i++) {
 
 
1291
  columns[i].sType = null;
1292
  }
1293
 
 
1294
  oSettings.aiDisplayMaster.push(iRow);
1295
 
1296
  var id = oSettings.rowIdFn(aDataIn);
1297
  if (id !== undefined) {
1298
- oSettings.aIds[id] = oData;
1299
  }
1300
 
1301
- if (nTr || !oSettings.oFeatures.bDeferRender) {
 
 
1302
  _fnCreateTr(oSettings, iRow, nTr, anTds);
1303
  }
1304
 
1305
  return iRow;
1306
  }
1307
 
1308
- function _fnAddTr(settings, trs) {
 
 
 
 
 
 
 
 
 
 
 
 
1309
  var row;
 
 
1310
  if (!(trs instanceof $)) {
1311
  trs = $(trs);
1312
  }
@@ -1317,15 +2437,45 @@
1317
  });
1318
  }
1319
 
1320
- function _fnNodeToDataIndex(oSettings, n) {
 
 
 
 
 
 
 
 
 
1321
  return (n._DT_RowIndex !== undefined) ? n._DT_RowIndex : null;
1322
  }
1323
 
1324
- function _fnNodeToColumnIndex(oSettings, iRow, n) {
1325
- return $.inArray(n, oSettings.aoData[iRow].anCells);
 
 
 
 
 
 
 
 
 
 
1326
  }
1327
 
1328
- function _fnGetCellData(settings, rowIdx, colIdx, type) {
 
 
 
 
 
 
 
 
 
 
 
1329
  var draw = settings.iDraw;
1330
  var col = settings.aoColumns[colIdx];
1331
  var rowData = settings.aoData[rowIdx]._aData;
@@ -1346,10 +2496,13 @@
1346
  return defaultContent;
1347
  }
1348
 
 
 
1349
  if ((cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined) {
1350
  cellData = defaultContent;
1351
  } else if (typeof cellData === 'function') {
1352
-
 
1353
  return cellData.call(rowData);
1354
  }
1355
 
@@ -1359,7 +2512,17 @@
1359
  return cellData;
1360
  }
1361
 
1362
- function _fnSetCellData(settings, rowIdx, colIdx, val) {
 
 
 
 
 
 
 
 
 
 
1363
  var col = settings.aoColumns[colIdx];
1364
  var rowData = settings.aoData[rowIdx]._aData;
1365
 
@@ -1370,17 +2533,35 @@
1370
  });
1371
  }
1372
 
 
 
1373
  var __reArray = /\[.*?\]$/;
1374
  var __reFn = /\(\)$/;
1375
 
1376
- function _fnSplitObjNotation(str) {
 
 
 
 
 
 
1377
  return $.map(str.match(/(\\.|[^\.])+/g) || [''], function (s) {
1378
- return s.replace(/\\./g, '.');
1379
  });
1380
  }
1381
 
1382
- function _fnGetObjectDataFn(mSource) {
1383
- if ($.isPlainObject(mSource)) {
 
 
 
 
 
 
 
 
 
 
1384
  /* Build an object of get functions, and wrap them in a single call */
1385
  var o = {};
1386
  $.each(mSource, function (key, val) {
@@ -1395,61 +2576,82 @@
1395
  t(data, type, row, meta) :
1396
  data;
1397
  };
1398
- } else if (mSource === null) {
 
1399
  /* Give an empty string for rendering / sorting etc */
1400
  return function (data) { // type, row and meta also passed, but not used
1401
  return data;
1402
  };
1403
- } else if (typeof mSource === 'function') {
 
1404
  return function (data, type, row, meta) {
1405
  return mSource(data, type, row, meta);
1406
  };
1407
  } else if (typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
1408
- mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1)) {
1409
-
 
 
 
 
 
 
1410
  var fetchData = function (data, type, src) {
1411
  var arrayNotation, funcNotation, out, innerSrc;
1412
 
1413
- if (src !== "") {
 
1414
  var a = _fnSplitObjNotation(src);
1415
 
1416
- for (var i = 0, iLen = a.length; i < iLen; i++) {
 
1417
  // Check if we are dealing with special notation
1418
  arrayNotation = a[i].match(__reArray);
1419
  funcNotation = a[i].match(__reFn);
1420
 
1421
- if (arrayNotation) {
 
1422
  // Array notation
1423
  a[i] = a[i].replace(__reArray, '');
1424
 
 
1425
  if (a[i] !== "") {
1426
- data = data[a[i]];
1427
  }
1428
  out = [];
1429
 
 
1430
  a.splice(0, i + 1);
1431
  innerSrc = a.join('.');
1432
 
 
1433
  if ($.isArray(data)) {
1434
  for (var j = 0, jLen = data.length; j < jLen; j++) {
1435
  out.push(fetchData(data[j], type, innerSrc));
1436
  }
1437
  }
 
 
 
1438
  var join = arrayNotation[0].substring(1, arrayNotation[0].length - 1);
1439
  data = (join === "") ? out : out.join(join);
1440
 
 
 
1441
  break;
1442
- } else if (funcNotation) {
 
1443
  // Function call
1444
  a[i] = a[i].replace(__reFn, '');
1445
- data = data[a[i]]();
1446
  continue;
1447
  }
1448
 
1449
- if (data === null || data[a[i]] === undefined) {
 
1450
  return undefined;
1451
  }
1452
- data = data[a[i]];
1453
  }
1454
  }
1455
 
@@ -1459,7 +2661,8 @@
1459
  return function (data, type) { // row and meta also passed, but not used
1460
  return fetchData(data, type, mSource);
1461
  };
1462
- } else {
 
1463
  /* Array or flat object mapping */
1464
  return function (data, type) { // row and meta also passed, but not used
1465
  return data[mSource];
@@ -1467,33 +2670,52 @@
1467
  }
1468
  }
1469
 
1470
- function _fnSetObjectDataFn(mSource) {
1471
- if ($.isPlainObject(mSource)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1472
  return _fnSetObjectDataFn(mSource._);
1473
- } else if (mSource === null) {
 
1474
  /* Nothing to do when the data source is null */
1475
  return function () {};
1476
- } else if (typeof mSource === 'function') {
 
1477
  return function (data, val, meta) {
1478
  mSource(data, 'set', val, meta);
1479
  };
1480
  } else if (typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
1481
- mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1)) {
 
1482
  /* Like the get, we need to get data from a nested object */
1483
  var setData = function (data, val, src) {
1484
- var a = _fnSplitObjNotation(src),
1485
- b;
1486
  var aLast = a[a.length - 1];
1487
  var arrayNotation, funcNotation, o, innerSrc;
1488
 
1489
- for (var i = 0, iLen = a.length - 1; i < iLen; i++) {
 
1490
  // Check if we are dealing with an array notation request
1491
  arrayNotation = a[i].match(__reArray);
1492
  funcNotation = a[i].match(__reFn);
1493
 
1494
- if (arrayNotation) {
 
1495
  a[i] = a[i].replace(__reArray, '');
1496
- data[a[i]] = [];
1497
 
1498
  // Get the remainder of the nested object to set so we can recurse
1499
  b = a.slice();
@@ -1501,39 +2723,59 @@
1501
  innerSrc = b.join('.');
1502
 
1503
  // Traverse each entry in the array setting the properties requested
1504
- if ($.isArray(val)) {
1505
- for (var j = 0, jLen = val.length; j < jLen; j++) {
 
 
1506
  o = {};
1507
  setData(o, val[j], innerSrc);
1508
- data[a[i]].push(o);
1509
  }
1510
- } else {
1511
-
1512
- data[a[i]] = val;
 
 
 
1513
  }
 
 
 
1514
  return;
1515
- } else if (funcNotation) {
 
1516
  // Function call
1517
  a[i] = a[i].replace(__reFn, '');
1518
- data = data[a[i]](val);
1519
  }
1520
- if (data[a[i]] === null || data[a[i]] === undefined) {
1521
- data[a[i]] = {};
 
 
 
 
1522
  }
1523
- data = data[a[i]];
1524
  }
1525
 
1526
- if (aLast.match(__reFn)) {
1527
- data = data[aLast.replace(__reFn, '')](val);
1528
- } else {
1529
- data[aLast.replace(__reArray, '')] = val;
 
 
 
 
 
 
1530
  }
1531
  };
1532
 
1533
  return function (data, val) { // meta is also passed in, but not used
1534
  return setData(data, val, mSource);
1535
  };
1536
- } else {
 
1537
  /* Array or flat object mapping */
1538
  return function (data, val) { // meta is also passed in, but not used
1539
  data[mSource] = val;
@@ -1541,38 +2783,86 @@
1541
  }
1542
  }
1543
 
1544
- function _fnGetDataMaster(settings) {
 
 
 
 
 
 
 
 
1545
  return _pluck(settings.aoData, '_aData');
1546
  }
1547
 
1548
- function _fnClearTable(settings) {
 
 
 
 
 
 
 
1549
  settings.aoData.length = 0;
1550
  settings.aiDisplayMaster.length = 0;
1551
  settings.aiDisplay.length = 0;
1552
  settings.aIds = {};
1553
  }
1554
 
1555
- function _fnDeleteIndex(a, iTarget, splice) {
 
 
 
 
 
 
 
 
 
1556
  var iTargetIndex = -1;
1557
 
1558
- for (var i = 0, iLen = a.length; i < iLen; i++) {
1559
- if (a[i] == iTarget) {
 
 
1560
  iTargetIndex = i;
1561
- } else if (a[i] > iTarget) {
 
1562
  a[i]--;
1563
  }
1564
  }
1565
 
1566
- if (iTargetIndex != -1 && splice === undefined) {
 
1567
  a.splice(iTargetIndex, 1);
1568
  }
1569
  }
1570
 
1571
- function _fnInvalidate(settings, rowIdx, src, colIdx) {
1572
- var row = settings.aoData[rowIdx];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1573
  var i, ien;
1574
  var cellWrite = function (cell, col) {
1575
-
 
 
1576
  while (cell.childNodes.length) {
1577
  cell.removeChild(cell.firstChild);
1578
  }
@@ -1580,6 +2870,7 @@
1580
  cell.innerHTML = _fnGetCellData(settings, rowIdx, col, 'display');
1581
  };
1582
 
 
1583
  if (src === 'dom' || ((!src || src === 'auto') && row.src === 'dom')) {
1584
  // Read the data from the DOM
1585
  row._aData = _fnGetRowElements(
@@ -1601,32 +2892,59 @@
1601
  }
1602
  }
1603
 
 
 
1604
  row._aSortData = null;
1605
  row._aFilterData = null;
 
 
 
1606
  var cols = settings.aoColumns;
1607
  if (colIdx !== undefined) {
1608
- cols[colIdx].sType = null;
1609
  } else {
1610
  for (i = 0, ien = cols.length; i < ien; i++) {
1611
  cols[i].sType = null;
1612
  }
 
 
1613
  _fnRowAttributes(settings, row);
1614
  }
1615
  }
1616
 
1617
- function _fnGetRowElements(settings, row, colIdx, d) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1618
  var
1619
  tds = [],
1620
  td = row.firstChild,
1621
- name, col, o, i = 0,
1622
- contents,
1623
  columns = settings.aoColumns,
1624
  objectRead = settings._rowReadObject;
1625
 
1626
  // Allow the data object to be passed in, or construct
1627
  d = d !== undefined ?
1628
  d :
1629
- objectRead ? {} : [];
 
 
1630
 
1631
  var attr = function (str, td) {
1632
  if (typeof str === 'string') {
@@ -1640,6 +2958,7 @@
1640
  }
1641
  };
1642
 
 
1643
  var cellProcess = function (cell) {
1644
  if (colIdx === undefined || colIdx === i) {
1645
  col = columns[i];
@@ -1653,7 +2972,8 @@
1653
  attr(col.mData.type, cell);
1654
  attr(col.mData.filter, cell);
1655
  } else {
1656
-
 
1657
  if (objectRead) {
1658
  if (!col._setter) {
1659
  // Cache the setter function
@@ -1690,6 +3010,7 @@
1690
  }
1691
  }
1692
 
 
1693
  var rowNode = row.firstChild ? row : row.nTr;
1694
 
1695
  if (rowNode) {
@@ -1705,8 +3026,18 @@
1705
  cells: tds
1706
  };
1707
  }
1708
-
1709
- function _fnCreateTr(oSettings, iRow, nTrIn, anTds) {
 
 
 
 
 
 
 
 
 
 
1710
  var
1711
  row = oSettings.aoData[iRow],
1712
  rowData = row._aData,
@@ -1714,17 +3045,24 @@
1714
  nTr, nTd, oCol,
1715
  i, iLen;
1716
 
1717
- if (row.nTr === null) {
 
1718
  nTr = nTrIn || document.createElement('tr');
1719
 
1720
  row.nTr = nTr;
1721
  row.anCells = cells;
1722
 
 
 
 
1723
  nTr._DT_RowIndex = iRow;
1724
 
 
1725
  _fnRowAttributes(oSettings, row);
1726
 
1727
- for (i = 0, iLen = oSettings.aoColumns.length; i < iLen; i++) {
 
 
1728
  oCol = oSettings.aoColumns[i];
1729
 
1730
  nTd = nTrIn ? anTds[i] : document.createElement(oCol.sCellType);
@@ -1735,6 +3073,7 @@
1735
 
1736
  cells.push(nTd);
1737
 
 
1738
  if ((!nTrIn || oCol.mRender || oCol.mData !== i) &&
1739
  (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i + '.display')
1740
  ) {
@@ -1742,18 +3081,22 @@
1742
  }
1743
 
1744
  /* Add user defined class */
1745
- if (oCol.sClass) {
 
1746
  nTd.className += ' ' + oCol.sClass;
1747
  }
1748
 
1749
  // Visibility - add or remove as required
1750
- if (oCol.bVisible && !nTrIn) {
 
1751
  nTr.appendChild(nTd);
1752
- } else if (!oCol.bVisible && nTrIn) {
 
1753
  nTd.parentNode.removeChild(nTd);
1754
  }
1755
 
1756
- if (oCol.fnCreatedCell) {
 
1757
  oCol.fnCreatedCell.call(oSettings.oInstance,
1758
  nTd, _fnGetCellData(oSettings, iRow, i), rowData, iRow, i
1759
  );
@@ -1763,10 +3106,21 @@
1763
  _fnCallbackFire(oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow]);
1764
  }
1765
 
 
 
1766
  row.nTr.setAttribute('role', 'row');
1767
  }
1768
 
1769
- function _fnRowAttributes(settings, row) {
 
 
 
 
 
 
 
 
 
1770
  var tr = row.nTr;
1771
  var data = row._aData;
1772
 
@@ -1799,7 +3153,14 @@
1799
  }
1800
  }
1801
 
1802
- function _fnBuildHead(oSettings) {
 
 
 
 
 
 
 
1803
  var i, ien, cell, row, column;
1804
  var thead = oSettings.nTHead;
1805
  var tfoot = oSettings.nTFoot;
@@ -1819,6 +3180,7 @@
1819
  cell.appendTo(row);
1820
  }
1821
 
 
1822
  if (oSettings.oFeatures.bSort) {
1823
  cell.addClass(column.sSortingClass);
1824
 
@@ -1844,11 +3206,17 @@
1844
  _fnDetectHeader(oSettings.aoHeader, thead);
1845
  }
1846
 
 
1847
  $(thead).find('>tr').attr('role', 'row');
1848
 
 
1849
  $(thead).find('>tr>th, >tr>td').addClass(classes.sHeaderTH);
1850
  $(tfoot).find('>tr>th, >tr>td').addClass(classes.sFooterTH);
1851
 
 
 
 
 
1852
  if (tfoot !== null) {
1853
  var cells = oSettings.aoFooter[0];
1854
 
@@ -1863,63 +3231,104 @@
1863
  }
1864
  }
1865
 
1866
- function _fnDrawHead(oSettings, aoSource, bIncludeHidden) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1867
  var i, iLen, j, jLen, k, kLen, n, nLocalTr;
1868
  var aoLocal = [];
1869
  var aApplied = [];
1870
  var iColumns = oSettings.aoColumns.length;
1871
  var iRowspan, iColspan;
1872
 
1873
- if (!aoSource) {
 
1874
  return;
1875
  }
1876
 
1877
- if (bIncludeHidden === undefined) {
 
1878
  bIncludeHidden = false;
1879
  }
1880
 
1881
- for (i = 0, iLen = aoSource.length; i < iLen; i++) {
 
 
1882
  aoLocal[i] = aoSource[i].slice();
1883
  aoLocal[i].nTr = aoSource[i].nTr;
1884
 
1885
- for (j = iColumns - 1; j >= 0; j--) {
1886
- if (!oSettings.aoColumns[j].bVisible && !bIncludeHidden) {
 
 
 
1887
  aoLocal[i].splice(j, 1);
1888
  }
1889
  }
 
 
1890
  aApplied.push([]);
1891
  }
1892
 
1893
- for (i = 0, iLen = aoLocal.length; i < iLen; i++) {
 
1894
  nLocalTr = aoLocal[i].nTr;
1895
 
1896
- if (nLocalTr) {
1897
- while ((n = nLocalTr.firstChild)) {
 
 
 
1898
  nLocalTr.removeChild(n);
1899
  }
1900
  }
1901
 
1902
- for (j = 0, jLen = aoLocal[i].length; j < jLen; j++) {
 
1903
  iRowspan = 1;
1904
  iColspan = 1;
1905
- if (aApplied[i][j] === undefined) {
 
 
 
 
 
1906
  nLocalTr.appendChild(aoLocal[i][j].cell);
1907
  aApplied[i][j] = 1;
1908
 
 
1909
  while (aoLocal[i + iRowspan] !== undefined &&
1910
- aoLocal[i][j].cell == aoLocal[i + iRowspan][j].cell) {
 
1911
  aApplied[i + iRowspan][j] = 1;
1912
  iRowspan++;
1913
  }
1914
 
 
1915
  while (aoLocal[i][j + iColspan] !== undefined &&
1916
- aoLocal[i][j].cell == aoLocal[i][j + iColspan].cell) {
 
1917
  /* Must update the applied array over the rows for the columns */
1918
- for (k = 0; k < iRowspan; k++) {
 
1919
  aApplied[i + k][j + iColspan] = 1;
1920
  }
1921
  iColspan++;
1922
  }
 
 
1923
  $(aoLocal[i][j].cell)
1924
  .attr('rowspan', iRowspan)
1925
  .attr('colspan', iColspan);
@@ -1928,13 +3337,22 @@
1928
  }
1929
  }
1930
 
1931
- function _fnDraw(oSettings) {
1932
 
 
 
 
 
 
 
 
 
1933
  var aPreDraw = _fnCallbackFire(oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings]);
1934
- if ($.inArray(false, aPreDraw) !== -1) {
 
1935
  _fnProcessingDisplay(oSettings, false);
1936
  return;
1937
  }
 
1938
  var i, iLen, n;
1939
  var anRows = [];
1940
  var iRowCount = 0;
@@ -1947,7 +3365,10 @@
1947
  var aiDisplay = oSettings.aiDisplay;
1948
 
1949
  oSettings.bDrawing = true;
1950
- if (iInitDisplayStart !== undefined && iInitDisplayStart !== -1) {
 
 
 
1951
  oSettings._iDisplayStart = bServerSide ?
1952
  iInitDisplayStart :
1953
  iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
@@ -1959,54 +3380,70 @@
1959
 
1960
  var iDisplayStart = oSettings._iDisplayStart;
1961
  var iDisplayEnd = oSettings.fnDisplayEnd();
1962
- if (oSettings.bDeferLoading) {
 
 
 
1963
  oSettings.bDeferLoading = false;
1964
  oSettings.iDraw++;
1965
  _fnProcessingDisplay(oSettings, false);
1966
- } else if (!bServerSide) {
 
1967
  oSettings.iDraw++;
1968
- } else if (!oSettings.bDestroying && !_fnAjaxUpdate(oSettings)) {
 
1969
  return;
1970
  }
1971
 
1972
- if (aiDisplay.length !== 0) {
 
1973
  var iStart = bServerSide ? 0 : iDisplayStart;
1974
  var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
1975
 
1976
- for (var j = iStart; j < iEnd; j++) {
 
1977
  var iDataIndex = aiDisplay[j];
1978
- var aoData = oSettings.aoData[iDataIndex];
1979
- if (aoData.nTr === null) {
 
1980
  _fnCreateTr(oSettings, iDataIndex);
1981
  }
1982
 
1983
  var nRow = aoData.nTr;
1984
 
1985
- if (iStripes !== 0) {
1986
- var sStripe = asStripeClasses[iRowCount % iStripes];
1987
- if (aoData._sRowStripe != sStripe) {
 
 
 
1988
  $(nRow).removeClass(aoData._sRowStripe).addClass(sStripe);
1989
  aoData._sRowStripe = sStripe;
1990
  }
1991
  }
1992
 
1993
- _fnCallbackFire(oSettings, 'aoRowCallback', null, [nRow, aoData._aData, iRowCount, j]);
 
 
 
 
1994
 
1995
  anRows.push(nRow);
1996
  iRowCount++;
1997
  }
1998
- } else {
1999
-
 
2000
  var sZero = oLang.sZeroRecords;
2001
- if (oSettings.iDraw == 1 && _fnDataSource(oSettings) == 'ajax') {
 
2002
  sZero = oLang.sLoadingRecords;
2003
- } else if (oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0) {
 
2004
  sZero = oLang.sEmptyTable;
2005
  }
2006
 
2007
- anRows[0] = $('<tr/>', {
2008
- 'class': iStripes ? asStripeClasses[0] : ''
2009
- })
2010
  .append($('<td />', {
2011
  'valign': 'top',
2012
  'colSpan': _fnVisbleColumns(oSettings),
@@ -2016,12 +3453,10 @@
2016
 
2017
  /* Header and footer callbacks */
2018
  _fnCallbackFire(oSettings, 'aoHeaderCallback', 'header', [$(oSettings.nTHead).children('tr')[0],
2019
- _fnGetDataMaster(oSettings), iDisplayStart, iDisplayEnd, aiDisplay
2020
- ]);
2021
 
2022
  _fnCallbackFire(oSettings, 'aoFooterCallback', 'footer', [$(oSettings.nTFoot).children('tr')[0],
2023
- _fnGetDataMaster(oSettings), iDisplayStart, iDisplayEnd, aiDisplay
2024
- ]);
2025
 
2026
  var body = $(oSettings.nTBody);
2027
 
@@ -2037,7 +3472,16 @@
2037
  oSettings.bDrawing = false;
2038
  }
2039
 
2040
- function _fnReDraw(settings, holdPosition) {
 
 
 
 
 
 
 
 
 
2041
  var
2042
  features = settings.oFeatures,
2043
  sort = features.bSort,
@@ -2058,6 +3502,8 @@
2058
  settings._iDisplayStart = 0;
2059
  }
2060
 
 
 
2061
  settings._drawHold = holdPosition;
2062
 
2063
  _fnDraw(settings);
@@ -2065,7 +3511,14 @@
2065
  settings._drawHold = false;
2066
  }
2067
 
2068
- function _fnAddOptionsHtml(oSettings) {
 
 
 
 
 
 
 
2069
  var classes = oSettings.oClasses;
2070
  var table = $(oSettings.nTable);
2071
  var holding = $('<div/>').insertBefore(table); // Holding element for speed
@@ -2081,37 +3534,53 @@
2081
  oSettings.nTableWrapper = insert[0];
2082
  oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
2083
 
 
2084
  var aDom = oSettings.sDom.split('');
2085
  var featureNode, cOption, nNewNode, cNext, sAttr, j;
2086
- for (var i = 0; i < aDom.length; i++) {
 
2087
  featureNode = null;
2088
  cOption = aDom[i];
2089
 
2090
- if (cOption == '<') {
 
2091
  /* New container div */
2092
  nNewNode = $('<div/>')[0];
2093
 
 
2094
  cNext = aDom[i + 1];
2095
- if (cNext == "'" || cNext == '"') {
 
2096
  sAttr = "";
2097
  j = 2;
2098
- while (aDom[i + j] != cNext) {
 
2099
  sAttr += aDom[i + j];
2100
  j++;
2101
  }
2102
 
2103
- if (sAttr == "H") {
 
 
2104
  sAttr = classes.sJUIHeader;
2105
- } else if (sAttr == "F") {
 
2106
  sAttr = classes.sJUIFooter;
2107
  }
2108
- if (sAttr.indexOf('.') != -1) {
 
 
 
 
 
2109
  var aSplit = sAttr.split('.');
2110
  nNewNode.id = aSplit[0].substr(1, aSplit[0].length - 1);
2111
  nNewNode.className = aSplit[1];
2112
- } else if (sAttr.charAt(0) == "#") {
 
2113
  nNewNode.id = sAttr.substr(1, sAttr.length - 1);
2114
- } else {
 
2115
  nNewNode.className = sAttr;
2116
  }
2117
 
@@ -2120,32 +3589,44 @@
2120
 
2121
  insert.append(nNewNode);
2122
  insert = $(nNewNode);
2123
- } else if (cOption == '>') {
 
2124
  /* End container div */
2125
  insert = insert.parent();
2126
- } else if (cOption == 'l' && features.bPaginate && features.bLengthChange) {
 
 
 
2127
  /* Length */
2128
  featureNode = _fnFeatureHtmlLength(oSettings);
2129
- } else if (cOption == 'f' && features.bFilter) {
 
2130
  /* Filter */
2131
  featureNode = _fnFeatureHtmlFilter(oSettings);
2132
- } else if (cOption == 'r' && features.bProcessing) {
 
2133
  /* pRocessing */
2134
  featureNode = _fnFeatureHtmlProcessing(oSettings);
2135
- } else if (cOption == 't') {
 
2136
  /* Table */
2137
  featureNode = _fnFeatureHtmlTable(oSettings);
2138
- } else if (cOption == 'i' && features.bInfo) {
 
2139
  /* Info */
2140
  featureNode = _fnFeatureHtmlInfo(oSettings);
2141
- } else if (cOption == 'p' && features.bPaginate) {
 
2142
  /* Pagination */
2143
  featureNode = _fnFeatureHtmlPaginate(oSettings);
2144
- } else if (DataTable.ext.feature.length !== 0) {
 
2145
  /* Plug-in features */
2146
  var aoFeatures = DataTable.ext.feature;
2147
- for (var k = 0, kLen = aoFeatures.length; k < kLen; k++) {
2148
- if (cOption == aoFeatures[k].cFeature) {
 
 
2149
  featureNode = aoFeatures[k].fnInit(oSettings);
2150
  break;
2151
  }
@@ -2153,10 +3634,12 @@
2153
  }
2154
 
2155
  /* Add to the 2D features array */
2156
- if (featureNode) {
 
2157
  var aanFeatures = oSettings.aanFeatures;
2158
 
2159
- if (!aanFeatures[cOption]) {
 
2160
  aanFeatures[cOption] = [];
2161
  }
2162
 
@@ -2164,11 +3647,24 @@
2164
  insert.append(featureNode);
2165
  }
2166
  }
 
 
2167
  holding.replaceWith(insert);
2168
  oSettings.nHolding = null;
2169
  }
2170
 
2171
- function _fnDetectHeader(aLayout, nThead) {
 
 
 
 
 
 
 
 
 
 
 
2172
  var nTrs = $(nThead).children('tr');
2173
  var nTr, nCell;
2174
  var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
@@ -2182,11 +3678,16 @@
2182
  };
2183
 
2184
  aLayout.splice(0, aLayout.length);
2185
- for (i = 0, iLen = nTrs.length; i < iLen; i++) {
 
 
 
2186
  aLayout.push([]);
2187
  }
2188
 
2189
- for (i = 0, iLen = nTrs.length; i < iLen; i++) {
 
 
2190
  nTr = nTrs[i];
2191
  iColumn = 0;
2192
 
@@ -2194,19 +3695,27 @@
2194
  nCell = nTr.firstChild;
2195
  while (nCell) {
2196
  if (nCell.nodeName.toUpperCase() == "TD" ||
2197
- nCell.nodeName.toUpperCase() == "TH") {
 
2198
  /* Get the col and rowspan attributes from the DOM and sanitise them */
2199
  iColspan = nCell.getAttribute('colspan') * 1;
2200
  iRowspan = nCell.getAttribute('rowspan') * 1;
2201
  iColspan = (!iColspan || iColspan === 0 || iColspan === 1) ? 1 : iColspan;
2202
  iRowspan = (!iRowspan || iRowspan === 0 || iRowspan === 1) ? 1 : iRowspan;
2203
 
 
 
 
2204
  iColShifted = fnShiftCol(aLayout, i, iColumn);
2205
 
 
2206
  bUnique = iColspan === 1 ? true : false;
2207
 
2208
- for (l = 0; l < iColspan; l++) {
2209
- for (k = 0; k < iRowspan; k++) {
 
 
 
2210
  aLayout[i + k][iColShifted + l] = {
2211
  "cell": nCell,
2212
  "unique": bUnique
@@ -2220,20 +3729,35 @@
2220
  }
2221
  }
2222
 
2223
- function _fnGetUniqueThs(oSettings, nHeader, aLayout) {
 
 
 
 
 
 
 
 
 
 
2224
  var aReturn = [];
2225
- if (!aLayout) {
 
2226
  aLayout = oSettings.aoHeader;
2227
- if (nHeader) {
 
2228
  aLayout = [];
2229
  _fnDetectHeader(aLayout, nHeader);
2230
  }
2231
  }
2232
 
2233
- for (var i = 0, iLen = aLayout.length; i < iLen; i++) {
2234
- for (var j = 0, jLen = aLayout[i].length; j < jLen; j++) {
 
 
2235
  if (aLayout[i][j].unique &&
2236
- (!aReturn[j] || !oSettings.bSortCellsTop)) {
 
2237
  aReturn[j] = aLayout[i][j].cell;
2238
  }
2239
  }
@@ -2242,10 +3766,22 @@
2242
  return aReturn;
2243
  }
2244
 
2245
- function _fnBuildAjax(oSettings, data, fn) {
 
 
 
 
 
 
 
 
 
 
2246
  // Compatibility with 1.9-, allow fnServerData and event to manipulate
2247
  _fnCallbackFire(oSettings, 'aoServerParams', 'serverParams', [data]);
2248
 
 
 
2249
  if (data && $.isArray(data)) {
2250
  var tmp = {};
2251
  var rbracket = /(.*?)\[\]$/;
@@ -2257,10 +3793,10 @@
2257
  // Support for arrays
2258
  var name = match[0];
2259
 
2260
- if (!tmp[name]) {
2261
- tmp[name] = [];
2262
  }
2263
- tmp[name].push(val.value);
2264
  } else {
2265
  tmp[val.name] = val.value;
2266
  }
@@ -2276,17 +3812,21 @@
2276
  fn(json);
2277
  };
2278
 
2279
- if ($.isPlainObject(ajax) && ajax.data) {
 
2280
  ajaxData = ajax.data;
2281
 
2282
  var newData = $.isFunction(ajaxData) ?
2283
  ajaxData(data, oSettings) : // fn can manipulate data or return
2284
- ajaxData; // an object object or array to merge
2285
 
 
2286
  data = $.isFunction(ajaxData) && newData ?
2287
  newData :
2288
  $.extend(true, data, newData);
2289
 
 
 
2290
  delete ajax.data;
2291
  }
2292
 
@@ -2319,32 +3859,35 @@
2319
  }
2320
  };
2321
 
 
2322
  oSettings.oAjaxData = data;
2323
 
 
2324
  _fnCallbackFire(oSettings, null, 'preXhr', [oSettings, data]);
2325
 
2326
- if (oSettings.fnServerData) {
2327
-
 
2328
  oSettings.fnServerData.call(instance,
2329
  oSettings.sAjaxSource,
2330
  $.map(data, function (val, key) { // Need to convert back to 1.9 trad format
2331
- return {
2332
- name: key,
2333
- value: val
2334
- };
2335
  }),
2336
  callback,
2337
  oSettings
2338
  );
2339
- } else if (oSettings.sAjaxSource || typeof ajax === 'string') {
 
2340
  // DataTables 1.9- compatibility
2341
  oSettings.jqXHR = $.ajax($.extend(baseAjax, {
2342
  url: ajax || oSettings.sAjaxSource
2343
  }));
2344
- } else if ($.isFunction(ajax)) {
 
2345
  // Is a function - let the caller define what needs to be done
2346
  oSettings.jqXHR = ajax.call(instance, data, callback, oSettings);
2347
- } else {
 
2348
  // Object to extend the base settings
2349
  oSettings.jqXHR = $.ajax($.extend(baseAjax, ajax));
2350
 
@@ -2353,7 +3896,15 @@
2353
  }
2354
  }
2355
 
2356
- function _fnAjaxUpdate(settings) {
 
 
 
 
 
 
 
 
2357
  if (settings.bAjaxDataGet) {
2358
  settings.iDraw++;
2359
  _fnProcessingDisplay(settings, true);
@@ -2371,15 +3922,27 @@
2371
  return true;
2372
  }
2373
 
2374
- function _fnAjaxParameters(settings) {
 
 
 
 
 
 
 
 
 
 
 
 
 
2375
  var
2376
  columns = settings.aoColumns,
2377
  columnCount = columns.length,
2378
  features = settings.oFeatures,
2379
  preSearch = settings.oPreviousSearch,
2380
  preColSearch = settings.aoPreSearchCols,
2381
- i, data = [],
2382
- dataProp, column, columnSearch,
2383
  sort = _fnSortFlatten(settings),
2384
  displayStart = settings._iDisplayStart,
2385
  displayLength = features.bPaginate !== false ?
@@ -2387,10 +3950,7 @@
2387
  -1;
2388
 
2389
  var param = function (name, value) {
2390
- data.push({
2391
- 'name': name,
2392
- 'value': value
2393
- });
2394
  };
2395
 
2396
  // DataTables 1.9- compatible method
@@ -2449,10 +4009,7 @@
2449
 
2450
  if (features.bSort) {
2451
  $.each(sort, function (i, val) {
2452
- d.order.push({
2453
- column: val.col,
2454
- dir: val.dir
2455
- });
2456
 
2457
  param('iSortCol_' + i, val.col);
2458
  param('sSortDir_' + i, val.dir);
@@ -2461,16 +4018,34 @@
2461
  param('iSortingCols', sort.length);
2462
  }
2463
 
 
 
2464
  var legacy = DataTable.ext.legacy.ajax;
2465
  if (legacy === null) {
2466
  return settings.sAjaxSource ? data : d;
2467
  }
2468
 
 
 
2469
  return legacy ? data : d;
2470
  }
2471
 
2472
- function _fnAjaxUpdateDraw(settings, json) {
2473
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2474
  var compat = function (old, modern) {
2475
  return json[old] !== undefined ? json[old] : json[modern];
2476
  };
@@ -2508,7 +4083,17 @@
2508
  _fnProcessingDisplay(settings, false);
2509
  }
2510
 
2511
- function _fnAjaxDataSrc(oSettings, json) {
 
 
 
 
 
 
 
 
 
 
2512
  var dataSrc = $.isPlainObject(oSettings.ajax) && oSettings.ajax.dataSrc !== undefined ?
2513
  oSettings.ajax.dataSrc :
2514
  oSettings.sAjaxDataProp; // Compatibility with 1.9-.
@@ -2524,7 +4109,14 @@
2524
  json;
2525
  }
2526
 
2527
- function _fnFeatureHtmlFilter(settings) {
 
 
 
 
 
 
 
2528
  var classes = settings.oClasses;
2529
  var tableId = settings.sTableId;
2530
  var language = settings.oLanguage;
@@ -2572,13 +4164,13 @@
2572
  var jqFilter = $('input', filter)
2573
  .val(previousSearch.sSearch)
2574
  .attr('placeholder', language.sSearchPlaceholder)
2575
- .bind(
2576
  'keyup.DT search.DT input.DT paste.DT cut.DT',
2577
  searchDelay ?
2578
  _fnThrottle(searchFn, searchDelay) :
2579
  searchFn
2580
  )
2581
- .bind('keypress.DT', function (e) {
2582
  /* Prevent form submission */
2583
  if (e.keyCode == 13) {
2584
  return false;
@@ -2586,6 +4178,7 @@
2586
  })
2587
  .attr('aria-controls', tableId);
2588
 
 
2589
  $(settings.nTable).on('search.dt.DT', function (ev, s) {
2590
  if (settings === s) {
2591
  // IE9 throws an 'unknown error' if document.activeElement is used
@@ -2602,7 +4195,16 @@
2602
  return filter[0];
2603
  }
2604
 
2605
- function _fnFilterComplete(oSettings, oInput, iForce) {
 
 
 
 
 
 
 
 
 
2606
  var oPrevSearch = oSettings.oPreviousSearch;
2607
  var aoPrevSearch = oSettings.aoPreSearchCols;
2608
  var fnSaveFilter = function (oFilter) {
@@ -2617,24 +4219,44 @@
2617
  return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
2618
  };
2619
 
 
 
2620
  _fnColumnTypes(oSettings);
2621
- if (_fnDataSource(oSettings) != 'ssp') {
 
 
 
2622
  /* Global filter */
2623
  _fnFilter(oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive);
2624
  fnSaveFilter(oInput);
2625
- for (var i = 0; i < aoPrevSearch.length; i++) {
 
 
 
2626
  _fnFilterColumn(oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
2627
  aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive);
2628
  }
 
 
2629
  _fnFilterCustom(oSettings);
2630
- } else {
 
2631
  fnSaveFilter(oInput);
2632
  }
 
 
2633
  oSettings.bFiltered = true;
2634
  _fnCallbackFire(oSettings, null, 'search', [oSettings]);
2635
  }
2636
 
2637
- function _fnFilterCustom(settings) {
 
 
 
 
 
 
 
2638
  var filters = DataTable.ext.search;
2639
  var displayRows = settings.aiDisplay;
2640
  var row, rowIdx;
@@ -2642,43 +4264,74 @@
2642
  for (var i = 0, ien = filters.length; i < ien; i++) {
2643
  var rows = [];
2644
 
 
2645
  for (var j = 0, jen = displayRows.length; j < jen; j++) {
2646
- rowIdx = displayRows[j];
2647
- row = settings.aoData[rowIdx];
2648
 
2649
  if (filters[i](settings, row._aFilterData, rowIdx, row._aData, j)) {
2650
  rows.push(rowIdx);
2651
  }
2652
  }
2653
 
 
 
2654
  displayRows.length = 0;
2655
  $.merge(displayRows, rows);
2656
  }
2657
  }
2658
 
2659
- function _fnFilterColumn(settings, searchStr, colIdx, regex, smart, caseInsensitive) {
 
 
 
 
 
 
 
 
 
 
 
 
2660
  if (searchStr === '') {
2661
  return;
2662
  }
2663
 
2664
  var data;
 
2665
  var display = settings.aiDisplay;
2666
  var rpSearch = _fnFilterCreateSearch(searchStr, regex, smart, caseInsensitive);
2667
 
2668
- for (var i = display.length - 1; i >= 0; i--) {
2669
- data = settings.aoData[display[i]]._aFilterData[colIdx];
2670
 
2671
- if (!rpSearch.test(data)) {
2672
- display.splice(i, 1);
2673
  }
2674
  }
 
 
2675
  }
2676
 
2677
- function _fnFilter(settings, input, force, regex, smart, caseInsensitive) {
 
 
 
 
 
 
 
 
 
 
 
 
2678
  var rpSearch = _fnFilterCreateSearch(input, regex, smart, caseInsensitive);
2679
  var prevSearch = settings.oPreviousSearch.sSearch;
2680
  var displayMaster = settings.aiDisplayMaster;
2681
  var display, invalidated, i;
 
2682
 
2683
  // Need to take account of custom filtering functions - always filter
2684
  if (DataTable.ext.search.length !== 0) {
@@ -2706,21 +4359,40 @@
2706
  // Search the display array
2707
  display = settings.aiDisplay;
2708
 
2709
- for (i = display.length - 1; i >= 0; i--) {
2710
- if (!rpSearch.test(settings.aoData[display[i]]._sFilterRow)) {
2711
- display.splice(i, 1);
2712
  }
2713
  }
 
 
2714
  }
2715
  }
2716
 
2717
- function _fnFilterCreateSearch(search, regex, smart, caseInsensitive) {
 
 
 
 
 
 
 
 
 
 
 
2718
  search = regex ?
2719
  search :
2720
  _fnEscapeRegex(search);
2721
 
2722
  if (smart) {
2723
-
 
 
 
 
 
 
2724
  var a = $.map(search.match(/"[^"]+"|[^ ]+/g) || [''], function (word) {
2725
  if (word.charAt(0) === '"') {
2726
  var m = word.match(/^"(.*)"$/);
@@ -2736,13 +4408,21 @@
2736
  return new RegExp(search, caseInsensitive ? 'i' : '');
2737
  }
2738
 
 
 
 
 
 
 
 
2739
  var _fnEscapeRegex = DataTable.util.escapeRegex;
2740
 
2741
  var __filter_div = $('<div>')[0];
2742
  var __filter_div_textContent = __filter_div.textContent !== undefined;
2743
 
2744
  // Update the filtering data for each row if needed (by invalidation or first run)
2745
- function _fnFilterData(settings) {
 
2746
  var columns = settings.aoColumns;
2747
  var column;
2748
  var i, j, ien, jen, filterData, cellData, row;
@@ -2761,10 +4441,12 @@
2761
  if (column.bSearchable) {
2762
  cellData = _fnGetCellData(settings, i, j, 'filter');
2763
 
2764
- if (fomatters[column.sType]) {
2765
- cellData = fomatters[column.sType](cellData);
2766
  }
2767
 
 
 
2768
  if (cellData === null) {
2769
  cellData = '';
2770
  }
@@ -2776,6 +4458,10 @@
2776
  cellData = '';
2777
  }
2778
 
 
 
 
 
2779
  if (cellData.indexOf && cellData.indexOf('&') !== -1) {
2780
  __filter_div.innerHTML = cellData;
2781
  cellData = __filter_div_textContent ?
@@ -2799,7 +4485,16 @@
2799
  return wasInvalidated;
2800
  }
2801
 
2802
- function _fnSearchToCamel(obj) {
 
 
 
 
 
 
 
 
 
2803
  return {
2804
  search: obj.sSearch,
2805
  smart: obj.bSmart,
@@ -2808,7 +4503,17 @@
2808
  };
2809
  }
2810
 
2811
- function _fnSearchToHung(obj) {
 
 
 
 
 
 
 
 
 
 
2812
  return {
2813
  sSearch: obj.search,
2814
  bSmart: obj.smart,
@@ -2817,7 +4522,14 @@
2817
  };
2818
  }
2819
 
2820
- function _fnFeatureHtmlInfo(settings) {
 
 
 
 
 
 
 
2821
  var
2822
  tid = settings.sTableId,
2823
  nodes = settings.aanFeatures.i,
@@ -2844,7 +4556,14 @@
2844
  return n[0];
2845
  }
2846
 
2847
- function _fnUpdateInfo(settings) {
 
 
 
 
 
 
 
2848
  /* Show information about the table */
2849
  var nodes = settings.aanFeatures.i;
2850
  if (nodes.length === 0) {
@@ -2880,8 +4599,11 @@
2880
  $(nodes).html(out);
2881
  }
2882
 
2883
- function _fnInfoMacros(settings, str) {
2884
 
 
 
 
 
2885
  var
2886
  formatter = settings.fnFormatNumber,
2887
  start = settings._iDisplayStart + 1,
@@ -2898,10 +4620,17 @@
2898
  replace(/_PAGES_/g, formatter.call(settings, all ? 1 : Math.ceil(vis / len)));
2899
  }
2900
 
2901
- function _fnInitialise(settings) {
 
 
 
 
 
 
 
 
2902
  var i, iLen, iAjaxStart = settings.iInitDisplayStart;
2903
- var columns = settings.aoColumns,
2904
- column;
2905
  var features = settings.oFeatures;
2906
  var deferLoading = settings.bDeferLoading; // value modified by the draw
2907
 
@@ -2939,6 +4668,10 @@
2939
 
2940
  _fnCallbackFire(settings, null, 'preInit', [settings]);
2941
 
 
 
 
 
2942
  _fnReDraw(settings);
2943
 
2944
  // Server-side processing init complete is done by _fnAjaxUpdateDraw
@@ -2954,6 +4687,9 @@
2954
  _fnAddData(settings, aData[i]);
2955
  }
2956
 
 
 
 
2957
  settings.iInitDisplayStart = iAjaxStart;
2958
 
2959
  _fnReDraw(settings);
@@ -2968,9 +4704,20 @@
2968
  }
2969
  }
2970
 
2971
- function _fnInitComplete(settings, json) {
 
 
 
 
 
 
 
 
 
2972
  settings._bInitComplete = true;
2973
 
 
 
2974
  if (json || settings.oInit.aaData) {
2975
  _fnAdjustColumnSizing(settings);
2976
  }
@@ -2979,16 +4726,27 @@
2979
  _fnCallbackFire(settings, 'aoInitComplete', 'init', [settings, json]);
2980
  }
2981
 
2982
- function _fnLengthChange(settings, val) {
 
 
2983
  var len = parseInt(val, 10);
2984
  settings._iDisplayLength = len;
2985
 
2986
  _fnLengthOverflow(settings);
2987
 
 
2988
  _fnCallbackFire(settings, null, 'length', [settings, len]);
2989
  }
2990
 
2991
- function _fnFeatureHtmlLength(settings) {
 
 
 
 
 
 
 
 
2992
  var
2993
  classes = settings.oClasses,
2994
  tableId = settings.sTableId,
@@ -3004,7 +4762,7 @@
3004
  });
3005
 
3006
  for (var i = 0, ien = lengths.length; i < ien; i++) {
3007
- select[0][i] = new Option(language[i], lengths[i]);
3008
  }
3009
 
3010
  var div = $('<div><label/></div>').addClass(classes.sLength);
@@ -3016,15 +4774,17 @@
3016
  settings.oLanguage.sLengthMenu.replace('_MENU_', select[0].outerHTML)
3017
  );
3018
 
 
 
3019
  $('select', div)
3020
  .val(settings._iDisplayLength)
3021
- .bind('change.DT', function (e) {
3022
  _fnLengthChange(settings, $(this).val());
3023
  _fnDraw(settings);
3024
  });
3025
 
3026
  // Update node value whenever anything changes the table's length
3027
- $(settings.nTable).bind('length.dt.DT', function (e, s, len) {
3028
  if (settings === s) {
3029
  $('select', div).val(len);
3030
  }
@@ -3033,10 +4793,24 @@
3033
  return div[0];
3034
  }
3035
 
3036
- function _fnFeatureHtmlPaginate(settings) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3037
  var
3038
  type = settings.sPaginationType,
3039
- plugin = DataTable.ext.pager[type],
3040
  modern = typeof plugin === 'function',
3041
  redraw = function (settings) {
3042
  _fnDraw(settings);
@@ -3049,7 +4823,8 @@
3049
  }
3050
 
3051
  /* Add a draw callback for the pagination on first instance, to update the paging display */
3052
- if (!features.p) {
 
3053
  node.id = settings.sTableId + '_paginate';
3054
 
3055
  settings.aoDrawCallback.push({
@@ -3081,37 +4856,58 @@
3081
  return node;
3082
  }
3083
 
3084
- function _fnPageChange(settings, action, redraw) {
 
 
 
 
 
 
 
 
 
 
 
3085
  var
3086
  start = settings._iDisplayStart,
3087
  len = settings._iDisplayLength,
3088
  records = settings.fnRecordsDisplay();
3089
 
3090
- if (records === 0 || len === -1) {
 
3091
  start = 0;
3092
- } else if (typeof action === "number") {
 
3093
  start = action * len;
3094
 
3095
- if (start > records) {
 
3096
  start = 0;
3097
  }
3098
- } else if (action == "first") {
 
3099
  start = 0;
3100
- } else if (action == "previous") {
 
3101
  start = len >= 0 ?
3102
  start - len :
3103
  0;
3104
 
3105
- if (start < 0) {
 
3106
  start = 0;
3107
  }
3108
- } else if (action == "next") {
3109
- if (start + len < records) {
 
 
3110
  start += len;
3111
  }
3112
- } else if (action == "last") {
 
3113
  start = Math.floor((records - 1) / len) * len;
3114
- } else {
 
3115
  _fnLog(settings, 0, "Unknown paging action: " + action, 5);
3116
  }
3117
 
@@ -3129,7 +4925,16 @@
3129
  return changed;
3130
  }
3131
 
3132
- function _fnFeatureHtmlProcessing(settings) {
 
 
 
 
 
 
 
 
 
3133
  return $('<div/>', {
3134
  'id': !settings.aanFeatures.r ? settings.sTableId + '_processing' : null,
3135
  'class': settings.oClasses.sProcessing
@@ -3138,7 +4943,15 @@
3138
  .insertBefore(settings.nTable)[0];
3139
  }
3140
 
3141
- function _fnProcessingDisplay(settings, show) {
 
 
 
 
 
 
 
 
3142
  if (settings.oFeatures.bProcessing) {
3143
  $(settings.aanFeatures.r).css('display', show ? 'block' : 'none');
3144
  }
@@ -3146,7 +4959,14 @@
3146
  _fnCallbackFire(settings, null, 'processing', [settings, show]);
3147
  }
3148
 
3149
- function _fnFeatureHtmlTable(settings) {
 
 
 
 
 
 
 
3150
  var table = $(settings.nTable);
3151
 
3152
  // Add the ARIA grid role to the table
@@ -3176,13 +4996,25 @@
3176
  footer = null;
3177
  }
3178
 
3179
- var scroller = $(_div, {
3180
- 'class': classes.sScrollWrapper
3181
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3182
  .append(
3183
- $(_div, {
3184
- 'class': classes.sScrollHead
3185
- })
3186
  .css({
3187
  overflow: 'hidden',
3188
  position: 'relative',
@@ -3190,9 +5022,7 @@
3190
  width: scrollX ? size(scrollX) : '100%'
3191
  })
3192
  .append(
3193
- $(_div, {
3194
- 'class': classes.sScrollHeadInner
3195
- })
3196
  .css({
3197
  'box-sizing': 'content-box',
3198
  width: scroll.sXInner || '100%'
@@ -3209,9 +5039,7 @@
3209
  )
3210
  )
3211
  .append(
3212
- $(_div, {
3213
- 'class': classes.sScrollBody
3214
- })
3215
  .css({
3216
  position: 'relative',
3217
  overflow: 'auto',
@@ -3222,18 +5050,14 @@
3222
 
3223
  if (footer) {
3224
  scroller.append(
3225
- $(_div, {
3226
- 'class': classes.sScrollFoot
3227
- })
3228
  .css({
3229
  overflow: 'hidden',
3230
  border: 0,
3231
  width: scrollX ? size(scrollX) : '100%'
3232
  })
3233
  .append(
3234
- $(_div, {
3235
- 'class': classes.sScrollFootInner
3236
- })
3237
  .append(
3238
  footerClone
3239
  .removeAttr('id')
@@ -3283,7 +5107,24 @@
3283
  return scroller[0];
3284
  }
3285
 
3286
- function _fnScrollDraw(settings) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3287
  // Given that this is such a monster function, a lot of variables are use
3288
  // to try and keep the minimised size as small as possible
3289
  var
@@ -3314,10 +5155,8 @@
3314
  headerTrgEls, footerTrgEls,
3315
  headerSrcEls, footerSrcEls,
3316
  headerCopy, footerCopy,
3317
- headerWidths = [],
3318
- footerWidths = [],
3319
- headerContent = [],
3320
- footerContent = [],
3321
  idx, correction, sanityWidth,
3322
  zeroOut = function (nSizer) {
3323
  var style = nSizer.style;
@@ -3328,6 +5167,9 @@
3328
  style.height = 0;
3329
  };
3330
 
 
 
 
3331
  var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
3332
 
3333
  if (settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined) {
@@ -3338,6 +5180,11 @@
3338
  settings.scrollBarVis = scrollBarVis;
3339
  }
3340
 
 
 
 
 
 
3341
  table.children('thead, tfoot').remove();
3342
 
3343
  if (footer) {
@@ -3346,12 +5193,22 @@
3346
  footerSrcEls = footerCopy.find('tr');
3347
  }
3348
 
 
3349
  headerCopy = header.clone().prependTo(table);
3350
  headerTrgEls = header.find('tr'); // original header is in its own table
3351
  headerSrcEls = headerCopy.find('tr');
3352
  headerCopy.find('th, td').removeAttr('tabindex');
3353
 
3354
- if (!scrollX) {
 
 
 
 
 
 
 
 
 
3355
  divBodyStyle.width = '100%';
3356
  divHeader[0].style.width = '100%';
3357
  }
@@ -3373,8 +5230,12 @@
3373
  // No x scrolling
3374
  tableStyle.width = "100%";
3375
 
 
 
 
3376
  if (ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
3377
- divBody.css('overflow-y') == "scroll")) {
 
3378
  tableStyle.width = _fnStringToCss(table.outerWidth() - barWidth);
3379
  }
3380
 
@@ -3388,15 +5249,22 @@
3388
  sanityWidth = table.outerWidth();
3389
  }
3390
 
 
 
 
 
3391
  _fnApplyToChildren(zeroOut, headerSrcEls);
3392
 
 
3393
  _fnApplyToChildren(function (nSizer) {
3394
  headerContent.push(nSizer.innerHTML);
3395
  headerWidths.push(_fnStringToCss($(nSizer).css('width')));
3396
  }, headerSrcEls);
3397
 
 
3398
  _fnApplyToChildren(function (nToSize, i) {
3399
-
 
3400
  if ($.inArray(nToSize, dtHeaderCells) !== -1) {
3401
  nToSize.style.width = headerWidths[i];
3402
  }
@@ -3404,7 +5272,9 @@
3404
 
3405
  $(headerSrcEls).height(0);
3406
 
3407
- if (footer) {
 
 
3408
  _fnApplyToChildren(zeroOut, footerSrcEls);
3409
 
3410
  _fnApplyToChildren(function (nSizer) {
@@ -3419,19 +5289,32 @@
3419
  $(footerSrcEls).height(0);
3420
  }
3421
 
 
 
 
 
 
 
 
 
 
3422
  _fnApplyToChildren(function (nSizer, i) {
3423
  nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">' + headerContent[i] + '</div>';
3424
  nSizer.style.width = headerWidths[i];
3425
  }, headerSrcEls);
3426
 
3427
- if (footer) {
 
3428
  _fnApplyToChildren(function (nSizer, i) {
3429
  nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">' + footerContent[i] + '</div>';
3430
  nSizer.style.width = footerWidths[i];
3431
  }, footerSrcEls);
3432
  }
3433
 
3434
- if (table.outerWidth() < sanityWidth) {
 
 
 
3435
  // The min width depends upon if we have a vertical scrollbar visible or not */
3436
  correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
3437
  divBody.css('overflow-y') == "scroll")) ?
@@ -3440,7 +5323,8 @@
3440
 
3441
  // IE6/7 are a law unto themselves...
3442
  if (ie67 && (divBodyEl.scrollHeight >
3443
- divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")) {
 
3444
  tableStyle.width = _fnStringToCss(correction - barWidth);
3445
  }
3446
 
@@ -3448,10 +5332,12 @@
3448
  if (scrollX === "" || scrollXInner !== "") {
3449
  _fnLog(settings, 1, 'Possible column misalignment', 6);
3450
  }
3451
- } else {
 
3452
  correction = '100%';
3453
  }
3454
 
 
3455
  divBodyStyle.width = _fnStringToCss(correction);
3456
  divHeaderStyle.width = _fnStringToCss(correction);
3457
 
@@ -3459,8 +5345,15 @@
3459
  settings.nScrollFoot.style.width = _fnStringToCss(correction);
3460
  }
3461
 
3462
- if (!scrollY) {
3463
 
 
 
 
 
 
 
 
 
3464
  if (ie67) {
3465
  divBodyStyle.height = _fnStringToCss(tableEl.offsetHeight + barWidth);
3466
  }
@@ -3471,9 +5364,11 @@
3471
  divHeaderTable[0].style.width = _fnStringToCss(iOuterWidth);
3472
  divHeaderInnerStyle.width = _fnStringToCss(iOuterWidth);
3473
 
 
 
3474
  var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
3475
  var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right');
3476
- divHeaderInnerStyle[padding] = bScrolling ? barWidth + "px" : "0px";
3477
 
3478
  if (footer) {
3479
  divFooterTable[0].style.width = _fnStringToCss(iOuterWidth);
@@ -3481,19 +5376,32 @@
3481
  divFooterInner[0].style[padding] = bScrolling ? barWidth + "px" : "0px";
3482
  }
3483
 
 
3484
  table.children('colgroup').insertBefore(table.children('thead'));
3485
 
 
3486
  divBody.scroll();
3487
 
 
 
3488
  if ((settings.bSorted || settings.bFiltered) && !settings._drawHold) {
3489
  divBodyEl.scrollTop = 0;
3490
  }
3491
  }
3492
 
3493
- function _fnApplyToChildren(fn, an1, an2) {
3494
- var index = 0,
3495
- i = 0,
3496
- iLen = an1.length;
 
 
 
 
 
 
 
 
 
3497
  var nNode1, nNode2;
3498
 
3499
  while (i < iLen) {
@@ -3518,9 +5426,19 @@
3518
  i++;
3519
  }
3520
  }
3521
- var __re_html_remove = /<.*?>/g;
3522
 
3523
- function _fnCalculateColumnWidths(oSettings) {
 
 
 
 
 
 
 
 
 
 
 
3524
  var
3525
  table = oSettings.nTable,
3526
  columns = oSettings.aoColumns,
@@ -3543,8 +5461,9 @@
3543
  tableWidthAttr = styleWidth;
3544
  }
3545
 
 
3546
  for (i = 0; i < visibleColumns.length; i++) {
3547
- column = columns[visibleColumns[i]];
3548
 
3549
  if (column.sWidth !== null) {
3550
  column.sWidth = _fnConvertToWidth(column.sWidthOrig, tableContainer);
@@ -3553,6 +5472,11 @@
3553
  }
3554
  }
3555
 
 
 
 
 
 
3556
  if (ie67 || !userInputs && !scrollX && !scrollY &&
3557
  columnCount == _fnVisbleColumns(oSettings) &&
3558
  columnCount == headerCells.length
@@ -3561,11 +5485,15 @@
3561
  var colIdx = _fnVisibleToColumnIndex(oSettings, i);
3562
 
3563
  if (colIdx !== null) {
3564
- columns[colIdx].sWidth = _fnStringToCss(headerCells.eq(i).width());
3565
  }
3566
  }
3567
- } else {
3568
-
 
 
 
 
3569
  var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
3570
  .css('visibility', 'hidden')
3571
  .removeAttr('id');
@@ -3574,6 +5502,9 @@
3574
  tmpTable.find('tbody tr').remove();
3575
  var tr = $('<tr/>').appendTo(tmpTable.find('tbody'));
3576
 
 
 
 
3577
  tmpTable.find('thead, tfoot').remove();
3578
  tmpTable
3579
  .append($(oSettings.nTHead).clone())
@@ -3586,12 +5517,15 @@
3586
  headerCells = _fnGetUniqueThs(oSettings, tmpTable.find('thead')[0]);
3587
 
3588
  for (i = 0; i < visibleColumns.length; i++) {
3589
- column = columns[visibleColumns[i]];
3590
 
3591
  headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
3592
  _fnStringToCss(column.sWidthOrig) :
3593
  '';
3594
 
 
 
 
3595
  if (column.sWidthOrig && scrollX) {
3596
  $(headerCells[i]).append($('<div/>').css({
3597
  width: column.sWidthOrig,
@@ -3603,10 +5537,11 @@
3603
  }
3604
  }
3605
 
 
3606
  if (oSettings.aoData.length) {
3607
  for (i = 0; i < visibleColumns.length; i++) {
3608
  columnIdx = visibleColumns[i];
3609
- column = columns[columnIdx];
3610
 
3611
  $(_fnGetWidestNode(oSettings, columnIdx))
3612
  .clone(false)
@@ -3615,19 +5550,32 @@
3615
  }
3616
  }
3617
 
 
 
3618
  $('[name]', tmpTable).removeAttr('name');
3619
 
3620
- var holder = $('<div/>').css(scrollX || scrollY ? {
3621
- position: 'absolute',
3622
- top: 0,
3623
- left: 0,
3624
- height: 1,
3625
- right: 0,
3626
- overflow: 'hidden'
3627
- } : {})
 
 
 
 
 
 
 
 
3628
  .append(tmpTable)
3629
  .appendTo(tableContainer);
3630
 
 
 
 
3631
  if (scrollX && scrollXInner) {
3632
  tmpTable.width(scrollXInner);
3633
  } else if (scrollX) {
@@ -3645,36 +5593,54 @@
3645
  tmpTable.width(tableWidthAttr);
3646
  }
3647
 
 
 
 
 
 
 
3648
  var total = 0;
3649
  for (i = 0; i < visibleColumns.length; i++) {
3650
  var cell = $(headerCells[i]);
3651
  var border = cell.outerWidth() - cell.width();
3652
 
 
 
3653
  var bounding = browser.bBounding ?
3654
  Math.ceil(headerCells[i].getBoundingClientRect().width) :
3655
  cell.outerWidth();
3656
 
 
 
3657
  total += bounding;
3658
 
3659
- columns[visibleColumns[i]].sWidth = _fnStringToCss(bounding - border);
 
3660
  }
3661
 
3662
  table.style.width = _fnStringToCss(total);
3663
 
 
3664
  holder.remove();
3665
  }
3666
 
 
 
 
 
3667
  if (tableWidthAttr) {
3668
  table.style.width = _fnStringToCss(tableWidthAttr);
3669
  }
3670
 
3671
  if ((tableWidthAttr || scrollX) && !oSettings._reszEvt) {
3672
  var bindResize = function () {
3673
- $(window).bind('resize.DT-' + oSettings.sInstance, _fnThrottle(function () {
3674
  _fnAdjustColumnSizing(oSettings);
3675
  }));
3676
  };
3677
 
 
 
3678
  if (ie67) {
3679
  setTimeout(bindResize, 1000);
3680
  } else {
@@ -3685,9 +5651,27 @@
3685
  }
3686
  }
3687
 
 
 
 
 
 
 
 
 
 
3688
  var _fnThrottle = DataTable.util.throttle;
3689
 
3690
- function _fnConvertToWidth(width, parent) {
 
 
 
 
 
 
 
 
 
3691
  if (!width) {
3692
  return 0;
3693
  }
@@ -3702,21 +5686,38 @@
3702
  return val;
3703
  }
3704
 
3705
- function _fnGetWidestNode(settings, colIdx) {
 
 
 
 
 
 
 
 
 
3706
  var idx = _fnGetMaxLenString(settings, colIdx);
3707
  if (idx < 0) {
3708
  return null;
3709
  }
3710
 
3711
- var data = settings.aoData[idx];
3712
  return !data.nTr ? // Might not have been created when deferred rendering
3713
  $('<td/>').html(_fnGetCellData(settings, idx, colIdx, 'display'))[0] :
3714
- data.anCells[colIdx];
3715
  }
3716
 
3717
- function _fnGetMaxLenString(settings, colIdx) {
3718
- var s, max = -1,
3719
- maxIdx = -1;
 
 
 
 
 
 
 
 
3720
 
3721
  for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
3722
  s = _fnGetCellData(settings, i, colIdx, 'display') + '';
@@ -3732,7 +5733,15 @@
3732
  return maxIdx;
3733
  }
3734
 
3735
- function _fnStringToCss(s) {
 
 
 
 
 
 
 
 
3736
  if (s === null) {
3737
  return '0px';
3738
  }
@@ -3742,13 +5751,17 @@
3742
  '0px' :
3743
  s + 'px';
3744
  }
 
3745
  // Check it has a unit character already
3746
  return s.match(/\d$/) ?
3747
  s + 'px' :
3748
  s;
3749
  }
3750
 
3751
- function _fnSortFlatten(settings) {
 
 
 
3752
  var
3753
  i, iLen, k, kLen,
3754
  aSort = [],
@@ -3767,6 +5780,9 @@
3767
  $.merge(nestedSort, a);
3768
  }
3769
  };
 
 
 
3770
  if ($.isArray(fixed)) {
3771
  add(fixed);
3772
  }
@@ -3774,27 +5790,34 @@
3774
  if (fixedObj && fixed.pre) {
3775
  add(fixed.pre);
3776
  }
 
3777
  add(settings.aaSorting);
 
3778
  if (fixedObj && fixed.post) {
3779
  add(fixed.post);
3780
  }
3781
- for (i = 0; i < nestedSort.length; i++) {
 
 
3782
  srcCol = nestedSort[i][0];
3783
- aDataSort = aoColumns[srcCol].aDataSort;
3784
- for (k = 0, kLen = aDataSort.length; k < kLen; k++) {
 
 
3785
  iCol = aDataSort[k];
3786
- sType = aoColumns[iCol].sType || 'string';
3787
 
3788
  if (nestedSort[i]._idx === undefined) {
3789
  nestedSort[i]._idx = $.inArray(nestedSort[i][1], aoColumns[iCol].asSorting);
3790
  }
 
3791
  aSort.push({
3792
  src: srcCol,
3793
  col: iCol,
3794
  dir: nestedSort[i][1],
3795
  index: nestedSort[i]._idx,
3796
  type: sType,
3797
- formatter: DataTable.ext.type.order[sType + "-pre"]
3798
  });
3799
  }
3800
  }
@@ -3802,7 +5825,14 @@
3802
  return aSort;
3803
  }
3804
 
3805
- function _fnSort(oSettings) {
 
 
 
 
 
 
 
3806
  var
3807
  i, ien, iLen, j, jLen, k, kLen,
3808
  sDataType, nTh,
@@ -3816,22 +5846,55 @@
3816
  displayMaster = oSettings.aiDisplayMaster,
3817
  aSort;
3818
 
 
 
 
3819
  _fnColumnTypes(oSettings);
3820
 
3821
  aSort = _fnSortFlatten(oSettings);
3822
 
3823
  for (i = 0, ien = aSort.length; i < ien; i++) {
3824
  sortCol = aSort[i];
 
 
3825
  if (sortCol.formatter) {
3826
  formatters++;
3827
  }
 
 
3828
  _fnSortData(oSettings, sortCol.col);
3829
  }
3830
- if (_fnDataSource(oSettings) != 'ssp' && aSort.length !== 0) {
3831
 
 
 
 
 
 
3832
  for (i = 0, iLen = displayMaster.length; i < iLen; i++) {
3833
- aiOrig[displayMaster[i]] = i;
3834
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3835
  if (formatters === aSort.length) {
3836
  // All sort types have formatting functions
3837
  displayMaster.sort(function (a, b) {
@@ -3840,10 +5903,13 @@
3840
  len = aSort.length,
3841
  dataA = aoData[a]._aSortData,
3842
  dataB = aoData[b]._aSortData;
 
3843
  for (k = 0; k < len; k++) {
3844
  sort = aSort[k];
3845
- x = dataA[sort.col];
3846
- y = dataB[sort.col];
 
 
3847
  test = x < y ? -1 : x > y ? 1 : 0;
3848
  if (test !== 0) {
3849
  return sort.dir === 'asc' ? test : -test;
@@ -3855,7 +5921,9 @@
3855
  return x < y ? -1 : x > y ? 1 : 0;
3856
  });
3857
  } else {
3858
-
 
 
3859
  displayMaster.sort(function (a, b) {
3860
  var
3861
  x, y, k, l, test, sort, fn,
@@ -3866,10 +5934,10 @@
3866
  for (k = 0; k < len; k++) {
3867
  sort = aSort[k];
3868
 
3869
- x = dataA[sort.col];
3870
- y = dataB[sort.col];
3871
 
3872
- fn = oExtSort[sort.type + "-" + sort.dir] || oExtSort["string-" + sort.dir];
3873
  test = fn(x, y);
3874
  if (test !== 0) {
3875
  return test;
@@ -3883,26 +5951,37 @@
3883
  }
3884
  }
3885
 
 
3886
  oSettings.bSorted = true;
3887
  }
3888
 
3889
- function _fnSortAria(settings) {
 
 
3890
  var label;
3891
  var nextSort;
3892
  var columns = settings.aoColumns;
3893
  var aSort = _fnSortFlatten(settings);
3894
  var oAria = settings.oLanguage.oAria;
3895
 
3896
- for (var i = 0, iLen = columns.length; i < iLen; i++) {
 
 
 
3897
  var col = columns[i];
3898
  var asSorting = col.asSorting;
3899
  var sTitle = col.sTitle.replace(/<.*?>/g, "");
3900
  var th = col.nTh;
 
 
 
3901
  th.removeAttribute('aria-sort');
 
 
3902
  if (col.bSortable) {
3903
  if (aSort.length > 0 && aSort[0].col == i) {
3904
  th.setAttribute('aria-sort', aSort[0].dir == "asc" ? "ascending" : "descending");
3905
- nextSort = asSorting[aSort[0].index + 1] || asSorting[0];
3906
  } else {
3907
  nextSort = asSorting[0];
3908
  }
@@ -3919,8 +5998,20 @@
3919
  }
3920
  }
3921
 
3922
- function _fnSortListener(settings, colIdx, append, callback) {
3923
- var col = settings.aoColumns[colIdx];
 
 
 
 
 
 
 
 
 
 
 
 
3924
  var sorting = settings.aaSorting;
3925
  var asSorting = col.asSorting;
3926
  var nextSortIdx;
@@ -3937,6 +6028,7 @@
3937
  0;
3938
  };
3939
 
 
3940
  if (typeof sorting[0] === 'number') {
3941
  sorting = settings.aaSorting = [sorting];
3942
  }
@@ -3957,7 +6049,7 @@
3957
  if (nextSortIdx === null) {
3958
  sorting.splice(sortIdx, 1);
3959
  } else {
3960
- sorting[sortIdx][1] = asSorting[nextSortIdx];
3961
  sorting[sortIdx]._idx = nextSortIdx;
3962
  }
3963
  } else {
@@ -3970,7 +6062,7 @@
3970
  nextSortIdx = next(sorting[0]);
3971
 
3972
  sorting.length = 1;
3973
- sorting[0][1] = asSorting[nextSortIdx];
3974
  sorting[0]._idx = nextSortIdx;
3975
  } else {
3976
  // Single column - sort only on this column
@@ -3988,8 +6080,18 @@
3988
  }
3989
  }
3990
 
3991
- function _fnSortAttachListener(settings, attachTo, colIdx, callback) {
3992
- var col = settings.aoColumns[colIdx];
 
 
 
 
 
 
 
 
 
 
3993
 
3994
  _fnBindAction(attachTo, {}, function (e) {
3995
  /* If the column is not sortable - don't to anything */
@@ -3997,12 +6099,16 @@
3997
  return;
3998
  }
3999
 
 
 
4000
  if (settings.oFeatures.bProcessing) {
4001
  _fnProcessingDisplay(settings, true);
4002
 
4003
  setTimeout(function () {
4004
  _fnSortListener(settings, colIdx, e.shiftKey, callback);
4005
 
 
 
4006
  if (_fnDataSource(settings) !== 'ssp') {
4007
  _fnProcessingDisplay(settings, false);
4008
  }
@@ -4013,7 +6119,15 @@
4013
  });
4014
  }
4015
 
4016
- function _fnSortingClasses(settings) {
 
 
 
 
 
 
 
 
4017
  var oldSort = settings.aLastSort;
4018
  var sortClass = settings.oClasses.sSortColumn;
4019
  var sort = _fnSortFlatten(settings);
@@ -4042,10 +6156,14 @@
4042
  settings.aLastSort = sort;
4043
  }
4044
 
4045
- function _fnSortData(settings, idx) {
 
 
 
 
4046
  // Custom sorting function - provided by the sort data type
4047
- var column = settings.aoColumns[idx];
4048
- var customSort = DataTable.ext.order[column.sSortDataType];
4049
  var customData;
4050
 
4051
  if (customSort) {
@@ -4056,7 +6174,7 @@
4056
 
4057
  // Use / populate cache
4058
  var row, cellData;
4059
- var formatter = DataTable.ext.type.order[column.sType + "-pre"];
4060
 
4061
  for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
4062
  row = settings.aoData[i];
@@ -4070,18 +6188,28 @@
4070
  customData[i] : // If there was a custom sort function, use data from there
4071
  _fnGetCellData(settings, i, idx, 'sort');
4072
 
4073
- row._aSortData[idx] = formatter ?
4074
  formatter(cellData) :
4075
  cellData;
4076
  }
4077
  }
4078
  }
4079
 
4080
- function _fnSaveState(settings) {
4081
- if (!settings.oFeatures.bStateSave || settings.bDestroying) {
 
 
 
 
 
 
 
 
 
4082
  return;
4083
  }
4084
 
 
4085
  var state = {
4086
  time: +new Date(),
4087
  start: settings._iDisplayStart,
@@ -4102,78 +6230,137 @@
4102
  settings.fnStateSaveCallback.call(settings.oInstance, settings, state);
4103
  }
4104
 
4105
- function _fnLoadState(settings, oInit) {
 
 
 
 
 
 
 
 
 
4106
  var i, ien;
4107
  var columns = settings.aoColumns;
 
 
 
 
 
4108
 
4109
- if (!settings.oFeatures.bStateSave) {
4110
- return;
4111
- }
 
 
 
 
4112
 
4113
- var state = settings.fnStateLoadCallback.call(settings.oInstance, settings);
4114
- if (!state || !state.time) {
4115
- return;
4116
- }
4117
- var abStateLoad = _fnCallbackFire(settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state]);
4118
- if ($.inArray(false, abStateLoad) !== -1) {
4119
- return;
4120
- }
4121
- var duration = settings.iStateDuration;
4122
- if (duration > 0 && state.time < +new Date() - (duration * 1000)) {
4123
- return;
4124
- }
4125
- if (columns.length !== state.columns.length) {
4126
- return;
4127
- }
4128
 
4129
- // Store the saved state so it might be accessed at any time
4130
- settings.oLoadedState = $.extend(true, {}, state);
 
 
 
4131
 
4132
- if (state.start !== undefined) {
4133
- settings._iDisplayStart = state.start;
4134
- settings.iInitDisplayStart = state.start;
4135
- }
4136
- if (state.length !== undefined) {
4137
- settings._iDisplayLength = state.length;
4138
- }
4139
 
4140
- if (state.order !== undefined) {
4141
- settings.aaSorting = [];
4142
- $.each(state.order, function (i, col) {
4143
- settings.aaSorting.push(col[0] >= columns.length ? [0, col[1]] :
4144
- col
4145
- );
4146
- });
4147
- }
 
4148
 
4149
- if (state.search !== undefined) {
4150
- $.extend(settings.oPreviousSearch, _fnSearchToHung(state.search));
4151
- }
 
 
 
 
 
 
 
4152
 
4153
- for (i = 0, ien = state.columns.length; i < ien; i++) {
4154
- var col = state.columns[i];
4155
- if (col.visible !== undefined) {
4156
- columns[i].bVisible = col.visible;
4157
  }
4158
 
4159
- if (col.search !== undefined) {
4160
- $.extend(settings.aoPreSearchCols[i], _fnSearchToHung(col.search));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4161
  }
 
 
 
 
 
 
 
 
4162
  }
4163
 
4164
- _fnCallbackFire(settings, 'aoStateLoaded', 'stateLoaded', [settings, state]);
 
 
 
 
 
4165
  }
4166
 
4167
- function _fnSettingsFromNode(table) {
 
 
 
 
 
 
 
 
4168
  var settings = DataTable.settings;
4169
  var idx = $.inArray(table, _pluck(settings, 'nTable'));
4170
 
4171
  return idx !== -1 ?
4172
- settings[idx] :
4173
  null;
4174
  }
4175
 
4176
- function _fnLog(settings, level, msg, tn) {
 
 
 
 
 
 
 
 
 
 
4177
  msg = 'DataTables warning: ' +
4178
  (settings ? 'table id=' + settings.sTableId + ' - ' : '') + msg;
4179
 
@@ -4203,7 +6390,17 @@
4203
  }
4204
  }
4205
 
4206
- function _fnMap(ret, src, name, mappedName) {
 
 
 
 
 
 
 
 
 
 
4207
  if ($.isArray(name)) {
4208
  $.each(name, function (i, val) {
4209
  if ($.isArray(val)) {
@@ -4225,7 +6422,26 @@
4225
  }
4226
  }
4227
 
4228
- function _fnExtend(out, extender, breakRefs) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4229
  var val;
4230
 
4231
  for (var prop in extender) {
@@ -4248,26 +6464,49 @@
4248
  return out;
4249
  }
4250
 
4251
- function _fnBindAction(n, oData, fn) {
 
 
 
 
 
 
 
 
 
 
 
4252
  $(n)
4253
- .bind('click.DT', oData, function (e) {
4254
  n.blur(); // Remove focus outline for mouse users
4255
  fn(e);
4256
  })
4257
- .bind('keypress.DT', oData, function (e) {
4258
  if (e.which === 13) {
4259
  e.preventDefault();
4260
  fn(e);
4261
  }
4262
  })
4263
- .bind('selectstart.DT', function () {
4264
  /* Take the brutal approach to cancelling text selection */
4265
  return false;
4266
  });
4267
  }
4268
 
4269
- function _fnCallbackReg(oSettings, sStore, fn, sName) {
4270
- if (fn) {
 
 
 
 
 
 
 
 
 
 
 
 
4271
  oSettings[sStore].push({
4272
  "fn": fn,
4273
  "sName": sName
@@ -4275,7 +6514,23 @@
4275
  }
4276
  }
4277
 
4278
- function _fnCallbackFire(settings, callbackArr, eventName, args) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4279
  var ret = [];
4280
 
4281
  if (callbackArr) {
@@ -4295,41 +6550,62 @@
4295
  return ret;
4296
  }
4297
 
4298
- function _fnLengthOverflow(settings) {
 
 
4299
  var
4300
  start = settings._iDisplayStart,
4301
  end = settings.fnDisplayEnd(),
4302
  len = settings._iDisplayLength;
4303
 
4304
- if (start >= end) {
 
 
4305
  start = end - len;
4306
  }
4307
 
 
4308
  start -= (start % len);
4309
 
4310
- if (len === -1 || start < 0) {
 
4311
  start = 0;
4312
  }
4313
 
4314
  settings._iDisplayStart = start;
4315
  }
4316
 
4317
- function _fnRenderer(settings, type) {
 
 
4318
  var renderer = settings.renderer;
4319
  var host = DataTable.ext.renderer[type];
4320
 
4321
  if ($.isPlainObject(renderer) && renderer[type]) {
4322
-
 
4323
  return host[renderer[type]] || host._;
4324
  } else if (typeof renderer === 'string') {
4325
-
 
4326
  return host[renderer] || host._;
4327
  }
4328
 
 
4329
  return host._;
4330
  }
4331
 
4332
- function _fnDataSource(settings) {
 
 
 
 
 
 
 
 
 
 
4333
  if (settings.oFeatures.bServerSide) {
4334
  return 'ssp';
4335
  } else if (settings.ajax || settings.sAjaxSource) {
@@ -4338,11 +6614,79 @@
4338
  return 'dom';
4339
  }
4340
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4341
  var __apiStruct = [];
4342
 
 
 
 
 
 
 
 
4343
  var __arrayProto = Array.prototype;
4344
 
4345
- var _toSettings = function (mixed) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4346
  var idx, jq;
4347
  var settings = DataTable.settings;
4348
  var tables = $.map(settings, function (el, i) {
@@ -4376,7 +6720,63 @@
4376
  }
4377
  };
4378
 
4379
- _Api = function (context, data) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4380
  if (!(this instanceof _Api)) {
4381
  return new _Api(context, data);
4382
  }
@@ -4397,6 +6797,7 @@
4397
  ctxSettings(context);
4398
  }
4399
 
 
4400
  this.context = _unique(settings);
4401
 
4402
  // Initial data
@@ -4416,31 +6817,46 @@
4416
 
4417
  DataTable.Api = _Api;
4418
 
 
 
4419
  $.extend(_Api.prototype, {
4420
- any: function () {
 
4421
  return this.count() !== 0;
4422
  },
 
4423
  concat: __arrayProto.concat,
 
4424
  context: [], // array of table settings objects
4425
- count: function () {
 
 
 
4426
  return this.flatten().length;
4427
  },
4428
- each: function (fn) {
 
 
4429
  for (var i = 0, ien = this.length; i < ien; i++) {
4430
  fn.call(this, this[i], i, this);
4431
  }
4432
 
4433
  return this;
4434
  },
4435
- eq: function (idx) {
 
 
4436
  var ctx = this.context;
4437
 
4438
  return ctx.length > idx ?
4439
  new _Api(ctx[idx], this[idx]) :
4440
  null;
4441
  },
4442
- filter: function (fn) {
 
 
4443
  var a = [];
 
4444
  if (__arrayProto.filter) {
4445
  a = __arrayProto.filter.call(this, fn, this);
4446
  } else {
@@ -4451,14 +6867,20 @@
4451
  }
4452
  }
4453
  }
 
4454
  return new _Api(this.context, a);
4455
  },
4456
- flatten: function () {
 
 
4457
  var a = [];
4458
  return new _Api(this.context, a.concat.apply(a, this.toArray()));
4459
  },
 
4460
  join: __arrayProto.join,
4461
- indexOf: __arrayProto.indexOf || function (obj, start) {
 
 
4462
  for (var i = (start || 0), ien = this.length; i < ien; i++) {
4463
  if (this[i] === obj) {
4464
  return i;
@@ -4466,10 +6888,10 @@
4466
  }
4467
  return -1;
4468
  },
 
4469
  iterator: function (flatten, type, fn, alwaysNew) {
4470
  var
4471
- a = [],
4472
- ret,
4473
  i, ien, j, jen,
4474
  context = this.context,
4475
  rows, items, item,
@@ -4534,12 +6956,17 @@
4534
  }
4535
  return this;
4536
  },
4537
- lastIndexOf: __arrayProto.lastIndexOf || function (obj, start) {
 
 
4538
  // Bit cheeky...
4539
  return this.indexOf.apply(this.toArray.reverse(), arguments);
4540
  },
 
4541
  length: 0,
4542
- map: function (fn) {
 
 
4543
  var a = [];
4544
 
4545
  if (__arrayProto.map) {
@@ -4553,43 +6980,76 @@
4553
 
4554
  return new _Api(this.context, a);
4555
  },
4556
- pluck: function (prop) {
 
 
4557
  return this.map(function (el) {
4558
- return el[prop];
4559
  });
4560
  },
 
4561
  pop: __arrayProto.pop,
 
4562
  push: __arrayProto.push,
4563
- reduce: __arrayProto.reduce || function (fn, init) {
 
 
 
4564
  return _fnReduce(this, fn, init, 0, this.length, 1);
4565
  },
4566
- reduceRight: __arrayProto.reduceRight || function (fn, init) {
 
 
4567
  return _fnReduce(this, fn, init, this.length - 1, -1, -1);
4568
  },
 
4569
  reverse: __arrayProto.reverse,
 
4570
  // Object with rows, columns and opts
4571
  selector: null,
 
4572
  shift: __arrayProto.shift,
 
 
 
 
 
4573
  sort: __arrayProto.sort, // ? name - order?
 
 
4574
  splice: __arrayProto.splice,
4575
- toArray: function () {
 
 
4576
  return __arrayProto.slice.call(this);
4577
  },
4578
- to$: function () {
 
 
4579
  return $(this);
4580
  },
4581
- toJQuery: function () {
 
 
4582
  return $(this);
4583
  },
4584
- unique: function () {
 
 
4585
  return new _Api(this.context, _unique(this));
4586
  },
 
4587
  unshift: __arrayProto.unshift
4588
  });
4589
- _Api.extend = function (scope, obj, ext) {
 
 
 
 
4590
  if (!ext.length || !obj || (!(obj instanceof _Api) && !obj.__dt_wrapper)) {
4591
  return;
4592
  }
 
4593
  var
4594
  i, ien,
4595
  j, jen,
@@ -4597,32 +7057,79 @@
4597
  methodScoping = function (scope, fn, struc) {
4598
  return function () {
4599
  var ret = fn.apply(scope, arguments);
 
 
4600
  _Api.extend(ret, ret, struc.methodExt);
4601
  return ret;
4602
  };
4603
  };
 
4604
  for (i = 0, ien = ext.length; i < ien; i++) {
4605
  struct = ext[i];
4606
- obj[struct.name] = typeof struct.val === 'function' ?
 
 
4607
  methodScoping(scope, struct.val, struct) :
4608
- $.isPlainObject(struct.val) ? {} :
 
4609
  struct.val;
4610
- obj[struct.name].__dt_wrapper = true;
4611
- _Api.extend(scope, obj[struct.name], struct.propExt);
 
 
 
4612
  }
4613
  };
4614
- _Api.register = _api_register = function (name, val) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4615
  if ($.isArray(name)) {
4616
  for (var j = 0, jen = name.length; j < jen; j++) {
4617
  _Api.register(name[j], val);
4618
  }
4619
  return;
4620
  }
 
4621
  var
4622
  i, ien,
4623
  heir = name.split('.'),
4624
  struct = __apiStruct,
4625
  key, method;
 
4626
  var find = function (src, name) {
4627
  for (var i = 0, ien = src.length; i < ien; i++) {
4628
  if (src[i].name === name) {
@@ -4631,11 +7138,13 @@
4631
  }
4632
  return null;
4633
  };
 
4634
  for (i = 0, ien = heir.length; i < ien; i++) {
4635
  method = heir[i].indexOf('()') !== -1;
4636
  key = method ?
4637
  heir[i].replace('()', '') :
4638
  heir[i];
 
4639
  var src = find(struct, key);
4640
  if (!src) {
4641
  src = {
@@ -4646,6 +7155,7 @@
4646
  };
4647
  struct.push(src);
4648
  }
 
4649
  if (i === ien - 1) {
4650
  src.val = val;
4651
  } else {
@@ -4655,75 +7165,135 @@
4655
  }
4656
  }
4657
  };
 
 
4658
  _Api.registerPlural = _api_registerPlural = function (pluralName, singularName, val) {
4659
  _Api.register(pluralName, val);
 
4660
  _Api.register(singularName, function () {
4661
  var ret = val.apply(this, arguments);
 
4662
  if (ret === this) {
 
4663
  return this;
4664
  } else if (ret instanceof _Api) {
 
 
4665
  return ret.length ?
4666
  $.isArray(ret[0]) ?
4667
  new _Api(ret.context, ret[0]) : // Array results are 'enhanced'
4668
  ret[0] :
4669
  undefined;
4670
  }
 
 
4671
  return ret;
4672
  });
4673
  };
4674
 
4675
- var __table_selector = function (selector, a) {
 
 
 
 
 
 
 
 
 
 
 
 
4676
  if (typeof selector === 'number') {
4677
- return [a[selector]];
4678
  }
 
 
4679
  var nodes = $.map(a, function (el, i) {
4680
  return el.nTable;
4681
  });
 
4682
  return $(nodes)
4683
  .filter(selector)
4684
  .map(function (i) {
 
4685
  var idx = $.inArray(this, nodes);
4686
- return a[idx];
4687
  })
4688
  .toArray();
4689
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4690
  _api_register('tables()', function (selector) {
 
4691
  return selector ?
4692
  new _Api(__table_selector(selector, this.context)) :
4693
  this;
4694
  });
 
 
4695
  _api_register('table()', function (selector) {
4696
  var tables = this.tables(selector);
4697
  var ctx = tables.context;
 
 
4698
  return ctx.length ?
4699
  new _Api(ctx[0]) :
4700
  tables;
4701
  });
 
 
4702
  _api_registerPlural('tables().nodes()', 'table().node()', function () {
4703
  return this.iterator('table', function (ctx) {
4704
  return ctx.nTable;
4705
  }, 1);
4706
  });
 
 
4707
  _api_registerPlural('tables().body()', 'table().body()', function () {
4708
  return this.iterator('table', function (ctx) {
4709
  return ctx.nTBody;
4710
  }, 1);
4711
  });
 
 
4712
  _api_registerPlural('tables().header()', 'table().header()', function () {
4713
  return this.iterator('table', function (ctx) {
4714
  return ctx.nTHead;
4715
  }, 1);
4716
  });
 
 
4717
  _api_registerPlural('tables().footer()', 'table().footer()', function () {
4718
  return this.iterator('table', function (ctx) {
4719
  return ctx.nTFoot;
4720
  }, 1);
4721
  });
 
 
4722
  _api_registerPlural('tables().containers()', 'table().container()', function () {
4723
  return this.iterator('table', function (ctx) {
4724
  return ctx.nTableWrapper;
4725
  }, 1);
4726
  });
 
 
 
 
 
 
4727
  _api_register('draw()', function (paging) {
4728
  return this.iterator('table', function (settings) {
4729
  if (paging === 'page') {
@@ -4734,10 +7304,33 @@
4734
  false :
4735
  true;
4736
  }
 
4737
  _fnReDraw(settings, paging === false);
4738
  }
4739
  });
4740
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4741
  _api_register('page()', function (action) {
4742
  if (action === undefined) {
4743
  return this.page.info().page; // not an expensive call
@@ -4748,6 +7341,26 @@
4748
  _fnPageChange(settings, action);
4749
  });
4750
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4751
  _api_register('page.info()', function (action) {
4752
  if (this.context.length === 0) {
4753
  return undefined;
@@ -4771,6 +7384,19 @@
4771
  "serverSide": _fnDataSource(settings) === 'ssp'
4772
  };
4773
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
4774
  _api_register('page.len()', function (len) {
4775
  // Note that we can't call this function 'length()' because `length`
4776
  // is a Javascript property of functions which defines how many arguments
@@ -4786,21 +7412,31 @@
4786
  _fnLengthChange(settings, len);
4787
  });
4788
  });
 
 
 
4789
  var __reload = function (settings, holdPosition, callback) {
 
4790
  if (callback) {
4791
  var api = new _Api(settings);
 
4792
  api.one('draw', function () {
4793
  callback(api.ajax.json());
4794
  });
4795
  }
 
4796
  if (_fnDataSource(settings) == 'ssp') {
4797
  _fnReDraw(settings, holdPosition);
4798
  } else {
4799
  _fnProcessingDisplay(settings, true);
 
 
4800
  var xhr = settings.jqXHR;
4801
  if (xhr && xhr.readyState !== 4) {
4802
  xhr.abort();
4803
  }
 
 
4804
  _fnBuildAjax(settings, [], function (json) {
4805
  _fnClearTable(settings);
4806
 
@@ -4808,30 +7444,74 @@
4808
  for (var i = 0, ien = data.length; i < ien; i++) {
4809
  _fnAddData(settings, data[i]);
4810
  }
 
4811
  _fnReDraw(settings, holdPosition);
4812
  _fnProcessingDisplay(settings, false);
4813
  });
4814
  }
4815
  };
 
 
 
 
 
 
 
 
 
4816
  _api_register('ajax.json()', function () {
4817
  var ctx = this.context;
4818
 
4819
  if (ctx.length > 0) {
4820
  return ctx[0].json;
4821
  }
 
 
4822
  });
 
 
 
 
 
4823
  _api_register('ajax.params()', function () {
4824
  var ctx = this.context;
4825
 
4826
  if (ctx.length > 0) {
4827
  return ctx[0].oAjaxData;
4828
  }
 
 
4829
  });
 
 
 
 
 
 
 
 
 
 
 
4830
  _api_register('ajax.reload()', function (callback, resetPaging) {
4831
  return this.iterator('table', function (settings) {
4832
  __reload(settings, resetPaging === false, callback);
4833
  });
4834
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4835
  _api_register('ajax.url()', function (url) {
4836
  var ctx = this.context;
4837
 
@@ -4848,31 +7528,59 @@
4848
  ctx.ajax :
4849
  ctx.sAjaxSource;
4850
  }
 
 
4851
  return this.iterator('table', function (settings) {
4852
  if ($.isPlainObject(settings.ajax)) {
4853
  settings.ajax.url = url;
4854
  } else {
4855
  settings.ajax = url;
4856
  }
 
 
 
4857
  });
4858
  });
 
 
 
 
 
 
 
 
 
 
 
4859
  _api_register('ajax.url().load()', function (callback, resetPaging) {
 
 
4860
  return this.iterator('table', function (ctx) {
4861
  __reload(ctx, resetPaging === false, callback);
4862
  });
4863
  });
4864
- var _selector_run = function (type, selector, selectFn, settings, opts) {
 
 
 
 
 
4865
  var
4866
- out = [],
4867
- res,
4868
  a, i, ien, j, jen,
4869
  selectorType = typeof selector;
 
 
 
4870
  if (!selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined) {
4871
  selector = [selector];
4872
  }
 
4873
  for (i = 0, ien = selector.length; i < ien; i++) {
4874
- a = selector[i] && selector[i].split ?
4875
- selector[i].split(',') : [selector[i]];
 
 
4876
 
4877
  for (j = 0, jen = a.length; j < jen; j++) {
4878
  res = selectFn(typeof a[j] === 'string' ? $.trim(a[j]) : a[j]);
@@ -4882,18 +7590,27 @@
4882
  }
4883
  }
4884
  }
4885
- var ext = _ext.selector[type];
 
 
4886
  if (ext.length) {
4887
  for (i = 0, ien = ext.length; i < ien; i++) {
4888
  out = ext[i](settings, opts, out);
4889
  }
4890
  }
 
4891
  return _unique(out);
4892
  };
4893
- var _selector_opts = function (opts) {
 
 
 
4894
  if (!opts) {
4895
  opts = {};
4896
  }
 
 
 
4897
  if (opts.filter && opts.search === undefined) {
4898
  opts.search = opts.filter;
4899
  }
@@ -4904,10 +7621,15 @@
4904
  page: 'all'
4905
  }, opts);
4906
  };
4907
- var _selector_first = function (inst) {
 
 
 
4908
  // Reduce the API instance to the first item found
4909
  for (var i = 0, ien = inst.length; i < ien; i++) {
4910
  if (inst[i].length > 0) {
 
 
4911
  inst[0] = inst[i];
4912
  inst[0].length = 1;
4913
  inst.length = 1;
@@ -4916,22 +7638,37 @@
4916
  return inst;
4917
  }
4918
  }
 
 
4919
  inst.length = 0;
4920
  return inst;
4921
  };
4922
- var _selector_row_indexes = function (settings, opts) {
 
 
 
4923
  var
4924
  i, ien, tmp, a = [],
4925
  displayFiltered = settings.aiDisplay,
4926
  displayMaster = settings.aiDisplayMaster;
 
4927
  var
4928
  search = opts.search, // none, applied, removed
4929
  order = opts.order, // applied, current, index (original - compatibility with 1.9)
4930
- page = opts.page; // all, current
 
4931
  if (_fnDataSource(settings) == 'ssp') {
4932
- return search === 'removed' ? [] :
 
 
 
 
 
4933
  _range(0, displayMaster.length);
4934
  } else if (page == 'current') {
 
 
 
4935
  for (i = settings._iDisplayStart, ien = settings.fnDisplayEnd(); i < ien; i++) {
4936
  a.push(displayFiltered[i]);
4937
  }
@@ -4951,37 +7688,69 @@
4951
  tmp = $.inArray(i, displayFiltered);
4952
 
4953
  if ((tmp === -1 && search == 'removed') ||
4954
- (tmp >= 0 && search == 'applied')) {
 
4955
  a.push(i);
4956
  }
4957
  }
4958
  }
4959
  }
 
4960
  return a;
4961
  };
4962
- var __row_selector = function (settings, selector, opts) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4963
  var run = function (sel) {
4964
  var selInt = _intVal(sel);
4965
  var i, ien;
 
 
 
 
4966
  if (selInt !== null && !opts) {
4967
  return [selInt];
4968
  }
4969
- var rows = _selector_row_indexes(settings, opts);
 
 
 
 
4970
  if (selInt !== null && $.inArray(selInt, rows) !== -1) {
 
4971
  return [selInt];
4972
- } else if (!sel) {
4973
  // Selector - none
4974
  return rows;
4975
  }
 
 
4976
  if (typeof sel === 'function') {
4977
  return $.map(rows, function (idx) {
4978
- var row = settings.aoData[idx];
4979
  return sel(idx, row._aData, row.nTr) ? idx : null;
4980
  });
4981
  }
 
 
4982
  var nodes = _removeEmpty(
4983
  _pluck_order(settings.aoData, rows, 'nTr')
4984
  );
 
4985
  // Selector - node
4986
  if (sel.nodeName) {
4987
  if (sel._DT_RowIndex !== undefined) {
@@ -4990,16 +7759,35 @@
4990
  return [sel._DT_CellIndex.row];
4991
  } else {
4992
  var host = $(sel).closest('*[data-dt-row]');
4993
- return host.length ? [host.data('dt-row')] : [];
 
 
4994
  }
4995
  }
 
 
 
 
 
 
 
 
 
 
4996
  if (typeof sel === 'string' && sel.charAt(0) === '#') {
4997
  // get row index from id
4998
- var rowObj = settings.aIds[sel.replace(/^#/, '')];
4999
  if (rowObj !== undefined) {
5000
  return [rowObj.idx];
5001
  }
 
 
 
5002
  }
 
 
 
 
5003
  return $(nodes)
5004
  .filter(sel)
5005
  .map(function () {
@@ -5007,19 +7795,27 @@
5007
  })
5008
  .toArray();
5009
  };
 
5010
  return _selector_run('row', selector, run, settings, opts);
5011
  };
 
 
5012
  _api_register('rows()', function (selector, opts) {
 
5013
  if (selector === undefined) {
5014
  selector = '';
5015
  } else if ($.isPlainObject(selector)) {
5016
  opts = selector;
5017
  selector = '';
5018
  }
 
5019
  opts = _selector_opts(opts);
 
5020
  var inst = this.iterator('table', function (settings) {
5021
  return __row_selector(settings, selector, opts);
5022
  }, 1);
 
 
5023
  inst.selector.rows = selector;
5024
  inst.selector.opts = opts;
5025
 
@@ -5028,7 +7824,7 @@
5028
 
5029
  _api_register('rows().nodes()', function () {
5030
  return this.iterator('row', function (settings, row) {
5031
- return settings.aoData[row].nTr || undefined;
5032
  }, 1);
5033
  });
5034
 
@@ -5040,7 +7836,7 @@
5040
 
5041
  _api_registerPlural('rows().cache()', 'row().cache()', function (type) {
5042
  return this.iterator('row', function (settings, row) {
5043
- var r = settings.aoData[row];
5044
  return type === 'search' ? r._aFilterData : r._aSortData;
5045
  }, 1);
5046
  });
@@ -5060,9 +7856,11 @@
5060
  _api_registerPlural('rows().ids()', 'row().id()', function (hash) {
5061
  var a = [];
5062
  var context = this.context;
 
 
5063
  for (var i = 0, ien = context.length; i < ien; i++) {
5064
  for (var j = 0, jen = this[i].length; j < jen; j++) {
5065
- var id = context[i].rowIdFn(context[i].aoData[this[i][j]]._aData);
5066
  a.push((hash === true ? '#' : '') + id);
5067
  }
5068
  }
@@ -5075,17 +7873,22 @@
5075
 
5076
  this.iterator('row', function (settings, row, thatIdx) {
5077
  var data = settings.aoData;
5078
- var rowData = data[row];
5079
  var i, ien, j, jen;
5080
  var loopRow, loopCells;
 
5081
  data.splice(row, 1);
 
 
5082
  for (i = 0, ien = data.length; i < ien; i++) {
5083
  loopRow = data[i];
5084
  loopCells = loopRow.anCells;
 
5085
  // Rows
5086
  if (loopRow.nTr !== null) {
5087
  loopRow.nTr._DT_RowIndex = i;
5088
  }
 
5089
  // Cells
5090
  if (loopCells !== null) {
5091
  for (j = 0, jen = loopCells.length; j < jen; j++) {
@@ -5093,68 +7896,102 @@
5093
  }
5094
  }
5095
  }
 
5096
  // Delete from the display arrays
5097
  _fnDeleteIndex(settings.aiDisplayMaster, row);
5098
  _fnDeleteIndex(settings.aiDisplay, row);
5099
- _fnDeleteIndex(that[thatIdx], row, false); // maintain local indexes
 
5100
  // Check for an 'overflow' they case for displaying the table
5101
  _fnLengthOverflow(settings);
 
5102
  // Remove the row's ID reference if there is one
5103
  var id = settings.rowIdFn(rowData._aData);
5104
  if (id !== undefined) {
5105
- delete settings.aIds[id];
5106
  }
5107
  });
 
5108
  this.iterator('table', function (settings) {
5109
  for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
5110
  settings.aoData[i].idx = i;
5111
  }
5112
  });
 
5113
  return this;
5114
  });
 
 
5115
  _api_register('rows.add()', function (rows) {
5116
  var newRows = this.iterator('table', function (settings) {
5117
  var row, i, ien;
5118
  var out = [];
 
5119
  for (i = 0, ien = rows.length; i < ien; i++) {
5120
  row = rows[i];
 
5121
  if (row.nodeName && row.nodeName.toUpperCase() === 'TR') {
5122
  out.push(_fnAddTr(settings, row)[0]);
5123
  } else {
5124
  out.push(_fnAddData(settings, row));
5125
  }
5126
  }
 
5127
  return out;
5128
  }, 1);
 
 
5129
  var modRows = this.rows(-1);
5130
  modRows.pop();
5131
  $.merge(modRows, newRows);
 
5132
  return modRows;
5133
  });
 
 
 
 
 
 
 
 
5134
  _api_register('row()', function (selector, opts) {
5135
  return _selector_first(this.rows(selector, opts));
5136
  });
 
 
5137
  _api_register('row().data()', function (data) {
5138
  var ctx = this.context;
5139
 
5140
  if (data === undefined) {
5141
  // Get
5142
  return ctx.length && this.length ?
5143
- ctx[0].aoData[this[0]]._aData :
5144
  undefined;
5145
  }
5146
- ctx[0].aoData[this[0]]._aData = data;
 
 
 
 
5147
  _fnInvalidate(ctx[0], this[0], 'data');
 
5148
  return this;
5149
  });
 
 
5150
  _api_register('row().node()', function () {
5151
  var ctx = this.context;
5152
 
5153
  return ctx.length && this.length ?
5154
- ctx[0].aoData[this[0]].nTr || null :
5155
  null;
5156
  });
 
 
5157
  _api_register('row.add()', function (row) {
 
 
5158
  if (row instanceof $ && row.length) {
5159
  row = row[0];
5160
  }
@@ -5165,9 +8002,16 @@
5165
  }
5166
  return _fnAddData(settings, row);
5167
  });
 
 
5168
  return this.row(rows[0]);
5169
  });
5170
- var __details_add = function (ctx, row, data, klass) {
 
 
 
 
 
5171
  var rows = [];
5172
  var addRow = function (r, k) {
5173
  // Recursion to allow for arrays of jQuery objects
@@ -5178,6 +8022,8 @@
5178
  return;
5179
  }
5180
 
 
 
5181
  if (r.nodeName && r.nodeName.toLowerCase() === 'tr') {
5182
  rows.push(r);
5183
  } else {
@@ -5185,26 +8031,35 @@
5185
  var created = $('<tr><td/></tr>').addClass(k);
5186
  $('td', created)
5187
  .addClass(k)
5188
- .html(r)[0].colSpan = _fnVisbleColumns(ctx);
 
5189
 
5190
  rows.push(created[0]);
5191
  }
5192
  };
 
5193
  addRow(data, klass);
5194
 
5195
  if (row._details) {
5196
- row._details.remove();
5197
  }
 
5198
  row._details = $(rows);
 
5199
  // If the children were already shown, that state should be retained
5200
  if (row._detailsShow) {
5201
  row._details.insertAfter(row.nTr);
5202
  }
5203
  };
5204
- var __details_remove = function (api, idx) {
 
 
 
5205
  var ctx = api.context;
 
5206
  if (ctx.length) {
5207
- var row = ctx[0].aoData[idx !== undefined ? idx : api[0]];
 
5208
  if (row && row._details) {
5209
  row._details.remove();
5210
 
@@ -5213,58 +8068,70 @@
5213
  }
5214
  }
5215
  };
 
 
5216
  var __details_display = function (api, show) {
5217
  var ctx = api.context;
5218
 
5219
  if (ctx.length && api.length) {
5220
- var row = ctx[0].aoData[api[0]];
5221
 
5222
  if (row._details) {
5223
  row._detailsShow = show;
 
5224
  if (show) {
5225
  row._details.insertAfter(row.nTr);
5226
  } else {
5227
  row._details.detach();
5228
  }
 
5229
  __details_events(ctx[0]);
5230
  }
5231
  }
5232
  };
5233
- var __details_events = function (settings) {
 
 
 
5234
  var api = new _Api(settings);
5235
  var namespace = '.dt.DT_details';
5236
  var drawEvent = 'draw' + namespace;
5237
  var colvisEvent = 'column-visibility' + namespace;
5238
  var destroyEvent = 'destroy' + namespace;
5239
  var data = settings.aoData;
 
5240
  api.off(drawEvent + ' ' + colvisEvent + ' ' + destroyEvent);
 
5241
  if (_pluck(data, '_details').length > 0) {
5242
  // On each draw, insert the required elements into the document
5243
  api.on(drawEvent, function (e, ctx) {
5244
  if (settings !== ctx) {
5245
  return;
5246
  }
5247
- api.rows({
5248
- page: 'current'
5249
- }).eq(0).each(function (idx) {
5250
  // Internal data grab
5251
- var row = data[idx];
5252
 
5253
  if (row._detailsShow) {
5254
  row._details.insertAfter(row.nTr);
5255
  }
5256
  });
5257
  });
 
5258
  // Column visibility change - update the colspan
5259
  api.on(colvisEvent, function (e, ctx, idx, vis) {
5260
  if (settings !== ctx) {
5261
  return;
5262
  }
 
5263
  // Update the colspan for the details rows (note, only if it already has
5264
  // a colspan)
5265
  var row, visible = _fnVisbleColumns(ctx);
 
5266
  for (var i = 0, ien = data.length; i < ien; i++) {
5267
  row = data[i];
 
5268
  if (row._details) {
5269
  row._details.children('td[colspan]').attr('colspan', visible);
5270
  }
@@ -5285,18 +8152,23 @@
5285
  });
5286
  }
5287
  };
 
5288
  // Strings for the method names to help minification
5289
  var _emp = '';
5290
  var _child_obj = _emp + 'row().child';
5291
  var _child_mth = _child_obj + '()';
5292
 
 
 
 
 
5293
  _api_register(_child_mth, function (data, klass) {
5294
  var ctx = this.context;
5295
 
5296
  if (data === undefined) {
5297
  // get
5298
  return ctx.length && this.length ?
5299
- ctx[0].aoData[this[0]]._details :
5300
  undefined;
5301
  } else if (data === true) {
5302
  // show
@@ -5306,41 +8178,71 @@
5306
  __details_remove(this);
5307
  } else if (ctx.length && this.length) {
5308
  // set
5309
- __details_add(ctx[0], ctx[0].aoData[this[0]], data, klass);
5310
  }
 
5311
  return this;
5312
  });
 
 
5313
  _api_register([
5314
  _child_obj + '.show()',
5315
  _child_mth + '.show()' // only when `child()` was called with parameters (without
5316
- ], function (show) { // it returns an object and this method is not executed)
5317
  __details_display(this, true);
5318
  return this;
5319
  });
 
 
5320
  _api_register([
5321
  _child_obj + '.hide()',
5322
  _child_mth + '.hide()' // only when `child()` was called with parameters (without
5323
- ], function () { // it returns an object and this method is not executed)
5324
  __details_display(this, false);
5325
  return this;
5326
  });
 
 
5327
  _api_register([
5328
  _child_obj + '.remove()',
5329
  _child_mth + '.remove()' // only when `child()` was called with parameters (without
5330
- ], function () { // it returns an object and this method is not executed)
5331
  __details_remove(this);
5332
  return this;
5333
  });
 
 
5334
  _api_register(_child_obj + '.isShown()', function () {
5335
  var ctx = this.context;
5336
 
5337
  if (ctx.length && this.length) {
5338
  // _detailsShown as false or undefined will fall through to return false
5339
- return ctx[0].aoData[this[0]]._detailsShow || false;
5340
  }
5341
  return false;
5342
  });
5343
- var __re_column_selector = /^(.+):(name|visIdx|visible)$/;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5344
  var __columnData = function (settings, column, r1, r2, rows) {
5345
  var a = [];
5346
  for (var row = 0, ien = rows.length; row < ien; row++) {
@@ -5348,11 +8250,15 @@
5348
  }
5349
  return a;
5350
  };
5351
- var __column_selector = function (settings, selector, opts) {
 
 
 
5352
  var
5353
  columns = settings.aoColumns,
5354
  names = _pluck(columns, 'sName'),
5355
  nodes = _pluck(columns, 'nTh');
 
5356
  var run = function (s) {
5357
  var selInt = _intVal(s);
5358
 
@@ -5360,12 +8266,16 @@
5360
  if (s === '') {
5361
  return _range(columns.length);
5362
  }
 
 
5363
  if (selInt !== null) {
5364
  return [selInt >= 0 ?
5365
  selInt : // Count from left
5366
  columns.length + selInt // Count from right (+ because its a negative value)
5367
  ];
5368
  }
 
 
5369
  if (typeof s === 'function') {
5370
  var rows = _selector_row_indexes(settings, opts);
5371
 
@@ -5373,13 +8283,16 @@
5373
  return s(
5374
  idx,
5375
  __columnData(settings, idx, 0, 0, rows),
5376
- nodes[idx]
5377
  ) ? idx : null;
5378
  });
5379
  }
 
 
5380
  var match = typeof s === 'string' ?
5381
  s.match(__re_column_selector) :
5382
  '';
 
5383
  if (match) {
5384
  switch (match[2]) {
5385
  case 'visIdx':
@@ -5391,7 +8304,7 @@
5391
  var visColumns = $.map(columns, function (col, i) {
5392
  return col.bVisible ? i : null;
5393
  });
5394
- return [visColumns[visColumns.length + idx]];
5395
  }
5396
  // Counting from the left
5397
  return [_fnVisibleToColumnIndex(settings, idx)];
@@ -5406,9 +8319,13 @@
5406
  return [];
5407
  }
5408
  }
 
 
5409
  if (s.nodeName && s._DT_CellIndex) {
5410
  return [s._DT_CellIndex.column];
5411
  }
 
 
5412
  var jqResult = $(nodes)
5413
  .filter(s)
5414
  .map(function () {
@@ -5419,21 +8336,33 @@
5419
  if (jqResult.length || !s.nodeName) {
5420
  return jqResult;
5421
  }
 
 
 
5422
  var host = $(s).closest('*[data-dt-column]');
5423
- return host.length ? [host.data('dt-column')] : [];
 
 
5424
  };
5425
 
5426
  return _selector_run('column', selector, run, settings, opts);
5427
  };
 
 
5428
  var __setColumnVis = function (settings, column, vis) {
5429
  var
5430
  cols = settings.aoColumns,
5431
- col = cols[column],
5432
  data = settings.aoData,
5433
  row, cells, i, ien, tr;
 
 
5434
  if (vis === undefined) {
5435
  return col.bVisible;
5436
  }
 
 
 
5437
  if (col.bVisible === vis) {
5438
  return;
5439
  }
@@ -5449,13 +8378,14 @@
5449
 
5450
  if (tr) {
5451
  // insertBefore can act like appendChild if 2nd arg is null
5452
- tr.insertBefore(cells[column], cells[insertBefore] || null);
5453
  }
5454
  }
5455
  } else {
5456
  // Remove column
5457
  $(_pluck(settings.aoData, 'anCells', column)).detach();
5458
  }
 
5459
  // Common actions
5460
  col.bVisible = vis;
5461
  _fnDrawHead(settings, settings.aoHeader);
@@ -5463,6 +8393,8 @@
5463
 
5464
  _fnSaveState(settings);
5465
  };
 
 
5466
  _api_register('columns()', function (selector, opts) {
5467
  // argument shifting
5468
  if (selector === undefined) {
@@ -5471,11 +8403,14 @@
5471
  opts = selector;
5472
  selector = '';
5473
  }
 
5474
  opts = _selector_opts(opts);
 
5475
  var inst = this.iterator('table', function (settings) {
5476
  return __column_selector(settings, selector, opts);
5477
  }, 1);
5478
 
 
5479
  inst.selector.cols = selector;
5480
  inst.selector.opts = opts;
5481
 
@@ -5521,11 +8456,12 @@
5521
  _api_registerPlural('columns().visible()', 'column().visible()', function (vis, calc) {
5522
  var ret = this.iterator('column', function (settings, column) {
5523
  if (vis === undefined) {
5524
- return settings.aoColumns[column].bVisible;
5525
  } // else
5526
  __setColumnVis(settings, column, vis);
5527
  });
5528
 
 
5529
  if (vis !== undefined) {
5530
  // Second loop once the first is done for events
5531
  this.iterator('column', function (settings, column) {
@@ -5536,6 +8472,7 @@
5536
  this.columns.adjust();
5537
  }
5538
  }
 
5539
  return ret;
5540
  });
5541
 
@@ -5546,11 +8483,13 @@
5546
  column;
5547
  }, 1);
5548
  });
 
5549
  _api_register('columns.adjust()', function () {
5550
  return this.iterator('table', function (settings) {
5551
  _fnAdjustColumnSizing(settings);
5552
  }, 1);
5553
  });
 
5554
  _api_register('column.index()', function (type, idx) {
5555
  if (this.context.length !== 0) {
5556
  var ctx = this.context[0];
@@ -5562,11 +8501,15 @@
5562
  }
5563
  }
5564
  });
 
5565
  _api_register('column()', function (selector, opts) {
5566
  return _selector_first(this.columns(selector, opts));
5567
  });
5568
 
5569
- var __cell_selector = function (settings, selector, opts) {
 
 
 
5570
  var data = settings.aoData;
5571
  var rows = _selector_row_indexes(settings, opts);
5572
  var cells = _removeEmpty(_pluck_order(data, rows, 'anCells'));
@@ -5574,34 +8517,45 @@
5574
  var row;
5575
  var columns = settings.aoColumns.length;
5576
  var a, i, ien, j, o, host;
 
5577
  var run = function (s) {
5578
  var fnSelector = typeof s === 'function';
 
5579
  if (s === null || s === undefined || fnSelector) {
5580
  // All cells and function selectors
5581
  a = [];
 
5582
  for (i = 0, ien = rows.length; i < ien; i++) {
5583
  row = rows[i];
 
5584
  for (j = 0; j < columns; j++) {
5585
  o = {
5586
  row: row,
5587
  column: j
5588
  };
 
5589
  if (fnSelector) {
5590
- host = data[row];
 
 
5591
  if (s(o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null)) {
5592
  a.push(o);
5593
  }
5594
  } else {
 
5595
  a.push(o);
5596
  }
5597
  }
5598
  }
 
5599
  return a;
5600
  }
 
5601
  // Selector - index
5602
  if ($.isPlainObject(s)) {
5603
  return [s];
5604
  }
 
5605
  // Selector - jQuery filtered cells
5606
  var jqResult = allCells
5607
  .filter(s)
@@ -5612,22 +8566,35 @@
5612
  };
5613
  })
5614
  .toArray();
 
5615
  if (jqResult.length || !s.nodeName) {
5616
  return jqResult;
5617
  }
 
 
 
 
5618
  host = $(s).closest('*[data-dt-row]');
5619
- return host.length ? [{
5620
- row: host.data('dt-row'),
5621
- column: host.data('dt-column')
5622
- }] : [];
 
 
5623
  };
 
5624
  return _selector_run('cell', selector, run, settings, opts);
5625
  };
 
 
 
 
5626
  _api_register('cells()', function (rowSelector, columnSelector, opts) {
5627
  // Argument shifting
5628
  if ($.isPlainObject(rowSelector)) {
5629
  // Indexes
5630
  if (rowSelector.row === undefined) {
 
5631
  opts = rowSelector;
5632
  rowSelector = null;
5633
  } else {
@@ -5640,11 +8607,15 @@
5640
  opts = columnSelector;
5641
  columnSelector = null;
5642
  }
 
 
5643
  if (columnSelector === null || columnSelector === undefined) {
5644
  return this.iterator('table', function (settings) {
5645
  return __cell_selector(settings, rowSelector, _selector_opts(opts));
5646
  });
5647
  }
 
 
5648
  var columns = this.columns(columnSelector, opts);
5649
  var rows = this.rows(rowSelector, opts);
5650
  var a, i, ien, j, jen;
@@ -5660,40 +8631,54 @@
5660
  });
5661
  }
5662
  }
 
5663
  return a;
5664
  }, 1);
 
5665
  $.extend(cells.selector, {
5666
  cols: columnSelector,
5667
  rows: rowSelector,
5668
  opts: opts
5669
  });
 
5670
  return cells;
5671
  });
 
 
5672
  _api_registerPlural('cells().nodes()', 'cell().node()', function () {
5673
  return this.iterator('cell', function (settings, row, column) {
5674
- var data = settings.aoData[row];
5675
 
5676
  return data && data.anCells ?
5677
- data.anCells[column] :
5678
  undefined;
5679
  }, 1);
5680
  });
 
 
5681
  _api_register('cells().data()', function () {
5682
  return this.iterator('cell', function (settings, row, column) {
5683
  return _fnGetCellData(settings, row, column);
5684
  }, 1);
5685
  });
 
 
5686
  _api_registerPlural('cells().cache()', 'cell().cache()', function (type) {
5687
  type = type === 'search' ? '_aFilterData' : '_aSortData';
 
5688
  return this.iterator('cell', function (settings, row, column) {
5689
- return settings.aoData[row][type][column];
5690
  }, 1);
5691
  });
 
 
5692
  _api_registerPlural('cells().render()', 'cell().render()', function (type) {
5693
  return this.iterator('cell', function (settings, row, column) {
5694
  return _fnGetCellData(settings, row, column, type);
5695
  }, 1);
5696
  });
 
 
5697
  _api_registerPlural('cells().indexes()', 'cell().index()', function () {
5698
  return this.iterator('cell', function (settings, row, column) {
5699
  return {
@@ -5703,14 +8688,21 @@
5703
  };
5704
  }, 1);
5705
  });
 
 
5706
  _api_registerPlural('cells().invalidate()', 'cell().invalidate()', function (src) {
5707
  return this.iterator('cell', function (settings, row, column) {
5708
  _fnInvalidate(settings, row, src, column);
5709
  });
5710
  });
 
 
 
5711
  _api_register('cell()', function (rowSelector, columnSelector, opts) {
5712
  return _selector_first(this.cells(rowSelector, columnSelector, opts));
5713
  });
 
 
5714
  _api_register('cell().data()', function (data) {
5715
  var ctx = this.context;
5716
  var cell = this[0];
@@ -5721,12 +8713,44 @@
5721
  _fnGetCellData(ctx[0], cell[0].row, cell[0].column) :
5722
  undefined;
5723
  }
 
 
5724
  _fnSetCellData(ctx[0], cell[0].row, cell[0].column, data);
5725
  _fnInvalidate(ctx[0], cell[0].row, 'data', cell[0].column);
5726
 
5727
  return this;
5728
  });
5729
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5730
  _api_register('order()', function (order, dir) {
5731
  var ctx = this.context;
5732
 
@@ -5736,24 +8760,40 @@
5736
  ctx[0].aaSorting :
5737
  undefined;
5738
  }
 
 
5739
  if (typeof order === 'number') {
5740
  // Simple column / direction passed in
5741
- order = [
5742
- [order, dir]
5743
- ];
5744
  } else if (order.length && !$.isArray(order[0])) {
5745
  // Arguments passed in (list of 1D arrays)
5746
  order = Array.prototype.slice.call(arguments);
5747
  }
 
 
5748
  return this.iterator('table', function (settings) {
5749
  settings.aaSorting = order.slice();
5750
  });
5751
  });
 
 
 
 
 
 
 
 
 
 
 
 
5752
  _api_register('order.listener()', function (node, column, callback) {
5753
  return this.iterator('table', function (settings) {
5754
  _fnSortAttachListener(settings, node, column, callback);
5755
  });
5756
  });
 
 
5757
  _api_register('order.fixed()', function (set) {
5758
  if (!set) {
5759
  var ctx = this.context;
@@ -5761,15 +8801,18 @@
5761
  ctx[0].aaSortingFixed :
5762
  undefined;
5763
 
5764
- return $.isArray(fixed) ? {
5765
- pre: fixed
5766
- } :
5767
  fixed;
5768
  }
 
5769
  return this.iterator('table', function (settings) {
5770
  settings.aaSortingFixed = $.extend(true, {}, set);
5771
  });
5772
  });
 
 
 
5773
  _api_register([
5774
  'columns().order()',
5775
  'column().order()'
@@ -5786,6 +8829,9 @@
5786
  settings.aaSorting = sort;
5787
  });
5788
  });
 
 
 
5789
  _api_register('search()', function (input, regex, smart, caseInsen) {
5790
  var ctx = this.context;
5791
 
@@ -5796,10 +8842,12 @@
5796
  undefined;
5797
  }
5798
 
 
5799
  return this.iterator('table', function (settings) {
5800
  if (!settings.oFeatures.bFilter) {
5801
  return;
5802
  }
 
5803
  _fnFilterComplete(settings, $.extend({}, settings.oPreviousSearch, {
5804
  "sSearch": input + "",
5805
  "bRegex": regex === null ? false : regex,
@@ -5808,6 +8856,8 @@
5808
  }), 1);
5809
  });
5810
  });
 
 
5811
  _api_registerPlural(
5812
  'columns().search()',
5813
  'column().search()',
@@ -5817,13 +8867,15 @@
5817
 
5818
  if (input === undefined) {
5819
  // get
5820
- return preSearch[column].sSearch;
5821
  }
 
 
5822
  if (!settings.oFeatures.bFilter) {
5823
  return;
5824
  }
5825
 
5826
- $.extend(preSearch[column], {
5827
  "sSearch": input + "",
5828
  "bRegex": regex === null ? false : regex,
5829
  "bSmart": smart === null ? true : smart,
@@ -5834,29 +8886,58 @@
5834
  });
5835
  }
5836
  );
 
 
 
 
 
5837
  _api_register('state()', function () {
5838
  return this.context.length ?
5839
  this.context[0].oSavedState :
5840
  null;
5841
  });
 
 
5842
  _api_register('state.clear()', function () {
5843
  return this.iterator('table', function (settings) {
5844
  // Save an empty object
5845
  settings.fnStateSaveCallback.call(settings.oInstance, settings, {});
5846
  });
5847
  });
 
 
5848
  _api_register('state.loaded()', function () {
5849
  return this.context.length ?
5850
  this.context[0].oLoadedState :
5851
  null;
5852
  });
 
 
5853
  _api_register('state.save()', function () {
5854
  return this.iterator('table', function (settings) {
5855
  _fnSaveState(settings);
5856
  });
5857
  });
5858
 
5859
- DataTable.versionCheck = DataTable.fnVersionCheck = function (version) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5860
  var aThis = DataTable.version.split('.');
5861
  var aThat = version.split('.');
5862
  var iThis, iThat;
@@ -5864,29 +8945,75 @@
5864
  for (var i = 0, iLen = aThat.length; i < iLen; i++) {
5865
  iThis = parseInt(aThis[i], 10) || 0;
5866
  iThat = parseInt(aThat[i], 10) || 0;
 
 
5867
  if (iThis === iThat) {
5868
  continue;
5869
  }
 
 
5870
  return iThis > iThat;
5871
  }
5872
 
5873
  return true;
5874
  };
5875
 
5876
- DataTable.isDataTable = DataTable.fnIsDataTable = function (table) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5877
  var t = $(table).get(0);
5878
  var is = false;
5879
 
 
 
 
 
5880
  $.each(DataTable.settings, function (i, o) {
5881
  var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
5882
  var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
 
5883
  if (o.nTable === t || head === t || foot === t) {
5884
  is = true;
5885
  }
5886
  });
 
5887
  return is;
5888
  };
5889
- DataTable.tables = DataTable.fnTables = function (visible) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5890
  var api = false;
5891
 
5892
  if ($.isPlainObject(visible)) {
@@ -5905,7 +9032,27 @@
5905
  a;
5906
  };
5907
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5908
  DataTable.camelToHungarian = _fnCamelToHungarian;
 
 
 
 
 
 
5909
  _api_register('$()', function (selector, opts) {
5910
  var
5911
  rows = this.rows(opts).nodes(), // Get all rows
@@ -5917,36 +9064,54 @@
5917
  ));
5918
  });
5919
 
 
 
5920
  $.each(['on', 'one', 'off'], function (i, key) {
5921
  _api_register(key + '()', function ( /* event, handler */ ) {
5922
  var args = Array.prototype.slice.call(arguments);
5923
- if (!args[0].match(/\.dt\b/)) {
5924
- args[0] += '.dt';
5925
- }
 
 
 
 
 
5926
  var inst = $(this.tables().nodes());
5927
  inst[key].apply(inst, args);
5928
  return this;
5929
  });
5930
  });
 
 
5931
  _api_register('clear()', function () {
5932
  return this.iterator('table', function (settings) {
5933
  _fnClearTable(settings);
5934
  });
5935
  });
 
 
5936
  _api_register('settings()', function () {
5937
  return new _Api(this.context, this.context);
5938
  });
 
 
5939
  _api_register('init()', function () {
5940
  var ctx = this.context;
5941
  return ctx.length ? ctx[0].oInit : null;
5942
  });
 
 
5943
  _api_register('data()', function () {
5944
  return this.iterator('table', function (settings) {
5945
  return _pluck(settings.aoData, '_aData');
5946
  }).flatten();
5947
  });
 
 
5948
  _api_register('destroy()', function (remove) {
5949
  remove = remove || false;
 
5950
  return this.iterator('table', function (settings) {
5951
  var orig = settings.nTableWrapper.parentNode;
5952
  var classes = settings.oClasses;
@@ -5961,15 +9126,24 @@
5961
  return r.nTr;
5962
  });
5963
  var i, ien;
 
 
 
5964
  settings.bDestroying = true;
 
 
5965
  _fnCallbackFire(settings, "aoDestroyCallback", "destroy", [settings]);
5966
 
 
5967
  if (!remove) {
5968
  new _Api(settings).columns().visible(true);
5969
  }
5970
 
5971
- jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
5972
- $(window).unbind('.DT-' + settings.sInstance);
 
 
 
5973
 
5974
  // When scrolling we had to break the table up - restore it
5975
  if (table != thead.parentNode) {
@@ -6007,18 +9181,23 @@
6007
 
6008
  // Remove the DataTables generated nodes, events and classes
6009
  var removedMethod = remove ? 'remove' : 'detach';
6010
- jqTable[removedMethod]();
6011
- jqWrapper[removedMethod]();
6012
 
6013
  // If we need to reattach the table to the document
6014
  if (!remove && orig) {
6015
  // insertBefore acts like appendChild if !arg[1]
6016
  orig.insertBefore(table, settings.nTableReinsertBefore);
6017
 
 
 
6018
  jqTable
6019
  .css('width', settings.sDestroyWidth)
6020
  .removeClass(classes.sTable);
6021
 
 
 
 
6022
  ien = settings.asDestroyStripes.length;
6023
 
6024
  if (ien) {
@@ -6028,6 +9207,7 @@
6028
  }
6029
  }
6030
 
 
6031
  var idx = $.inArray(settings, DataTable.settings);
6032
  if (idx !== -1) {
6033
  DataTable.settings.splice(idx, 1);
@@ -6035,15 +9215,26 @@
6035
  });
6036
  });
6037
 
 
 
6038
  $.each(['column', 'row', 'cell'], function (i, type) {
6039
  _api_register(type + 's().every()', function (fn) {
6040
  var opts = this.selector.opts;
6041
  var api = this;
6042
 
6043
  return this.iterator(type, function (settings, arg1, arg2, arg3, arg4) {
6044
-
 
 
 
 
 
 
 
 
 
6045
  fn.call(
6046
- api[type](
6047
  arg1,
6048
  type === 'cell' ? arg2 : opts,
6049
  type === 'cell' ? opts : undefined
@@ -6054,6 +9245,9 @@
6054
  });
6055
  });
6056
 
 
 
 
6057
  _api_register('i18n()', function (token, def, plural) {
6058
  var ctx = this.context[0];
6059
  var resolved = _fnGetObjectDataFn(token)(ctx.oLanguage);
@@ -6063,118 +9257,1517 @@
6063
  }
6064
 
6065
  if (plural !== undefined && $.isPlainObject(resolved)) {
6066
- resolved = resolved[plural] !== undefined ?
6067
- resolved[plural] :
6068
  resolved._;
6069
  }
6070
 
6071
  return resolved.replace('%d', plural); // nb: plural might be undefined,
6072
  });
6073
 
6074
- DataTable.version = "1.10.12";
6075
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6076
  DataTable.settings = [];
6077
 
 
 
 
 
 
 
6078
  DataTable.models = {};
6079
 
6080
- DataTable.models.oSearch = {
6081
 
 
 
 
 
 
 
 
 
 
 
 
 
6082
  "bCaseInsensitive": true,
6083
 
 
 
 
 
 
6084
  "sSearch": "",
6085
 
 
 
 
 
 
 
 
6086
  "bRegex": false,
6087
 
 
 
 
 
 
6088
  "bSmart": true
6089
  };
6090
 
 
 
 
 
 
 
 
 
 
6091
  DataTable.models.oRow = {
 
 
 
 
 
6092
  "nTr": null,
 
 
 
 
 
 
 
6093
  "anCells": null,
 
 
 
 
 
 
 
 
 
 
6094
  "_aData": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
6095
  "_aSortData": null,
 
 
 
 
 
 
 
 
6096
  "_aFilterData": null,
 
 
 
 
 
 
 
 
 
 
6097
  "_sFilterRow": null,
 
 
 
 
 
 
 
 
 
6098
  "_sRowStripe": "",
 
 
 
 
 
 
 
 
 
 
6099
  "src": null,
 
 
 
 
 
 
 
 
6100
  "idx": -1
6101
  };
6102
 
6103
- DataTable.models.oColumn = {
6104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6105
  "idx": null,
 
 
 
 
 
 
 
 
 
 
6106
  "aDataSort": null,
 
 
 
 
 
 
 
 
 
6107
  "asSorting": null,
 
 
 
 
 
 
6108
  "bSearchable": null,
 
 
 
 
 
6109
  "bSortable": null,
 
 
 
 
 
6110
  "bVisible": null,
 
 
 
 
 
 
 
 
6111
  "_sManualType": null,
 
 
 
 
 
 
 
 
6112
  "_bAttrSrc": false,
6113
 
 
 
 
 
 
 
 
 
 
 
 
 
6114
  "fnCreatedCell": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6115
  "fnGetData": null,
 
 
 
 
 
 
 
 
 
 
 
 
6116
  "fnSetData": null,
 
 
 
 
 
 
 
 
6117
  "mData": null,
 
 
 
 
 
 
 
 
 
6118
  "mRender": null,
 
 
 
 
 
 
 
6119
  "nTh": null,
 
 
 
 
 
 
 
 
6120
  "nTf": null,
 
 
 
 
 
 
6121
  "sClass": null,
 
 
 
 
 
 
 
 
 
 
 
 
6122
  "sContentPadding": null,
 
 
 
 
 
 
 
 
6123
  "sDefaultContent": null,
 
 
 
 
 
 
6124
  "sName": null,
 
 
 
 
 
 
 
6125
  "sSortDataType": 'std',
 
 
 
 
 
 
6126
  "sSortingClass": null,
 
 
 
 
 
 
 
6127
  "sSortingClassJUI": null,
 
 
 
 
 
6128
  "sTitle": null,
 
 
 
 
 
 
6129
  "sType": null,
 
 
 
 
 
 
6130
  "sWidth": null,
 
 
 
 
 
 
6131
  "sWidthOrig": null
6132
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6133
  DataTable.defaults = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6134
  "aaData": null,
6135
- "aaSorting": [
6136
- [0, 'asc']
6137
- ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6138
  "aaSortingFixed": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6139
  "ajax": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6140
  "aLengthMenu": [10, 25, 50, 100],
 
 
 
 
 
 
 
 
 
 
 
 
 
6141
  "aoColumns": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6142
  "aoColumnDefs": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6143
  "aoSearchCols": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6144
  "asStripeClasses": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6145
  "bAutoWidth": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6146
  "bDeferRender": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6147
  "bDestroy": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6148
  "bFilter": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6149
  "bInfo": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6150
  "bJQueryUI": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6151
  "bLengthChange": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6152
  "bPaginate": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6153
  "bProcessing": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6154
  "bRetrieve": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6155
  "bScrollCollapse": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6156
  "bServerSide": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6157
  "bSort": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6158
  "bSortMulti": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6159
  "bSortCellsTop": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6160
  "bSortClasses": true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6161
  "bStateSave": false,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6162
  "fnCreatedRow": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6163
  "fnDrawCallback": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6164
  "fnFooterCallback": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6165
  "fnFormatNumber": function (toFormat) {
6166
  return toFormat.toString().replace(
6167
  /\B(?=(\d{3})+(?!\d))/g,
6168
  this.oLanguage.sThousands
6169
  );
6170
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6171
  "fnHeaderCallback": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6172
  "fnInfoCallback": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6173
  "fnInitComplete": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6174
  "fnPreDrawCallback": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6175
  "fnRowCallback": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6176
  "fnServerData": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6177
  "fnServerParams": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6178
  "fnStateLoadCallback": function (settings) {
6179
  try {
6180
  return JSON.parse(
@@ -6185,8 +10778,96 @@
6185
  } catch (e) {
6186
  }
6187
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6188
  "fnStateLoadParams": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6189
  "fnStateLoaded": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6190
  "fnStateSaveCallback": function (settings, data) {
6191
  try {
6192
  (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
@@ -6196,227 +10877,2627 @@
6196
  } catch (e) {
6197
  }
6198
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6199
  "fnStateSaveParams": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6200
  "iStateDuration": 7200,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6201
  "iDeferLoading": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6202
  "iDisplayLength": 10,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6203
  "iDisplayStart": 0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6204
  "iTabIndex": 0,
 
 
 
 
 
 
 
 
 
6205
  "oClasses": {},
 
 
 
 
 
 
 
 
6206
  "oLanguage": {
 
 
 
 
 
 
 
6207
  "oAria": {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6208
  "sSortAscending": ": activate to sort column ascending",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6209
  "sSortDescending": ": activate to sort column descending"
6210
  },
 
 
 
 
 
 
 
6211
  "oPaginate": {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6212
  "sFirst": "First",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6213
  "sLast": "Last",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6214
  "sNext": "Next",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6215
  "sPrevious": "Previous"
6216
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6217
  "sEmptyTable": "No data available in table",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6218
  "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6219
  "sInfoEmpty": "Showing 0 to 0 of 0 entries",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6220
  "sInfoFiltered": "(filtered from _MAX_ total entries)",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6221
  "sInfoPostFix": "",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6222
  "sDecimal": "",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6223
  "sThousands": ",",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6224
  "sLengthMenu": "Show _MENU_ entries",
6225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6226
  "sLoadingRecords": "Loading...",
6227
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6228
  "sProcessing": "Processing...",
6229
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6230
  "sSearch": "Search:",
6231
 
 
 
 
 
 
 
 
 
6232
  "sSearchPlaceholder": "",
6233
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6234
  "sUrl": "",
6235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6236
  "sZeroRecords": "No matching records found"
6237
  },
6238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6239
  "oSearch": $.extend({}, DataTable.models.oSearch),
6240
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6241
  "sAjaxDataProp": "data",
6242
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6243
  "sAjaxSource": null,
6244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6245
  "sDom": "lfrtip",
6246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6247
  "searchDelay": null,
6248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6249
  "sPaginationType": "simple_numbers",
6250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6251
  "sScrollX": "",
6252
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6253
  "sScrollXInner": "",
6254
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6255
  "sScrollY": "",
6256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6257
  "sServerMethod": "GET",
6258
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6259
  "renderer": null,
6260
 
 
 
 
 
 
 
 
 
6261
  "rowId": "DT_RowId"
6262
  };
6263
 
6264
  _fnHungarianMap(DataTable.defaults);
6265
 
6266
- DataTable.defaults.column = {
6267
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6268
  "aDataSort": null,
6269
  "iDataSort": -1,
6270
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6271
  "asSorting": ['asc', 'desc'],
6272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6273
  "bSearchable": true,
6274
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6275
  "bSortable": true,
6276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6277
  "bVisible": true,
6278
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6279
  "fnCreatedCell": null,
6280
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6281
  "mData": null,
6282
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6283
  "mRender": null,
6284
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6285
  "sCellType": "td",
6286
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6287
  "sClass": "",
6288
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6289
  "sContentPadding": "",
6290
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6291
  "sDefaultContent": null,
6292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6293
  "sName": "",
6294
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6295
  "sSortDataType": "std",
6296
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6297
  "sTitle": null,
6298
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6299
  "sType": null,
6300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6301
  "sWidth": null
6302
  };
6303
 
6304
  _fnHungarianMap(DataTable.defaults.column);
6305
 
6306
- DataTable.models.oSettings = {
6307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6308
  "oFeatures": {
 
 
 
 
 
 
 
 
6309
  "bAutoWidth": null,
 
 
 
 
 
 
 
 
 
 
6310
  "bDeferRender": null,
 
 
 
 
 
 
 
 
 
6311
  "bFilter": null,
 
 
 
 
 
 
 
 
6312
  "bInfo": null,
 
 
 
 
 
 
 
 
6313
  "bLengthChange": null,
6314
 
 
 
 
 
 
 
 
6315
  "bPaginate": null,
 
 
 
 
 
 
 
 
6316
  "bProcessing": null,
 
 
 
 
 
 
 
 
 
6317
  "bServerSide": null,
 
 
 
 
 
 
 
6318
  "bSort": null,
 
 
 
 
 
 
 
6319
  "bSortMulti": null,
 
 
 
 
 
 
 
 
 
6320
  "bSortClasses": null,
 
 
 
 
 
 
 
6321
  "bStateSave": null
6322
  },
6323
 
 
 
 
 
6324
  "oScroll": {
 
 
 
 
 
 
 
6325
  "bCollapse": null,
 
 
 
 
 
 
 
6326
  "iBarWidth": 0,
 
 
 
 
 
 
 
 
6327
  "sX": null,
 
 
 
 
 
 
 
 
 
6328
  "sXInner": null,
 
 
 
 
 
 
 
 
6329
  "sY": null
6330
  },
 
 
 
 
 
 
6331
  "oLanguage": {
 
 
 
 
 
 
6332
  "fnInfoCallback": null
6333
  },
 
 
 
 
 
6334
  "oBrowser": {
 
 
 
 
 
 
6335
  "bScrollOversize": false,
 
 
 
 
 
 
 
 
6336
  "bScrollbarLeft": false,
 
 
 
 
 
 
6337
  "bBounding": false,
 
 
 
 
 
 
6338
  "barWidth": 0
6339
  },
 
6340
  "ajax": null,
6341
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6342
  "aanFeatures": [],
 
 
 
 
 
 
 
6343
  "aoData": [],
 
 
 
 
 
 
6344
  "aiDisplay": [],
 
 
 
 
 
 
6345
  "aiDisplayMaster": [],
 
 
 
 
 
 
6346
  "aIds": {},
 
 
 
 
 
 
6347
  "aoColumns": [],
 
 
 
 
 
 
6348
  "aoHeader": [],
 
 
 
 
 
 
6349
  "aoFooter": [],
 
 
 
 
 
 
 
 
 
6350
  "oPreviousSearch": {},
 
 
 
 
 
 
 
 
6351
  "aoPreSearchCols": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
6352
  "aaSorting": null,
 
 
 
 
 
 
 
 
 
6353
  "aaSortingFixed": [],
 
 
 
 
 
 
 
 
6354
  "asStripeClasses": null,
 
 
 
 
 
 
6355
  "asDestroyStripes": [],
 
 
 
 
 
 
6356
  "sDestroyWidth": 0,
 
 
 
 
 
 
6357
  "aoRowCallback": [],
 
 
 
 
 
 
6358
  "aoHeaderCallback": [],
 
 
 
 
 
 
6359
  "aoFooterCallback": [],
 
 
 
 
 
 
6360
  "aoDrawCallback": [],
 
 
 
 
 
 
6361
  "aoRowCreatedCallback": [],
 
 
 
 
 
 
 
6362
  "aoPreDrawCallback": [],
 
 
 
 
 
 
6363
  "aoInitComplete": [],
 
 
 
 
 
 
 
6364
  "aoStateSaveParams": [],
 
 
 
 
 
 
 
6365
  "aoStateLoadParams": [],
 
 
 
 
 
 
 
6366
  "aoStateLoaded": [],
 
 
 
 
 
 
6367
  "sTableId": "",
 
 
 
 
 
 
6368
  "nTable": null,
 
 
 
 
 
 
6369
  "nTHead": null,
 
 
 
 
 
 
6370
  "nTFoot": null,
 
 
 
 
 
 
6371
  "nTBody": null,
 
 
 
 
 
 
6372
  "nTableWrapper": null,
 
 
 
 
 
 
 
 
 
6373
  "bDeferLoading": false,
 
 
 
 
 
 
6374
  "bInitialised": false,
 
 
 
 
 
 
 
6375
  "aoOpenRows": [],
 
 
 
 
 
 
 
 
 
6376
  "sDom": null,
 
 
 
 
 
 
6377
  "searchDelay": null,
 
 
 
 
 
 
 
 
6378
  "sPaginationType": "two_button",
 
 
 
 
 
 
 
 
6379
  "iStateDuration": 0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6380
  "aoStateSave": [],
 
 
 
 
 
 
 
 
 
 
 
 
6381
  "aoStateLoad": [],
 
 
 
 
 
 
6382
  "oSavedState": null,
 
 
 
 
 
 
6383
  "oLoadedState": null,
 
 
 
 
 
 
 
 
6384
  "sAjaxSource": null,
 
 
 
 
 
 
 
 
 
6385
  "sAjaxDataProp": null,
 
 
 
 
 
 
6386
  "bAjaxDataGet": true,
 
 
 
 
 
 
 
 
6387
  "jqXHR": null,
 
 
 
 
 
 
6388
  "json": undefined,
 
 
 
 
 
 
6389
  "oAjaxData": undefined,
 
 
 
 
 
 
 
6390
  "fnServerData": null,
 
 
 
 
 
 
 
6391
  "aoServerParams": [],
 
 
 
 
 
 
 
 
6392
  "sServerMethod": null,
 
 
 
 
 
 
 
6393
  "fnFormatNumber": null,
 
 
 
 
 
 
 
 
6394
  "aLengthMenu": null,
 
 
 
 
 
 
 
6395
  "iDraw": 0,
 
 
 
 
 
 
6396
  "bDrawing": false,
 
 
 
 
 
 
6397
  "iDrawError": -1,
 
 
 
 
 
 
6398
  "_iDisplayLength": 10,
 
 
 
 
 
 
6399
  "_iDisplayStart": 0,
 
 
 
 
 
 
 
 
 
 
6400
  "_iRecordsTotal": 0,
 
 
 
 
 
 
 
 
 
 
6401
  "_iRecordsDisplay": 0,
 
 
 
 
 
 
 
6402
  "bJUI": null,
 
 
 
 
 
 
6403
  "oClasses": {},
 
 
 
 
 
 
 
 
 
6404
  "bFiltered": false,
 
 
 
 
 
 
 
 
 
6405
  "bSorted": false,
 
 
 
 
 
 
 
 
 
6406
  "bSortCellsTop": null,
 
 
 
 
 
 
6407
  "oInit": null,
 
 
 
 
 
 
 
6408
  "aoDestroyCallback": [],
6409
- "fnRecordsTotal": function () {
 
 
 
 
 
 
6410
  return _fnDataSource(this) == 'ssp' ?
6411
  this._iRecordsTotal * 1 :
6412
  this.aiDisplayMaster.length;
6413
  },
6414
- "fnRecordsDisplay": function () {
 
 
 
 
 
 
6415
  return _fnDataSource(this) == 'ssp' ?
6416
  this._iRecordsDisplay * 1 :
6417
  this.aiDisplay.length;
6418
  },
6419
- "fnDisplayEnd": function () {
 
 
 
 
 
 
6420
  var
6421
  len = this._iDisplayLength,
6422
  start = this._iDisplayStart,
@@ -6435,57 +13516,588 @@
6435
  calc;
6436
  }
6437
  },
 
 
 
 
 
 
6438
  "oInstance": null,
 
 
 
 
 
 
 
 
6439
  "sInstance": null,
 
 
 
 
 
6440
  "iTabIndex": 0,
 
 
 
 
6441
  "nScrollHead": null,
 
 
 
 
6442
  "nScrollFoot": null,
 
 
 
 
 
 
6443
  "aLastSort": [],
 
 
 
 
 
 
6444
  "oPlugins": {},
 
 
 
 
 
 
6445
  "rowIdFn": null,
 
 
 
 
 
 
6446
  "rowId": null
6447
  };
6448
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6449
  DataTable.ext = _ext = {
6450
-
 
 
 
 
 
 
 
6451
  buttons: {},
 
 
 
 
 
 
 
6452
  classes: {},
6453
 
 
 
 
 
 
6454
  builder: "-source-",
 
 
 
 
 
 
 
 
 
 
6455
  errMode: "alert",
6456
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6457
  feature: [],
6458
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6459
  search: [],
6460
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6461
  selector: {
6462
  cell: [],
6463
  column: [],
6464
  row: []
6465
  },
 
 
 
 
 
 
 
 
 
 
 
6466
  internal: {},
6467
 
 
 
 
 
 
 
6468
  legacy: {
 
 
 
 
 
 
 
6469
  ajax: null
6470
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6471
  pager: {},
 
6472
  renderer: {
6473
  pageButton: {},
6474
  header: {}
6475
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6476
  order: {},
6477
 
 
 
 
 
 
 
 
 
 
 
6478
  type: {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6479
  detect: [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6480
  search: {},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6481
  order: {}
6482
  },
 
 
 
 
 
 
 
6483
  _unique: 0,
 
 
 
 
 
 
 
 
 
 
 
 
 
6484
  fnVersionCheck: DataTable.fnVersionCheck,
 
 
 
 
 
 
6485
  iApiIndex: 0,
 
 
 
 
 
 
6486
  oJUIClasses: {},
 
 
 
 
 
 
6487
  sVersion: DataTable.version
6488
  };
 
 
 
 
 
6489
  $.extend(_ext, {
6490
  afnFiltering: _ext.search,
6491
  aTypes: _ext.type.detect,
@@ -6498,32 +14110,44 @@
6498
  oPagination: _ext.pager
6499
  });
6500
 
 
6501
  $.extend(DataTable.ext.classes, {
6502
  "sTable": "dataTable",
6503
  "sNoFooter": "no-footer",
 
 
6504
  "sPageButton": "paginate_button",
6505
  "sPageButtonActive": "current",
6506
  "sPageButtonDisabled": "disabled",
 
 
6507
  "sStripeOdd": "odd",
6508
  "sStripeEven": "even",
 
 
6509
  "sRowEmpty": "dataTables_empty",
 
 
6510
  "sWrapper": "dataTables_wrapper",
6511
  "sFilter": "dataTables_filter",
6512
  "sInfo": "dataTables_info",
6513
- "sPaging": "dataTables_paginate paging_",
6514
- /* Note that the type is postfixed */
6515
  "sLength": "dataTables_length",
6516
  "sProcessing": "dataTables_processing",
 
 
6517
  "sSortAsc": "sorting_asc",
6518
  "sSortDesc": "sorting_desc",
6519
- "sSortable": "sorting",
6520
- /* Sortable in both directions */
6521
  "sSortableAsc": "sorting_asc_disabled",
6522
  "sSortableDesc": "sorting_desc_disabled",
6523
  "sSortableNone": "sorting_disabled",
6524
- "sSortColumn": "sorting_",
6525
- /* Note that an int is postfixed for the sorting order */
 
6526
  "sFilterInput": "",
 
 
6527
  "sLengthSelect": "",
6528
 
6529
  /* Scrolling */
@@ -6549,7 +14173,14 @@
6549
  "sJUIHeader": "",
6550
  "sJUIFooter": ""
6551
  });
 
 
6552
  (function () {
 
 
 
 
 
6553
  var _empty = '';
6554
  _empty = '';
6555
 
@@ -6565,8 +14196,9 @@
6565
 
6566
  /* Features */
6567
  "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi " +
6568
- "ui-buttonset-multi paging_",
6569
- /* Note that the type is postfixed */
 
6570
  "sSortAsc": _stateDefault + " sorting_asc",
6571
  "sSortDesc": _stateDefault + " sorting_desc",
6572
  "sSortable": _stateDefault + " sorting",
@@ -6593,6 +14225,9 @@
6593
  });
6594
 
6595
  }());
 
 
 
6596
  var extPagination = DataTable.ext.pager;
6597
 
6598
  function _numbers(page, pages) {
@@ -6623,25 +14258,41 @@
6623
  numbers.DT_el = 'span';
6624
  return numbers;
6625
  }
 
 
6626
  $.extend(extPagination, {
6627
  simple: function (page, pages) {
6628
  return ['previous', 'next'];
6629
  },
 
6630
  full: function (page, pages) {
6631
  return ['first', 'previous', 'next', 'last'];
6632
  },
 
6633
  numbers: function (page, pages) {
6634
  return [_numbers(page, pages)];
6635
  },
 
6636
  simple_numbers: function (page, pages) {
6637
  return ['previous', _numbers(page, pages), 'next'];
6638
  },
 
6639
  full_numbers: function (page, pages) {
6640
  return ['first', 'previous', _numbers(page, pages), 'next', 'last'];
6641
  },
 
 
 
 
 
 
6642
  _numbers: _numbers,
 
 
6643
  numbers_length: 7
6644
  });
 
 
6645
  $.extend(true, DataTable.ext.renderer, {
6646
  pageButton: {
6647
  _: function (settings, host, idx, buttons, page, pages) {
@@ -6707,19 +14358,18 @@
6707
  node = $('<a>', {
6708
  'class': classes.sPageButton + ' ' + btnClass,
6709
  'aria-controls': settings.sTableId,
6710
- 'aria-label': aria[button],
6711
  'data-dt-idx': counter,
6712
  'tabindex': settings.iTabIndex,
6713
  'id': idx === 0 && typeof button === 'string' ?
6714
- settings.sTableId + '_' + button : null
 
6715
  })
6716
  .html(btnDisplay)
6717
  .appendTo(container);
6718
 
6719
  _fnBindAction(
6720
- node, {
6721
- action: button
6722
- }, clickHandler
6723
  );
6724
 
6725
  counter++;
@@ -6727,28 +14377,50 @@
6727
  }
6728
  }
6729
  };
 
 
 
 
6730
  var activeEl;
6731
 
6732
  try {
 
 
 
 
6733
  activeEl = $(host).find(document.activeElement).data('dt-idx');
6734
  } catch (e) {
6735
  }
6736
 
6737
  attach($(host).empty(), buttons);
6738
 
6739
- if (activeEl) {
6740
  $(host).find('[data-dt-idx=' + activeEl + ']').focus();
6741
  }
6742
  }
6743
  }
6744
  });
 
 
 
 
 
6745
  $.extend(DataTable.ext.type.detect, [
6746
- function (d, settings) {
 
 
 
6747
  var decimal = settings.oLanguage.sDecimal;
6748
  return _isNumber(d, decimal) ? 'num' + decimal : null;
6749
  },
6750
- function (d, settings) {
6751
- if (d && !(d instanceof Date) && (!_re_date_start.test(d) || !_re_date_end.test(d))) {
 
 
 
 
 
 
6752
  return null;
6753
  }
6754
  var parsed = Date.parse(d);
@@ -6756,29 +14428,44 @@
6756
  },
6757
 
6758
  // Formatted numbers
6759
- function (d, settings) {
 
6760
  var decimal = settings.oLanguage.sDecimal;
6761
  return _isNumber(d, decimal, true) ? 'num-fmt' + decimal : null;
6762
  },
6763
 
6764
  // HTML numeric
6765
- function (d, settings) {
 
6766
  var decimal = settings.oLanguage.sDecimal;
6767
  return _htmlNumeric(d, decimal) ? 'html-num' + decimal : null;
6768
  },
6769
 
6770
  // HTML numeric, formatted
6771
- function (d, settings) {
 
6772
  var decimal = settings.oLanguage.sDecimal;
6773
  return _htmlNumeric(d, decimal, true) ? 'html-num-fmt' + decimal : null;
6774
  },
6775
 
6776
  // HTML (this is strict checking - there must be html)
6777
- function (d, settings) {
 
6778
  return _empty(d) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
6779
  'html' : null;
6780
  }
6781
  ]);
 
 
 
 
 
 
 
 
 
 
 
6782
  $.extend(DataTable.ext.type.search, {
6783
  html: function (data) {
6784
  return _empty(data) ?
@@ -6799,10 +14486,16 @@
6799
  }
6800
  });
6801
 
 
 
6802
  var __numericReplace = function (d, decimalPlace, re1, re2) {
6803
  if (d !== 0 && (!d || d === '-')) {
6804
  return -Infinity;
6805
  }
 
 
 
 
6806
  if (decimalPlace) {
6807
  d = _numToDecimal(d, decimalPlace);
6808
  }
@@ -6820,43 +14513,51 @@
6820
  return d * 1;
6821
  };
6822
 
6823
- function _addNumericSort(decimalPlace) {
6824
- $.each({
6825
- // Plain numbers
6826
- "num": function (d) {
6827
- return __numericReplace(d, decimalPlace);
6828
- },
6829
-
6830
- // Formatted numbers
6831
- "num-fmt": function (d) {
6832
- return __numericReplace(d, decimalPlace, _re_formatted_numeric);
6833
- },
6834
-
6835
- // HTML numeric
6836
- "html-num": function (d) {
6837
- return __numericReplace(d, decimalPlace, _re_html);
6838
- },
6839
 
6840
- // HTML numeric, formatted
6841
- "html-num-fmt": function (d) {
6842
- return __numericReplace(d, decimalPlace, _re_html, _re_formatted_numeric);
6843
- }
6844
- },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6845
  function (key, fn) {
6846
  // Add the ordering method
6847
- _ext.type.order[key + decimalPlace + '-pre'] = fn;
6848
 
6849
  // For HTML types add a search formatter that will strip the HTML
6850
  if (key.match(/^html\-/)) {
6851
- _ext.type.search[key + decimalPlace] = _ext.type.search.html;
6852
  }
6853
  }
6854
  );
6855
  }
 
 
 
6856
  $.extend(_ext.type.order, {
6857
  // Dates
6858
  "date-pre": function (d) {
6859
- return Date.parse(d) || 0;
6860
  },
6861
 
6862
  // html
@@ -6867,7 +14568,11 @@
6867
  a.replace(/<.*?>/g, "").toLowerCase() :
6868
  a + '';
6869
  },
 
 
6870
  "string-pre": function (a) {
 
 
6871
  return _empty(a) ?
6872
  '' :
6873
  typeof a === 'string' ?
@@ -6877,6 +14582,8 @@
6877
  a.toString();
6878
  },
6879
 
 
 
6880
  "string-asc": function (x, y) {
6881
  return ((x < y) ? -1 : ((x > y) ? 1 : 0));
6882
  },
@@ -6886,15 +14593,22 @@
6886
  }
6887
  });
6888
 
 
 
6889
  _addNumericSort('');
6890
 
 
6891
  $.extend(true, DataTable.ext.renderer, {
6892
  header: {
6893
  _: function (settings, cell, column, classes) {
6894
-
 
 
 
 
6895
  $(settings.nTable).on('order.dt.DT', function (e, ctx, sorting, columns) {
6896
  if (settings !== ctx) { // need to check this this is the host
6897
- return; // table, not a nested one
6898
  }
6899
 
6900
  var colIdx = column.idx;
@@ -6905,8 +14619,8 @@
6905
  classes.sSortAsc + ' ' +
6906
  classes.sSortDesc
6907
  )
6908
- .addClass(columns[colIdx] == 'asc' ?
6909
- classes.sSortAsc : columns[colIdx] == 'desc' ?
6910
  classes.sSortDesc :
6911
  column.sSortingClass
6912
  );
@@ -6932,8 +14646,8 @@
6932
 
6933
  cell
6934
  .removeClass(classes.sSortAsc + " " + classes.sSortDesc)
6935
- .addClass(columns[colIdx] == 'asc' ?
6936
- classes.sSortAsc : columns[colIdx] == 'desc' ?
6937
  classes.sSortDesc :
6938
  column.sSortingClass
6939
  );
@@ -6947,8 +14661,8 @@
6947
  classes.sSortJUIAscAllowed + " " +
6948
  classes.sSortJUIDescAllowed
6949
  )
6950
- .addClass(columns[colIdx] == 'asc' ?
6951
- classes.sSortJUIAsc : columns[colIdx] == 'desc' ?
6952
  classes.sSortJUIDesc :
6953
  column.sSortingClassJUI
6954
  );
@@ -6956,12 +14670,46 @@
6956
  }
6957
  }
6958
  });
 
 
 
 
 
 
 
 
6959
  var __htmlEscapeEntities = function (d) {
6960
  return typeof d === 'string' ?
6961
  d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
6962
  d;
6963
  };
6964
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6965
  DataTable.render = {
6966
  number: function (thousands, decimal, precision, prefix, postfix) {
6967
  return {
@@ -6973,10 +14721,14 @@
6973
  var negative = d < 0 ? '-' : '';
6974
  var flo = parseFloat(d);
6975
 
 
 
 
6976
  if (isNaN(flo)) {
6977
  return __htmlEscapeEntities(d);
6978
  }
6979
 
 
6980
  d = Math.abs(flo);
6981
 
6982
  var intPart = parseInt(d, 10);
@@ -7001,7 +14753,21 @@
7001
  }
7002
  };
7003
 
7004
- function _fnExternApiFunc(fn) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7005
  return function () {
7006
  var args = [_fnSettingsFromNode(this[DataTable.ext.iApiIndex])].concat(
7007
  Array.prototype.slice.call(arguments)
@@ -7009,6 +14775,15 @@
7009
  return DataTable.ext.internal[fn].apply(this, args);
7010
  };
7011
  }
 
 
 
 
 
 
 
 
 
7012
  $.extend(DataTable.ext.internal, {
7013
  _fnExternApiFunc: _fnExternApiFunc,
7014
  _fnBuildAjax: _fnBuildAjax,
@@ -7099,8 +14874,12 @@
7099
  _fnDataSource: _fnDataSource,
7100
  _fnRowAttributes: _fnRowAttributes,
7101
  _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
 
 
7102
  });
7103
 
 
 
7104
  $.fn.dataTable = DataTable;
7105
 
7106
  // Provide access to the host jQuery object (circular reference)
@@ -7119,12 +14898,176 @@
7119
  // All properties that are available to $.fn.dataTable should also be
7120
  // available on $.fn.DataTable
7121
  $.each(DataTable, function (prop, val) {
7122
- $.fn.DataTable[prop] = val;
7123
  });
7124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7125
  return $.fn.dataTable;
7126
  }));
7127
 
 
7128
  (function (window, document, undefined) {
7129
 
7130
  var factory = function ($, DataTable) {
1
+ /*! DataTables 1.10.15
2
+ * ©2008-2017 SpryMedia Ltd - datatables.net/license
3
  */
4
 
5
+ /**
6
+ * @summary DataTables
7
+ * @description Paginate, search and order HTML tables
8
+ * @version 1.10.15
9
+ * @file jquery.dataTables.js
10
+ * @author SpryMedia Ltd
11
+ * @contact www.datatables.net
12
+ * @copyright Copyright 2008-2017 SpryMedia Ltd.
13
+ *
14
+ * This source file is free software, available under the following license:
15
+ * MIT license - http://datatables.net/license
16
+ *
17
+ * This source file is distributed in the hope that it will be useful, but
18
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
20
+ *
21
+ * For details please refer to: http://www.datatables.net
22
+ */
23
+
24
+ /*jslint evil: true, undef: true, browser: true */
25
+ /*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
26
+
27
  (function (factory) {
28
  "use strict";
29
 
57
  (function ($, window, document, undefined) {
58
  "use strict";
59
 
60
+ /**
61
+ * DataTables is a plug-in for the jQuery Javascript library. It is a highly
62
+ * flexible tool, based upon the foundations of progressive enhancement,
63
+ * which will add advanced interaction controls to any HTML table. For a
64
+ * full list of features please refer to
65
+ * [DataTables.net](href="http://datatables.net).
66
+ *
67
+ * Note that the `DataTable` object is not a global variable but is aliased
68
+ * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
69
+ * be accessed.
70
+ *
71
+ * @class
72
+ * @param {object} [init={}] Configuration object for DataTables. Options
73
+ * are defined by {@link DataTable.defaults}
74
+ * @requires jQuery 1.7+
75
+ *
76
+ * @example
77
+ * // Basic initialisation
78
+ * $(document).ready( function {
79
+ * $('#example').dataTable();
80
+ * } );
81
+ *
82
+ * @example
83
+ * // Initialisation with configuration options - in this case, disable
84
+ * // pagination and sorting.
85
+ * $(document).ready( function {
86
+ * $('#example').dataTable( {
87
+ * "paginate": false,
88
+ * "sort": false
89
+ * } );
90
+ * } );
91
+ */
92
+ var DataTable = function (options)
93
+ {
94
+ /**
95
+ * Perform a jQuery selector action on the table's TR elements (from the tbody) and
96
+ * return the resulting jQuery object.
97
+ * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
98
+ * @param {object} [oOpts] Optional parameters for modifying the rows to be included
99
+ * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
100
+ * criterion ("applied") or all TR elements (i.e. no filter).
101
+ * @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
102
+ * Can be either 'current', whereby the current sorting of the table is used, or
103
+ * 'original' whereby the original order the data was read into the table is used.
104
+ * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
105
+ * ("current") or not ("all"). If 'current' is given, then order is assumed to be
106
+ * 'current' and filter is 'applied', regardless of what they might be given as.
107
+ * @returns {object} jQuery object, filtered by the given selector.
108
+ * @dtopt API
109
+ * @deprecated Since v1.10
110
+ *
111
+ * @example
112
+ * $(document).ready(function() {
113
+ * var oTable = $('#example').dataTable();
114
+ *
115
+ * // Highlight every second row
116
+ * oTable.$('tr:odd').css('backgroundColor', 'blue');
117
+ * } );
118
+ *
119
+ * @example
120
+ * $(document).ready(function() {
121
+ * var oTable = $('#example').dataTable();
122
+ *
123
+ * // Filter to rows with 'Webkit' in them, add a background colour and then
124
+ * // remove the filter, thus highlighting the 'Webkit' rows only.
125
+ * oTable.fnFilter('Webkit');
126
+ * oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
127
+ * oTable.fnFilter('');
128
+ * } );
129
+ */
130
+ this.$ = function (sSelector, oOpts)
131
+ {
132
  return this.api(true).$(sSelector, oOpts);
133
  };
134
 
135
+
136
+ /**
137
+ * Almost identical to $ in operation, but in this case returns the data for the matched
138
+ * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
139
+ * rather than any descendants, so the data can be obtained for the row/cell. If matching
140
+ * rows are found, the data returned is the original data array/object that was used to
141
+ * create the row (or a generated array if from a DOM source).
142
+ *
143
+ * This method is often useful in-combination with $ where both functions are given the
144
+ * same parameters and the array indexes will match identically.
145
+ * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
146
+ * @param {object} [oOpts] Optional parameters for modifying the rows to be included
147
+ * @param {string} [oOpts.filter=none] Select elements that meet the current filter
148
+ * criterion ("applied") or all elements (i.e. no filter).
149
+ * @param {string} [oOpts.order=current] Order of the data in the processed array.
150
+ * Can be either 'current', whereby the current sorting of the table is used, or
151
+ * 'original' whereby the original order the data was read into the table is used.
152
+ * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
153
+ * ("current") or not ("all"). If 'current' is given, then order is assumed to be
154
+ * 'current' and filter is 'applied', regardless of what they might be given as.
155
+ * @returns {array} Data for the matched elements. If any elements, as a result of the
156
+ * selector, were not TR, TD or TH elements in the DataTable, they will have a null
157
+ * entry in the array.
158
+ * @dtopt API
159
+ * @deprecated Since v1.10
160
+ *
161
+ * @example
162
+ * $(document).ready(function() {
163
+ * var oTable = $('#example').dataTable();
164
+ *
165
+ * // Get the data from the first row in the table
166
+ * var data = oTable._('tr:first');
167
+ *
168
+ * // Do something useful with the data
169
+ * alert( "First cell is: "+data[0] );
170
+ * } );
171
+ *
172
+ * @example
173
+ * $(document).ready(function() {
174
+ * var oTable = $('#example').dataTable();
175
+ *
176
+ * // Filter to 'Webkit' and get all data for
177
+ * oTable.fnFilter('Webkit');
178
+ * var data = oTable._('tr', {"search": "applied"});
179
+ *
180
+ * // Do something with the data
181
+ * alert( data.length+" rows matched the search" );
182
+ * } );
183
+ */
184
+ this._ = function (sSelector, oOpts)
185
+ {
186
  return this.api(true).rows(sSelector, oOpts).data();
187
  };
188
 
189
+
190
+ /**
191
+ * Create a DataTables Api instance, with the currently selected tables for
192
+ * the Api's context.
193
+ * @param {boolean} [traditional=false] Set the API instance's context to be
194
+ * only the table referred to by the `DataTable.ext.iApiIndex` option, as was
195
+ * used in the API presented by DataTables 1.9- (i.e. the traditional mode),
196
+ * or if all tables captured in the jQuery object should be used.
197
+ * @return {DataTables.Api}
198
+ */
199
+ this.api = function (traditional)
200
+ {
201
  return traditional ?
202
  new _Api(
203
+ _fnSettingsFromNode(this[ _ext.iApiIndex ])
204
  ) :
205
  new _Api(this);
206
  };
207
 
208
+
209
+ /**
210
+ * Add a single new row or multiple rows of data to the table. Please note
211
+ * that this is suitable for client-side processing only - if you are using
212
+ * server-side processing (i.e. "bServerSide": true), then to add data, you
213
+ * must add it to the data source, i.e. the server-side, through an Ajax call.
214
+ * @param {array|object} data The data to be added to the table. This can be:
215
+ * <ul>
216
+ * <li>1D array of data - add a single row with the data provided</li>
217
+ * <li>2D array of arrays - add multiple rows in a single call</li>
218
+ * <li>object - data object when using <i>mData</i></li>
219
+ * <li>array of objects - multiple data objects when using <i>mData</i></li>
220
+ * </ul>
221
+ * @param {bool} [redraw=true] redraw the table or not
222
+ * @returns {array} An array of integers, representing the list of indexes in
223
+ * <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
224
+ * the table.
225
+ * @dtopt API
226
+ * @deprecated Since v1.10
227
+ *
228
+ * @example
229
+ * // Global var for counter
230
+ * var giCount = 2;
231
+ *
232
+ * $(document).ready(function() {
233
+ * $('#example').dataTable();
234
+ * } );
235
+ *
236
+ * function fnClickAddRow() {
237
+ * $('#example').dataTable().fnAddData( [
238
+ * giCount+".1",
239
+ * giCount+".2",
240
+ * giCount+".3",
241
+ * giCount+".4" ]
242
+ * );
243
+ *
244
+ * giCount++;
245
+ * }
246
+ */
247
+ this.fnAddData = function (data, redraw)
248
+ {
249
  var api = this.api(true);
250
 
251
  /* Check if we want to add multiple rows or not */
260
  return rows.flatten().toArray();
261
  };
262
 
263
+
264
+ /**
265
+ * This function will make DataTables recalculate the column sizes, based on the data
266
+ * contained in the table and the sizes applied to the columns (in the DOM, CSS or
267
+ * through the sWidth parameter). This can be useful when the width of the table's
268
+ * parent element changes (for example a window resize).
269
+ * @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
270
+ * @dtopt API
271
+ * @deprecated Since v1.10
272
+ *
273
+ * @example
274
+ * $(document).ready(function() {
275
+ * var oTable = $('#example').dataTable( {
276
+ * "sScrollY": "200px",
277
+ * "bPaginate": false
278
+ * } );
279
+ *
280
+ * $(window).on('resize', function () {
281
+ * oTable.fnAdjustColumnSizing();
282
+ * } );
283
+ * } );
284
+ */
285
+ this.fnAdjustColumnSizing = function (bRedraw)
286
+ {
287
  var api = this.api(true).columns.adjust();
288
  var settings = api.settings()[0];
289
  var scroll = settings.oScroll;
296
  }
297
  };
298
 
299
+
300
+ /**
301
+ * Quickly and simply clear a table
302
+ * @param {bool} [bRedraw=true] redraw the table or not
303
+ * @dtopt API
304
+ * @deprecated Since v1.10
305
+ *
306
+ * @example
307
+ * $(document).ready(function() {
308
+ * var oTable = $('#example').dataTable();
309
+ *
310
+ * // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
311
+ * oTable.fnClearTable();
312
+ * } );
313
+ */
314
+ this.fnClearTable = function (bRedraw)
315
+ {
316
  var api = this.api(true).clear();
317
 
318
  if (bRedraw === undefined || bRedraw) {
320
  }
321
  };
322
 
323
+
324
+ /**
325
+ * The exact opposite of 'opening' a row, this function will close any rows which
326
+ * are currently 'open'.
327
+ * @param {node} nTr the table row to 'close'
328
+ * @returns {int} 0 on success, or 1 if failed (can't find the row)
329
+ * @dtopt API
330
+ * @deprecated Since v1.10
331
+ *
332
+ * @example
333
+ * $(document).ready(function() {
334
+ * var oTable;
335
+ *
336
+ * // 'open' an information row when a row is clicked on
337
+ * $('#example tbody tr').click( function () {
338
+ * if ( oTable.fnIsOpen(this) ) {
339
+ * oTable.fnClose( this );
340
+ * } else {
341
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
342
+ * }
343
+ * } );
344
+ *
345
+ * oTable = $('#example').dataTable();
346
+ * } );
347
+ */
348
+ this.fnClose = function (nTr)
349
+ {
350
  this.api(true).row(nTr).child.hide();
351
  };
352
 
353
+
354
+ /**
355
+ * Remove a row for the table
356
+ * @param {mixed} target The index of the row from aoData to be deleted, or
357
+ * the TR element you want to delete
358
+ * @param {function|null} [callBack] Callback function
359
+ * @param {bool} [redraw=true] Redraw the table or not
360
+ * @returns {array} The row that was deleted
361
+ * @dtopt API
362
+ * @deprecated Since v1.10
363
+ *
364
+ * @example
365
+ * $(document).ready(function() {
366
+ * var oTable = $('#example').dataTable();
367
+ *
368
+ * // Immediately remove the first row
369
+ * oTable.fnDeleteRow( 0 );
370
+ * } );
371
+ */
372
+ this.fnDeleteRow = function (target, callback, redraw)
373
+ {
374
  var api = this.api(true);
375
  var rows = api.rows(target);
376
  var settings = rows.settings()[0];
377
+ var data = settings.aoData[ rows[0][0] ];
378
 
379
  rows.remove();
380
 
389
  return data;
390
  };
391
 
392
+
393
+ /**
394
+ * Restore the table to it's original state in the DOM by removing all of DataTables
395
+ * enhancements, alterations to the DOM structure of the table and event listeners.
396
+ * @param {boolean} [remove=false] Completely remove the table from the DOM
397
+ * @dtopt API
398
+ * @deprecated Since v1.10
399
+ *
400
+ * @example
401
+ * $(document).ready(function() {
402
+ * // This example is fairly pointless in reality, but shows how fnDestroy can be used
403
+ * var oTable = $('#example').dataTable();
404
+ * oTable.fnDestroy();
405
+ * } );
406
+ */
407
+ this.fnDestroy = function (remove)
408
+ {
409
  this.api(true).destroy(remove);
410
  };
411
 
412
+
413
+ /**
414
+ * Redraw the table
415
+ * @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
416
+ * @dtopt API
417
+ * @deprecated Since v1.10
418
+ *
419
+ * @example
420
+ * $(document).ready(function() {
421
+ * var oTable = $('#example').dataTable();
422
+ *
423
+ * // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
424
+ * oTable.fnDraw();
425
+ * } );
426
+ */
427
+ this.fnDraw = function (complete)
428
+ {
429
  // Note that this isn't an exact match to the old call to _fnDraw - it takes
430
  // into account the new data, but can hold position.
431
  this.api(true).draw(complete);
432
  };
433
 
434
+
435
+ /**
436
+ * Filter the input based on data
437
+ * @param {string} sInput String to filter the table on
438
+ * @param {int|null} [iColumn] Column to limit filtering to
439
+ * @param {bool} [bRegex=false] Treat as regular expression or not
440
+ * @param {bool} [bSmart=true] Perform smart filtering or not
441
+ * @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
442
+ * @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
443
+ * @dtopt API
444
+ * @deprecated Since v1.10
445
+ *
446
+ * @example
447
+ * $(document).ready(function() {
448
+ * var oTable = $('#example').dataTable();
449
+ *
450
+ * // Sometime later - filter...
451
+ * oTable.fnFilter( 'test string' );
452
+ * } );
453
+ */
454
+ this.fnFilter = function (sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive)
455
+ {
456
  var api = this.api(true);
457
 
458
  if (iColumn === null || iColumn === undefined) {
464
  api.draw();
465
  };
466
 
467
+
468
+ /**
469
+ * Get the data for the whole table, an individual row or an individual cell based on the
470
+ * provided parameters.
471
+ * @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
472
+ * a TR node then the data source for the whole row will be returned. If given as a
473
+ * TD/TH cell node then iCol will be automatically calculated and the data for the
474
+ * cell returned. If given as an integer, then this is treated as the aoData internal
475
+ * data index for the row (see fnGetPosition) and the data for that row used.
476
+ * @param {int} [col] Optional column index that you want the data of.
477
+ * @returns {array|object|string} If mRow is undefined, then the data for all rows is
478
+ * returned. If mRow is defined, just data for that row, and is iCol is
479
+ * defined, only data for the designated cell is returned.
480
+ * @dtopt API
481
+ * @deprecated Since v1.10
482
+ *
483
+ * @example
484
+ * // Row data
485
+ * $(document).ready(function() {
486
+ * oTable = $('#example').dataTable();
487
+ *
488
+ * oTable.$('tr').click( function () {
489
+ * var data = oTable.fnGetData( this );
490
+ * // ... do something with the array / object of data for the row
491
+ * } );
492
+ * } );
493
+ *
494
+ * @example
495
+ * // Individual cell data
496
+ * $(document).ready(function() {
497
+ * oTable = $('#example').dataTable();
498
+ *
499
+ * oTable.$('td').click( function () {
500
+ * var sData = oTable.fnGetData( this );
501
+ * alert( 'The cell clicked on had the value of '+sData );
502
+ * } );
503
+ * } );
504
+ */
505
+ this.fnGetData = function (src, col)
506
+ {
507
  var api = this.api(true);
508
 
509
  if (src !== undefined) {
517
  return api.data().toArray();
518
  };
519
 
520
+
521
+ /**
522
+ * Get an array of the TR nodes that are used in the table's body. Note that you will
523
+ * typically want to use the '$' API method in preference to this as it is more
524
+ * flexible.
525
+ * @param {int} [iRow] Optional row index for the TR element you want
526
+ * @returns {array|node} If iRow is undefined, returns an array of all TR elements
527
+ * in the table's body, or iRow is defined, just the TR element requested.
528
+ * @dtopt API
529
+ * @deprecated Since v1.10
530
+ *
531
+ * @example
532
+ * $(document).ready(function() {
533
+ * var oTable = $('#example').dataTable();
534
+ *
535
+ * // Get the nodes from the table
536
+ * var nNodes = oTable.fnGetNodes( );
537
+ * } );
538
+ */
539
+ this.fnGetNodes = function (iRow)
540
+ {
541
  var api = this.api(true);
542
 
543
  return iRow !== undefined ?
545
  api.rows().nodes().flatten().toArray();
546
  };
547
 
548
+
549
+ /**
550
+ * Get the array indexes of a particular cell from it's DOM element
551
+ * and column index including hidden columns
552
+ * @param {node} node this can either be a TR, TD or TH in the table's body
553
+ * @returns {int} If nNode is given as a TR, then a single index is returned, or
554
+ * if given as a cell, an array of [row index, column index (visible),
555
+ * column index (all)] is given.
556
+ * @dtopt API
557
+ * @deprecated Since v1.10
558
+ *
559
+ * @example
560
+ * $(document).ready(function() {
561
+ * $('#example tbody td').click( function () {
562
+ * // Get the position of the current data from the node
563
+ * var aPos = oTable.fnGetPosition( this );
564
+ *
565
+ * // Get the data array for this row
566
+ * var aData = oTable.fnGetData( aPos[0] );
567
+ *
568
+ * // Update the data array and return the value
569
+ * aData[ aPos[1] ] = 'clicked';
570
+ * this.innerHTML = 'clicked';
571
+ * } );
572
+ *
573
+ * // Init DataTables
574
+ * oTable = $('#example').dataTable();
575
+ * } );
576
+ */
577
+ this.fnGetPosition = function (node)
578
+ {
579
  var api = this.api(true);
580
  var nodeName = node.nodeName.toUpperCase();
581
 
593
  return null;
594
  };
595
 
596
+
597
+ /**
598
+ * Check to see if a row is 'open' or not.
599
+ * @param {node} nTr the table row to check
600
+ * @returns {boolean} true if the row is currently open, false otherwise
601
+ * @dtopt API
602
+ * @deprecated Since v1.10
603
+ *
604
+ * @example
605
+ * $(document).ready(function() {
606
+ * var oTable;
607
+ *
608
+ * // 'open' an information row when a row is clicked on
609
+ * $('#example tbody tr').click( function () {
610
+ * if ( oTable.fnIsOpen(this) ) {
611
+ * oTable.fnClose( this );
612
+ * } else {
613
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
614
+ * }
615
+ * } );
616
+ *
617
+ * oTable = $('#example').dataTable();
618
+ * } );
619
+ */
620
+ this.fnIsOpen = function (nTr)
621
+ {
622
  return this.api(true).row(nTr).child.isShown();
623
  };
624
 
625
+
626
+ /**
627
+ * This function will place a new row directly after a row which is currently
628
+ * on display on the page, with the HTML contents that is passed into the
629
+ * function. This can be used, for example, to ask for confirmation that a
630
+ * particular record should be deleted.
631
+ * @param {node} nTr The table row to 'open'
632
+ * @param {string|node|jQuery} mHtml The HTML to put into the row
633
+ * @param {string} sClass Class to give the new TD cell
634
+ * @returns {node} The row opened. Note that if the table row passed in as the
635
+ * first parameter, is not found in the table, this method will silently
636
+ * return.
637
+ * @dtopt API
638
+ * @deprecated Since v1.10
639
+ *
640
+ * @example
641
+ * $(document).ready(function() {
642
+ * var oTable;
643
+ *
644
+ * // 'open' an information row when a row is clicked on
645
+ * $('#example tbody tr').click( function () {
646
+ * if ( oTable.fnIsOpen(this) ) {
647
+ * oTable.fnClose( this );
648
+ * } else {
649
+ * oTable.fnOpen( this, "Temporary row opened", "info_row" );
650
+ * }
651
+ * } );
652
+ *
653
+ * oTable = $('#example').dataTable();
654
+ * } );
655
+ */
656
+ this.fnOpen = function (nTr, mHtml, sClass)
657
+ {
658
  return this.api(true)
659
  .row(nTr)
660
  .child(mHtml, sClass)
662
  .child()[0];
663
  };
664
 
665
+
666
+ /**
667
+ * Change the pagination - provides the internal logic for pagination in a simple API
668
+ * function. With this function you can have a DataTables table go to the next,
669
+ * previous, first or last pages.
670
+ * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
671
+ * or page number to jump to (integer), note that page 0 is the first page.
672
+ * @param {bool} [bRedraw=true] Redraw the table or not
673
+ * @dtopt API
674
+ * @deprecated Since v1.10
675
+ *
676
+ * @example
677
+ * $(document).ready(function() {
678
+ * var oTable = $('#example').dataTable();
679
+ * oTable.fnPageChange( 'next' );
680
+ * } );
681
+ */
682
+ this.fnPageChange = function (mAction, bRedraw)
683
+ {
684
  var api = this.api(true).page(mAction);
685
 
686
  if (bRedraw === undefined || bRedraw) {
688
  }
689
  };
690
 
691
+
692
+ /**
693
+ * Show a particular column
694
+ * @param {int} iCol The column whose display should be changed
695
+ * @param {bool} bShow Show (true) or hide (false) the column
696
+ * @param {bool} [bRedraw=true] Redraw the table or not
697
+ * @dtopt API
698
+ * @deprecated Since v1.10
699
+ *
700
+ * @example
701
+ * $(document).ready(function() {
702
+ * var oTable = $('#example').dataTable();
703
+ *
704
+ * // Hide the second column after initialisation
705
+ * oTable.fnSetColumnVis( 1, false );
706
+ * } );
707
+ */
708
+ this.fnSetColumnVis = function (iCol, bShow, bRedraw)
709
+ {
710
  var api = this.api(true).column(iCol).visible(bShow);
711
 
712
  if (bRedraw === undefined || bRedraw) {
714
  }
715
  };
716
 
717
+
718
+ /**
719
+ * Get the settings for a particular table for external manipulation
720
+ * @returns {object} DataTables settings object. See
721
+ * {@link DataTable.models.oSettings}
722
+ * @dtopt API
723
+ * @deprecated Since v1.10
724
+ *
725
+ * @example
726
+ * $(document).ready(function() {
727
+ * var oTable = $('#example').dataTable();
728
+ * var oSettings = oTable.fnSettings();
729
+ *
730
+ * // Show an example parameter from the settings
731
+ * alert( oSettings._iDisplayStart );
732
+ * } );
733
+ */
734
+ this.fnSettings = function ()
735
+ {
736
  return _fnSettingsFromNode(this[_ext.iApiIndex]);
737
  };
738
 
739
+
740
+ /**
741
+ * Sort the table by a particular column
742
+ * @param {int} iCol the data index to sort on. Note that this will not match the
743
+ * 'display index' if you have hidden data entries
744
+ * @dtopt API
745
+ * @deprecated Since v1.10
746
+ *
747
+ * @example
748
+ * $(document).ready(function() {
749
+ * var oTable = $('#example').dataTable();
750
+ *
751
+ * // Sort immediately with columns 0 and 1
752
+ * oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
753
+ * } );
754
+ */
755
+ this.fnSort = function (aaSort)
756
+ {
757
  this.api(true).order(aaSort).draw();
758
  };
759
 
760
+
761
+ /**
762
+ * Attach a sort listener to an element for a given column
763
+ * @param {node} nNode the element to attach the sort listener to
764
+ * @param {int} iColumn the column that a click on this node will sort on
765
+ * @param {function} [fnCallback] callback function when sort is run
766
+ * @dtopt API
767
+ * @deprecated Since v1.10
768
+ *
769
+ * @example
770
+ * $(document).ready(function() {
771
+ * var oTable = $('#example').dataTable();
772
+ *
773
+ * // Sort on column 1, when 'sorter' is clicked on
774
+ * oTable.fnSortListener( document.getElementById('sorter'), 1 );
775
+ * } );
776
+ */
777
+ this.fnSortListener = function (nNode, iColumn, fnCallback)
778
+ {
779
  this.api(true).order.listener(nNode, iColumn, fnCallback);
780
  };
781
 
782
+
783
+ /**
784
+ * Update a table cell or row - this method will accept either a single value to
785
+ * update the cell with, an array of values with one element for each column or
786
+ * an object in the same format as the original data source. The function is
787
+ * self-referencing in order to make the multi column updates easier.
788
+ * @param {object|array|string} mData Data to update the cell/row with
789
+ * @param {node|int} mRow TR element you want to update or the aoData index
790
+ * @param {int} [iColumn] The column to update, give as null or undefined to
791
+ * update a whole row.
792
+ * @param {bool} [bRedraw=true] Redraw the table or not
793
+ * @param {bool} [bAction=true] Perform pre-draw actions or not
794
+ * @returns {int} 0 on success, 1 on error
795
+ * @dtopt API
796
+ * @deprecated Since v1.10
797
+ *
798
+ * @example
799
+ * $(document).ready(function() {
800
+ * var oTable = $('#example').dataTable();
801
+ * oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
802
+ * oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
803
+ * } );
804
+ */
805
+ this.fnUpdate = function (mData, mRow, iColumn, bRedraw, bAction)
806
+ {
807
  var api = this.api(true);
808
 
809
  if (iColumn === undefined || iColumn === null) {
822
  return 0;
823
  };
824
 
825
+
826
+ /**
827
+ * Provide a common method for plug-ins to check the version of DataTables being used, in order
828
+ * to ensure compatibility.
829
+ * @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
830
+ * formats "X" and "X.Y" are also acceptable.
831
+ * @returns {boolean} true if this version of DataTables is greater or equal to the required
832
+ * version, or false if this version of DataTales is not suitable
833
+ * @method
834
+ * @dtopt API
835
+ * @deprecated Since v1.10
836
+ *
837
+ * @example
838
+ * $(document).ready(function() {
839
+ * var oTable = $('#example').dataTable();
840
+ * alert( oTable.fnVersionCheck( '1.9.0' ) );
841
+ * } );
842
+ */
843
  this.fnVersionCheck = _ext.fnVersionCheck;
844
 
845
+
846
  var _that = this;
847
  var emptyInit = options === undefined;
848
  var len = this.length;
869
  options;
870
 
871
  /*global oInit,_that,emptyInit*/
872
+ var i = 0, iLen, j, jLen, k, kLen;
 
873
  var sId = this.getAttribute('id');
874
  var bInitHandedOff = false;
875
  var defaults = DataTable.defaults;
876
  var $this = $(this);
877
 
878
+
879
  /* Sanity check */
880
+ if (this.nodeName.toLowerCase() != 'table')
881
+ {
882
  _fnLog(null, 0, 'Non-table node initialisation (' + this.nodeName + ')', 2);
883
  return;
884
  }
894
  /* Setting up the initialisation object */
895
  _fnCamelToHungarian(defaults, $.extend(oInit, $this.data()));
896
 
897
+
898
+
899
  /* Check to see if we are re-initialising a table */
900
  var allSettings = DataTable.settings;
901
+ for (i = 0, iLen = allSettings.length; i < iLen; i++)
902
+ {
903
  var s = allSettings[i];
904
 
905
  /* Base check on table node */
906
+ if (s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this))
907
+ {
908
  var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
909
  var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
910
 
911
+ if (emptyInit || bRetrieve)
912
+ {
913
  return s.oInstance;
914
+ } else if (bDestroy)
915
+ {
916
  s.oInstance.fnDestroy();
917
  break;
918
+ } else
919
+ {
920
  _fnLog(s, 0, 'Cannot reinitialise DataTable', 3);
921
  return;
922
  }
923
  }
924
 
925
+ /* If the element we are initialising has the same ID as a table which was previously
926
+ * initialised, but the table nodes don't match (from before) then we destroy the old
927
+ * instance by simply deleting it. This is under the assumption that the table has been
928
+ * destroyed by other methods. Anyone using non-id selectors will need to do this manually
929
+ */
930
+ if (s.sTableId == this.id)
931
+ {
932
  allSettings.splice(i, 1);
933
  break;
934
  }
935
  }
936
 
937
  /* Ensure the table has an ID - required for accessibility */
938
+ if (sId === null || sId === "")
939
+ {
940
  sId = "DataTables_Table_" + (DataTable.ext._unique++);
941
  this.id = sId;
942
  }
960
  // Backwards compatibility, before we apply all the defaults
961
  _fnCompatOpts(oInit);
962
 
963
+ if (oInit.oLanguage)
964
+ {
965
  _fnLanguageCompat(oInit.oLanguage);
966
  }
967
 
968
  // If the length menu is given, but the init display length is not, use the length menu
969
+ if (oInit.aLengthMenu && !oInit.iDisplayLength)
970
+ {
971
  oInit.iDisplayLength = $.isArray(oInit.aLengthMenu[0]) ?
972
  oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
973
  }
974
 
975
+ // Apply the defaults and init options to make a single init object will all
976
+ // options defined from defaults and instance options.
977
  oInit = _fnExtend($.extend(true, {}, defaults), oInit);
978
 
979
+
980
  // Map the initialisation options onto the settings object
981
  _fnMap(oSettings.oFeatures, oInit, [
982
  "bPaginate",
1011
  "fnStateSaveCallback",
1012
  "renderer",
1013
  "searchDelay",
1014
+ "rowId",
1015
+ ["iCookieDuration", "iStateDuration"], // backwards compat
1016
  ["oSearch", "oPreviousSearch"],
1017
  ["aoSearchCols", "aoPreSearchCols"],
1018
  ["iDisplayLength", "_iDisplayLength"],
1047
  var oClasses = oSettings.oClasses;
1048
 
1049
  // @todo Remove in 1.11
1050
+ if (oInit.bJQueryUI)
1051
+ {
1052
+ /* Use the JUI classes object for display. You could clone the oStdClasses object if
1053
+ * you want to have multiple tables with multiple independent classes
1054
+ */
1055
  $.extend(oClasses, DataTable.ext.oJUIClasses, oInit.oClasses);
1056
 
1057
+ if (oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip")
1058
+ {
1059
+ /* Set the DOM to use a layout suitable for jQuery UI's theming */
1060
  oSettings.sDom = '<"H"lfr>t<"F"ip>';
1061
  }
1062
 
1065
  } else if ($.isPlainObject(oSettings.renderer) && !oSettings.renderer.header) {
1066
  oSettings.renderer.header = 'jqueryui';
1067
  }
1068
+ } else
1069
+ {
1070
  $.extend(oClasses, DataTable.ext.classes, oInit.oClasses);
1071
  }
1072
  $this.addClass(oClasses.sTable);
1073
 
1074
+
1075
+ if (oSettings.iInitDisplayStart === undefined)
1076
+ {
1077
  /* Display start point, taking into account the save saving */
1078
  oSettings.iInitDisplayStart = oInit.iDisplayStart;
1079
  oSettings._iDisplayStart = oInit.iDisplayStart;
1080
  }
1081
 
1082
+ if (oInit.iDeferLoading !== null)
1083
+ {
1084
  oSettings.bDeferLoading = true;
1085
  var tmp = $.isArray(oInit.iDeferLoading);
1086
  oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
1091
  var oLanguage = oSettings.oLanguage;
1092
  $.extend(true, oLanguage, oInit.oLanguage);
1093
 
1094
+ if (oLanguage.sUrl)
1095
+ {
1096
+ /* Get the language definitions from a file - because this Ajax call makes the language
1097
+ * get async to the remainder of this function we use bInitHandedOff to indicate that
1098
+ * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
1099
+ */
1100
  $.ajax({
1101
  dataType: 'json',
1102
  url: oLanguage.sUrl,
1113
  });
1114
  bInitHandedOff = true;
1115
  }
1116
+
1117
+ /*
1118
+ * Stripes
1119
+ */
1120
+ if (oInit.asStripeClasses === null)
1121
+ {
1122
  oSettings.asStripeClasses = [
1123
  oClasses.sStripeOdd,
1124
  oClasses.sStripeEven
1125
  ];
1126
  }
1127
 
1128
+ /* Remove row stripe classes if they are already on the table row */
1129
  var stripeClasses = oSettings.asStripeClasses;
1130
  var rowOne = $this.children('tbody').find('tr').eq(0);
1131
  if ($.inArray(true, $.map(stripeClasses, function (el, i) {
1135
  oSettings.asDestroyStripes = stripeClasses.slice();
1136
  }
1137
 
1138
+ /*
1139
+ * Columns
1140
+ * See if we should load columns automatically or use defined ones
1141
+ */
1142
  var anThs = [];
1143
  var aoColumnsInit;
1144
  var nThead = this.getElementsByTagName('thead');
1145
+ if (nThead.length !== 0)
1146
+ {
1147
  _fnDetectHeader(oSettings.aoHeader, nThead[0]);
1148
  anThs = _fnGetUniqueThs(oSettings);
1149
  }
1150
 
1151
+ /* If not given a column array, generate one with nulls */
1152
+ if (oInit.aoColumns === null)
1153
+ {
1154
  aoColumnsInit = [];
1155
+ for (i = 0, iLen = anThs.length; i < iLen; i++)
1156
+ {
1157
  aoColumnsInit.push(null);
1158
  }
1159
+ } else
1160
+ {
1161
  aoColumnsInit = oInit.aoColumns;
1162
  }
1163
 
1164
+ /* Add the columns */
1165
+ for (i = 0, iLen = aoColumnsInit.length; i < iLen; i++)
1166
+ {
1167
  _fnAddColumn(oSettings, anThs ? anThs[i] : null);
1168
  }
1169
 
1170
+ /* Apply the column definitions */
1171
  _fnApplyColumnDefs(oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
1172
  _fnColumnOptions(oSettings, iCol, oDef);
1173
  });
1174
 
1175
+ /* HTML5 attribute detection - build an mData object automatically if the
1176
+ * attributes are found
1177
+ */
1178
  if (rowOne.length) {
1179
  var a = function (cell, name) {
1180
  return cell.getAttribute('data-' + name) !== null ? name : null;
1202
  }
1203
 
1204
  var features = oSettings.oFeatures;
1205
+ var loadedInit = function () {
1206
+ /*
1207
+ * Sorting
1208
+ * @todo For modularisation (1.11) this needs to do into a sort start up handler
1209
+ */
1210
+
1211
+ // If aaSorting is not defined, then we use the first indicator in asSorting
1212
+ // in case that has been altered, so the default sort reflects that option
1213
+ if (oInit.aaSorting === undefined) {
1214
+ var sorting = oSettings.aaSorting;
1215
+ for (i = 0, iLen = sorting.length; i < iLen; i++) {
1216
+ sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
1217
+ }
1218
+ }
1219
 
1220
+ /* Do a first pass on the sorting classes (allows any size changes to be taken into
1221
+ * account, and also will apply sorting disabled classes if disabled
1222
+ */
1223
+ _fnSortingClasses(oSettings);
 
1224
 
1225
+ if (features.bSort) {
1226
+ _fnCallbackReg(oSettings, 'aoDrawCallback', function () {
1227
+ if (oSettings.bSorted) {
1228
+ var aSort = _fnSortFlatten(oSettings);
1229
+ var sortedColumns = {};
 
1230
 
1231
+ $.each(aSort, function (i, val) {
1232
+ sortedColumns[ val.src ] = val.dir;
1233
+ });
1234
+
1235
+ _fnCallbackFire(oSettings, null, 'order', [oSettings, aSort, sortedColumns]);
1236
+ _fnSortAria(oSettings);
1237
+ }
1238
+ });
1239
+ }
1240
 
 
1241
  _fnCallbackReg(oSettings, 'aoDrawCallback', function () {
1242
+ if (oSettings.bSorted || _fnDataSource(oSettings) === 'ssp' || features.bDeferRender) {
1243
+ _fnSortingClasses(oSettings);
1244
+ }
1245
+ }, 'sc');
1246
 
 
 
 
1247
 
1248
+ /*
1249
+ * Final init
1250
+ * Cache the header, body and footer as required, creating them if needed
1251
+ */
1252
+
1253
+ // Work around for Webkit bug 83867 - store the caption-side before removing from doc
1254
+ var captions = $this.children('caption').each(function () {
1255
+ this._captionSide = $(this).css('caption-side');
1256
  });
 
1257
 
1258
+ var thead = $this.children('thead');
1259
+ if (thead.length === 0) {
1260
+ thead = $('<thead/>').appendTo($this);
1261
  }
1262
+ oSettings.nTHead = thead[0];
 
 
 
 
1263
 
1264
+ var tbody = $this.children('tbody');
1265
+ if (tbody.length === 0) {
1266
+ tbody = $('<tbody/>').appendTo($this);
1267
+ }
1268
+ oSettings.nTBody = tbody[0];
1269
 
1270
+ var tfoot = $this.children('tfoot');
1271
+ if (tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "")) {
1272
+ // If we are a scrolling table, and no footer has been given, then we need to create
1273
+ // a tfoot element for the caption element to be appended to
1274
+ tfoot = $('<tfoot/>').appendTo($this);
1275
+ }
1276
 
1277
+ if (tfoot.length === 0 || tfoot.children().length === 0) {
1278
+ $this.addClass(oClasses.sNoFooter);
1279
+ } else if (tfoot.length > 0) {
1280
+ oSettings.nTFoot = tfoot[0];
1281
+ _fnDetectHeader(oSettings.aoFooter, oSettings.nTFoot);
1282
+ }
1283
 
1284
+ /* Check if there is data passing into the constructor */
1285
+ if (oInit.aaData) {
1286
+ for (i = 0; i < oInit.aaData.length; i++) {
1287
+ _fnAddData(oSettings, oInit.aaData[ i ]);
1288
+ }
1289
+ } else if (oSettings.bDeferLoading || _fnDataSource(oSettings) == 'dom') {
1290
+ /* Grab the data from the page - only do this when deferred loading or no Ajax
1291
+ * source since there is no point in reading the DOM data if we are then going
1292
+ * to replace it with Ajax data
1293
+ */
1294
+ _fnAddTr(oSettings, $(oSettings.nTBody).children('tr'));
1295
  }
 
 
 
1296
 
1297
+ /* Copy the data index array */
1298
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
1299
+
1300
+ /* Initialisation complete - table can be drawn */
1301
+ oSettings.bInitialised = true;
1302
+
1303
+ /* Check if we need to initialise the table (it might not have been handed off to the
1304
+ * language processor)
1305
+ */
1306
+ if (bInitHandedOff === false) {
1307
+ _fnInitialise(oSettings);
1308
+ }
1309
+ };
1310
 
1311
+ /* Must be done after everything which can be overridden by the state saving! */
1312
+ if (oInit.bStateSave)
1313
+ {
1314
+ features.bStateSave = true;
1315
+ _fnCallbackReg(oSettings, 'aoDrawCallback', _fnSaveState, 'state_save');
1316
+ _fnLoadState(oSettings, oInit, loadedInit);
1317
+ } else {
1318
+ loadedInit();
1319
  }
1320
+
1321
  });
1322
  _that = null;
1323
  return this;
1324
  };
1325
+
1326
+
1327
+ /*
1328
+ * It is useful to have variables which are scoped locally so only the
1329
+ * DataTables functions can access them and they don't leak into global space.
1330
+ * At the same time these functions are often useful over multiple files in the
1331
+ * core and API, so we list, or at least document, all variables which are used
1332
+ * by DataTables as private variables here. This also ensures that there is no
1333
+ * clashing of variable names and that they can easily referenced for reuse.
1334
+ */
1335
+
1336
+
1337
+ // Defined else where
1338
+ // _selector_run
1339
+ // _selector_opts
1340
+ // _selector_first
1341
+ // _selector_row_indexes
1342
+
1343
  var _ext; // DataTable.ext
1344
  var _Api; // DataTable.Api
1345
  var _api_register; // DataTable.Api.register
1348
  var _re_dic = {};
1349
  var _re_new_lines = /[\r\n]/g;
1350
  var _re_html = /<.*?>/g;
 
 
1351
 
1352
+ // This is not strict ISO8601 - Date.parse() is quite lax, although
1353
+ // implementations differ between browsers.
1354
+ var _re_date = /^\d{2,4}[\.\/\-]\d{1,2}[\.\/\-]\d{1,2}([T ]{1}\d{1,2}[:\.]\d{2}([\.:]\d{2})?)?$/;
1355
+
1356
+ // Escape regular expression special characters
1357
  var _re_escape_regex = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-'].join('|\\') + ')', 'g');
1358
 
1359
+ // http://en.wikipedia.org/wiki/Foreign_exchange_market
1360
+ // - \u20BD - Russian ruble.
1361
+ // - \u20a9 - South Korean Won
1362
+ // - \u20BA - Turkish Lira
1363
+ // - \u20B9 - Indian Rupee
1364
+ // - R - Brazil (R$) and South Africa
1365
+ // - fr - Swiss Franc
1366
+ // - kr - Swedish krona, Norwegian krone and Danish krone
1367
+ // - \u2009 is thin space and \u202F is narrow no-break space, both used in many
1368
+ // standards as thousands separators.
1369
  var _re_formatted_numeric = /[',$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfk]/gi;
1370
+
1371
+
1372
  var _empty = function (d) {
1373
  return !d || d === true || d === '-' ? true : false;
1374
  };
1375
 
1376
+
1377
  var _intVal = function (s) {
1378
  var integer = parseInt(s, 10);
1379
  return !isNaN(integer) && isFinite(s) ? integer : null;
1380
  };
1381
 
1382
+ // Convert from a formatted number with characters other than `.` as the
1383
+ // decimal place, to a Javascript number
1384
  var _numToDecimal = function (num, decimalPoint) {
1385
  // Cache created regular expressions for speed as this function is called often
1386
+ if (!_re_dic[ decimalPoint ]) {
1387
+ _re_dic[ decimalPoint ] = new RegExp(_fnEscapeRegex(decimalPoint), 'g');
1388
  }
1389
  return typeof num === 'string' && decimalPoint !== '.' ?
1390
+ num.replace(/\./g, '').replace(_re_dic[ decimalPoint ], '.') :
1391
  num;
1392
  };
1393
 
1394
+
1395
  var _isNumber = function (d, decimalPoint, formatted) {
1396
  var strType = typeof d === 'string';
1397
 
1398
+ // If empty return immediately so there must be a number if it is a
1399
+ // formatted string (this stops the string "k", or "kr", etc being detected
1400
+ // as a formatted number for currency
1401
  if (_empty(d)) {
1402
  return true;
1403
  }
1413
  return !isNaN(parseFloat(d)) && isFinite(d);
1414
  };
1415
 
1416
+
1417
+ // A string without HTML in it can be considered to be HTML still
1418
  var _isHtml = function (d) {
1419
  return _empty(d) || typeof d === 'string';
1420
  };
1421
 
1422
+
1423
  var _htmlNumeric = function (d, decimalPoint, formatted) {
1424
  if (_empty(d)) {
1425
  return true;
1433
  null;
1434
  };
1435
 
1436
+
1437
  var _pluck = function (a, prop, prop2) {
1438
  var out = [];
1439
+ var i = 0, ien = a.length;
 
1440
 
1441
+ // Could have the test in the loop for slightly smaller code, but speed
1442
+ // is essential here
1443
  if (prop2 !== undefined) {
1444
  for (; i < ien; i++) {
1445
+ if (a[i] && a[i][ prop ]) {
1446
+ out.push(a[i][ prop ][ prop2 ]);
1447
  }
1448
  }
1449
  } else {
1450
  for (; i < ien; i++) {
1451
  if (a[i]) {
1452
+ out.push(a[i][ prop ]);
1453
  }
1454
  }
1455
  }
1457
  return out;
1458
  };
1459
 
1460
+
1461
+ // Basically the same as _pluck, but rather than looping over `a` we use `order`
1462
+ // as the indexes to pick from `a`
1463
+ var _pluck_order = function (a, order, prop, prop2)
1464
+ {
1465
  var out = [];
1466
+ var i = 0, ien = order.length;
1467
+
1468
+ // Could have the test in the loop for slightly smaller code, but speed
1469
+ // is essential here
1470
  if (prop2 !== undefined) {
1471
  for (; i < ien; i++) {
1472
+ if (a[ order[i] ][ prop ]) {
1473
+ out.push(a[ order[i] ][ prop ][ prop2 ]);
1474
  }
1475
  }
1476
  } else {
1477
  for (; i < ien; i++) {
1478
+ out.push(a[ order[i] ][ prop ]);
1479
  }
1480
  }
1481
 
1482
  return out;
1483
  };
1484
+
1485
+
1486
+ var _range = function (len, start)
1487
+ {
1488
  var out = [];
1489
  var end;
1490
 
1503
  return out;
1504
  };
1505
 
1506
+
1507
+ var _removeEmpty = function (a)
1508
+ {
1509
  var out = [];
1510
 
1511
  for (var i = 0, ien = a.length; i < ien; i++) {
1517
  return out;
1518
  };
1519
 
1520
+
1521
  var _stripHtml = function (d) {
1522
  return d.replace(_re_html, '');
1523
  };
1524
 
 
1525
 
1526
+ /**
1527
+ * Determine if all values in the array are unique. This means we can short
1528
+ * cut the _unique method at the cost of a single loop. A sorted array is used
1529
+ * to easily check the values.
1530
+ *
1531
+ * @param {array} src Source array
1532
+ * @return {boolean} true if all unique, false otherwise
1533
+ * @ignore
1534
+ */
1535
+ var _areAllUnique = function (src) {
1536
+ if (src.length < 2) {
1537
+ return true;
1538
+ }
1539
+
1540
+ var sorted = src.slice().sort();
1541
+ var last = sorted[0];
1542
+
1543
+ for (var i = 1, ien = sorted.length; i < ien; i++) {
1544
+ if (sorted[i] === last) {
1545
+ return false;
1546
+ }
1547
+
1548
+ last = sorted[i];
1549
+ }
1550
+
1551
+ return true;
1552
+ };
1553
+
1554
+
1555
+ /**
1556
+ * Find the unique elements in a source array.
1557
+ *
1558
+ * @param {array} src Source array
1559
+ * @return {array} Array of unique items
1560
+ * @ignore
1561
+ */
1562
+ var _unique = function (src)
1563
+ {
1564
+ if (_areAllUnique(src)) {
1565
+ return src.slice();
1566
+ }
1567
+
1568
+ // A faster unique method is to use object keys to identify used values,
1569
+ // but this doesn't work with arrays or objects, which we must also
1570
+ // consider. See jsperf.com/compare-array-unique-versions/4 for more
1571
+ // information.
1572
  var
1573
  out = [],
1574
  val,
1591
  return out;
1592
  };
1593
 
 
1594
 
1595
+ /**
1596
+ * DataTables utility methods
1597
+ *
1598
+ * This namespace provides helper methods that DataTables uses internally to
1599
+ * create a DataTable, but which are not exclusively used only for DataTables.
1600
+ * These methods can be used by extension authors to save the duplication of
1601
+ * code.
1602
+ *
1603
+ * @namespace
1604
+ */
1605
+ DataTable.util = {
1606
+ /**
1607
+ * Throttle the calls to a function. Arguments and context are maintained
1608
+ * for the throttled function.
1609
+ *
1610
+ * @param {function} fn Function to be called
1611
+ * @param {integer} freq Call frequency in mS
1612
+ * @return {function} Wrapped function
1613
+ */
1614
  throttle: function (fn, freq) {
1615
  var
1616
  frequency = freq !== undefined ? freq : 200,
1637
  };
1638
  },
1639
 
1640
+ /**
1641
+ * Escape a string such that it can be used in a regular expression
1642
+ *
1643
+ * @param {string} val string to escape
1644
+ * @returns {string} escaped string
1645
+ */
1646
  escapeRegex: function (val) {
1647
  return val.replace(_re_escape_regex, '\\$1');
1648
  }
1649
  };
1650
 
1651
+
1652
+
1653
+ /**
1654
+ * Create a mapping object that allows camel case parameters to be looked up
1655
+ * for their Hungarian counterparts. The mapping is stored in a private
1656
+ * parameter called `_hungarianMap` which can be accessed on the source object.
1657
+ * @param {object} o
1658
+ * @memberof DataTable#oApi
1659
+ */
1660
+ function _fnHungarianMap(o)
1661
+ {
1662
  var
1663
  hungarian = 'a aa ai ao as b fn i m o s ',
1664
  match,
1668
  $.each(o, function (key, val) {
1669
  match = key.match(/^([^A-Z]+?)([A-Z])/);
1670
 
1671
+ if (match && hungarian.indexOf(match[1] + ' ') !== -1)
1672
+ {
1673
  newKey = key.replace(match[0], match[2].toLowerCase());
1674
+ map[ newKey ] = key;
1675
 
1676
+ if (match[1] === 'o')
1677
+ {
1678
  _fnHungarianMap(o[key]);
1679
  }
1680
  }
1683
  o._hungarianMap = map;
1684
  }
1685
 
1686
+
1687
+ /**
1688
+ * Convert from camel case parameters to Hungarian, based on a Hungarian map
1689
+ * created by _fnHungarianMap.
1690
+ * @param {object} src The model object which holds all parameters that can be
1691
+ * mapped.
1692
+ * @param {object} user The object to convert from camel case to Hungarian.
1693
+ * @param {boolean} force When set to `true`, properties which already have a
1694
+ * Hungarian value in the `user` object will be overwritten. Otherwise they
1695
+ * won't be.
1696
+ * @memberof DataTable#oApi
1697
+ */
1698
+ function _fnCamelToHungarian(src, user, force)
1699
+ {
1700
  if (!src._hungarianMap) {
1701
  _fnHungarianMap(src);
1702
  }
1704
  var hungarianKey;
1705
 
1706
  $.each(user, function (key, val) {
1707
+ hungarianKey = src._hungarianMap[ key ];
1708
 
1709
+ if (hungarianKey !== undefined && (force || user[hungarianKey] === undefined))
1710
+ {
1711
  // For objects, we need to buzz down into the object to copy parameters
1712
+ if (hungarianKey.charAt(0) === 'o')
1713
+ {
1714
  // Copy the camelCase options over to the hungarian
1715
+ if (!user[ hungarianKey ]) {
1716
+ user[ hungarianKey ] = {};
1717
  }
1718
  $.extend(true, user[hungarianKey], user[key]);
1719
 
1720
  _fnCamelToHungarian(src[hungarianKey], user[hungarianKey], force);
1721
  } else {
1722
+ user[hungarianKey] = user[ key ];
1723
  }
1724
  }
1725
  });
1726
  }
1727
 
1728
+
1729
+ /**
1730
+ * Language compatibility - when certain options are given, and others aren't, we
1731
+ * need to duplicate the values over, in order to provide backwards compatibility
1732
+ * with older language files.
1733
+ * @param {object} oSettings dataTables settings object
1734
+ * @memberof DataTable#oApi
1735
+ */
1736
+ function _fnLanguageCompat(lang)
1737
+ {
1738
  var defaults = DataTable.defaults.oLanguage;
1739
  var zeroRecords = lang.sZeroRecords;
1740
 
1741
+ /* Backwards compatibility - if there is no sEmptyTable given, then use the same as
1742
+ * sZeroRecords - assuming that is given.
1743
+ */
1744
  if (!lang.sEmptyTable && zeroRecords &&
1745
+ defaults.sEmptyTable === "No data available in table")
1746
+ {
1747
  _fnMap(lang, lang, 'sZeroRecords', 'sEmptyTable');
1748
  }
1749
 
1750
+ /* Likewise with loading records */
1751
  if (!lang.sLoadingRecords && zeroRecords &&
1752
+ defaults.sLoadingRecords === "Loading...")
1753
+ {
1754
  _fnMap(lang, lang, 'sZeroRecords', 'sLoadingRecords');
1755
  }
1756
 
1757
+ // Old parameter name of the thousands separator mapped onto the new
1758
  if (lang.sInfoThousands) {
1759
  lang.sThousands = lang.sInfoThousands;
1760
  }
1765
  }
1766
  }
1767
 
1768
+
1769
+ /**
1770
+ * Map one parameter onto another
1771
+ * @param {object} o Object to map
1772
+ * @param {*} knew The new parameter name
1773
+ * @param {*} old The old parameter name
1774
+ */
1775
  var _fnCompatMap = function (o, knew, old) {
1776
+ if (o[ knew ] !== undefined) {
1777
+ o[ old ] = o[ knew ];
1778
  }
1779
  };
1780
 
1781
+
1782
+ /**
1783
+ * Provide backwards compatibility for the main DT options. Note that the new
1784
+ * options are mapped onto the old parameters, so this is an external interface
1785
+ * change only.
1786
+ * @param {object} init Object to map
1787
+ */
1788
+ function _fnCompatOpts(init)
1789
+ {
1790
  _fnCompatMap(init, 'ordering', 'bSort');
1791
  _fnCompatMap(init, 'orderMulti', 'bSortMulti');
1792
  _fnCompatMap(init, 'orderClasses', 'bSortClasses');
1798
  _fnCompatMap(init, 'pageLength', 'iDisplayLength');
1799
  _fnCompatMap(init, 'searching', 'bFilter');
1800
 
1801
+ // Boolean initialisation of x-scrolling
1802
  if (typeof init.sScrollX === 'boolean') {
1803
  init.sScrollX = init.sScrollX ? '100%' : '';
1804
  }
1806
  init.scrollX = init.scrollX ? '100%' : '';
1807
  }
1808
 
1809
+ // Column search objects are in an array, so it needs to be converted
1810
+ // element by element
1811
  var searchCols = init.aoSearchCols;
1812
 
1813
  if (searchCols) {
1819
  }
1820
  }
1821
 
1822
+
1823
+ /**
1824
+ * Provide backwards compatibility for column options. Note that the new options
1825
+ * are mapped onto the old parameters, so this is an external interface change
1826
+ * only.
1827
+ * @param {object} init Object to map
1828
+ */
1829
+ function _fnCompatCols(init)
1830
+ {
1831
  _fnCompatMap(init, 'orderable', 'bSortable');
1832
  _fnCompatMap(init, 'orderData', 'aDataSort');
1833
  _fnCompatMap(init, 'orderSequence', 'asSorting');
1834
  _fnCompatMap(init, 'orderDataType', 'sortDataType');
1835
 
1836
+ // orderData can be given as an integer
1837
  var dataSort = init.aDataSort;
1838
+ if (typeof dataSort === 'number' && !$.isArray(dataSort)) {
1839
  init.aDataSort = [dataSort];
1840
  }
1841
  }
1842
 
 
1843
 
1844
+ /**
1845
+ * Browser feature detection for capabilities, quirks
1846
+ * @param {object} settings dataTables settings object
1847
+ * @memberof DataTable#oApi
1848
+ */
1849
+ function _fnBrowserDetect(settings)
1850
+ {
1851
+ // We don't need to do this every time DataTables is constructed, the values
1852
+ // calculated are specific to the browser and OS configuration which we
1853
+ // don't expect to change between initialisations
1854
  if (!DataTable.__browser) {
1855
  var browser = {};
1856
  DataTable.__browser = browser;
1857
 
1858
+ // Scrolling feature / quirks detection
1859
  var n = $('<div/>')
1860
  .css({
1861
  position: 'fixed',
1862
  top: 0,
1863
+ left: $(window).scrollLeft() * -1, // allow for scrolling
1864
  height: 1,
1865
  width: 1,
1866
  overflow: 'hidden'
1887
  var outer = n.children();
1888
  var inner = outer.children();
1889
 
1890
+ // Numbers below, in order, are:
1891
+ // inner.offsetWidth, inner.clientWidth, outer.offsetWidth, outer.clientWidth
1892
+ //
1893
+ // IE6 XP: 100 100 100 83
1894
+ // IE7 Vista: 100 100 100 83
1895
+ // IE 8+ Windows: 83 83 100 83
1896
+ // Evergreen Windows: 83 83 100 83
1897
+ // Evergreen Mac with scrollbars: 85 85 100 85
1898
+ // Evergreen Mac without scrollbars: 100 100 100 100
1899
+
1900
+ // Get scrollbar width
1901
  browser.barWidth = outer[0].offsetWidth - outer[0].clientWidth;
1902
 
1903
+ // IE6/7 will oversize a width 100% element inside a scrolling element, to
1904
+ // include the width of the scrollbar, while other browsers ensure the inner
1905
+ // element is contained without forcing scrolling
1906
  browser.bScrollOversize = inner[0].offsetWidth === 100 && outer[0].clientWidth !== 100;
1907
 
1908
+ // In rtl text layout, some browsers (most, but not all) will place the
1909
+ // scrollbar on the left, rather than the right.
1910
  browser.bScrollbarLeft = Math.round(inner.offset().left) !== 1;
1911
 
1912
+ // IE8- don't provide height and width for getBoundingClientRect
1913
  browser.bBounding = n[0].getBoundingClientRect().width ? true : false;
1914
 
1915
  n.remove();
1919
  settings.oScroll.iBarWidth = DataTable.__browser.barWidth;
1920
  }
1921
 
1922
+
1923
+ /**
1924
+ * Array.prototype reduce[Right] method, used for browsers which don't support
1925
+ * JS 1.6. Done this way to reduce code size, since we iterate either way
1926
+ * @param {object} settings dataTables settings object
1927
+ * @memberof DataTable#oApi
1928
+ */
1929
+ function _fnReduce(that, fn, init, start, end, inc)
1930
+ {
1931
  var
1932
  i = start,
1933
  value,
1954
  return value;
1955
  }
1956
 
1957
+ /**
1958
+ * Add a column to the list used for the table with default values
1959
+ * @param {object} oSettings dataTables settings object
1960
+ * @param {node} nTh The th element for this column
1961
+ * @memberof DataTable#oApi
1962
+ */
1963
+ function _fnAddColumn(oSettings, nTh)
1964
+ {
1965
  // Add column to aoColumns array
1966
  var oDefaults = DataTable.defaults.column;
1967
  var iCol = oSettings.aoColumns.length;
1974
  });
1975
  oSettings.aoColumns.push(oCol);
1976
 
1977
+ // Add search object for column specific search. Note that the `searchCols[ iCol ]`
1978
+ // passed into extend can be undefined. This allows the user to give a default
1979
+ // with only some of the parameters defined, and also not give a default
1980
  var searchCols = oSettings.aoPreSearchCols;
1981
+ searchCols[ iCol ] = $.extend({}, DataTable.models.oSearch, searchCols[ iCol ]);
1982
 
1983
+ // Use the default column options function to initialise classes etc
1984
  _fnColumnOptions(oSettings, iCol, $(nTh).data());
1985
  }
1986
 
1987
+
1988
+ /**
1989
+ * Apply options for a column
1990
+ * @param {object} oSettings dataTables settings object
1991
+ * @param {int} iCol column index to consider
1992
+ * @param {object} oOptions object with sType, bVisible and bSearchable etc
1993
+ * @memberof DataTable#oApi
1994
+ */
1995
+ function _fnColumnOptions(oSettings, iCol, oOptions)
1996
+ {
1997
+ var oCol = oSettings.aoColumns[ iCol ];
1998
  var oClasses = oSettings.oClasses;
1999
  var th = $(oCol.nTh);
2000
 
2001
+ // Try to get width information from the DOM. We can't get it from CSS
2002
+ // as we'd need to parse the CSS stylesheet. `width` option can override
2003
  if (!oCol.sWidthOrig) {
2004
  // Width attribute
2005
  oCol.sWidthOrig = th.attr('width') || null;
2006
+
2007
+ // Style attribute
2008
  var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%]+)/);
2009
  if (t) {
2010
  oCol.sWidthOrig = t[1];
2011
  }
2012
  }
 
2013
 
2014
+ /* User specified column options */
2015
+ if (oOptions !== undefined && oOptions !== null)
2016
+ {
2017
+ // Backwards compatibility
2018
  _fnCompatCols(oOptions);
2019
 
2020
  // Map camel case parameters to their Hungarian counterparts
2021
  _fnCamelToHungarian(DataTable.defaults.column, oOptions);
2022
+
2023
+ /* Backwards compatibility for mDataProp */
2024
+ if (oOptions.mDataProp !== undefined && !oOptions.mData)
2025
+ {
2026
  oOptions.mData = oOptions.mDataProp;
2027
  }
2028
+
2029
+ if (oOptions.sType)
2030
+ {
2031
  oCol._sManualType = oOptions.sType;
2032
  }
2033
+
2034
+ // `class` is a reserved word in Javascript, so we need to provide
2035
+ // the ability to use a valid name for the camel case input
2036
+ if (oOptions.className && !oOptions.sClass)
2037
+ {
2038
  oOptions.sClass = oOptions.className;
2039
  }
2040
 
2041
  $.extend(oCol, oOptions);
2042
  _fnMap(oCol, oOptions, "sWidth", "sWidthOrig");
2043
+
2044
+ /* iDataSort to be applied (backwards compatibility), but aDataSort will take
2045
+ * priority if defined
2046
+ */
2047
+ if (oOptions.iDataSort !== undefined)
2048
+ {
2049
  oCol.aDataSort = [oOptions.iDataSort];
2050
  }
2051
  _fnMap(oCol, oOptions, "aDataSort");
2052
  }
2053
+
2054
+ /* Cache the data get and set functions for speed */
2055
  var mDataSrc = oCol.mData;
2056
  var mData = _fnGetObjectDataFn(mDataSrc);
2057
  var mRender = oCol.mRender ? _fnGetObjectDataFn(oCol.mRender) : null;
2075
  return _fnSetObjectDataFn(mDataSrc)(rowData, val, meta);
2076
  };
2077
 
2078
+ // Indicate if DataTables should read DOM data as an object or array
2079
+ // Used in _fnGetRowElements
2080
  if (typeof mDataSrc !== 'number') {
2081
  oSettings._rowReadObject = true;
2082
  }
2083
 
2084
+ /* Feature sorting overrides column specific when off */
2085
+ if (!oSettings.oFeatures.bSort)
2086
+ {
2087
  oCol.bSortable = false;
2088
  th.addClass(oClasses.sSortableNone); // Have to add class here as order event isn't called
2089
  }
2090
 
2091
+ /* Check that the class assignment is correct for sorting */
2092
  var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
2093
  var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
2094
+ if (!oCol.bSortable || (!bAsc && !bDesc))
2095
+ {
2096
  oCol.sSortingClass = oClasses.sSortableNone;
2097
  oCol.sSortingClassJUI = "";
2098
+ } else if (bAsc && !bDesc)
2099
+ {
2100
  oCol.sSortingClass = oClasses.sSortableAsc;
2101
  oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
2102
+ } else if (!bAsc && bDesc)
2103
+ {
2104
  oCol.sSortingClass = oClasses.sSortableDesc;
2105
  oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
2106
+ } else
2107
+ {
2108
  oCol.sSortingClass = oClasses.sSortable;
2109
  oCol.sSortingClassJUI = oClasses.sSortJUI;
2110
  }
2111
  }
2112
 
2113
+
2114
+ /**
2115
+ * Adjust the table column widths for new data. Note: you would probably want to
2116
+ * do a redraw after calling this function!
2117
+ * @param {object} settings dataTables settings object
2118
+ * @memberof DataTable#oApi
2119
+ */
2120
+ function _fnAdjustColumnSizing(settings)
2121
+ {
2122
  /* Not interested in doing column width calculation if auto-width is disabled */
2123
+ if (settings.oFeatures.bAutoWidth !== false)
2124
+ {
2125
  var columns = settings.aoColumns;
2126
 
2127
  _fnCalculateColumnWidths(settings);
2128
+ for (var i = 0, iLen = columns.length; i < iLen; i++)
2129
+ {
2130
  columns[i].nTh.style.width = columns[i].sWidth;
2131
  }
2132
  }
2133
 
2134
  var scroll = settings.oScroll;
2135
+ if (scroll.sY !== '' || scroll.sX !== '')
2136
+ {
2137
  _fnScrollDraw(settings);
2138
  }
2139
 
2140
  _fnCallbackFire(settings, null, 'column-sizing', [settings]);
2141
  }
2142
 
2143
+
2144
+ /**
2145
+ * Covert the index of a visible column to the index in the data array (take account
2146
+ * of hidden columns)
2147
+ * @param {object} oSettings dataTables settings object
2148
+ * @param {int} iMatch Visible column index to lookup
2149
+ * @returns {int} i the data index
2150
+ * @memberof DataTable#oApi
2151
+ */
2152
+ function _fnVisibleToColumnIndex(oSettings, iMatch)
2153
+ {
2154
  var aiVis = _fnGetColumns(oSettings, 'bVisible');
2155
 
2156
  return typeof aiVis[iMatch] === 'number' ?
2158
  null;
2159
  }
2160
 
2161
+
2162
+ /**
2163
+ * Covert the index of an index in the data array and convert it to the visible
2164
+ * column index (take account of hidden columns)
2165
+ * @param {int} iMatch Column index to lookup
2166
+ * @param {object} oSettings dataTables settings object
2167
+ * @returns {int} i the data index
2168
+ * @memberof DataTable#oApi
2169
+ */
2170
+ function _fnColumnIndexToVisible(oSettings, iMatch)
2171
+ {
2172
  var aiVis = _fnGetColumns(oSettings, 'bVisible');
2173
  var iPos = $.inArray(iMatch, aiVis);
2174
 
2175
  return iPos !== -1 ? iPos : null;
2176
  }
2177
 
2178
+
2179
+ /**
2180
+ * Get the number of visible columns
2181
+ * @param {object} oSettings dataTables settings object
2182
+ * @returns {int} i the number of visible columns
2183
+ * @memberof DataTable#oApi
2184
+ */
2185
+ function _fnVisbleColumns(oSettings)
2186
+ {
2187
  var vis = 0;
2188
 
2189
  // No reduce in IE8, use a loop for now
2196
  return vis;
2197
  }
2198
 
2199
+
2200
+ /**
2201
+ * Get an array of column indexes that match a given property
2202
+ * @param {object} oSettings dataTables settings object
2203
+ * @param {string} sParam Parameter in aoColumns to look for - typically
2204
+ * bVisible or bSearchable
2205
+ * @returns {array} Array of indexes with matched properties
2206
+ * @memberof DataTable#oApi
2207
+ */
2208
+ function _fnGetColumns(oSettings, sParam)
2209
+ {
2210
  var a = [];
2211
 
2212
  $.map(oSettings.aoColumns, function (val, i) {
2218
  return a;
2219
  }
2220
 
2221
+
2222
+ /**
2223
+ * Calculate the 'type' of a column
2224
+ * @param {object} settings dataTables settings object
2225
+ * @memberof DataTable#oApi
2226
+ */
2227
+ function _fnColumnTypes(settings)
2228
+ {
2229
  var columns = settings.aoColumns;
2230
  var data = settings.aoData;
2231
  var types = DataTable.ext.type.detect;
2232
  var i, ien, j, jen, k, ken;
2233
  var col, cell, detectedType, cache;
2234
 
2235
+ // For each column, spin over the
2236
  for (i = 0, ien = columns.length; i < ien; i++) {
2237
  col = columns[i];
2238
  cache = [];
2242
  } else if (!col.sType) {
2243
  for (j = 0, jen = types.length; j < jen; j++) {
2244
  for (k = 0, ken = data.length; k < ken; k++) {
2245
+ // Use a cache array so we only need to get the type data
2246
+ // from the formatter once (when using multiple detectors)
2247
  if (cache[k] === undefined) {
2248
  cache[k] = _fnGetCellData(settings, k, i, 'type');
2249
  }
2250
 
2251
  detectedType = types[j](cache[k], settings);
2252
 
2253
+ // If null, then this type can't apply to this column, so
2254
+ // rather than testing all cells, break out. There is an
2255
+ // exception for the last type which is `html`. We need to
2256
+ // scan all rows since it is possible to mix string and HTML
2257
+ // types
2258
  if (!detectedType && j !== types.length - 1) {
2259
  break;
2260
  }
2261
+
2262
+ // Only a single match is needed for html type since it is
2263
+ // bottom of the pile and very similar to string
2264
  if (detectedType === 'html') {
2265
  break;
2266
  }
2267
  }
2268
+
2269
+ // Type is valid for all data points in the column - use this
2270
+ // type
2271
  if (detectedType) {
2272
  col.sType = detectedType;
2273
  break;
2274
  }
2275
  }
2276
+
2277
+ // Fall back - if no type was detected, always use string
2278
  if (!col.sType) {
2279
  col.sType = 'string';
2280
  }
2282
  }
2283
  }
2284
 
2285
+
2286
+ /**
2287
+ * Take the column definitions and static columns arrays and calculate how
2288
+ * they relate to column indexes. The callback function will then apply the
2289
+ * definition found for a column to a suitable configuration object.
2290
+ * @param {object} oSettings dataTables settings object
2291
+ * @param {array} aoColDefs The aoColumnDefs array that is to be applied
2292
+ * @param {array} aoCols The aoColumns array that defines columns individually
2293
+ * @param {function} fn Callback function - takes two parameters, the calculated
2294
+ * column index and the definition for that column.
2295
+ * @memberof DataTable#oApi
2296
+ */
2297
+ function _fnApplyColumnDefs(oSettings, aoColDefs, aoCols, fn)
2298
+ {
2299
  var i, iLen, j, jLen, k, kLen, def;
2300
  var columns = oSettings.aoColumns;
2301
 
2302
+ // Column definitions with aTargets
2303
+ if (aoColDefs)
2304
+ {
2305
+ /* Loop over the definitions array - loop in reverse so first instance has priority */
2306
+ for (i = aoColDefs.length - 1; i >= 0; i--)
2307
+ {
2308
  def = aoColDefs[i];
2309
+
2310
+ /* Each definition can target multiple columns, as it is an array */
2311
  var aTargets = def.targets !== undefined ?
2312
  def.targets :
2313
  def.aTargets;
2314
 
2315
+ if (!$.isArray(aTargets))
2316
+ {
2317
  aTargets = [aTargets];
2318
  }
2319
 
2320
+ for (j = 0, jLen = aTargets.length; j < jLen; j++)
2321
+ {
2322
+ if (typeof aTargets[j] === 'number' && aTargets[j] >= 0)
2323
+ {
2324
  /* Add columns that we don't yet know about */
2325
+ while (columns.length <= aTargets[j])
2326
+ {
2327
  _fnAddColumn(oSettings);
2328
  }
2329
+
2330
+ /* Integer, basic index */
2331
  fn(aTargets[j], def);
2332
+ } else if (typeof aTargets[j] === 'number' && aTargets[j] < 0)
2333
+ {
2334
  /* Negative integer, right to left column counting */
2335
  fn(columns.length + aTargets[j], def);
2336
+ } else if (typeof aTargets[j] === 'string')
2337
+ {
2338
  /* Class name matching on TH element */
2339
+ for (k = 0, kLen = columns.length; k < kLen; k++)
2340
+ {
2341
  if (aTargets[j] == "_all" ||
2342
+ $(columns[k].nTh).hasClass(aTargets[j]))
2343
+ {
2344
  fn(k, def);
2345
  }
2346
  }
2349
  }
2350
  }
2351
 
2352
+ // Statically defined columns array
2353
+ if (aoCols)
2354
+ {
2355
+ for (i = 0, iLen = aoCols.length; i < iLen; i++)
2356
+ {
2357
  fn(i, aoCols[i]);
2358
  }
2359
  }
2360
  }
2361
 
2362
+ /**
2363
+ * Add a data array to the table, creating DOM node etc. This is the parallel to
2364
+ * _fnGatherData, but for adding rows from a Javascript source, rather than a
2365
+ * DOM source.
2366
+ * @param {object} oSettings dataTables settings object
2367
+ * @param {array} aData data array to be added
2368
+ * @param {node} [nTr] TR element to add to the table - optional. If not given,
2369
+ * DataTables will create a row automatically
2370
+ * @param {array} [anTds] Array of TD|TH elements for the row - must be given
2371
+ * if nTr is.
2372
+ * @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
2373
+ * @memberof DataTable#oApi
2374
+ */
2375
+ function _fnAddData(oSettings, aDataIn, nTr, anTds)
2376
+ {
2377
  /* Create the object for storing information about this new row */
2378
  var iRow = oSettings.aoData.length;
2379
  var oData = $.extend(true, {}, DataTable.models.oRow, {
2384
  oData._aData = aDataIn;
2385
  oSettings.aoData.push(oData);
2386
 
2387
+ /* Create the cells */
2388
  var nTd, sThisType;
2389
  var columns = oSettings.aoColumns;
2390
 
2391
+ // Invalidate the column types as the new data needs to be revalidated
2392
+ for (var i = 0, iLen = columns.length; i < iLen; i++)
2393
+ {
2394
  columns[i].sType = null;
2395
  }
2396
 
2397
+ /* Add to the display array */
2398
  oSettings.aiDisplayMaster.push(iRow);
2399
 
2400
  var id = oSettings.rowIdFn(aDataIn);
2401
  if (id !== undefined) {
2402
+ oSettings.aIds[ id ] = oData;
2403
  }
2404
 
2405
+ /* Create the DOM information, or register it if already present */
2406
+ if (nTr || !oSettings.oFeatures.bDeferRender)
2407
+ {
2408
  _fnCreateTr(oSettings, iRow, nTr, anTds);
2409
  }
2410
 
2411
  return iRow;
2412
  }
2413
 
2414
+
2415
+ /**
2416
+ * Add one or more TR elements to the table. Generally we'd expect to
2417
+ * use this for reading data from a DOM sourced table, but it could be
2418
+ * used for an TR element. Note that if a TR is given, it is used (i.e.
2419
+ * it is not cloned).
2420
+ * @param {object} settings dataTables settings object
2421
+ * @param {array|node|jQuery} trs The TR element(s) to add to the table
2422
+ * @returns {array} Array of indexes for the added rows
2423
+ * @memberof DataTable#oApi
2424
+ */
2425
+ function _fnAddTr(settings, trs)
2426
+ {
2427
  var row;
2428
+
2429
+ // Allow an individual node to be passed in
2430
  if (!(trs instanceof $)) {
2431
  trs = $(trs);
2432
  }
2437
  });
2438
  }
2439
 
2440
+
2441
+ /**
2442
+ * Take a TR element and convert it to an index in aoData
2443
+ * @param {object} oSettings dataTables settings object
2444
+ * @param {node} n the TR element to find
2445
+ * @returns {int} index if the node is found, null if not
2446
+ * @memberof DataTable#oApi
2447
+ */
2448
+ function _fnNodeToDataIndex(oSettings, n)
2449
+ {
2450
  return (n._DT_RowIndex !== undefined) ? n._DT_RowIndex : null;
2451
  }
2452
 
2453
+
2454
+ /**
2455
+ * Take a TD element and convert it into a column data index (not the visible index)
2456
+ * @param {object} oSettings dataTables settings object
2457
+ * @param {int} iRow The row number the TD/TH can be found in
2458
+ * @param {node} n The TD/TH element to find
2459
+ * @returns {int} index if the node is found, -1 if not
2460
+ * @memberof DataTable#oApi
2461
+ */
2462
+ function _fnNodeToColumnIndex(oSettings, iRow, n)
2463
+ {
2464
+ return $.inArray(n, oSettings.aoData[ iRow ].anCells);
2465
  }
2466
 
2467
+
2468
+ /**
2469
+ * Get the data for a given cell from the internal cache, taking into account data mapping
2470
+ * @param {object} settings dataTables settings object
2471
+ * @param {int} rowIdx aoData row id
2472
+ * @param {int} colIdx Column index
2473
+ * @param {string} type data get type ('display', 'type' 'filter' 'sort')
2474
+ * @returns {*} Cell data
2475
+ * @memberof DataTable#oApi
2476
+ */
2477
+ function _fnGetCellData(settings, rowIdx, colIdx, type)
2478
+ {
2479
  var draw = settings.iDraw;
2480
  var col = settings.aoColumns[colIdx];
2481
  var rowData = settings.aoData[rowIdx]._aData;
2496
  return defaultContent;
2497
  }
2498
 
2499
+ // When the data source is null and a specific data type is requested (i.e.
2500
+ // not the original data), we can use default column data
2501
  if ((cellData === rowData || cellData === null) && defaultContent !== null && type !== undefined) {
2502
  cellData = defaultContent;
2503
  } else if (typeof cellData === 'function') {
2504
+ // If the data source is a function, then we run it and use the return,
2505
+ // executing in the scope of the data object (for instances)
2506
  return cellData.call(rowData);
2507
  }
2508
 
2512
  return cellData;
2513
  }
2514
 
2515
+
2516
+ /**
2517
+ * Set the value for a specific cell, into the internal data cache
2518
+ * @param {object} settings dataTables settings object
2519
+ * @param {int} rowIdx aoData row id
2520
+ * @param {int} colIdx Column index
2521
+ * @param {*} val Value to set
2522
+ * @memberof DataTable#oApi
2523
+ */
2524
+ function _fnSetCellData(settings, rowIdx, colIdx, val)
2525
+ {
2526
  var col = settings.aoColumns[colIdx];
2527
  var rowData = settings.aoData[rowIdx]._aData;
2528
 
2533
  });
2534
  }
2535
 
2536
+
2537
+ // Private variable that is used to match action syntax in the data property object
2538
  var __reArray = /\[.*?\]$/;
2539
  var __reFn = /\(\)$/;
2540
 
2541
+ /**
2542
+ * Split string on periods, taking into account escaped periods
2543
+ * @param {string} str String to split
2544
+ * @return {array} Split string
2545
+ */
2546
+ function _fnSplitObjNotation(str)
2547
+ {
2548
  return $.map(str.match(/(\\.|[^\.])+/g) || [''], function (s) {
2549
+ return s.replace(/\\\./g, '.');
2550
  });
2551
  }
2552
 
2553
+
2554
+ /**
2555
+ * Return a function that can be used to get data from a source object, taking
2556
+ * into account the ability to use nested objects as a source
2557
+ * @param {string|int|function} mSource The data source for the object
2558
+ * @returns {function} Data get function
2559
+ * @memberof DataTable#oApi
2560
+ */
2561
+ function _fnGetObjectDataFn(mSource)
2562
+ {
2563
+ if ($.isPlainObject(mSource))
2564
+ {
2565
  /* Build an object of get functions, and wrap them in a single call */
2566
  var o = {};
2567
  $.each(mSource, function (key, val) {
2576
  t(data, type, row, meta) :
2577
  data;
2578
  };
2579
+ } else if (mSource === null)
2580
+ {
2581
  /* Give an empty string for rendering / sorting etc */
2582
  return function (data) { // type, row and meta also passed, but not used
2583
  return data;
2584
  };
2585
+ } else if (typeof mSource === 'function')
2586
+ {
2587
  return function (data, type, row, meta) {
2588
  return mSource(data, type, row, meta);
2589
  };
2590
  } else if (typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2591
+ mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1))
2592
+ {
2593
+ /* If there is a . in the source string then the data source is in a
2594
+ * nested object so we loop over the data for each level to get the next
2595
+ * level down. On each loop we test for undefined, and if found immediately
2596
+ * return. This allows entire objects to be missing and sDefaultContent to
2597
+ * be used if defined, rather than throwing an error
2598
+ */
2599
  var fetchData = function (data, type, src) {
2600
  var arrayNotation, funcNotation, out, innerSrc;
2601
 
2602
+ if (src !== "")
2603
+ {
2604
  var a = _fnSplitObjNotation(src);
2605
 
2606
+ for (var i = 0, iLen = a.length; i < iLen; i++)
2607
+ {
2608
  // Check if we are dealing with special notation
2609
  arrayNotation = a[i].match(__reArray);
2610
  funcNotation = a[i].match(__reFn);
2611
 
2612
+ if (arrayNotation)
2613
+ {
2614
  // Array notation
2615
  a[i] = a[i].replace(__reArray, '');
2616
 
2617
+ // Condition allows simply [] to be passed in
2618
  if (a[i] !== "") {
2619
+ data = data[ a[i] ];
2620
  }
2621
  out = [];
2622
 
2623
+ // Get the remainder of the nested object to get
2624
  a.splice(0, i + 1);
2625
  innerSrc = a.join('.');
2626
 
2627
+ // Traverse each entry in the array getting the properties requested
2628
  if ($.isArray(data)) {
2629
  for (var j = 0, jLen = data.length; j < jLen; j++) {
2630
  out.push(fetchData(data[j], type, innerSrc));
2631
  }
2632
  }
2633
+
2634
+ // If a string is given in between the array notation indicators, that
2635
+ // is used to join the strings together, otherwise an array is returned
2636
  var join = arrayNotation[0].substring(1, arrayNotation[0].length - 1);
2637
  data = (join === "") ? out : out.join(join);
2638
 
2639
+ // The inner call to fetchData has already traversed through the remainder
2640
+ // of the source requested, so we exit from the loop
2641
  break;
2642
+ } else if (funcNotation)
2643
+ {
2644
  // Function call
2645
  a[i] = a[i].replace(__reFn, '');
2646
+ data = data[ a[i] ]();
2647
  continue;
2648
  }
2649
 
2650
+ if (data === null || data[ a[i] ] === undefined)
2651
+ {
2652
  return undefined;
2653
  }
2654
+ data = data[ a[i] ];
2655
  }
2656
  }
2657
 
2661
  return function (data, type) { // row and meta also passed, but not used
2662
  return fetchData(data, type, mSource);
2663
  };
2664
+ } else
2665
+ {
2666
  /* Array or flat object mapping */
2667
  return function (data, type) { // row and meta also passed, but not used
2668
  return data[mSource];
2670
  }
2671
  }
2672
 
2673
+
2674
+ /**
2675
+ * Return a function that can be used to set data from a source object, taking
2676
+ * into account the ability to use nested objects as a source
2677
+ * @param {string|int|function} mSource The data source for the object
2678
+ * @returns {function} Data set function
2679
+ * @memberof DataTable#oApi
2680
+ */
2681
+ function _fnSetObjectDataFn(mSource)
2682
+ {
2683
+ if ($.isPlainObject(mSource))
2684
+ {
2685
+ /* Unlike get, only the underscore (global) option is used for for
2686
+ * setting data since we don't know the type here. This is why an object
2687
+ * option is not documented for `mData` (which is read/write), but it is
2688
+ * for `mRender` which is read only.
2689
+ */
2690
  return _fnSetObjectDataFn(mSource._);
2691
+ } else if (mSource === null)
2692
+ {
2693
  /* Nothing to do when the data source is null */
2694
  return function () {};
2695
+ } else if (typeof mSource === 'function')
2696
+ {
2697
  return function (data, val, meta) {
2698
  mSource(data, 'set', val, meta);
2699
  };
2700
  } else if (typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
2701
+ mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1))
2702
+ {
2703
  /* Like the get, we need to get data from a nested object */
2704
  var setData = function (data, val, src) {
2705
+ var a = _fnSplitObjNotation(src), b;
 
2706
  var aLast = a[a.length - 1];
2707
  var arrayNotation, funcNotation, o, innerSrc;
2708
 
2709
+ for (var i = 0, iLen = a.length - 1; i < iLen; i++)
2710
+ {
2711
  // Check if we are dealing with an array notation request
2712
  arrayNotation = a[i].match(__reArray);
2713
  funcNotation = a[i].match(__reFn);
2714
 
2715
+ if (arrayNotation)
2716
+ {
2717
  a[i] = a[i].replace(__reArray, '');
2718
+ data[ a[i] ] = [];
2719
 
2720
  // Get the remainder of the nested object to set so we can recurse
2721
  b = a.slice();
2723
  innerSrc = b.join('.');
2724
 
2725
  // Traverse each entry in the array setting the properties requested
2726
+ if ($.isArray(val))
2727
+ {
2728
+ for (var j = 0, jLen = val.length; j < jLen; j++)
2729
+ {
2730
  o = {};
2731
  setData(o, val[j], innerSrc);
2732
+ data[ a[i] ].push(o);
2733
  }
2734
+ } else
2735
+ {
2736
+ // We've been asked to save data to an array, but it
2737
+ // isn't array data to be saved. Best that can be done
2738
+ // is to just save the value.
2739
+ data[ a[i] ] = val;
2740
  }
2741
+
2742
+ // The inner call to setData has already traversed through the remainder
2743
+ // of the source and has set the data, thus we can exit here
2744
  return;
2745
+ } else if (funcNotation)
2746
+ {
2747
  // Function call
2748
  a[i] = a[i].replace(__reFn, '');
2749
+ data = data[ a[i] ](val);
2750
  }
2751
+
2752
+ // If the nested object doesn't currently exist - since we are
2753
+ // trying to set the value - create it
2754
+ if (data[ a[i] ] === null || data[ a[i] ] === undefined)
2755
+ {
2756
+ data[ a[i] ] = {};
2757
  }
2758
+ data = data[ a[i] ];
2759
  }
2760
 
2761
+ // Last item in the input - i.e, the actual set
2762
+ if (aLast.match(__reFn))
2763
+ {
2764
+ // Function call
2765
+ data = data[ aLast.replace(__reFn, '') ](val);
2766
+ } else
2767
+ {
2768
+ // If array notation is used, we just want to strip it and use the property name
2769
+ // and assign the value. If it isn't used, then we get the result we want anyway
2770
+ data[ aLast.replace(__reArray, '') ] = val;
2771
  }
2772
  };
2773
 
2774
  return function (data, val) { // meta is also passed in, but not used
2775
  return setData(data, val, mSource);
2776
  };
2777
+ } else
2778
+ {
2779
  /* Array or flat object mapping */
2780
  return function (data, val) { // meta is also passed in, but not used
2781
  data[mSource] = val;
2783
  }
2784
  }
2785
 
2786
+
2787
+ /**
2788
+ * Return an array with the full table data
2789
+ * @param {object} oSettings dataTables settings object
2790
+ * @returns array {array} aData Master data array
2791
+ * @memberof DataTable#oApi
2792
+ */
2793
+ function _fnGetDataMaster(settings)
2794
+ {
2795
  return _pluck(settings.aoData, '_aData');
2796
  }
2797
 
2798
+
2799
+ /**
2800
+ * Nuke the table
2801
+ * @param {object} oSettings dataTables settings object
2802
+ * @memberof DataTable#oApi
2803
+ */
2804
+ function _fnClearTable(settings)
2805
+ {
2806
  settings.aoData.length = 0;
2807
  settings.aiDisplayMaster.length = 0;
2808
  settings.aiDisplay.length = 0;
2809
  settings.aIds = {};
2810
  }
2811
 
2812
+
2813
+ /**
2814
+ * Take an array of integers (index array) and remove a target integer (value - not
2815
+ * the key!)
2816
+ * @param {array} a Index array to target
2817
+ * @param {int} iTarget value to find
2818
+ * @memberof DataTable#oApi
2819
+ */
2820
+ function _fnDeleteIndex(a, iTarget, splice)
2821
+ {
2822
  var iTargetIndex = -1;
2823
 
2824
+ for (var i = 0, iLen = a.length; i < iLen; i++)
2825
+ {
2826
+ if (a[i] == iTarget)
2827
+ {
2828
  iTargetIndex = i;
2829
+ } else if (a[i] > iTarget)
2830
+ {
2831
  a[i]--;
2832
  }
2833
  }
2834
 
2835
+ if (iTargetIndex != -1 && splice === undefined)
2836
+ {
2837
  a.splice(iTargetIndex, 1);
2838
  }
2839
  }
2840
 
2841
+
2842
+ /**
2843
+ * Mark cached data as invalid such that a re-read of the data will occur when
2844
+ * the cached data is next requested. Also update from the data source object.
2845
+ *
2846
+ * @param {object} settings DataTables settings object
2847
+ * @param {int} rowIdx Row index to invalidate
2848
+ * @param {string} [src] Source to invalidate from: undefined, 'auto', 'dom'
2849
+ * or 'data'
2850
+ * @param {int} [colIdx] Column index to invalidate. If undefined the whole
2851
+ * row will be invalidated
2852
+ * @memberof DataTable#oApi
2853
+ *
2854
+ * @todo For the modularisation of v1.11 this will need to become a callback, so
2855
+ * the sort and filter methods can subscribe to it. That will required
2856
+ * initialisation options for sorting, which is why it is not already baked in
2857
+ */
2858
+ function _fnInvalidate(settings, rowIdx, src, colIdx)
2859
+ {
2860
+ var row = settings.aoData[ rowIdx ];
2861
  var i, ien;
2862
  var cellWrite = function (cell, col) {
2863
+ // This is very frustrating, but in IE if you just write directly
2864
+ // to innerHTML, and elements that are overwritten are GC'ed,
2865
+ // even if there is a reference to them elsewhere
2866
  while (cell.childNodes.length) {
2867
  cell.removeChild(cell.firstChild);
2868
  }
2870
  cell.innerHTML = _fnGetCellData(settings, rowIdx, col, 'display');
2871
  };
2872
 
2873
+ // Are we reading last data from DOM or the data object?
2874
  if (src === 'dom' || ((!src || src === 'auto') && row.src === 'dom')) {
2875
  // Read the data from the DOM
2876
  row._aData = _fnGetRowElements(
2892
  }
2893
  }
2894
 
2895
+ // For both row and cell invalidation, the cached data for sorting and
2896
+ // filtering is nulled out
2897
  row._aSortData = null;
2898
  row._aFilterData = null;
2899
+
2900
+ // Invalidate the type for a specific column (if given) or all columns since
2901
+ // the data might have changed
2902
  var cols = settings.aoColumns;
2903
  if (colIdx !== undefined) {
2904
+ cols[ colIdx ].sType = null;
2905
  } else {
2906
  for (i = 0, ien = cols.length; i < ien; i++) {
2907
  cols[i].sType = null;
2908
  }
2909
+
2910
+ // Update DataTables special `DT_*` attributes for the row
2911
  _fnRowAttributes(settings, row);
2912
  }
2913
  }
2914
 
2915
+
2916
+ /**
2917
+ * Build a data source object from an HTML row, reading the contents of the
2918
+ * cells that are in the row.
2919
+ *
2920
+ * @param {object} settings DataTables settings object
2921
+ * @param {node|object} TR element from which to read data or existing row
2922
+ * object from which to re-read the data from the cells
2923
+ * @param {int} [colIdx] Optional column index
2924
+ * @param {array|object} [d] Data source object. If `colIdx` is given then this
2925
+ * parameter should also be given and will be used to write the data into.
2926
+ * Only the column in question will be written
2927
+ * @returns {object} Object with two parameters: `data` the data read, in
2928
+ * document order, and `cells` and array of nodes (they can be useful to the
2929
+ * caller, so rather than needing a second traversal to get them, just return
2930
+ * them from here).
2931
+ * @memberof DataTable#oApi
2932
+ */
2933
+ function _fnGetRowElements(settings, row, colIdx, d)
2934
+ {
2935
  var
2936
  tds = [],
2937
  td = row.firstChild,
2938
+ name, col, o, i = 0, contents,
 
2939
  columns = settings.aoColumns,
2940
  objectRead = settings._rowReadObject;
2941
 
2942
  // Allow the data object to be passed in, or construct
2943
  d = d !== undefined ?
2944
  d :
2945
+ objectRead ?
2946
+ {} :
2947
+ [];
2948
 
2949
  var attr = function (str, td) {
2950
  if (typeof str === 'string') {
2958
  }
2959
  };
2960
 
2961
+ // Read data from a cell and store into the data object
2962
  var cellProcess = function (cell) {
2963
  if (colIdx === undefined || colIdx === i) {
2964
  col = columns[i];
2972
  attr(col.mData.type, cell);
2973
  attr(col.mData.filter, cell);
2974
  } else {
2975
+ // Depending on the `data` option for the columns the data can
2976
+ // be read to either an object or an array.
2977
  if (objectRead) {
2978
  if (!col._setter) {
2979
  // Cache the setter function
3010
  }
3011
  }
3012
 
3013
+ // Read the ID from the DOM if present
3014
  var rowNode = row.firstChild ? row : row.nTr;
3015
 
3016
  if (rowNode) {
3026
  cells: tds
3027
  };
3028
  }
3029
+ /**
3030
+ * Create a new TR element (and it's TD children) for a row
3031
+ * @param {object} oSettings dataTables settings object
3032
+ * @param {int} iRow Row to consider
3033
+ * @param {node} [nTrIn] TR element to add to the table - optional. If not given,
3034
+ * DataTables will create a row automatically
3035
+ * @param {array} [anTds] Array of TD|TH elements for the row - must be given
3036
+ * if nTr is.
3037
+ * @memberof DataTable#oApi
3038
+ */
3039
+ function _fnCreateTr(oSettings, iRow, nTrIn, anTds)
3040
+ {
3041
  var
3042
  row = oSettings.aoData[iRow],
3043
  rowData = row._aData,
3045
  nTr, nTd, oCol,
3046
  i, iLen;
3047
 
3048
+ if (row.nTr === null)
3049
+ {
3050
  nTr = nTrIn || document.createElement('tr');
3051
 
3052
  row.nTr = nTr;
3053
  row.anCells = cells;
3054
 
3055
+ /* Use a private property on the node to allow reserve mapping from the node
3056
+ * to the aoData array for fast look up
3057
+ */
3058
  nTr._DT_RowIndex = iRow;
3059
 
3060
+ /* Special parameters can be given by the data source to be used on the row */
3061
  _fnRowAttributes(oSettings, row);
3062
 
3063
+ /* Process each column */
3064
+ for (i = 0, iLen = oSettings.aoColumns.length; i < iLen; i++)
3065
+ {
3066
  oCol = oSettings.aoColumns[i];
3067
 
3068
  nTd = nTrIn ? anTds[i] : document.createElement(oCol.sCellType);
3073
 
3074
  cells.push(nTd);
3075
 
3076
+ // Need to create the HTML if new, or if a rendering function is defined
3077
  if ((!nTrIn || oCol.mRender || oCol.mData !== i) &&
3078
  (!$.isPlainObject(oCol.mData) || oCol.mData._ !== i + '.display')
3079
  ) {
3081
  }
3082
 
3083
  /* Add user defined class */
3084
+ if (oCol.sClass)
3085
+ {
3086
  nTd.className += ' ' + oCol.sClass;
3087
  }
3088
 
3089
  // Visibility - add or remove as required
3090
+ if (oCol.bVisible && !nTrIn)
3091
+ {
3092
  nTr.appendChild(nTd);
3093
+ } else if (!oCol.bVisible && nTrIn)
3094
+ {
3095
  nTd.parentNode.removeChild(nTd);
3096
  }
3097
 
3098
+ if (oCol.fnCreatedCell)
3099
+ {
3100
  oCol.fnCreatedCell.call(oSettings.oInstance,
3101
  nTd, _fnGetCellData(oSettings, iRow, i), rowData, iRow, i
3102
  );
3106
  _fnCallbackFire(oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow]);
3107
  }
3108
 
3109
+ // Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
3110
+ // and deployed
3111
  row.nTr.setAttribute('role', 'row');
3112
  }
3113
 
3114
+
3115
+ /**
3116
+ * Add attributes to a row based on the special `DT_*` parameters in a data
3117
+ * source object.
3118
+ * @param {object} settings DataTables settings object
3119
+ * @param {object} DataTables row object for the row to be modified
3120
+ * @memberof DataTable#oApi
3121
+ */
3122
+ function _fnRowAttributes(settings, row)
3123
+ {
3124
  var tr = row.nTr;
3125
  var data = row._aData;
3126
 
3153
  }
3154
  }
3155
 
3156
+
3157
+ /**
3158
+ * Create the HTML header for the table
3159
+ * @param {object} oSettings dataTables settings object
3160
+ * @memberof DataTable#oApi
3161
+ */
3162
+ function _fnBuildHead(oSettings)
3163
+ {
3164
  var i, ien, cell, row, column;
3165
  var thead = oSettings.nTHead;
3166
  var tfoot = oSettings.nTFoot;
3180
  cell.appendTo(row);
3181
  }
3182
 
3183
+ // 1.11 move into sorting
3184
  if (oSettings.oFeatures.bSort) {
3185
  cell.addClass(column.sSortingClass);
3186
 
3206
  _fnDetectHeader(oSettings.aoHeader, thead);
3207
  }
3208
 
3209
+ /* ARIA role for the rows */
3210
  $(thead).find('>tr').attr('role', 'row');
3211
 
3212
+ /* Deal with the footer - add classes if required */
3213
  $(thead).find('>tr>th, >tr>td').addClass(classes.sHeaderTH);
3214
  $(tfoot).find('>tr>th, >tr>td').addClass(classes.sFooterTH);
3215
 
3216
+ // Cache the footer cells. Note that we only take the cells from the first
3217
+ // row in the footer. If there is more than one row the user wants to
3218
+ // interact with, they need to use the table().foot() method. Note also this
3219
+ // allows cells to be used for multiple columns using colspan
3220
  if (tfoot !== null) {
3221
  var cells = oSettings.aoFooter[0];
3222
 
3231
  }
3232
  }
3233
 
3234
+
3235
+ /**
3236
+ * Draw the header (or footer) element based on the column visibility states. The
3237
+ * methodology here is to use the layout array from _fnDetectHeader, modified for
3238
+ * the instantaneous column visibility, to construct the new layout. The grid is
3239
+ * traversed over cell at a time in a rows x columns grid fashion, although each
3240
+ * cell insert can cover multiple elements in the grid - which is tracks using the
3241
+ * aApplied array. Cell inserts in the grid will only occur where there isn't
3242
+ * already a cell in that position.
3243
+ * @param {object} oSettings dataTables settings object
3244
+ * @param array {objects} aoSource Layout array from _fnDetectHeader
3245
+ * @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
3246
+ * @memberof DataTable#oApi
3247
+ */
3248
+ function _fnDrawHead(oSettings, aoSource, bIncludeHidden)
3249
+ {
3250
  var i, iLen, j, jLen, k, kLen, n, nLocalTr;
3251
  var aoLocal = [];
3252
  var aApplied = [];
3253
  var iColumns = oSettings.aoColumns.length;
3254
  var iRowspan, iColspan;
3255
 
3256
+ if (!aoSource)
3257
+ {
3258
  return;
3259
  }
3260
 
3261
+ if (bIncludeHidden === undefined)
3262
+ {
3263
  bIncludeHidden = false;
3264
  }
3265
 
3266
+ /* Make a copy of the master layout array, but without the visible columns in it */
3267
+ for (i = 0, iLen = aoSource.length; i < iLen; i++)
3268
+ {
3269
  aoLocal[i] = aoSource[i].slice();
3270
  aoLocal[i].nTr = aoSource[i].nTr;
3271
 
3272
+ /* Remove any columns which are currently hidden */
3273
+ for (j = iColumns - 1; j >= 0; j--)
3274
+ {
3275
+ if (!oSettings.aoColumns[j].bVisible && !bIncludeHidden)
3276
+ {
3277
  aoLocal[i].splice(j, 1);
3278
  }
3279
  }
3280
+
3281
+ /* Prep the applied array - it needs an element for each row */
3282
  aApplied.push([]);
3283
  }
3284
 
3285
+ for (i = 0, iLen = aoLocal.length; i < iLen; i++)
3286
+ {
3287
  nLocalTr = aoLocal[i].nTr;
3288
 
3289
+ /* All cells are going to be replaced, so empty out the row */
3290
+ if (nLocalTr)
3291
+ {
3292
+ while ((n = nLocalTr.firstChild))
3293
+ {
3294
  nLocalTr.removeChild(n);
3295
  }
3296
  }
3297
 
3298
+ for (j = 0, jLen = aoLocal[i].length; j < jLen; j++)
3299
+ {
3300
  iRowspan = 1;
3301
  iColspan = 1;
3302
+
3303
+ /* Check to see if there is already a cell (row/colspan) covering our target
3304
+ * insert point. If there is, then there is nothing to do.
3305
+ */
3306
+ if (aApplied[i][j] === undefined)
3307
+ {
3308
  nLocalTr.appendChild(aoLocal[i][j].cell);
3309
  aApplied[i][j] = 1;
3310
 
3311
+ /* Expand the cell to cover as many rows as needed */
3312
  while (aoLocal[i + iRowspan] !== undefined &&
3313
+ aoLocal[i][j].cell == aoLocal[i + iRowspan][j].cell)
3314
+ {
3315
  aApplied[i + iRowspan][j] = 1;
3316
  iRowspan++;
3317
  }
3318
 
3319
+ /* Expand the cell to cover as many columns as needed */
3320
  while (aoLocal[i][j + iColspan] !== undefined &&
3321
+ aoLocal[i][j].cell == aoLocal[i][j + iColspan].cell)
3322
+ {
3323
  /* Must update the applied array over the rows for the columns */
3324
+ for (k = 0; k < iRowspan; k++)
3325
+ {
3326
  aApplied[i + k][j + iColspan] = 1;
3327
  }
3328
  iColspan++;
3329
  }
3330
+
3331
+ /* Do the actual expansion in the DOM */
3332
  $(aoLocal[i][j].cell)
3333
  .attr('rowspan', iRowspan)
3334
  .attr('colspan', iColspan);
3337
  }
3338
  }
3339
 
 
3340
 
3341
+ /**
3342
+ * Insert the required TR nodes into the table for display
3343
+ * @param {object} oSettings dataTables settings object
3344
+ * @memberof DataTable#oApi
3345
+ */
3346
+ function _fnDraw(oSettings)
3347
+ {
3348
+ /* Provide a pre-callback function which can be used to cancel the draw is false is returned */
3349
  var aPreDraw = _fnCallbackFire(oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings]);
3350
+ if ($.inArray(false, aPreDraw) !== -1)
3351
+ {
3352
  _fnProcessingDisplay(oSettings, false);
3353
  return;
3354
  }
3355
+
3356
  var i, iLen, n;
3357
  var anRows = [];
3358
  var iRowCount = 0;
3365
  var aiDisplay = oSettings.aiDisplay;
3366
 
3367
  oSettings.bDrawing = true;
3368
+
3369
+ /* Check and see if we have an initial draw position from state saving */
3370
+ if (iInitDisplayStart !== undefined && iInitDisplayStart !== -1)
3371
+ {
3372
  oSettings._iDisplayStart = bServerSide ?
3373
  iInitDisplayStart :
3374
  iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
3380
 
3381
  var iDisplayStart = oSettings._iDisplayStart;
3382
  var iDisplayEnd = oSettings.fnDisplayEnd();
3383
+
3384
+ /* Server-side processing draw intercept */
3385
+ if (oSettings.bDeferLoading)
3386
+ {
3387
  oSettings.bDeferLoading = false;
3388
  oSettings.iDraw++;
3389
  _fnProcessingDisplay(oSettings, false);
3390
+ } else if (!bServerSide)
3391
+ {
3392
  oSettings.iDraw++;
3393
+ } else if (!oSettings.bDestroying && !_fnAjaxUpdate(oSettings))
3394
+ {
3395
  return;
3396
  }
3397
 
3398
+ if (aiDisplay.length !== 0)
3399
+ {
3400
  var iStart = bServerSide ? 0 : iDisplayStart;
3401
  var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
3402
 
3403
+ for (var j = iStart; j < iEnd; j++)
3404
+ {
3405
  var iDataIndex = aiDisplay[j];
3406
+ var aoData = oSettings.aoData[ iDataIndex ];
3407
+ if (aoData.nTr === null)
3408
+ {
3409
  _fnCreateTr(oSettings, iDataIndex);
3410
  }
3411
 
3412
  var nRow = aoData.nTr;
3413
 
3414
+ /* Remove the old striping classes and then add the new one */
3415
+ if (iStripes !== 0)
3416
+ {
3417
+ var sStripe = asStripeClasses[ iRowCount % iStripes ];
3418
+ if (aoData._sRowStripe != sStripe)
3419
+ {
3420
  $(nRow).removeClass(aoData._sRowStripe).addClass(sStripe);
3421
  aoData._sRowStripe = sStripe;
3422
  }
3423
  }
3424
 
3425
+ // Row callback functions - might want to manipulate the row
3426
+ // iRowCount and j are not currently documented. Are they at all
3427
+ // useful?
3428
+ _fnCallbackFire(oSettings, 'aoRowCallback', null,
3429
+ [nRow, aoData._aData, iRowCount, j]);
3430
 
3431
  anRows.push(nRow);
3432
  iRowCount++;
3433
  }
3434
+ } else
3435
+ {
3436
+ /* Table is empty - create a row with an empty message in it */
3437
  var sZero = oLang.sZeroRecords;
3438
+ if (oSettings.iDraw == 1 && _fnDataSource(oSettings) == 'ajax')
3439
+ {
3440
  sZero = oLang.sLoadingRecords;
3441
+ } else if (oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0)
3442
+ {
3443
  sZero = oLang.sEmptyTable;
3444
  }
3445
 
3446
+ anRows[ 0 ] = $('<tr/>', {'class': iStripes ? asStripeClasses[0] : ''})
 
 
3447
  .append($('<td />', {
3448
  'valign': 'top',
3449
  'colSpan': _fnVisbleColumns(oSettings),
3453
 
3454
  /* Header and footer callbacks */
3455
  _fnCallbackFire(oSettings, 'aoHeaderCallback', 'header', [$(oSettings.nTHead).children('tr')[0],
3456
+ _fnGetDataMaster(oSettings), iDisplayStart, iDisplayEnd, aiDisplay]);
 
3457
 
3458
  _fnCallbackFire(oSettings, 'aoFooterCallback', 'footer', [$(oSettings.nTFoot).children('tr')[0],
3459
+ _fnGetDataMaster(oSettings), iDisplayStart, iDisplayEnd, aiDisplay]);
 
3460
 
3461
  var body = $(oSettings.nTBody);
3462
 
3472
  oSettings.bDrawing = false;
3473
  }
3474
 
3475
+
3476
+ /**
3477
+ * Redraw the table - taking account of the various features which are enabled
3478
+ * @param {object} oSettings dataTables settings object
3479
+ * @param {boolean} [holdPosition] Keep the current paging position. By default
3480
+ * the paging is reset to the first page
3481
+ * @memberof DataTable#oApi
3482
+ */
3483
+ function _fnReDraw(settings, holdPosition)
3484
+ {
3485
  var
3486
  features = settings.oFeatures,
3487
  sort = features.bSort,
3502
  settings._iDisplayStart = 0;
3503
  }
3504
 
3505
+ // Let any modules know about the draw hold position state (used by
3506
+ // scrolling internally)
3507
  settings._drawHold = holdPosition;
3508
 
3509
  _fnDraw(settings);
3511
  settings._drawHold = false;
3512
  }
3513
 
3514
+
3515
+ /**
3516
+ * Add the options to the page HTML for the table
3517
+ * @param {object} oSettings dataTables settings object
3518
+ * @memberof DataTable#oApi
3519
+ */
3520
+ function _fnAddOptionsHtml(oSettings)
3521
+ {
3522
  var classes = oSettings.oClasses;
3523
  var table = $(oSettings.nTable);
3524
  var holding = $('<div/>').insertBefore(table); // Holding element for speed
3534
  oSettings.nTableWrapper = insert[0];
3535
  oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
3536
 
3537
+ /* Loop over the user set positioning and place the elements as needed */
3538
  var aDom = oSettings.sDom.split('');
3539
  var featureNode, cOption, nNewNode, cNext, sAttr, j;
3540
+ for (var i = 0; i < aDom.length; i++)
3541
+ {
3542
  featureNode = null;
3543
  cOption = aDom[i];
3544
 
3545
+ if (cOption == '<')
3546
+ {
3547
  /* New container div */
3548
  nNewNode = $('<div/>')[0];
3549
 
3550
+ /* Check to see if we should append an id and/or a class name to the container */
3551
  cNext = aDom[i + 1];
3552
+ if (cNext == "'" || cNext == '"')
3553
+ {
3554
  sAttr = "";
3555
  j = 2;
3556
+ while (aDom[i + j] != cNext)
3557
+ {
3558
  sAttr += aDom[i + j];
3559
  j++;
3560
  }
3561
 
3562
+ /* Replace jQuery UI constants @todo depreciated */
3563
+ if (sAttr == "H")
3564
+ {
3565
  sAttr = classes.sJUIHeader;
3566
+ } else if (sAttr == "F")
3567
+ {
3568
  sAttr = classes.sJUIFooter;
3569
  }
3570
+
3571
+ /* The attribute can be in the format of "#id.class", "#id" or "class" This logic
3572
+ * breaks the string into parts and applies them as needed
3573
+ */
3574
+ if (sAttr.indexOf('.') != -1)
3575
+ {
3576
  var aSplit = sAttr.split('.');
3577
  nNewNode.id = aSplit[0].substr(1, aSplit[0].length - 1);
3578
  nNewNode.className = aSplit[1];
3579
+ } else if (sAttr.charAt(0) == "#")
3580
+ {
3581
  nNewNode.id = sAttr.substr(1, sAttr.length - 1);
3582
+ } else
3583
+ {
3584
  nNewNode.className = sAttr;
3585
  }
3586
 
3589
 
3590
  insert.append(nNewNode);
3591
  insert = $(nNewNode);
3592
+ } else if (cOption == '>')
3593
+ {
3594
  /* End container div */
3595
  insert = insert.parent();
3596
+ }
3597
+ // @todo Move options into their own plugins?
3598
+ else if (cOption == 'l' && features.bPaginate && features.bLengthChange)
3599
+ {
3600
  /* Length */
3601
  featureNode = _fnFeatureHtmlLength(oSettings);
3602
+ } else if (cOption == 'f' && features.bFilter)
3603
+ {
3604
  /* Filter */
3605
  featureNode = _fnFeatureHtmlFilter(oSettings);
3606
+ } else if (cOption == 'r' && features.bProcessing)
3607
+ {
3608
  /* pRocessing */
3609
  featureNode = _fnFeatureHtmlProcessing(oSettings);
3610
+ } else if (cOption == 't')
3611
+ {
3612
  /* Table */
3613
  featureNode = _fnFeatureHtmlTable(oSettings);
3614
+ } else if (cOption == 'i' && features.bInfo)
3615
+ {
3616
  /* Info */
3617
  featureNode = _fnFeatureHtmlInfo(oSettings);
3618
+ } else if (cOption == 'p' && features.bPaginate)
3619
+ {
3620
  /* Pagination */
3621
  featureNode = _fnFeatureHtmlPaginate(oSettings);
3622
+ } else if (DataTable.ext.feature.length !== 0)
3623
+ {
3624
  /* Plug-in features */
3625
  var aoFeatures = DataTable.ext.feature;
3626
+ for (var k = 0, kLen = aoFeatures.length; k < kLen; k++)
3627
+ {
3628
+ if (cOption == aoFeatures[k].cFeature)
3629
+ {
3630
  featureNode = aoFeatures[k].fnInit(oSettings);
3631
  break;
3632
  }
3634
  }
3635
 
3636
  /* Add to the 2D features array */
3637
+ if (featureNode)
3638
+ {
3639
  var aanFeatures = oSettings.aanFeatures;
3640
 
3641
+ if (!aanFeatures[cOption])
3642
+ {
3643
  aanFeatures[cOption] = [];
3644
  }
3645
 
3647
  insert.append(featureNode);
3648
  }
3649
  }
3650
+
3651
+ /* Built our DOM structure - replace the holding div with what we want */
3652
  holding.replaceWith(insert);
3653
  oSettings.nHolding = null;
3654
  }
3655
 
3656
+
3657
+ /**
3658
+ * Use the DOM source to create up an array of header cells. The idea here is to
3659
+ * create a layout grid (array) of rows x columns, which contains a reference
3660
+ * to the cell that that point in the grid (regardless of col/rowspan), such that
3661
+ * any column / row could be removed and the new grid constructed
3662
+ * @param array {object} aLayout Array to store the calculated layout in
3663
+ * @param {node} nThead The header/footer element for the table
3664
+ * @memberof DataTable#oApi
3665
+ */
3666
+ function _fnDetectHeader(aLayout, nThead)
3667
+ {
3668
  var nTrs = $(nThead).children('tr');
3669
  var nTr, nCell;
3670
  var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
3678
  };
3679
 
3680
  aLayout.splice(0, aLayout.length);
3681
+
3682
+ /* We know how many rows there are in the layout - so prep it */
3683
+ for (i = 0, iLen = nTrs.length; i < iLen; i++)
3684
+ {
3685
  aLayout.push([]);
3686
  }
3687
 
3688
+ /* Calculate a layout array */
3689
+ for (i = 0, iLen = nTrs.length; i < iLen; i++)
3690
+ {
3691
  nTr = nTrs[i];
3692
  iColumn = 0;
3693
 
3695
  nCell = nTr.firstChild;
3696
  while (nCell) {
3697
  if (nCell.nodeName.toUpperCase() == "TD" ||
3698
+ nCell.nodeName.toUpperCase() == "TH")
3699
+ {
3700
  /* Get the col and rowspan attributes from the DOM and sanitise them */
3701
  iColspan = nCell.getAttribute('colspan') * 1;
3702
  iRowspan = nCell.getAttribute('rowspan') * 1;
3703
  iColspan = (!iColspan || iColspan === 0 || iColspan === 1) ? 1 : iColspan;
3704
  iRowspan = (!iRowspan || iRowspan === 0 || iRowspan === 1) ? 1 : iRowspan;
3705
 
3706
+ /* There might be colspan cells already in this row, so shift our target
3707
+ * accordingly
3708
+ */
3709
  iColShifted = fnShiftCol(aLayout, i, iColumn);
3710
 
3711
+ /* Cache calculation for unique columns */
3712
  bUnique = iColspan === 1 ? true : false;
3713
 
3714
+ /* If there is col / rowspan, copy the information into the layout grid */
3715
+ for (l = 0; l < iColspan; l++)
3716
+ {
3717
+ for (k = 0; k < iRowspan; k++)
3718
+ {
3719
  aLayout[i + k][iColShifted + l] = {
3720
  "cell": nCell,
3721
  "unique": bUnique
3729
  }
3730
  }
3731
 
3732
+
3733
+ /**
3734
+ * Get an array of unique th elements, one for each column
3735
+ * @param {object} oSettings dataTables settings object
3736
+ * @param {node} nHeader automatically detect the layout from this node - optional
3737
+ * @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
3738
+ * @returns array {node} aReturn list of unique th's
3739
+ * @memberof DataTable#oApi
3740
+ */
3741
+ function _fnGetUniqueThs(oSettings, nHeader, aLayout)
3742
+ {
3743
  var aReturn = [];
3744
+ if (!aLayout)
3745
+ {
3746
  aLayout = oSettings.aoHeader;
3747
+ if (nHeader)
3748
+ {
3749
  aLayout = [];
3750
  _fnDetectHeader(aLayout, nHeader);
3751
  }
3752
  }
3753
 
3754
+ for (var i = 0, iLen = aLayout.length; i < iLen; i++)
3755
+ {
3756
+ for (var j = 0, jLen = aLayout[i].length; j < jLen; j++)
3757
+ {
3758
  if (aLayout[i][j].unique &&
3759
+ (!aReturn[j] || !oSettings.bSortCellsTop))
3760
+ {
3761
  aReturn[j] = aLayout[i][j].cell;
3762
  }
3763
  }
3766
  return aReturn;
3767
  }
3768
 
3769
+ /**
3770
+ * Create an Ajax call based on the table's settings, taking into account that
3771
+ * parameters can have multiple forms, and backwards compatibility.
3772
+ *
3773
+ * @param {object} oSettings dataTables settings object
3774
+ * @param {array} data Data to send to the server, required by
3775
+ * DataTables - may be augmented by developer callbacks
3776
+ * @param {function} fn Callback function to run when data is obtained
3777
+ */
3778
+ function _fnBuildAjax(oSettings, data, fn)
3779
+ {
3780
  // Compatibility with 1.9-, allow fnServerData and event to manipulate
3781
  _fnCallbackFire(oSettings, 'aoServerParams', 'serverParams', [data]);
3782
 
3783
+ // Convert to object based for 1.10+ if using the old array scheme which can
3784
+ // come from server-side processing or serverParams
3785
  if (data && $.isArray(data)) {
3786
  var tmp = {};
3787
  var rbracket = /(.*?)\[\]$/;
3793
  // Support for arrays
3794
  var name = match[0];
3795
 
3796
+ if (!tmp[ name ]) {
3797
+ tmp[ name ] = [];
3798
  }
3799
+ tmp[ name ].push(val.value);
3800
  } else {
3801
  tmp[val.name] = val.value;
3802
  }
3812
  fn(json);
3813
  };
3814
 
3815
+ if ($.isPlainObject(ajax) && ajax.data)
3816
+ {
3817
  ajaxData = ajax.data;
3818
 
3819
  var newData = $.isFunction(ajaxData) ?
3820
  ajaxData(data, oSettings) : // fn can manipulate data or return
3821
+ ajaxData; // an object object or array to merge
3822
 
3823
+ // If the function returned something, use that alone
3824
  data = $.isFunction(ajaxData) && newData ?
3825
  newData :
3826
  $.extend(true, data, newData);
3827
 
3828
+ // Remove the data property as we've resolved it already and don't want
3829
+ // jQuery to do it again (it is restored at the end of the function)
3830
  delete ajax.data;
3831
  }
3832
 
3859
  }
3860
  };
3861
 
3862
+ // Store the data submitted for the API
3863
  oSettings.oAjaxData = data;
3864
 
3865
+ // Allow plug-ins and external processes to modify the data
3866
  _fnCallbackFire(oSettings, null, 'preXhr', [oSettings, data]);
3867
 
3868
+ if (oSettings.fnServerData)
3869
+ {
3870
+ // DataTables 1.9- compatibility
3871
  oSettings.fnServerData.call(instance,
3872
  oSettings.sAjaxSource,
3873
  $.map(data, function (val, key) { // Need to convert back to 1.9 trad format
3874
+ return {name: key, value: val};
 
 
 
3875
  }),
3876
  callback,
3877
  oSettings
3878
  );
3879
+ } else if (oSettings.sAjaxSource || typeof ajax === 'string')
3880
+ {
3881
  // DataTables 1.9- compatibility
3882
  oSettings.jqXHR = $.ajax($.extend(baseAjax, {
3883
  url: ajax || oSettings.sAjaxSource
3884
  }));
3885
+ } else if ($.isFunction(ajax))
3886
+ {
3887
  // Is a function - let the caller define what needs to be done
3888
  oSettings.jqXHR = ajax.call(instance, data, callback, oSettings);
3889
+ } else
3890
+ {
3891
  // Object to extend the base settings
3892
  oSettings.jqXHR = $.ajax($.extend(baseAjax, ajax));
3893
 
3896
  }
3897
  }
3898
 
3899
+
3900
+ /**
3901
+ * Update the table using an Ajax call
3902
+ * @param {object} settings dataTables settings object
3903
+ * @returns {boolean} Block the table drawing or not
3904
+ * @memberof DataTable#oApi
3905
+ */
3906
+ function _fnAjaxUpdate(settings)
3907
+ {
3908
  if (settings.bAjaxDataGet) {
3909
  settings.iDraw++;
3910
  _fnProcessingDisplay(settings, true);
3922
  return true;
3923
  }
3924
 
3925
+
3926
+ /**
3927
+ * Build up the parameters in an object needed for a server-side processing
3928
+ * request. Note that this is basically done twice, is different ways - a modern
3929
+ * method which is used by default in DataTables 1.10 which uses objects and
3930
+ * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
3931
+ * the sAjaxSource option is used in the initialisation, or the legacyAjax
3932
+ * option is set.
3933
+ * @param {object} oSettings dataTables settings object
3934
+ * @returns {bool} block the table drawing or not
3935
+ * @memberof DataTable#oApi
3936
+ */
3937
+ function _fnAjaxParameters(settings)
3938
+ {
3939
  var
3940
  columns = settings.aoColumns,
3941
  columnCount = columns.length,
3942
  features = settings.oFeatures,
3943
  preSearch = settings.oPreviousSearch,
3944
  preColSearch = settings.aoPreSearchCols,
3945
+ i, data = [], dataProp, column, columnSearch,
 
3946
  sort = _fnSortFlatten(settings),
3947
  displayStart = settings._iDisplayStart,
3948
  displayLength = features.bPaginate !== false ?
3950
  -1;
3951
 
3952
  var param = function (name, value) {
3953
+ data.push({'name': name, 'value': value});
 
 
 
3954
  };
3955
 
3956
  // DataTables 1.9- compatible method
4009
 
4010
  if (features.bSort) {
4011
  $.each(sort, function (i, val) {
4012
+ d.order.push({column: val.col, dir: val.dir});
 
 
 
4013
 
4014
  param('iSortCol_' + i, val.col);
4015
  param('sSortDir_' + i, val.dir);
4018
  param('iSortingCols', sort.length);
4019
  }
4020
 
4021
+ // If the legacy.ajax parameter is null, then we automatically decide which
4022
+ // form to use, based on sAjaxSource
4023
  var legacy = DataTable.ext.legacy.ajax;
4024
  if (legacy === null) {
4025
  return settings.sAjaxSource ? data : d;
4026
  }
4027
 
4028
+ // Otherwise, if legacy has been specified then we use that to decide on the
4029
+ // form
4030
  return legacy ? data : d;
4031
  }
4032
 
 
4033
 
4034
+ /**
4035
+ * Data the data from the server (nuking the old) and redraw the table
4036
+ * @param {object} oSettings dataTables settings object
4037
+ * @param {object} json json data return from the server.
4038
+ * @param {string} json.sEcho Tracking flag for DataTables to match requests
4039
+ * @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
4040
+ * @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
4041
+ * @param {array} json.aaData The data to display on this page
4042
+ * @param {string} [json.sColumns] Column ordering (sName, comma separated)
4043
+ * @memberof DataTable#oApi
4044
+ */
4045
+ function _fnAjaxUpdateDraw(settings, json)
4046
+ {
4047
+ // v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
4048
+ // Support both
4049
  var compat = function (old, modern) {
4050
  return json[old] !== undefined ? json[old] : json[modern];
4051
  };
4083
  _fnProcessingDisplay(settings, false);
4084
  }
4085
 
4086
+
4087
+ /**
4088
+ * Get the data from the JSON data source to use for drawing a table. Using
4089
+ * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
4090
+ * source object, or from a processing function.
4091
+ * @param {object} oSettings dataTables settings object
4092
+ * @param {object} json Data source object / array from the server
4093
+ * @return {array} Array of data to use
4094
+ */
4095
+ function _fnAjaxDataSrc(oSettings, json)
4096
+ {
4097
  var dataSrc = $.isPlainObject(oSettings.ajax) && oSettings.ajax.dataSrc !== undefined ?
4098
  oSettings.ajax.dataSrc :
4099
  oSettings.sAjaxDataProp; // Compatibility with 1.9-.
4109
  json;
4110
  }
4111
 
4112
+ /**
4113
+ * Generate the node required for filtering text
4114
+ * @returns {node} Filter control element
4115
+ * @param {object} oSettings dataTables settings object
4116
+ * @memberof DataTable#oApi
4117
+ */
4118
+ function _fnFeatureHtmlFilter(settings)
4119
+ {
4120
  var classes = settings.oClasses;
4121
  var tableId = settings.sTableId;
4122
  var language = settings.oLanguage;
4164
  var jqFilter = $('input', filter)
4165
  .val(previousSearch.sSearch)
4166
  .attr('placeholder', language.sSearchPlaceholder)
4167
+ .on(
4168
  'keyup.DT search.DT input.DT paste.DT cut.DT',
4169
  searchDelay ?
4170
  _fnThrottle(searchFn, searchDelay) :
4171
  searchFn
4172
  )
4173
+ .on('keypress.DT', function (e) {
4174
  /* Prevent form submission */
4175
  if (e.keyCode == 13) {
4176
  return false;
4178
  })
4179
  .attr('aria-controls', tableId);
4180
 
4181
+ // Update the input elements whenever the table is filtered
4182
  $(settings.nTable).on('search.dt.DT', function (ev, s) {
4183
  if (settings === s) {
4184
  // IE9 throws an 'unknown error' if document.activeElement is used
4195
  return filter[0];
4196
  }
4197
 
4198
+
4199
+ /**
4200
+ * Filter the table using both the global filter and column based filtering
4201
+ * @param {object} oSettings dataTables settings object
4202
+ * @param {object} oSearch search information
4203
+ * @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
4204
+ * @memberof DataTable#oApi
4205
+ */
4206
+ function _fnFilterComplete(oSettings, oInput, iForce)
4207
+ {
4208
  var oPrevSearch = oSettings.oPreviousSearch;
4209
  var aoPrevSearch = oSettings.aoPreSearchCols;
4210
  var fnSaveFilter = function (oFilter) {
4219
  return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
4220
  };
4221
 
4222
+ // Resolve any column types that are unknown due to addition or invalidation
4223
+ // @todo As per sort - can this be moved into an event handler?
4224
  _fnColumnTypes(oSettings);
4225
+
4226
+ /* In server-side processing all filtering is done by the server, so no point hanging around here */
4227
+ if (_fnDataSource(oSettings) != 'ssp')
4228
+ {
4229
  /* Global filter */
4230
  _fnFilter(oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive);
4231
  fnSaveFilter(oInput);
4232
+
4233
+ /* Now do the individual column filter */
4234
+ for (var i = 0; i < aoPrevSearch.length; i++)
4235
+ {
4236
  _fnFilterColumn(oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
4237
  aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive);
4238
  }
4239
+
4240
+ /* Custom filtering */
4241
  _fnFilterCustom(oSettings);
4242
+ } else
4243
+ {
4244
  fnSaveFilter(oInput);
4245
  }
4246
+
4247
+ /* Tell the draw function we have been filtering */
4248
  oSettings.bFiltered = true;
4249
  _fnCallbackFire(oSettings, null, 'search', [oSettings]);
4250
  }
4251
 
4252
+
4253
+ /**
4254
+ * Apply custom filtering functions
4255
+ * @param {object} oSettings dataTables settings object
4256
+ * @memberof DataTable#oApi
4257
+ */
4258
+ function _fnFilterCustom(settings)
4259
+ {
4260
  var filters = DataTable.ext.search;
4261
  var displayRows = settings.aiDisplay;
4262
  var row, rowIdx;
4264
  for (var i = 0, ien = filters.length; i < ien; i++) {
4265
  var rows = [];
4266
 
4267
+ // Loop over each row and see if it should be included
4268
  for (var j = 0, jen = displayRows.length; j < jen; j++) {
4269
+ rowIdx = displayRows[ j ];
4270
+ row = settings.aoData[ rowIdx ];
4271
 
4272
  if (filters[i](settings, row._aFilterData, rowIdx, row._aData, j)) {
4273
  rows.push(rowIdx);
4274
  }
4275
  }
4276
 
4277
+ // So the array reference doesn't break set the results into the
4278
+ // existing array
4279
  displayRows.length = 0;
4280
  $.merge(displayRows, rows);
4281
  }
4282
  }
4283
 
4284
+
4285
+ /**
4286
+ * Filter the table on a per-column basis
4287
+ * @param {object} oSettings dataTables settings object
4288
+ * @param {string} sInput string to filter on
4289
+ * @param {int} iColumn column to filter
4290
+ * @param {bool} bRegex treat search string as a regular expression or not
4291
+ * @param {bool} bSmart use smart filtering or not
4292
+ * @param {bool} bCaseInsensitive Do case insenstive matching or not
4293
+ * @memberof DataTable#oApi
4294
+ */
4295
+ function _fnFilterColumn(settings, searchStr, colIdx, regex, smart, caseInsensitive)
4296
+ {
4297
  if (searchStr === '') {
4298
  return;
4299
  }
4300
 
4301
  var data;
4302
+ var out = [];
4303
  var display = settings.aiDisplay;
4304
  var rpSearch = _fnFilterCreateSearch(searchStr, regex, smart, caseInsensitive);
4305
 
4306
+ for (var i = 0; i < display.length; i++) {
4307
+ data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
4308
 
4309
+ if (rpSearch.test(data)) {
4310
+ out.push(display[i]);
4311
  }
4312
  }
4313
+
4314
+ settings.aiDisplay = out;
4315
  }
4316
 
4317
+
4318
+ /**
4319
+ * Filter the data table based on user input and draw the table
4320
+ * @param {object} settings dataTables settings object
4321
+ * @param {string} input string to filter on
4322
+ * @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
4323
+ * @param {bool} regex treat as a regular expression or not
4324
+ * @param {bool} smart perform smart filtering or not
4325
+ * @param {bool} caseInsensitive Do case insenstive matching or not
4326
+ * @memberof DataTable#oApi
4327
+ */
4328
+ function _fnFilter(settings, input, force, regex, smart, caseInsensitive)
4329
+ {
4330
  var rpSearch = _fnFilterCreateSearch(input, regex, smart, caseInsensitive);
4331
  var prevSearch = settings.oPreviousSearch.sSearch;
4332
  var displayMaster = settings.aiDisplayMaster;
4333
  var display, invalidated, i;
4334
+ var filtered = [];
4335
 
4336
  // Need to take account of custom filtering functions - always filter
4337
  if (DataTable.ext.search.length !== 0) {
4359
  // Search the display array
4360
  display = settings.aiDisplay;
4361
 
4362
+ for (i = 0; i < display.length; i++) {
4363
+ if (rpSearch.test(settings.aoData[ display[i] ]._sFilterRow)) {
4364
+ filtered.push(display[i]);
4365
  }
4366
  }
4367
+
4368
+ settings.aiDisplay = filtered;
4369
  }
4370
  }
4371
 
4372
+
4373
+ /**
4374
+ * Build a regular expression object suitable for searching a table
4375
+ * @param {string} sSearch string to search for
4376
+ * @param {bool} bRegex treat as a regular expression or not
4377
+ * @param {bool} bSmart perform smart filtering or not
4378
+ * @param {bool} bCaseInsensitive Do case insensitive matching or not
4379
+ * @returns {RegExp} constructed object
4380
+ * @memberof DataTable#oApi
4381
+ */
4382
+ function _fnFilterCreateSearch(search, regex, smart, caseInsensitive)
4383
+ {
4384
  search = regex ?
4385
  search :
4386
  _fnEscapeRegex(search);
4387
 
4388
  if (smart) {
4389
+ /* For smart filtering we want to allow the search to work regardless of
4390
+ * word order. We also want double quoted text to be preserved, so word
4391
+ * order is important - a la google. So this is what we want to
4392
+ * generate:
4393
+ *
4394
+ * ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
4395
+ */
4396
  var a = $.map(search.match(/"[^"]+"|[^ ]+/g) || [''], function (word) {
4397
  if (word.charAt(0) === '"') {
4398
  var m = word.match(/^"(.*)"$/);
4408
  return new RegExp(search, caseInsensitive ? 'i' : '');
4409
  }
4410
 
4411
+
4412
+ /**
4413
+ * Escape a string such that it can be used in a regular expression
4414
+ * @param {string} sVal string to escape
4415
+ * @returns {string} escaped string
4416
+ * @memberof DataTable#oApi
4417
+ */
4418
  var _fnEscapeRegex = DataTable.util.escapeRegex;
4419
 
4420
  var __filter_div = $('<div>')[0];
4421
  var __filter_div_textContent = __filter_div.textContent !== undefined;
4422
 
4423
  // Update the filtering data for each row if needed (by invalidation or first run)
4424
+ function _fnFilterData(settings)
4425
+ {
4426
  var columns = settings.aoColumns;
4427
  var column;
4428
  var i, j, ien, jen, filterData, cellData, row;
4441
  if (column.bSearchable) {
4442
  cellData = _fnGetCellData(settings, i, j, 'filter');
4443
 
4444
+ if (fomatters[ column.sType ]) {
4445
+ cellData = fomatters[ column.sType ](cellData);
4446
  }
4447
 
4448
+ // Search in DataTables 1.10 is string based. In 1.11 this
4449
+ // should be altered to also allow strict type checking.
4450
  if (cellData === null) {
4451
  cellData = '';
4452
  }
4458
  cellData = '';
4459
  }
4460
 
4461
+ // If it looks like there is an HTML entity in the string,
4462
+ // attempt to decode it so sorting works as expected. Note that
4463
+ // we could use a single line of jQuery to do this, but the DOM
4464
+ // method used here is much faster http://jsperf.com/html-decode
4465
  if (cellData.indexOf && cellData.indexOf('&') !== -1) {
4466
  __filter_div.innerHTML = cellData;
4467
  cellData = __filter_div_textContent ?
4485
  return wasInvalidated;
4486
  }
4487
 
4488
+
4489
+ /**
4490
+ * Convert from the internal Hungarian notation to camelCase for external
4491
+ * interaction
4492
+ * @param {object} obj Object to convert
4493
+ * @returns {object} Inverted object
4494
+ * @memberof DataTable#oApi
4495
+ */
4496
+ function _fnSearchToCamel(obj)
4497
+ {
4498
  return {
4499
  search: obj.sSearch,
4500
  smart: obj.bSmart,
4503
  };
4504
  }
4505
 
4506
+
4507
+
4508
+ /**
4509
+ * Convert from camelCase notation to the internal Hungarian. We could use the
4510
+ * Hungarian convert function here, but this is cleaner
4511
+ * @param {object} obj Object to convert
4512
+ * @returns {object} Inverted object
4513
+ * @memberof DataTable#oApi
4514
+ */
4515
+ function _fnSearchToHung(obj)
4516
+ {
4517
  return {
4518
  sSearch: obj.search,
4519
  bSmart: obj.smart,
4522
  };
4523
  }
4524
 
4525
+ /**
4526
+ * Generate the node required for the info display
4527
+ * @param {object} oSettings dataTables settings object
4528
+ * @returns {node} Information element
4529
+ * @memberof DataTable#oApi
4530
+ */
4531
+ function _fnFeatureHtmlInfo(settings)
4532
+ {
4533
  var
4534
  tid = settings.sTableId,
4535
  nodes = settings.aanFeatures.i,
4556
  return n[0];
4557
  }
4558
 
4559
+
4560
+ /**
4561
+ * Update the information elements in the display
4562
+ * @param {object} settings dataTables settings object
4563
+ * @memberof DataTable#oApi
4564
+ */
4565
+ function _fnUpdateInfo(settings)
4566
+ {
4567
  /* Show information about the table */
4568
  var nodes = settings.aanFeatures.i;
4569
  if (nodes.length === 0) {
4599
  $(nodes).html(out);
4600
  }
4601
 
 
4602
 
4603
+ function _fnInfoMacros(settings, str)
4604
+ {
4605
+ // When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
4606
+ // internally
4607
  var
4608
  formatter = settings.fnFormatNumber,
4609
  start = settings._iDisplayStart + 1,
4620
  replace(/_PAGES_/g, formatter.call(settings, all ? 1 : Math.ceil(vis / len)));
4621
  }
4622
 
4623
+
4624
+
4625
+ /**
4626
+ * Draw the table for the first time, adding all required features
4627
+ * @param {object} settings dataTables settings object
4628
+ * @memberof DataTable#oApi
4629
+ */
4630
+ function _fnInitialise(settings)
4631
+ {
4632
  var i, iLen, iAjaxStart = settings.iInitDisplayStart;
4633
+ var columns = settings.aoColumns, column;
 
4634
  var features = settings.oFeatures;
4635
  var deferLoading = settings.bDeferLoading; // value modified by the draw
4636
 
4668
 
4669
  _fnCallbackFire(settings, null, 'preInit', [settings]);
4670
 
4671
+ // If there is default sorting required - let's do it. The sort function
4672
+ // will do the drawing for us. Otherwise we draw the table regardless of the
4673
+ // Ajax source - this allows the table to look initialised for Ajax sourcing
4674
+ // data (show 'loading' message possibly)
4675
  _fnReDraw(settings);
4676
 
4677
  // Server-side processing init complete is done by _fnAjaxUpdateDraw
4687
  _fnAddData(settings, aData[i]);
4688
  }
4689
 
4690
+ // Reset the init display for cookie saving. We've already done
4691
+ // a filter, and therefore cleared it before. So we need to make
4692
+ // it appear 'fresh'
4693
  settings.iInitDisplayStart = iAjaxStart;
4694
 
4695
  _fnReDraw(settings);
4704
  }
4705
  }
4706
 
4707
+
4708
+ /**
4709
+ * Draw the table for the first time, adding all required features
4710
+ * @param {object} oSettings dataTables settings object
4711
+ * @param {object} [json] JSON from the server that completed the table, if using Ajax source
4712
+ * with client-side processing (optional)
4713
+ * @memberof DataTable#oApi
4714
+ */
4715
+ function _fnInitComplete(settings, json)
4716
+ {
4717
  settings._bInitComplete = true;
4718
 
4719
+ // When data was added after the initialisation (data or Ajax) we need to
4720
+ // calculate the column sizing
4721
  if (json || settings.oInit.aaData) {
4722
  _fnAdjustColumnSizing(settings);
4723
  }
4726
  _fnCallbackFire(settings, 'aoInitComplete', 'init', [settings, json]);
4727
  }
4728
 
4729
+
4730
+ function _fnLengthChange(settings, val)
4731
+ {
4732
  var len = parseInt(val, 10);
4733
  settings._iDisplayLength = len;
4734
 
4735
  _fnLengthOverflow(settings);
4736
 
4737
+ // Fire length change event
4738
  _fnCallbackFire(settings, null, 'length', [settings, len]);
4739
  }
4740
 
4741
+
4742
+ /**
4743
+ * Generate the node required for user display length changing
4744
+ * @param {object} settings dataTables settings object
4745
+ * @returns {node} Display length feature node
4746
+ * @memberof DataTable#oApi
4747
+ */
4748
+ function _fnFeatureHtmlLength(settings)
4749
+ {
4750
  var
4751
  classes = settings.oClasses,
4752
  tableId = settings.sTableId,
4762
  });
4763
 
4764
  for (var i = 0, ien = lengths.length; i < ien; i++) {
4765
+ select[0][ i ] = new Option(language[i], lengths[i]);
4766
  }
4767
 
4768
  var div = $('<div><label/></div>').addClass(classes.sLength);
4774
  settings.oLanguage.sLengthMenu.replace('_MENU_', select[0].outerHTML)
4775
  );
4776
 
4777
+ // Can't use `select` variable as user might provide their own and the
4778
+ // reference is broken by the use of outerHTML
4779
  $('select', div)
4780
  .val(settings._iDisplayLength)
4781
+ .on('change.DT', function (e) {
4782
  _fnLengthChange(settings, $(this).val());
4783
  _fnDraw(settings);
4784
  });
4785
 
4786
  // Update node value whenever anything changes the table's length
4787
+ $(settings.nTable).on('length.dt.DT', function (e, s, len) {
4788
  if (settings === s) {
4789
  $('select', div).val(len);
4790
  }
4793
  return div[0];
4794
  }
4795
 
4796
+
4797
+
4798
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
4799
+ * Note that most of the paging logic is done in
4800
+ * DataTable.ext.pager
4801
+ */
4802
+
4803
+ /**
4804
+ * Generate the node required for default pagination
4805
+ * @param {object} oSettings dataTables settings object
4806
+ * @returns {node} Pagination feature node
4807
+ * @memberof DataTable#oApi
4808
+ */
4809
+ function _fnFeatureHtmlPaginate(settings)
4810
+ {
4811
  var
4812
  type = settings.sPaginationType,
4813
+ plugin = DataTable.ext.pager[ type ],
4814
  modern = typeof plugin === 'function',
4815
  redraw = function (settings) {
4816
  _fnDraw(settings);
4823
  }
4824
 
4825
  /* Add a draw callback for the pagination on first instance, to update the paging display */
4826
+ if (!features.p)
4827
+ {
4828
  node.id = settings.sTableId + '_paginate';
4829
 
4830
  settings.aoDrawCallback.push({
4856
  return node;
4857
  }
4858
 
4859
+
4860
+ /**
4861
+ * Alter the display settings to change the page
4862
+ * @param {object} settings DataTables settings object
4863
+ * @param {string|int} action Paging action to take: "first", "previous",
4864
+ * "next" or "last" or page number to jump to (integer)
4865
+ * @param [bool] redraw Automatically draw the update or not
4866
+ * @returns {bool} true page has changed, false - no change
4867
+ * @memberof DataTable#oApi
4868
+ */
4869
+ function _fnPageChange(settings, action, redraw)
4870
+ {
4871
  var
4872
  start = settings._iDisplayStart,
4873
  len = settings._iDisplayLength,
4874
  records = settings.fnRecordsDisplay();
4875
 
4876
+ if (records === 0 || len === -1)
4877
+ {
4878
  start = 0;
4879
+ } else if (typeof action === "number")
4880
+ {
4881
  start = action * len;
4882
 
4883
+ if (start > records)
4884
+ {
4885
  start = 0;
4886
  }
4887
+ } else if (action == "first")
4888
+ {
4889
  start = 0;
4890
+ } else if (action == "previous")
4891
+ {
4892
  start = len >= 0 ?
4893
  start - len :
4894
  0;
4895
 
4896
+ if (start < 0)
4897
+ {
4898
  start = 0;
4899
  }
4900
+ } else if (action == "next")
4901
+ {
4902
+ if (start + len < records)
4903
+ {
4904
  start += len;
4905
  }
4906
+ } else if (action == "last")
4907
+ {
4908
  start = Math.floor((records - 1) / len) * len;
4909
+ } else
4910
+ {
4911
  _fnLog(settings, 0, "Unknown paging action: " + action, 5);
4912
  }
4913
 
4925
  return changed;
4926
  }
4927
 
4928
+
4929
+
4930
+ /**
4931
+ * Generate the node required for the processing node
4932
+ * @param {object} settings dataTables settings object
4933
+ * @returns {node} Processing element
4934
+ * @memberof DataTable#oApi
4935
+ */
4936
+ function _fnFeatureHtmlProcessing(settings)
4937
+ {
4938
  return $('<div/>', {
4939
  'id': !settings.aanFeatures.r ? settings.sTableId + '_processing' : null,
4940
  'class': settings.oClasses.sProcessing
4943
  .insertBefore(settings.nTable)[0];
4944
  }
4945
 
4946
+
4947
+ /**
4948
+ * Display or hide the processing indicator
4949
+ * @param {object} settings dataTables settings object
4950
+ * @param {bool} show Show the processing indicator (true) or not (false)
4951
+ * @memberof DataTable#oApi
4952
+ */
4953
+ function _fnProcessingDisplay(settings, show)
4954
+ {
4955
  if (settings.oFeatures.bProcessing) {
4956
  $(settings.aanFeatures.r).css('display', show ? 'block' : 'none');
4957
  }
4959
  _fnCallbackFire(settings, null, 'processing', [settings, show]);
4960
  }
4961
 
4962
+ /**
4963
+ * Add any control elements for the table - specifically scrolling
4964
+ * @param {object} settings dataTables settings object
4965
+ * @returns {node} Node to add to the DOM
4966
+ * @memberof DataTable#oApi
4967
+ */
4968
+ function _fnFeatureHtmlTable(settings)
4969
+ {
4970
  var table = $(settings.nTable);
4971
 
4972
  // Add the ARIA grid role to the table
4996
  footer = null;
4997
  }
4998
 
4999
+ /*
5000
+ * The HTML structure that we want to generate in this function is:
5001
+ * div - scroller
5002
+ * div - scroll head
5003
+ * div - scroll head inner
5004
+ * table - scroll head table
5005
+ * thead - thead
5006
+ * div - scroll body
5007
+ * table - table (master table)
5008
+ * thead - thead clone for sizing
5009
+ * tbody - tbody
5010
+ * div - scroll foot
5011
+ * div - scroll foot inner
5012
+ * table - scroll foot table
5013
+ * tfoot - tfoot
5014
+ */
5015
+ var scroller = $(_div, {'class': classes.sScrollWrapper})
5016
  .append(
5017
+ $(_div, {'class': classes.sScrollHead})
 
 
5018
  .css({
5019
  overflow: 'hidden',
5020
  position: 'relative',
5022
  width: scrollX ? size(scrollX) : '100%'
5023
  })
5024
  .append(
5025
+ $(_div, {'class': classes.sScrollHeadInner})
 
 
5026
  .css({
5027
  'box-sizing': 'content-box',
5028
  width: scroll.sXInner || '100%'
5039
  )
5040
  )
5041
  .append(
5042
+ $(_div, {'class': classes.sScrollBody})
 
 
5043
  .css({
5044
  position: 'relative',
5045
  overflow: 'auto',
5050
 
5051
  if (footer) {
5052
  scroller.append(
5053
+ $(_div, {'class': classes.sScrollFoot})
 
 
5054
  .css({
5055
  overflow: 'hidden',
5056
  border: 0,
5057
  width: scrollX ? size(scrollX) : '100%'
5058
  })
5059
  .append(
5060
+ $(_div, {'class': classes.sScrollFootInner})
 
 
5061
  .append(
5062
  footerClone
5063
  .removeAttr('id')
5107
  return scroller[0];
5108
  }
5109
 
5110
+
5111
+
5112
+ /**
5113
+ * Update the header, footer and body tables for resizing - i.e. column
5114
+ * alignment.
5115
+ *
5116
+ * Welcome to the most horrible function DataTables. The process that this
5117
+ * function follows is basically:
5118
+ * 1. Re-create the table inside the scrolling div
5119
+ * 2. Take live measurements from the DOM
5120
+ * 3. Apply the measurements to align the columns
5121
+ * 4. Clean up
5122
+ *
5123
+ * @param {object} settings dataTables settings object
5124
+ * @memberof DataTable#oApi
5125
+ */
5126
+ function _fnScrollDraw(settings)
5127
+ {
5128
  // Given that this is such a monster function, a lot of variables are use
5129
  // to try and keep the minimised size as small as possible
5130
  var
5155
  headerTrgEls, footerTrgEls,
5156
  headerSrcEls, footerSrcEls,
5157
  headerCopy, footerCopy,
5158
+ headerWidths = [], footerWidths = [],
5159
+ headerContent = [], footerContent = [],
 
 
5160
  idx, correction, sanityWidth,
5161
  zeroOut = function (nSizer) {
5162
  var style = nSizer.style;
5167
  style.height = 0;
5168
  };
5169
 
5170
+ // If the scrollbar visibility has changed from the last draw, we need to
5171
+ // adjust the column sizes as the table width will have changed to account
5172
+ // for the scrollbar
5173
  var scrollBarVis = divBodyEl.scrollHeight > divBodyEl.clientHeight;
5174
 
5175
  if (settings.scrollBarVis !== scrollBarVis && settings.scrollBarVis !== undefined) {
5180
  settings.scrollBarVis = scrollBarVis;
5181
  }
5182
 
5183
+ /*
5184
+ * 1. Re-create the table inside the scrolling div
5185
+ */
5186
+
5187
+ // Remove the old minimised thead and tfoot elements in the inner table
5188
  table.children('thead, tfoot').remove();
5189
 
5190
  if (footer) {
5193
  footerSrcEls = footerCopy.find('tr');
5194
  }
5195
 
5196
+ // Clone the current header and footer elements and then place it into the inner table
5197
  headerCopy = header.clone().prependTo(table);
5198
  headerTrgEls = header.find('tr'); // original header is in its own table
5199
  headerSrcEls = headerCopy.find('tr');
5200
  headerCopy.find('th, td').removeAttr('tabindex');
5201
 
5202
+
5203
+ /*
5204
+ * 2. Take live measurements from the DOM - do not alter the DOM itself!
5205
+ */
5206
+
5207
+ // Remove old sizing and apply the calculated column widths
5208
+ // Get the unique column headers in the newly created (cloned) header. We want to apply the
5209
+ // calculated sizes to this header
5210
+ if (!scrollX)
5211
+ {
5212
  divBodyStyle.width = '100%';
5213
  divHeader[0].style.width = '100%';
5214
  }
5230
  // No x scrolling
5231
  tableStyle.width = "100%";
5232
 
5233
+ // IE7 will make the width of the table when 100% include the scrollbar
5234
+ // - which is shouldn't. When there is a scrollbar we need to take this
5235
+ // into account.
5236
  if (ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
5237
+ divBody.css('overflow-y') == "scroll")
5238
+ ) {
5239
  tableStyle.width = _fnStringToCss(table.outerWidth() - barWidth);
5240
  }
5241
 
5249
  sanityWidth = table.outerWidth();
5250
  }
5251
 
5252
+ // Hidden header should have zero height, so remove padding and borders. Then
5253
+ // set the width based on the real headers
5254
+
5255
+ // Apply all styles in one pass
5256
  _fnApplyToChildren(zeroOut, headerSrcEls);
5257
 
5258
+ // Read all widths in next pass
5259
  _fnApplyToChildren(function (nSizer) {
5260
  headerContent.push(nSizer.innerHTML);
5261
  headerWidths.push(_fnStringToCss($(nSizer).css('width')));
5262
  }, headerSrcEls);
5263
 
5264
+ // Apply all widths in final pass
5265
  _fnApplyToChildren(function (nToSize, i) {
5266
+ // Only apply widths to the DataTables detected header cells - this
5267
+ // prevents complex headers from having contradictory sizes applied
5268
  if ($.inArray(nToSize, dtHeaderCells) !== -1) {
5269
  nToSize.style.width = headerWidths[i];
5270
  }
5272
 
5273
  $(headerSrcEls).height(0);
5274
 
5275
+ /* Same again with the footer if we have one */
5276
+ if (footer)
5277
+ {
5278
  _fnApplyToChildren(zeroOut, footerSrcEls);
5279
 
5280
  _fnApplyToChildren(function (nSizer) {
5289
  $(footerSrcEls).height(0);
5290
  }
5291
 
5292
+
5293
+ /*
5294
+ * 3. Apply the measurements
5295
+ */
5296
+
5297
+ // "Hide" the header and footer that we used for the sizing. We need to keep
5298
+ // the content of the cell so that the width applied to the header and body
5299
+ // both match, but we want to hide it completely. We want to also fix their
5300
+ // width to what they currently are
5301
  _fnApplyToChildren(function (nSizer, i) {
5302
  nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">' + headerContent[i] + '</div>';
5303
  nSizer.style.width = headerWidths[i];
5304
  }, headerSrcEls);
5305
 
5306
+ if (footer)
5307
+ {
5308
  _fnApplyToChildren(function (nSizer, i) {
5309
  nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">' + footerContent[i] + '</div>';
5310
  nSizer.style.width = footerWidths[i];
5311
  }, footerSrcEls);
5312
  }
5313
 
5314
+ // Sanity check that the table is of a sensible width. If not then we are going to get
5315
+ // misalignment - try to prevent this by not allowing the table to shrink below its min width
5316
+ if (table.outerWidth() < sanityWidth)
5317
+ {
5318
  // The min width depends upon if we have a vertical scrollbar visible or not */
5319
  correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
5320
  divBody.css('overflow-y') == "scroll")) ?
5323
 
5324
  // IE6/7 are a law unto themselves...
5325
  if (ie67 && (divBodyEl.scrollHeight >
5326
+ divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
5327
+ ) {
5328
  tableStyle.width = _fnStringToCss(correction - barWidth);
5329
  }
5330
 
5332
  if (scrollX === "" || scrollXInner !== "") {
5333
  _fnLog(settings, 1, 'Possible column misalignment', 6);
5334
  }
5335
+ } else
5336
+ {
5337
  correction = '100%';
5338
  }
5339
 
5340
+ // Apply to the container elements
5341
  divBodyStyle.width = _fnStringToCss(correction);
5342
  divHeaderStyle.width = _fnStringToCss(correction);
5343
 
5345
  settings.nScrollFoot.style.width = _fnStringToCss(correction);
5346
  }
5347
 
 
5348
 
5349
+ /*
5350
+ * 4. Clean up
5351
+ */
5352
+ if (!scrollY) {
5353
+ /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
5354
+ * the scrollbar height from the visible display, rather than adding it on. We need to
5355
+ * set the height in order to sort this. Don't want to do it in any other browsers.
5356
+ */
5357
  if (ie67) {
5358
  divBodyStyle.height = _fnStringToCss(tableEl.offsetHeight + barWidth);
5359
  }
5364
  divHeaderTable[0].style.width = _fnStringToCss(iOuterWidth);
5365
  divHeaderInnerStyle.width = _fnStringToCss(iOuterWidth);
5366
 
5367
+ // Figure out if there are scrollbar present - if so then we need a the header and footer to
5368
+ // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
5369
  var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
5370
  var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right');
5371
+ divHeaderInnerStyle[ padding ] = bScrolling ? barWidth + "px" : "0px";
5372
 
5373
  if (footer) {
5374
  divFooterTable[0].style.width = _fnStringToCss(iOuterWidth);
5376
  divFooterInner[0].style[padding] = bScrolling ? barWidth + "px" : "0px";
5377
  }
5378
 
5379
+ // Correct DOM ordering for colgroup - comes before the thead
5380
  table.children('colgroup').insertBefore(table.children('thead'));
5381
 
5382
+ /* Adjust the position of the header in case we loose the y-scrollbar */
5383
  divBody.scroll();
5384
 
5385
+ // If sorting or filtering has occurred, jump the scrolling back to the top
5386
+ // only if we aren't holding the position
5387
  if ((settings.bSorted || settings.bFiltered) && !settings._drawHold) {
5388
  divBodyEl.scrollTop = 0;
5389
  }
5390
  }
5391
 
5392
+
5393
+
5394
+ /**
5395
+ * Apply a given function to the display child nodes of an element array (typically
5396
+ * TD children of TR rows
5397
+ * @param {function} fn Method to apply to the objects
5398
+ * @param array {nodes} an1 List of elements to look through for display children
5399
+ * @param array {nodes} an2 Another list (identical structure to the first) - optional
5400
+ * @memberof DataTable#oApi
5401
+ */
5402
+ function _fnApplyToChildren(fn, an1, an2)
5403
+ {
5404
+ var index = 0, i = 0, iLen = an1.length;
5405
  var nNode1, nNode2;
5406
 
5407
  while (i < iLen) {
5426
  i++;
5427
  }
5428
  }
 
5429
 
5430
+
5431
+
5432
+ var __re_html_remove = /<.*?>/g;
5433
+
5434
+
5435
+ /**
5436
+ * Calculate the width of columns for the table
5437
+ * @param {object} oSettings dataTables settings object
5438
+ * @memberof DataTable#oApi
5439
+ */
5440
+ function _fnCalculateColumnWidths(oSettings)
5441
+ {
5442
  var
5443
  table = oSettings.nTable,
5444
  columns = oSettings.aoColumns,
5461
  tableWidthAttr = styleWidth;
5462
  }
5463
 
5464
+ /* Convert any user input sizes into pixel sizes */
5465
  for (i = 0; i < visibleColumns.length; i++) {
5466
+ column = columns[ visibleColumns[i] ];
5467
 
5468
  if (column.sWidth !== null) {
5469
  column.sWidth = _fnConvertToWidth(column.sWidthOrig, tableContainer);
5472
  }
5473
  }
5474
 
5475
+ /* If the number of columns in the DOM equals the number that we have to
5476
+ * process in DataTables, then we can use the offsets that are created by
5477
+ * the web- browser. No custom sizes can be set in order for this to happen,
5478
+ * nor scrolling used
5479
+ */
5480
  if (ie67 || !userInputs && !scrollX && !scrollY &&
5481
  columnCount == _fnVisbleColumns(oSettings) &&
5482
  columnCount == headerCells.length
5485
  var colIdx = _fnVisibleToColumnIndex(oSettings, i);
5486
 
5487
  if (colIdx !== null) {
5488
+ columns[ colIdx ].sWidth = _fnStringToCss(headerCells.eq(i).width());
5489
  }
5490
  }
5491
+ } else
5492
+ {
5493
+ // Otherwise construct a single row, worst case, table with the widest
5494
+ // node in the data, assign any user defined widths, then insert it into
5495
+ // the DOM and allow the browser to do all the hard work of calculating
5496
+ // table widths
5497
  var tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table
5498
  .css('visibility', 'hidden')
5499
  .removeAttr('id');
5502
  tmpTable.find('tbody tr').remove();
5503
  var tr = $('<tr/>').appendTo(tmpTable.find('tbody'));
5504
 
5505
+ // Clone the table header and footer - we can't use the header / footer
5506
+ // from the cloned table, since if scrolling is active, the table's
5507
+ // real header and footer are contained in different table tags
5508
  tmpTable.find('thead, tfoot').remove();
5509
  tmpTable
5510
  .append($(oSettings.nTHead).clone())
5517
  headerCells = _fnGetUniqueThs(oSettings, tmpTable.find('thead')[0]);
5518
 
5519
  for (i = 0; i < visibleColumns.length; i++) {
5520
+ column = columns[ visibleColumns[i] ];
5521
 
5522
  headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
5523
  _fnStringToCss(column.sWidthOrig) :
5524
  '';
5525
 
5526
+ // For scrollX we need to force the column width otherwise the
5527
+ // browser will collapse it. If this width is smaller than the
5528
+ // width the column requires, then it will have no effect
5529
  if (column.sWidthOrig && scrollX) {
5530
  $(headerCells[i]).append($('<div/>').css({
5531
  width: column.sWidthOrig,
5537
  }
5538
  }
5539
 
5540
+ // Find the widest cell for each column and put it into the table
5541
  if (oSettings.aoData.length) {
5542
  for (i = 0; i < visibleColumns.length; i++) {
5543
  columnIdx = visibleColumns[i];
5544
+ column = columns[ columnIdx ];
5545
 
5546
  $(_fnGetWidestNode(oSettings, columnIdx))
5547
  .clone(false)
5550
  }
5551
  }
5552
 
5553
+ // Tidy the temporary table - remove name attributes so there aren't
5554
+ // duplicated in the dom (radio elements for example)
5555
  $('[name]', tmpTable).removeAttr('name');
5556
 
5557
+ // Table has been built, attach to the document so we can work with it.
5558
+ // A holding element is used, positioned at the top of the container
5559
+ // with minimal height, so it has no effect on if the container scrolls
5560
+ // or not. Otherwise it might trigger scrolling when it actually isn't
5561
+ // needed
5562
+ var holder = $('<div/>').css(scrollX || scrollY ?
5563
+ {
5564
+ position: 'absolute',
5565
+ top: 0,
5566
+ left: 0,
5567
+ height: 1,
5568
+ right: 0,
5569
+ overflow: 'hidden'
5570
+ } :
5571
+ {}
5572
+ )
5573
  .append(tmpTable)
5574
  .appendTo(tableContainer);
5575
 
5576
+ // When scrolling (X or Y) we want to set the width of the table as
5577
+ // appropriate. However, when not scrolling leave the table width as it
5578
+ // is. This results in slightly different, but I think correct behaviour
5579
  if (scrollX && scrollXInner) {
5580
  tmpTable.width(scrollXInner);
5581
  } else if (scrollX) {
5593
  tmpTable.width(tableWidthAttr);
5594
  }
5595
 
5596
+ // Get the width of each column in the constructed table - we need to
5597
+ // know the inner width (so it can be assigned to the other table's
5598
+ // cells) and the outer width so we can calculate the full width of the
5599
+ // table. This is safe since DataTables requires a unique cell for each
5600
+ // column, but if ever a header can span multiple columns, this will
5601
+ // need to be modified.
5602
  var total = 0;
5603
  for (i = 0; i < visibleColumns.length; i++) {
5604
  var cell = $(headerCells[i]);
5605
  var border = cell.outerWidth() - cell.width();
5606
 
5607
+ // Use getBounding... where possible (not IE8-) because it can give
5608
+ // sub-pixel accuracy, which we then want to round up!
5609
  var bounding = browser.bBounding ?
5610
  Math.ceil(headerCells[i].getBoundingClientRect().width) :
5611
  cell.outerWidth();
5612
 
5613
+ // Total is tracked to remove any sub-pixel errors as the outerWidth
5614
+ // of the table might not equal the total given here (IE!).
5615
  total += bounding;
5616
 
5617
+ // Width for each column to use
5618
+ columns[ visibleColumns[i] ].sWidth = _fnStringToCss(bounding - border);
5619
  }
5620
 
5621
  table.style.width = _fnStringToCss(total);
5622
 
5623
+ // Finished with the table - ditch it
5624
  holder.remove();
5625
  }
5626
 
5627
+ // If there is a width attr, we want to attach an event listener which
5628
+ // allows the table sizing to automatically adjust when the window is
5629
+ // resized. Use the width attr rather than CSS, since we can't know if the
5630
+ // CSS is a relative value or absolute - DOM read is always px.
5631
  if (tableWidthAttr) {
5632
  table.style.width = _fnStringToCss(tableWidthAttr);
5633
  }
5634
 
5635
  if ((tableWidthAttr || scrollX) && !oSettings._reszEvt) {
5636
  var bindResize = function () {
5637
+ $(window).on('resize.DT-' + oSettings.sInstance, _fnThrottle(function () {
5638
  _fnAdjustColumnSizing(oSettings);
5639
  }));
5640
  };
5641
 
5642
+ // IE6/7 will crash if we bind a resize event handler on page load.
5643
+ // To be removed in 1.11 which drops IE6/7 support
5644
  if (ie67) {
5645
  setTimeout(bindResize, 1000);
5646
  } else {
5651
  }
5652
  }
5653
 
5654
+
5655
+ /**
5656
+ * Throttle the calls to a function. Arguments and context are maintained for
5657
+ * the throttled function
5658
+ * @param {function} fn Function to be called
5659
+ * @param {int} [freq=200] call frequency in mS
5660
+ * @returns {function} wrapped function
5661
+ * @memberof DataTable#oApi
5662
+ */
5663
  var _fnThrottle = DataTable.util.throttle;
5664
 
5665
+
5666
+ /**
5667
+ * Convert a CSS unit width to pixels (e.g. 2em)
5668
+ * @param {string} width width to be converted
5669
+ * @param {node} parent parent to get the with for (required for relative widths) - optional
5670
+ * @returns {int} width in pixels
5671
+ * @memberof DataTable#oApi
5672
+ */
5673
+ function _fnConvertToWidth(width, parent)
5674
+ {
5675
  if (!width) {
5676
  return 0;
5677
  }
5686
  return val;
5687
  }
5688
 
5689
+
5690
+ /**
5691
+ * Get the widest node
5692
+ * @param {object} settings dataTables settings object
5693
+ * @param {int} colIdx column of interest
5694
+ * @returns {node} widest table node
5695
+ * @memberof DataTable#oApi
5696
+ */
5697
+ function _fnGetWidestNode(settings, colIdx)
5698
+ {
5699
  var idx = _fnGetMaxLenString(settings, colIdx);
5700
  if (idx < 0) {
5701
  return null;
5702
  }
5703
 
5704
+ var data = settings.aoData[ idx ];
5705
  return !data.nTr ? // Might not have been created when deferred rendering
5706
  $('<td/>').html(_fnGetCellData(settings, idx, colIdx, 'display'))[0] :
5707
+ data.anCells[ colIdx ];
5708
  }
5709
 
5710
+
5711
+ /**
5712
+ * Get the maximum strlen for each data column
5713
+ * @param {object} settings dataTables settings object
5714
+ * @param {int} colIdx column of interest
5715
+ * @returns {string} max string length for each column
5716
+ * @memberof DataTable#oApi
5717
+ */
5718
+ function _fnGetMaxLenString(settings, colIdx)
5719
+ {
5720
+ var s, max = -1, maxIdx = -1;
5721
 
5722
  for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
5723
  s = _fnGetCellData(settings, i, colIdx, 'display') + '';
5733
  return maxIdx;
5734
  }
5735
 
5736
+
5737
+ /**
5738
+ * Append a CSS unit (only if required) to a string
5739
+ * @param {string} value to css-ify
5740
+ * @returns {string} value with css unit
5741
+ * @memberof DataTable#oApi
5742
+ */
5743
+ function _fnStringToCss(s)
5744
+ {
5745
  if (s === null) {
5746
  return '0px';
5747
  }
5751
  '0px' :
5752
  s + 'px';
5753
  }
5754
+
5755
  // Check it has a unit character already
5756
  return s.match(/\d$/) ?
5757
  s + 'px' :
5758
  s;
5759
  }
5760
 
5761
+
5762
+
5763
+ function _fnSortFlatten(settings)
5764
+ {
5765
  var
5766
  i, iLen, k, kLen,
5767
  aSort = [],
5780
  $.merge(nestedSort, a);
5781
  }
5782
  };
5783
+
5784
+ // Build the sort array, with pre-fix and post-fix options if they have been
5785
+ // specified
5786
  if ($.isArray(fixed)) {
5787
  add(fixed);
5788
  }
5790
  if (fixedObj && fixed.pre) {
5791
  add(fixed.pre);
5792
  }
5793
+
5794
  add(settings.aaSorting);
5795
+
5796
  if (fixedObj && fixed.post) {
5797
  add(fixed.post);
5798
  }
5799
+
5800
+ for (i = 0; i < nestedSort.length; i++)
5801
+ {
5802
  srcCol = nestedSort[i][0];
5803
+ aDataSort = aoColumns[ srcCol ].aDataSort;
5804
+
5805
+ for (k = 0, kLen = aDataSort.length; k < kLen; k++)
5806
+ {
5807
  iCol = aDataSort[k];
5808
+ sType = aoColumns[ iCol ].sType || 'string';
5809
 
5810
  if (nestedSort[i]._idx === undefined) {
5811
  nestedSort[i]._idx = $.inArray(nestedSort[i][1], aoColumns[iCol].asSorting);
5812
  }
5813
+
5814
  aSort.push({
5815
  src: srcCol,
5816
  col: iCol,
5817
  dir: nestedSort[i][1],
5818
  index: nestedSort[i]._idx,
5819
  type: sType,
5820
+ formatter: DataTable.ext.type.order[ sType + "-pre" ]
5821
  });
5822
  }
5823
  }
5825
  return aSort;
5826
  }
5827
 
5828
+ /**
5829
+ * Change the order of the table
5830
+ * @param {object} oSettings dataTables settings object
5831
+ * @memberof DataTable#oApi
5832
+ * @todo This really needs split up!
5833
+ */
5834
+ function _fnSort(oSettings)
5835
+ {
5836
  var
5837
  i, ien, iLen, j, jLen, k, kLen,
5838
  sDataType, nTh,
5846
  displayMaster = oSettings.aiDisplayMaster,
5847
  aSort;
5848
 
5849
+ // Resolve any column types that are unknown due to addition or invalidation
5850
+ // @todo Can this be moved into a 'data-ready' handler which is called when
5851
+ // data is going to be used in the table?
5852
  _fnColumnTypes(oSettings);
5853
 
5854
  aSort = _fnSortFlatten(oSettings);
5855
 
5856
  for (i = 0, ien = aSort.length; i < ien; i++) {
5857
  sortCol = aSort[i];
5858
+
5859
+ // Track if we can use the fast sort algorithm
5860
  if (sortCol.formatter) {
5861
  formatters++;
5862
  }
5863
+
5864
+ // Load the data needed for the sort, for each cell
5865
  _fnSortData(oSettings, sortCol.col);
5866
  }
 
5867
 
5868
+ /* No sorting required if server-side or no sorting array */
5869
+ if (_fnDataSource(oSettings) != 'ssp' && aSort.length !== 0)
5870
+ {
5871
+ // Create a value - key array of the current row positions such that we can use their
5872
+ // current position during the sort, if values match, in order to perform stable sorting
5873
  for (i = 0, iLen = displayMaster.length; i < iLen; i++) {
5874
+ aiOrig[ displayMaster[i] ] = i;
5875
+ }
5876
+
5877
+ /* Do the sort - here we want multi-column sorting based on a given data source (column)
5878
+ * and sorting function (from oSort) in a certain direction. It's reasonably complex to
5879
+ * follow on it's own, but this is what we want (example two column sorting):
5880
+ * fnLocalSorting = function(a,b){
5881
+ * var iTest;
5882
+ * iTest = oSort['string-asc']('data11', 'data12');
5883
+ * if (iTest !== 0)
5884
+ * return iTest;
5885
+ * iTest = oSort['numeric-desc']('data21', 'data22');
5886
+ * if (iTest !== 0)
5887
+ * return iTest;
5888
+ * return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
5889
+ * }
5890
+ * Basically we have a test for each sorting column, if the data in that column is equal,
5891
+ * test the next column. If all columns match, then we use a numeric sort on the row
5892
+ * positions in the original data array to provide a stable sort.
5893
+ *
5894
+ * Note - I know it seems excessive to have two sorting methods, but the first is around
5895
+ * 15% faster, so the second is only maintained for backwards compatibility with sorting
5896
+ * methods which do not have a pre-sort formatting function.
5897
+ */
5898
  if (formatters === aSort.length) {
5899
  // All sort types have formatting functions
5900
  displayMaster.sort(function (a, b) {
5903
  len = aSort.length,
5904
  dataA = aoData[a]._aSortData,
5905
  dataB = aoData[b]._aSortData;
5906
+
5907
  for (k = 0; k < len; k++) {
5908
  sort = aSort[k];
5909
+
5910
+ x = dataA[ sort.col ];
5911
+ y = dataB[ sort.col ];
5912
+
5913
  test = x < y ? -1 : x > y ? 1 : 0;
5914
  if (test !== 0) {
5915
  return sort.dir === 'asc' ? test : -test;
5921
  return x < y ? -1 : x > y ? 1 : 0;
5922
  });
5923
  } else {
5924
+ // Depreciated - remove in 1.11 (providing a plug-in option)
5925
+ // Not all sort types have formatting methods, so we have to call their sorting
5926
+ // methods.
5927
  displayMaster.sort(function (a, b) {
5928
  var
5929
  x, y, k, l, test, sort, fn,
5934
  for (k = 0; k < len; k++) {
5935
  sort = aSort[k];
5936
 
5937
+ x = dataA[ sort.col ];
5938
+ y = dataB[ sort.col ];
5939
 
5940
+ fn = oExtSort[ sort.type + "-" + sort.dir ] || oExtSort[ "string-" + sort.dir ];
5941
  test = fn(x, y);
5942
  if (test !== 0) {
5943
  return test;
5951
  }
5952
  }
5953
 
5954
+ /* Tell the draw function that we have sorted the data */
5955
  oSettings.bSorted = true;
5956
  }
5957
 
5958
+
5959
+ function _fnSortAria(settings)
5960
+ {
5961
  var label;
5962
  var nextSort;
5963
  var columns = settings.aoColumns;
5964
  var aSort = _fnSortFlatten(settings);
5965
  var oAria = settings.oLanguage.oAria;
5966
 
5967
+ // ARIA attributes - need to loop all columns, to update all (removing old
5968
+ // attributes as needed)
5969
+ for (var i = 0, iLen = columns.length; i < iLen; i++)
5970
+ {
5971
  var col = columns[i];
5972
  var asSorting = col.asSorting;
5973
  var sTitle = col.sTitle.replace(/<.*?>/g, "");
5974
  var th = col.nTh;
5975
+
5976
+ // IE7 is throwing an error when setting these properties with jQuery's
5977
+ // attr() and removeAttr() methods...
5978
  th.removeAttribute('aria-sort');
5979
+
5980
+ /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
5981
  if (col.bSortable) {
5982
  if (aSort.length > 0 && aSort[0].col == i) {
5983
  th.setAttribute('aria-sort', aSort[0].dir == "asc" ? "ascending" : "descending");
5984
+ nextSort = asSorting[ aSort[0].index + 1 ] || asSorting[0];
5985
  } else {
5986
  nextSort = asSorting[0];
5987
  }
5998
  }
5999
  }
6000
 
6001
+
6002
+ /**
6003
+ * Function to run on user sort request
6004
+ * @param {object} settings dataTables settings object
6005
+ * @param {node} attachTo node to attach the handler to
6006
+ * @param {int} colIdx column sorting index
6007
+ * @param {boolean} [append=false] Append the requested sort to the existing
6008
+ * sort if true (i.e. multi-column sort)
6009
+ * @param {function} [callback] callback function
6010
+ * @memberof DataTable#oApi
6011
+ */
6012
+ function _fnSortListener(settings, colIdx, append, callback)
6013
+ {
6014
+ var col = settings.aoColumns[ colIdx ];
6015
  var sorting = settings.aaSorting;
6016
  var asSorting = col.asSorting;
6017
  var nextSortIdx;
6028
  0;
6029
  };
6030
 
6031
+ // Convert to 2D array if needed
6032
  if (typeof sorting[0] === 'number') {
6033
  sorting = settings.aaSorting = [sorting];
6034
  }
6049
  if (nextSortIdx === null) {
6050
  sorting.splice(sortIdx, 1);
6051
  } else {
6052
+ sorting[sortIdx][1] = asSorting[ nextSortIdx ];
6053
  sorting[sortIdx]._idx = nextSortIdx;
6054
  }
6055
  } else {
6062
  nextSortIdx = next(sorting[0]);
6063
 
6064
  sorting.length = 1;
6065
+ sorting[0][1] = asSorting[ nextSortIdx ];
6066
  sorting[0]._idx = nextSortIdx;
6067
  } else {
6068
  // Single column - sort only on this column
6080
  }
6081
  }
6082
 
6083
+
6084
+ /**
6085
+ * Attach a sort handler (click) to a node
6086
+ * @param {object} settings dataTables settings object
6087
+ * @param {node} attachTo node to attach the handler to
6088
+ * @param {int} colIdx column sorting index
6089
+ * @param {function} [callback] callback function
6090
+ * @memberof DataTable#oApi
6091
+ */
6092
+ function _fnSortAttachListener(settings, attachTo, colIdx, callback)
6093
+ {
6094
+ var col = settings.aoColumns[ colIdx ];
6095
 
6096
  _fnBindAction(attachTo, {}, function (e) {
6097
  /* If the column is not sortable - don't to anything */
6099
  return;
6100
  }
6101
 
6102
+ // If processing is enabled use a timeout to allow the processing
6103
+ // display to be shown - otherwise to it synchronously
6104
  if (settings.oFeatures.bProcessing) {
6105
  _fnProcessingDisplay(settings, true);
6106
 
6107
  setTimeout(function () {
6108
  _fnSortListener(settings, colIdx, e.shiftKey, callback);
6109
 
6110
+ // In server-side processing, the draw callback will remove the
6111
+ // processing display
6112
  if (_fnDataSource(settings) !== 'ssp') {
6113
  _fnProcessingDisplay(settings, false);
6114
  }
6119
  });
6120
  }
6121
 
6122
+
6123
+ /**
6124
+ * Set the sorting classes on table's body, Note: it is safe to call this function
6125
+ * when bSort and bSortClasses are false
6126
+ * @param {object} oSettings dataTables settings object
6127
+ * @memberof DataTable#oApi
6128
+ */
6129
+ function _fnSortingClasses(settings)
6130
+ {
6131
  var oldSort = settings.aLastSort;
6132
  var sortClass = settings.oClasses.sSortColumn;
6133
  var sort = _fnSortFlatten(settings);
6156
  settings.aLastSort = sort;
6157
  }
6158
 
6159
+
6160
+ // Get the data to sort a column, be it from cache, fresh (populating the
6161
+ // cache), or from a sort formatter
6162
+ function _fnSortData(settings, idx)
6163
+ {
6164
  // Custom sorting function - provided by the sort data type
6165
+ var column = settings.aoColumns[ idx ];
6166
+ var customSort = DataTable.ext.order[ column.sSortDataType ];
6167
  var customData;
6168
 
6169
  if (customSort) {
6174
 
6175
  // Use / populate cache
6176
  var row, cellData;
6177
+ var formatter = DataTable.ext.type.order[ column.sType + "-pre" ];
6178
 
6179
  for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
6180
  row = settings.aoData[i];
6188
  customData[i] : // If there was a custom sort function, use data from there
6189
  _fnGetCellData(settings, i, idx, 'sort');
6190
 
6191
+ row._aSortData[ idx ] = formatter ?
6192
  formatter(cellData) :
6193
  cellData;
6194
  }
6195
  }
6196
  }
6197
 
6198
+
6199
+
6200
+ /**
6201
+ * Save the state of a table
6202
+ * @param {object} oSettings dataTables settings object
6203
+ * @memberof DataTable#oApi
6204
+ */
6205
+ function _fnSaveState(settings)
6206
+ {
6207
+ if (!settings.oFeatures.bStateSave || settings.bDestroying)
6208
+ {
6209
  return;
6210
  }
6211
 
6212
+ /* Store the interesting variables */
6213
  var state = {
6214
  time: +new Date(),
6215
  start: settings._iDisplayStart,
6230
  settings.fnStateSaveCallback.call(settings.oInstance, settings, state);
6231
  }
6232
 
6233
+
6234
+ /**
6235
+ * Attempt to load a saved table state
6236
+ * @param {object} oSettings dataTables settings object
6237
+ * @param {object} oInit DataTables init object so we can override settings
6238
+ * @param {function} callback Callback to execute when the state has been loaded
6239
+ * @memberof DataTable#oApi
6240
+ */
6241
+ function _fnLoadState(settings, oInit, callback)
6242
+ {
6243
  var i, ien;
6244
  var columns = settings.aoColumns;
6245
+ var loaded = function (s) {
6246
+ if (!s || !s.time) {
6247
+ callback();
6248
+ return;
6249
+ }
6250
 
6251
+ // Allow custom and plug-in manipulation functions to alter the saved data set and
6252
+ // cancelling of loading by returning false
6253
+ var abStateLoad = _fnCallbackFire(settings, 'aoStateLoadParams', 'stateLoadParams', [settings, s]);
6254
+ if ($.inArray(false, abStateLoad) !== -1) {
6255
+ callback();
6256
+ return;
6257
+ }
6258
 
6259
+ // Reject old data
6260
+ var duration = settings.iStateDuration;
6261
+ if (duration > 0 && s.time < +new Date() - (duration * 1000)) {
6262
+ callback();
6263
+ return;
6264
+ }
 
 
 
 
 
 
 
 
 
6265
 
6266
+ // Number of columns have changed - all bets are off, no restore of settings
6267
+ if (s.columns && columns.length !== s.columns.length) {
6268
+ callback();
6269
+ return;
6270
+ }
6271
 
6272
+ // Store the saved state so it might be accessed at any time
6273
+ settings.oLoadedState = $.extend(true, {}, s);
 
 
 
 
 
6274
 
6275
+ // Restore key features - todo - for 1.11 this needs to be done by
6276
+ // subscribed events
6277
+ if (s.start !== undefined) {
6278
+ settings._iDisplayStart = s.start;
6279
+ settings.iInitDisplayStart = s.start;
6280
+ }
6281
+ if (s.length !== undefined) {
6282
+ settings._iDisplayLength = s.length;
6283
+ }
6284
 
6285
+ // Order
6286
+ if (s.order !== undefined) {
6287
+ settings.aaSorting = [];
6288
+ $.each(s.order, function (i, col) {
6289
+ settings.aaSorting.push(col[0] >= columns.length ?
6290
+ [0, col[1]] :
6291
+ col
6292
+ );
6293
+ });
6294
+ }
6295
 
6296
+ // Search
6297
+ if (s.search !== undefined) {
6298
+ $.extend(settings.oPreviousSearch, _fnSearchToHung(s.search));
 
6299
  }
6300
 
6301
+ // Columns
6302
+ //
6303
+ if (s.columns) {
6304
+ for (i = 0, ien = s.columns.length; i < ien; i++) {
6305
+ var col = s.columns[i];
6306
+
6307
+ // Visibility
6308
+ if (col.visible !== undefined) {
6309
+ columns[i].bVisible = col.visible;
6310
+ }
6311
+
6312
+ // Search
6313
+ if (col.search !== undefined) {
6314
+ $.extend(settings.aoPreSearchCols[i], _fnSearchToHung(col.search));
6315
+ }
6316
+ }
6317
  }
6318
+
6319
+ _fnCallbackFire(settings, 'aoStateLoaded', 'stateLoaded', [settings, s]);
6320
+ callback();
6321
+ }
6322
+
6323
+ if (!settings.oFeatures.bStateSave) {
6324
+ callback();
6325
+ return;
6326
  }
6327
 
6328
+ var state = settings.fnStateLoadCallback.call(settings.oInstance, settings, loaded);
6329
+
6330
+ if (state !== undefined) {
6331
+ loaded(state);
6332
+ }
6333
+ // otherwise, wait for the loaded callback to be executed
6334
  }
6335
 
6336
+
6337
+ /**
6338
+ * Return the settings object for a particular table
6339
+ * @param {node} table table we are using as a dataTable
6340
+ * @returns {object} Settings object - or null if not found
6341
+ * @memberof DataTable#oApi
6342
+ */
6343
+ function _fnSettingsFromNode(table)
6344
+ {
6345
  var settings = DataTable.settings;
6346
  var idx = $.inArray(table, _pluck(settings, 'nTable'));
6347
 
6348
  return idx !== -1 ?
6349
+ settings[ idx ] :
6350
  null;
6351
  }
6352
 
6353
+
6354
+ /**
6355
+ * Log an error message
6356
+ * @param {object} settings dataTables settings object
6357
+ * @param {int} level log error messages, or display them to the user
6358
+ * @param {string} msg error message
6359
+ * @param {int} tn Technical note id to get more information about the error.
6360
+ * @memberof DataTable#oApi
6361
+ */
6362
+ function _fnLog(settings, level, msg, tn)
6363
+ {
6364
  msg = 'DataTables warning: ' +
6365
  (settings ? 'table id=' + settings.sTableId + ' - ' : '') + msg;
6366
 
6390
  }
6391
  }
6392
 
6393
+
6394
+ /**
6395
+ * See if a property is defined on one object, if so assign it to the other object
6396
+ * @param {object} ret target object
6397
+ * @param {object} src source object
6398
+ * @param {string} name property
6399
+ * @param {string} [mappedName] name to map too - optional, name used if not given
6400
+ * @memberof DataTable#oApi
6401
+ */
6402
+ function _fnMap(ret, src, name, mappedName)
6403
+ {
6404
  if ($.isArray(name)) {
6405
  $.each(name, function (i, val) {
6406
  if ($.isArray(val)) {
6422
  }
6423
  }
6424
 
6425
+
6426
+ /**
6427
+ * Extend objects - very similar to jQuery.extend, but deep copy objects, and
6428
+ * shallow copy arrays. The reason we need to do this, is that we don't want to
6429
+ * deep copy array init values (such as aaSorting) since the dev wouldn't be
6430
+ * able to override them, but we do want to deep copy arrays.
6431
+ * @param {object} out Object to extend
6432
+ * @param {object} extender Object from which the properties will be applied to
6433
+ * out
6434
+ * @param {boolean} breakRefs If true, then arrays will be sliced to take an
6435
+ * independent copy with the exception of the `data` or `aaData` parameters
6436
+ * if they are present. This is so you can pass in a collection to
6437
+ * DataTables and have that used as your data source without breaking the
6438
+ * references
6439
+ * @returns {object} out Reference, just for convenience - out === the return.
6440
+ * @memberof DataTable#oApi
6441
+ * @todo This doesn't take account of arrays inside the deep copied objects.
6442
+ */
6443
+ function _fnExtend(out, extender, breakRefs)
6444
+ {
6445
  var val;
6446
 
6447
  for (var prop in extender) {
6464
  return out;
6465
  }
6466
 
6467
+
6468
+ /**
6469
+ * Bind an event handers to allow a click or return key to activate the callback.
6470
+ * This is good for accessibility since a return on the keyboard will have the
6471
+ * same effect as a click, if the element has focus.
6472
+ * @param {element} n Element to bind the action to
6473
+ * @param {object} oData Data object to pass to the triggered function
6474
+ * @param {function} fn Callback function for when the event is triggered
6475
+ * @memberof DataTable#oApi
6476
+ */
6477
+ function _fnBindAction(n, oData, fn)
6478
+ {
6479
  $(n)
6480
+ .on('click.DT', oData, function (e) {
6481
  n.blur(); // Remove focus outline for mouse users
6482
  fn(e);
6483
  })
6484
+ .on('keypress.DT', oData, function (e) {
6485
  if (e.which === 13) {
6486
  e.preventDefault();
6487
  fn(e);
6488
  }
6489
  })
6490
+ .on('selectstart.DT', function () {
6491
  /* Take the brutal approach to cancelling text selection */
6492
  return false;
6493
  });
6494
  }
6495
 
6496
+
6497
+ /**
6498
+ * Register a callback function. Easily allows a callback function to be added to
6499
+ * an array store of callback functions that can then all be called together.
6500
+ * @param {object} oSettings dataTables settings object
6501
+ * @param {string} sStore Name of the array storage for the callbacks in oSettings
6502
+ * @param {function} fn Function to be called back
6503
+ * @param {string} sName Identifying name for the callback (i.e. a label)
6504
+ * @memberof DataTable#oApi
6505
+ */
6506
+ function _fnCallbackReg(oSettings, sStore, fn, sName)
6507
+ {
6508
+ if (fn)
6509
+ {
6510
  oSettings[sStore].push({
6511
  "fn": fn,
6512
  "sName": sName
6514
  }
6515
  }
6516
 
6517
+
6518
+ /**
6519
+ * Fire callback functions and trigger events. Note that the loop over the
6520
+ * callback array store is done backwards! Further note that you do not want to
6521
+ * fire off triggers in time sensitive applications (for example cell creation)
6522
+ * as its slow.
6523
+ * @param {object} settings dataTables settings object
6524
+ * @param {string} callbackArr Name of the array storage for the callbacks in
6525
+ * oSettings
6526
+ * @param {string} eventName Name of the jQuery custom event to trigger. If
6527
+ * null no trigger is fired
6528
+ * @param {array} args Array of arguments to pass to the callback function /
6529
+ * trigger
6530
+ * @memberof DataTable#oApi
6531
+ */
6532
+ function _fnCallbackFire(settings, callbackArr, eventName, args)
6533
+ {
6534
  var ret = [];
6535
 
6536
  if (callbackArr) {
6550
  return ret;
6551
  }
6552
 
6553
+
6554
+ function _fnLengthOverflow(settings)
6555
+ {
6556
  var
6557
  start = settings._iDisplayStart,
6558
  end = settings.fnDisplayEnd(),
6559
  len = settings._iDisplayLength;
6560
 
6561
+ /* If we have space to show extra rows (backing up from the end point - then do so */
6562
+ if (start >= end)
6563
+ {
6564
  start = end - len;
6565
  }
6566
 
6567
+ // Keep the start record on the current page
6568
  start -= (start % len);
6569
 
6570
+ if (len === -1 || start < 0)
6571
+ {
6572
  start = 0;
6573
  }
6574
 
6575
  settings._iDisplayStart = start;
6576
  }
6577
 
6578
+
6579
+ function _fnRenderer(settings, type)
6580
+ {
6581
  var renderer = settings.renderer;
6582
  var host = DataTable.ext.renderer[type];
6583
 
6584
  if ($.isPlainObject(renderer) && renderer[type]) {
6585
+ // Specific renderer for this type. If available use it, otherwise use
6586
+ // the default.
6587
  return host[renderer[type]] || host._;
6588
  } else if (typeof renderer === 'string') {
6589
+ // Common renderer - if there is one available for this type use it,
6590
+ // otherwise use the default
6591
  return host[renderer] || host._;
6592
  }
6593
 
6594
+ // Use the default
6595
  return host._;
6596
  }
6597
 
6598
+
6599
+ /**
6600
+ * Detect the data source being used for the table. Used to simplify the code
6601
+ * a little (ajax) and to make it compress a little smaller.
6602
+ *
6603
+ * @param {object} settings dataTables settings object
6604
+ * @returns {string} Data source
6605
+ * @memberof DataTable#oApi
6606
+ */
6607
+ function _fnDataSource(settings)
6608
+ {
6609
  if (settings.oFeatures.bServerSide) {
6610
  return 'ssp';
6611
  } else if (settings.ajax || settings.sAjaxSource) {
6614
  return 'dom';
6615
  }
6616
 
6617
+
6618
+
6619
+
6620
+ /**
6621
+ * Computed structure of the DataTables API, defined by the options passed to
6622
+ * `DataTable.Api.register()` when building the API.
6623
+ *
6624
+ * The structure is built in order to speed creation and extension of the Api
6625
+ * objects since the extensions are effectively pre-parsed.
6626
+ *
6627
+ * The array is an array of objects with the following structure, where this
6628
+ * base array represents the Api prototype base:
6629
+ *
6630
+ * [
6631
+ * {
6632
+ * name: 'data' -- string - Property name
6633
+ * val: function () {}, -- function - Api method (or undefined if just an object
6634
+ * methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
6635
+ * propExt: [ ... ] -- array - Array of Api object definitions to extend the property
6636
+ * },
6637
+ * {
6638
+ * name: 'row'
6639
+ * val: {},
6640
+ * methodExt: [ ... ],
6641
+ * propExt: [
6642
+ * {
6643
+ * name: 'data'
6644
+ * val: function () {},
6645
+ * methodExt: [ ... ],
6646
+ * propExt: [ ... ]
6647
+ * },
6648
+ * ...
6649
+ * ]
6650
+ * }
6651
+ * ]
6652
+ *
6653
+ * @type {Array}
6654
+ * @ignore
6655
+ */
6656
  var __apiStruct = [];
6657
 
6658
+
6659
+ /**
6660
+ * `Array.prototype` reference.
6661
+ *
6662
+ * @type object
6663
+ * @ignore
6664
+ */
6665
  var __arrayProto = Array.prototype;
6666
 
6667
+
6668
+ /**
6669
+ * Abstraction for `context` parameter of the `Api` constructor to allow it to
6670
+ * take several different forms for ease of use.
6671
+ *
6672
+ * Each of the input parameter types will be converted to a DataTables settings
6673
+ * object where possible.
6674
+ *
6675
+ * @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
6676
+ * of:
6677
+ *
6678
+ * * `string` - jQuery selector. Any DataTables' matching the given selector
6679
+ * with be found and used.
6680
+ * * `node` - `TABLE` node which has already been formed into a DataTable.
6681
+ * * `jQuery` - A jQuery object of `TABLE` nodes.
6682
+ * * `object` - DataTables settings object
6683
+ * * `DataTables.Api` - API instance
6684
+ * @return {array|null} Matching DataTables settings objects. `null` or
6685
+ * `undefined` is returned if no matching DataTable is found.
6686
+ * @ignore
6687
+ */
6688
+ var _toSettings = function (mixed)
6689
+ {
6690
  var idx, jq;
6691
  var settings = DataTable.settings;
6692
  var tables = $.map(settings, function (el, i) {
6720
  }
6721
  };
6722
 
6723
+
6724
+ /**
6725
+ * DataTables API class - used to control and interface with one or more
6726
+ * DataTables enhanced tables.
6727
+ *
6728
+ * The API class is heavily based on jQuery, presenting a chainable interface
6729
+ * that you can use to interact with tables. Each instance of the API class has
6730
+ * a "context" - i.e. the tables that it will operate on. This could be a single
6731
+ * table, all tables on a page or a sub-set thereof.
6732
+ *
6733
+ * Additionally the API is designed to allow you to easily work with the data in
6734
+ * the tables, retrieving and manipulating it as required. This is done by
6735
+ * presenting the API class as an array like interface. The contents of the
6736
+ * array depend upon the actions requested by each method (for example
6737
+ * `rows().nodes()` will return an array of nodes, while `rows().data()` will
6738
+ * return an array of objects or arrays depending upon your table's
6739
+ * configuration). The API object has a number of array like methods (`push`,
6740
+ * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
6741
+ * `unique` etc) to assist your working with the data held in a table.
6742
+ *
6743
+ * Most methods (those which return an Api instance) are chainable, which means
6744
+ * the return from a method call also has all of the methods available that the
6745
+ * top level object had. For example, these two calls are equivalent:
6746
+ *
6747
+ * // Not chained
6748
+ * api.row.add( {...} );
6749
+ * api.draw();
6750
+ *
6751
+ * // Chained
6752
+ * api.row.add( {...} ).draw();
6753
+ *
6754
+ * @class DataTable.Api
6755
+ * @param {array|object|string|jQuery} context DataTable identifier. This is
6756
+ * used to define which DataTables enhanced tables this API will operate on.
6757
+ * Can be one of:
6758
+ *
6759
+ * * `string` - jQuery selector. Any DataTables' matching the given selector
6760
+ * with be found and used.
6761
+ * * `node` - `TABLE` node which has already been formed into a DataTable.
6762
+ * * `jQuery` - A jQuery object of `TABLE` nodes.
6763
+ * * `object` - DataTables settings object
6764
+ * @param {array} [data] Data to initialise the Api instance with.
6765
+ *
6766
+ * @example
6767
+ * // Direct initialisation during DataTables construction
6768
+ * var api = $('#example').DataTable();
6769
+ *
6770
+ * @example
6771
+ * // Initialisation using a DataTables jQuery object
6772
+ * var api = $('#example').dataTable().api();
6773
+ *
6774
+ * @example
6775
+ * // Initialisation as a constructor
6776
+ * var api = new $.fn.DataTable.Api( 'table.dataTable' );
6777
+ */
6778
+ _Api = function (context, data)
6779
+ {
6780
  if (!(this instanceof _Api)) {
6781
  return new _Api(context, data);
6782
  }
6797
  ctxSettings(context);
6798
  }
6799
 
6800
+ // Remove duplicates
6801
  this.context = _unique(settings);
6802
 
6803
  // Initial data
6817
 
6818
  DataTable.Api = _Api;
6819
 
6820
+ // Don't destroy the existing prototype, just extend it. Required for jQuery 2's
6821
+ // isPlainObject.
6822
  $.extend(_Api.prototype, {
6823
+ any: function ()
6824
+ {
6825
  return this.count() !== 0;
6826
  },
6827
+
6828
  concat: __arrayProto.concat,
6829
+
6830
  context: [], // array of table settings objects
6831
+
6832
+
6833
+ count: function ()
6834
+ {
6835
  return this.flatten().length;
6836
  },
6837
+
6838
+ each: function (fn)
6839
+ {
6840
  for (var i = 0, ien = this.length; i < ien; i++) {
6841
  fn.call(this, this[i], i, this);
6842
  }
6843
 
6844
  return this;
6845
  },
6846
+
6847
+ eq: function (idx)
6848
+ {
6849
  var ctx = this.context;
6850
 
6851
  return ctx.length > idx ?
6852
  new _Api(ctx[idx], this[idx]) :
6853
  null;
6854
  },
6855
+
6856
+ filter: function (fn)
6857
+ {
6858
  var a = [];
6859
+
6860
  if (__arrayProto.filter) {
6861
  a = __arrayProto.filter.call(this, fn, this);
6862
  } else {
6867
  }
6868
  }
6869
  }
6870
+
6871
  return new _Api(this.context, a);
6872
  },
6873
+
6874
+ flatten: function ()
6875
+ {
6876
  var a = [];
6877
  return new _Api(this.context, a.concat.apply(a, this.toArray()));
6878
  },
6879
+
6880
  join: __arrayProto.join,
6881
+
6882
+ indexOf: __arrayProto.indexOf || function (obj, start)
6883
+ {
6884
  for (var i = (start || 0), ien = this.length; i < ien; i++) {
6885
  if (this[i] === obj) {
6886
  return i;
6888
  }
6889
  return -1;
6890
  },
6891
+
6892
  iterator: function (flatten, type, fn, alwaysNew) {
6893
  var
6894
+ a = [], ret,
 
6895
  i, ien, j, jen,
6896
  context = this.context,
6897
  rows, items, item,
6956
  }
6957
  return this;
6958
  },
6959
+
6960
+ lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
6961
+ {
6962
  // Bit cheeky...
6963
  return this.indexOf.apply(this.toArray.reverse(), arguments);
6964
  },
6965
+
6966
  length: 0,
6967
+
6968
+ map: function (fn)
6969
+ {
6970
  var a = [];
6971
 
6972
  if (__arrayProto.map) {
6980
 
6981
  return new _Api(this.context, a);
6982
  },
6983
+
6984
+ pluck: function (prop)
6985
+ {
6986
  return this.map(function (el) {
6987
+ return el[ prop ];
6988
  });
6989
  },
6990
+
6991
  pop: __arrayProto.pop,
6992
+
6993
  push: __arrayProto.push,
6994
+
6995
+ // Does not return an API instance
6996
+ reduce: __arrayProto.reduce || function (fn, init)
6997
+ {
6998
  return _fnReduce(this, fn, init, 0, this.length, 1);
6999
  },
7000
+
7001
+ reduceRight: __arrayProto.reduceRight || function (fn, init)
7002
+ {
7003
  return _fnReduce(this, fn, init, this.length - 1, -1, -1);
7004
  },
7005
+
7006
  reverse: __arrayProto.reverse,
7007
+
7008
  // Object with rows, columns and opts
7009
  selector: null,
7010
+
7011
  shift: __arrayProto.shift,
7012
+
7013
+ slice: function () {
7014
+ return new _Api(this.context, this);
7015
+ },
7016
+
7017
  sort: __arrayProto.sort, // ? name - order?
7018
+
7019
+
7020
  splice: __arrayProto.splice,
7021
+
7022
+ toArray: function ()
7023
+ {
7024
  return __arrayProto.slice.call(this);
7025
  },
7026
+
7027
+ to$: function ()
7028
+ {
7029
  return $(this);
7030
  },
7031
+
7032
+ toJQuery: function ()
7033
+ {
7034
  return $(this);
7035
  },
7036
+
7037
+ unique: function ()
7038
+ {
7039
  return new _Api(this.context, _unique(this));
7040
  },
7041
+
7042
  unshift: __arrayProto.unshift
7043
  });
7044
+
7045
+
7046
+ _Api.extend = function (scope, obj, ext)
7047
+ {
7048
+ // Only extend API instances and static properties of the API
7049
  if (!ext.length || !obj || (!(obj instanceof _Api) && !obj.__dt_wrapper)) {
7050
  return;
7051
  }
7052
+
7053
  var
7054
  i, ien,
7055
  j, jen,
7057
  methodScoping = function (scope, fn, struc) {
7058
  return function () {
7059
  var ret = fn.apply(scope, arguments);
7060
+
7061
+ // Method extension
7062
  _Api.extend(ret, ret, struc.methodExt);
7063
  return ret;
7064
  };
7065
  };
7066
+
7067
  for (i = 0, ien = ext.length; i < ien; i++) {
7068
  struct = ext[i];
7069
+
7070
+ // Value
7071
+ obj[ struct.name ] = typeof struct.val === 'function' ?
7072
  methodScoping(scope, struct.val, struct) :
7073
+ $.isPlainObject(struct.val) ?
7074
+ {} :
7075
  struct.val;
7076
+
7077
+ obj[ struct.name ].__dt_wrapper = true;
7078
+
7079
+ // Property extension
7080
+ _Api.extend(scope, obj[ struct.name ], struct.propExt);
7081
  }
7082
  };
7083
+
7084
+
7085
+ // @todo - Is there need for an augment function?
7086
+ // _Api.augment = function ( inst, name )
7087
+ // {
7088
+ // // Find src object in the structure from the name
7089
+ // var parts = name.split('.');
7090
+
7091
+ // _Api.extend( inst, obj );
7092
+ // };
7093
+
7094
+
7095
+ // [
7096
+ // {
7097
+ // name: 'data' -- string - Property name
7098
+ // val: function () {}, -- function - Api method (or undefined if just an object
7099
+ // methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
7100
+ // propExt: [ ... ] -- array - Array of Api object definitions to extend the property
7101
+ // },
7102
+ // {
7103
+ // name: 'row'
7104
+ // val: {},
7105
+ // methodExt: [ ... ],
7106
+ // propExt: [
7107
+ // {
7108
+ // name: 'data'
7109
+ // val: function () {},
7110
+ // methodExt: [ ... ],
7111
+ // propExt: [ ... ]
7112
+ // },
7113
+ // ...
7114
+ // ]
7115
+ // }
7116
+ // ]
7117
+
7118
+ _Api.register = _api_register = function (name, val)
7119
+ {
7120
  if ($.isArray(name)) {
7121
  for (var j = 0, jen = name.length; j < jen; j++) {
7122
  _Api.register(name[j], val);
7123
  }
7124
  return;
7125
  }
7126
+
7127
  var
7128
  i, ien,
7129
  heir = name.split('.'),
7130
  struct = __apiStruct,
7131
  key, method;
7132
+
7133
  var find = function (src, name) {
7134
  for (var i = 0, ien = src.length; i < ien; i++) {
7135
  if (src[i].name === name) {
7138
  }
7139
  return null;
7140
  };
7141
+
7142
  for (i = 0, ien = heir.length; i < ien; i++) {
7143
  method = heir[i].indexOf('()') !== -1;
7144
  key = method ?
7145
  heir[i].replace('()', '') :
7146
  heir[i];
7147
+
7148
  var src = find(struct, key);
7149
  if (!src) {
7150
  src = {
7155
  };
7156
  struct.push(src);
7157
  }
7158
+
7159
  if (i === ien - 1) {
7160
  src.val = val;
7161
  } else {
7165
  }
7166
  }
7167
  };
7168
+
7169
+
7170
  _Api.registerPlural = _api_registerPlural = function (pluralName, singularName, val) {
7171
  _Api.register(pluralName, val);
7172
+
7173
  _Api.register(singularName, function () {
7174
  var ret = val.apply(this, arguments);
7175
+
7176
  if (ret === this) {
7177
+ // Returned item is the API instance that was passed in, return it
7178
  return this;
7179
  } else if (ret instanceof _Api) {
7180
+ // New API instance returned, want the value from the first item
7181
+ // in the returned array for the singular result.
7182
  return ret.length ?
7183
  $.isArray(ret[0]) ?
7184
  new _Api(ret.context, ret[0]) : // Array results are 'enhanced'
7185
  ret[0] :
7186
  undefined;
7187
  }
7188
+
7189
+ // Non-API return - just fire it back
7190
  return ret;
7191
  });
7192
  };
7193
 
7194
+
7195
+ /**
7196
+ * Selector for HTML tables. Apply the given selector to the give array of
7197
+ * DataTables settings objects.
7198
+ *
7199
+ * @param {string|integer} [selector] jQuery selector string or integer
7200
+ * @param {array} Array of DataTables settings objects to be filtered
7201
+ * @return {array}
7202
+ * @ignore
7203
+ */
7204
+ var __table_selector = function (selector, a)
7205
+ {
7206
+ // Integer is used to pick out a table by index
7207
  if (typeof selector === 'number') {
7208
+ return [a[ selector ]];
7209
  }
7210
+
7211
+ // Perform a jQuery selector on the table nodes
7212
  var nodes = $.map(a, function (el, i) {
7213
  return el.nTable;
7214
  });
7215
+
7216
  return $(nodes)
7217
  .filter(selector)
7218
  .map(function (i) {
7219
+ // Need to translate back from the table node to the settings
7220
  var idx = $.inArray(this, nodes);
7221
+ return a[ idx ];
7222
  })
7223
  .toArray();
7224
  };
7225
+
7226
+
7227
+
7228
+ /**
7229
+ * Context selector for the API's context (i.e. the tables the API instance
7230
+ * refers to.
7231
+ *
7232
+ * @name DataTable.Api#tables
7233
+ * @param {string|integer} [selector] Selector to pick which tables the iterator
7234
+ * should operate on. If not given, all tables in the current context are
7235
+ * used. This can be given as a jQuery selector (for example `':gt(0)'`) to
7236
+ * select multiple tables or as an integer to select a single table.
7237
+ * @returns {DataTable.Api} Returns a new API instance if a selector is given.
7238
+ */
7239
  _api_register('tables()', function (selector) {
7240
+ // A new instance is created if there was a selector specified
7241
  return selector ?
7242
  new _Api(__table_selector(selector, this.context)) :
7243
  this;
7244
  });
7245
+
7246
+
7247
  _api_register('table()', function (selector) {
7248
  var tables = this.tables(selector);
7249
  var ctx = tables.context;
7250
+
7251
+ // Truncate to the first matched table
7252
  return ctx.length ?
7253
  new _Api(ctx[0]) :
7254
  tables;
7255
  });
7256
+
7257
+
7258
  _api_registerPlural('tables().nodes()', 'table().node()', function () {
7259
  return this.iterator('table', function (ctx) {
7260
  return ctx.nTable;
7261
  }, 1);
7262
  });
7263
+
7264
+
7265
  _api_registerPlural('tables().body()', 'table().body()', function () {
7266
  return this.iterator('table', function (ctx) {
7267
  return ctx.nTBody;
7268
  }, 1);
7269
  });
7270
+
7271
+
7272
  _api_registerPlural('tables().header()', 'table().header()', function () {
7273
  return this.iterator('table', function (ctx) {
7274
  return ctx.nTHead;
7275
  }, 1);
7276
  });
7277
+
7278
+
7279
  _api_registerPlural('tables().footer()', 'table().footer()', function () {
7280
  return this.iterator('table', function (ctx) {
7281
  return ctx.nTFoot;
7282
  }, 1);
7283
  });
7284
+
7285
+
7286
  _api_registerPlural('tables().containers()', 'table().container()', function () {
7287
  return this.iterator('table', function (ctx) {
7288
  return ctx.nTableWrapper;
7289
  }, 1);
7290
  });
7291
+
7292
+
7293
+
7294
+ /**
7295
+ * Redraw the tables in the current context.
7296
+ */
7297
  _api_register('draw()', function (paging) {
7298
  return this.iterator('table', function (settings) {
7299
  if (paging === 'page') {
7304
  false :
7305
  true;
7306
  }
7307
+
7308
  _fnReDraw(settings, paging === false);
7309
  }
7310
  });
7311
  });
7312
+
7313
+
7314
+
7315
+ /**
7316
+ * Get the current page index.
7317
+ *
7318
+ * @return {integer} Current page index (zero based)
7319
+ *//**
7320
+ * Set the current page.
7321
+ *
7322
+ * Note that if you attempt to show a page which does not exist, DataTables will
7323
+ * not throw an error, but rather reset the paging.
7324
+ *
7325
+ * @param {integer|string} action The paging action to take. This can be one of:
7326
+ * * `integer` - The page index to jump to
7327
+ * * `string` - An action to take:
7328
+ * * `first` - Jump to first page.
7329
+ * * `next` - Jump to the next page
7330
+ * * `previous` - Jump to previous page
7331
+ * * `last` - Jump to the last page.
7332
+ * @returns {DataTables.Api} this
7333
+ */
7334
  _api_register('page()', function (action) {
7335
  if (action === undefined) {
7336
  return this.page.info().page; // not an expensive call
7341
  _fnPageChange(settings, action);
7342
  });
7343
  });
7344
+
7345
+
7346
+ /**
7347
+ * Paging information for the first table in the current context.
7348
+ *
7349
+ * If you require paging information for another table, use the `table()` method
7350
+ * with a suitable selector.
7351
+ *
7352
+ * @return {object} Object with the following properties set:
7353
+ * * `page` - Current page index (zero based - i.e. the first page is `0`)
7354
+ * * `pages` - Total number of pages
7355
+ * * `start` - Display index for the first record shown on the current page
7356
+ * * `end` - Display index for the last record shown on the current page
7357
+ * * `length` - Display length (number of records). Note that generally `start
7358
+ * + length = end`, but this is not always true, for example if there are
7359
+ * only 2 records to show on the final page, with a length of 10.
7360
+ * * `recordsTotal` - Full data set length
7361
+ * * `recordsDisplay` - Data set length once the current filtering criterion
7362
+ * are applied.
7363
+ */
7364
  _api_register('page.info()', function (action) {
7365
  if (this.context.length === 0) {
7366
  return undefined;
7384
  "serverSide": _fnDataSource(settings) === 'ssp'
7385
  };
7386
  });
7387
+
7388
+
7389
+ /**
7390
+ * Get the current page length.
7391
+ *
7392
+ * @return {integer} Current page length. Note `-1` indicates that all records
7393
+ * are to be shown.
7394
+ *//**
7395
+ * Set the current page length.
7396
+ *
7397
+ * @param {integer} Page length to set. Use `-1` to show all records.
7398
+ * @returns {DataTables.Api} this
7399
+ */
7400
  _api_register('page.len()', function (len) {
7401
  // Note that we can't call this function 'length()' because `length`
7402
  // is a Javascript property of functions which defines how many arguments
7412
  _fnLengthChange(settings, len);
7413
  });
7414
  });
7415
+
7416
+
7417
+
7418
  var __reload = function (settings, holdPosition, callback) {
7419
+ // Use the draw event to trigger a callback
7420
  if (callback) {
7421
  var api = new _Api(settings);
7422
+
7423
  api.one('draw', function () {
7424
  callback(api.ajax.json());
7425
  });
7426
  }
7427
+
7428
  if (_fnDataSource(settings) == 'ssp') {
7429
  _fnReDraw(settings, holdPosition);
7430
  } else {
7431
  _fnProcessingDisplay(settings, true);
7432
+
7433
+ // Cancel an existing request
7434
  var xhr = settings.jqXHR;
7435
  if (xhr && xhr.readyState !== 4) {
7436
  xhr.abort();
7437
  }
7438
+
7439
+ // Trigger xhr
7440
  _fnBuildAjax(settings, [], function (json) {
7441
  _fnClearTable(settings);
7442
 
7444
  for (var i = 0, ien = data.length; i < ien; i++) {
7445
  _fnAddData(settings, data[i]);
7446
  }
7447
+
7448
  _fnReDraw(settings, holdPosition);
7449
  _fnProcessingDisplay(settings, false);
7450
  });
7451
  }
7452
  };
7453
+
7454
+
7455
+ /**
7456
+ * Get the JSON response from the last Ajax request that DataTables made to the
7457
+ * server. Note that this returns the JSON from the first table in the current
7458
+ * context.
7459
+ *
7460
+ * @return {object} JSON received from the server.
7461
+ */
7462
  _api_register('ajax.json()', function () {
7463
  var ctx = this.context;
7464
 
7465
  if (ctx.length > 0) {
7466
  return ctx[0].json;
7467
  }
7468
+
7469
+ // else return undefined;
7470
  });
7471
+
7472
+
7473
+ /**
7474
+ * Get the data submitted in the last Ajax request
7475
+ */
7476
  _api_register('ajax.params()', function () {
7477
  var ctx = this.context;
7478
 
7479
  if (ctx.length > 0) {
7480
  return ctx[0].oAjaxData;
7481
  }
7482
+
7483
+ // else return undefined;
7484
  });
7485
+
7486
+
7487
+ /**
7488
+ * Reload tables from the Ajax data source. Note that this function will
7489
+ * automatically re-draw the table when the remote data has been loaded.
7490
+ *
7491
+ * @param {boolean} [reset=true] Reset (default) or hold the current paging
7492
+ * position. A full re-sort and re-filter is performed when this method is
7493
+ * called, which is why the pagination reset is the default action.
7494
+ * @returns {DataTables.Api} this
7495
+ */
7496
  _api_register('ajax.reload()', function (callback, resetPaging) {
7497
  return this.iterator('table', function (settings) {
7498
  __reload(settings, resetPaging === false, callback);
7499
  });
7500
  });
7501
+
7502
+
7503
+ /**
7504
+ * Get the current Ajax URL. Note that this returns the URL from the first
7505
+ * table in the current context.
7506
+ *
7507
+ * @return {string} Current Ajax source URL
7508
+ *//**
7509
+ * Set the Ajax URL. Note that this will set the URL for all tables in the
7510
+ * current context.
7511
+ *
7512
+ * @param {string} url URL to set.
7513
+ * @returns {DataTables.Api} this
7514
+ */
7515
  _api_register('ajax.url()', function (url) {
7516
  var ctx = this.context;
7517
 
7528
  ctx.ajax :
7529
  ctx.sAjaxSource;
7530
  }
7531
+
7532
+ // set
7533
  return this.iterator('table', function (settings) {
7534
  if ($.isPlainObject(settings.ajax)) {
7535
  settings.ajax.url = url;
7536
  } else {
7537
  settings.ajax = url;
7538
  }
7539
+ // No need to consider sAjaxSource here since DataTables gives priority
7540
+ // to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
7541
+ // value of `sAjaxSource` redundant.
7542
  });
7543
  });
7544
+
7545
+
7546
+ /**
7547
+ * Load data from the newly set Ajax URL. Note that this method is only
7548
+ * available when `ajax.url()` is used to set a URL. Additionally, this method
7549
+ * has the same effect as calling `ajax.reload()` but is provided for
7550
+ * convenience when setting a new URL. Like `ajax.reload()` it will
7551
+ * automatically redraw the table once the remote data has been loaded.
7552
+ *
7553
+ * @returns {DataTables.Api} this
7554
+ */
7555
  _api_register('ajax.url().load()', function (callback, resetPaging) {
7556
+ // Same as a reload, but makes sense to present it for easy access after a
7557
+ // url change
7558
  return this.iterator('table', function (ctx) {
7559
  __reload(ctx, resetPaging === false, callback);
7560
  });
7561
  });
7562
+
7563
+
7564
+
7565
+
7566
+ var _selector_run = function (type, selector, selectFn, settings, opts)
7567
+ {
7568
  var
7569
+ out = [], res,
 
7570
  a, i, ien, j, jen,
7571
  selectorType = typeof selector;
7572
+
7573
+ // Can't just check for isArray here, as an API or jQuery instance might be
7574
+ // given with their array like look
7575
  if (!selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined) {
7576
  selector = [selector];
7577
  }
7578
+
7579
  for (i = 0, ien = selector.length; i < ien; i++) {
7580
+ // Only split on simple strings - complex expressions will be jQuery selectors
7581
+ a = selector[i] && selector[i].split && !selector[i].match(/[\[\(:]/) ?
7582
+ selector[i].split(',') :
7583
+ [selector[i]];
7584
 
7585
  for (j = 0, jen = a.length; j < jen; j++) {
7586
  res = selectFn(typeof a[j] === 'string' ? $.trim(a[j]) : a[j]);
7590
  }
7591
  }
7592
  }
7593
+
7594
+ // selector extensions
7595
+ var ext = _ext.selector[ type ];
7596
  if (ext.length) {
7597
  for (i = 0, ien = ext.length; i < ien; i++) {
7598
  out = ext[i](settings, opts, out);
7599
  }
7600
  }
7601
+
7602
  return _unique(out);
7603
  };
7604
+
7605
+
7606
+ var _selector_opts = function (opts)
7607
+ {
7608
  if (!opts) {
7609
  opts = {};
7610
  }
7611
+
7612
+ // Backwards compatibility for 1.9- which used the terminology filter rather
7613
+ // than search
7614
  if (opts.filter && opts.search === undefined) {
7615
  opts.search = opts.filter;
7616
  }
7621
  page: 'all'
7622
  }, opts);
7623
  };
7624
+
7625
+
7626
+ var _selector_first = function (inst)
7627
+ {
7628
  // Reduce the API instance to the first item found
7629
  for (var i = 0, ien = inst.length; i < ien; i++) {
7630
  if (inst[i].length > 0) {
7631
+ // Assign the first element to the first item in the instance
7632
+ // and truncate the instance and context
7633
  inst[0] = inst[i];
7634
  inst[0].length = 1;
7635
  inst.length = 1;
7638
  return inst;
7639
  }
7640
  }
7641
+
7642
+ // Not found - return an empty instance
7643
  inst.length = 0;
7644
  return inst;
7645
  };
7646
+
7647
+
7648
+ var _selector_row_indexes = function (settings, opts)
7649
+ {
7650
  var
7651
  i, ien, tmp, a = [],
7652
  displayFiltered = settings.aiDisplay,
7653
  displayMaster = settings.aiDisplayMaster;
7654
+
7655
  var
7656
  search = opts.search, // none, applied, removed
7657
  order = opts.order, // applied, current, index (original - compatibility with 1.9)
7658
+ page = opts.page; // all, current
7659
+
7660
  if (_fnDataSource(settings) == 'ssp') {
7661
+ // In server-side processing mode, most options are irrelevant since
7662
+ // rows not shown don't exist and the index order is the applied order
7663
+ // Removed is a special case - for consistency just return an empty
7664
+ // array
7665
+ return search === 'removed' ?
7666
+ [] :
7667
  _range(0, displayMaster.length);
7668
  } else if (page == 'current') {
7669
+ // Current page implies that order=current and fitler=applied, since it is
7670
+ // fairly senseless otherwise, regardless of what order and search actually
7671
+ // are
7672
  for (i = settings._iDisplayStart, ien = settings.fnDisplayEnd(); i < ien; i++) {
7673
  a.push(displayFiltered[i]);
7674
  }
7688
  tmp = $.inArray(i, displayFiltered);
7689
 
7690
  if ((tmp === -1 && search == 'removed') ||
7691
+ (tmp >= 0 && search == 'applied'))
7692
+ {
7693
  a.push(i);
7694
  }
7695
  }
7696
  }
7697
  }
7698
+
7699
  return a;
7700
  };
7701
+
7702
+
7703
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7704
+ * Rows
7705
+ *
7706
+ * {} - no selector - use all available rows
7707
+ * {integer} - row aoData index
7708
+ * {node} - TR node
7709
+ * {string} - jQuery selector to apply to the TR elements
7710
+ * {array} - jQuery array of nodes, or simply an array of TR nodes
7711
+ *
7712
+ */
7713
+
7714
+
7715
+ var __row_selector = function (settings, selector, opts)
7716
+ {
7717
+ var rows;
7718
  var run = function (sel) {
7719
  var selInt = _intVal(sel);
7720
  var i, ien;
7721
+
7722
+ // Short cut - selector is a number and no options provided (default is
7723
+ // all records, so no need to check if the index is in there, since it
7724
+ // must be - dev error if the index doesn't exist).
7725
  if (selInt !== null && !opts) {
7726
  return [selInt];
7727
  }
7728
+
7729
+ if (!rows) {
7730
+ rows = _selector_row_indexes(settings, opts);
7731
+ }
7732
+
7733
  if (selInt !== null && $.inArray(selInt, rows) !== -1) {
7734
+ // Selector - integer
7735
  return [selInt];
7736
+ } else if (sel === null || sel === undefined || sel === '') {
7737
  // Selector - none
7738
  return rows;
7739
  }
7740
+
7741
+ // Selector - function
7742
  if (typeof sel === 'function') {
7743
  return $.map(rows, function (idx) {
7744
+ var row = settings.aoData[ idx ];
7745
  return sel(idx, row._aData, row.nTr) ? idx : null;
7746
  });
7747
  }
7748
+
7749
+ // Get nodes in the order from the `rows` array with null values removed
7750
  var nodes = _removeEmpty(
7751
  _pluck_order(settings.aoData, rows, 'nTr')
7752
  );
7753
+
7754
  // Selector - node
7755
  if (sel.nodeName) {
7756
  if (sel._DT_RowIndex !== undefined) {
7759
  return [sel._DT_CellIndex.row];
7760
  } else {
7761
  var host = $(sel).closest('*[data-dt-row]');
7762
+ return host.length ?
7763
+ [host.data('dt-row')] :
7764
+ [];
7765
  }
7766
  }
7767
+
7768
+ // ID selector. Want to always be able to select rows by id, regardless
7769
+ // of if the tr element has been created or not, so can't rely upon
7770
+ // jQuery here - hence a custom implementation. This does not match
7771
+ // Sizzle's fast selector or HTML4 - in HTML5 the ID can be anything,
7772
+ // but to select it using a CSS selector engine (like Sizzle or
7773
+ // querySelect) it would need to need to be escaped for some characters.
7774
+ // DataTables simplifies this for row selectors since you can select
7775
+ // only a row. A # indicates an id any anything that follows is the id -
7776
+ // unescaped.
7777
  if (typeof sel === 'string' && sel.charAt(0) === '#') {
7778
  // get row index from id
7779
+ var rowObj = settings.aIds[ sel.replace(/^#/, '') ];
7780
  if (rowObj !== undefined) {
7781
  return [rowObj.idx];
7782
  }
7783
+
7784
+ // need to fall through to jQuery in case there is DOM id that
7785
+ // matches
7786
  }
7787
+
7788
+ // Selector - jQuery selector string, array of nodes or jQuery object/
7789
+ // As jQuery's .filter() allows jQuery objects to be passed in filter,
7790
+ // it also allows arrays, so this will cope with all three options
7791
  return $(nodes)
7792
  .filter(sel)
7793
  .map(function () {
7795
  })
7796
  .toArray();
7797
  };
7798
+
7799
  return _selector_run('row', selector, run, settings, opts);
7800
  };
7801
+
7802
+
7803
  _api_register('rows()', function (selector, opts) {
7804
+ // argument shifting
7805
  if (selector === undefined) {
7806
  selector = '';
7807
  } else if ($.isPlainObject(selector)) {
7808
  opts = selector;
7809
  selector = '';
7810
  }
7811
+
7812
  opts = _selector_opts(opts);
7813
+
7814
  var inst = this.iterator('table', function (settings) {
7815
  return __row_selector(settings, selector, opts);
7816
  }, 1);
7817
+
7818
+ // Want argument shifting here and in __row_selector?
7819
  inst.selector.rows = selector;
7820
  inst.selector.opts = opts;
7821
 
7824
 
7825
  _api_register('rows().nodes()', function () {
7826
  return this.iterator('row', function (settings, row) {
7827
+ return settings.aoData[ row ].nTr || undefined;
7828
  }, 1);
7829
  });
7830
 
7836
 
7837
  _api_registerPlural('rows().cache()', 'row().cache()', function (type) {
7838
  return this.iterator('row', function (settings, row) {
7839
+ var r = settings.aoData[ row ];
7840
  return type === 'search' ? r._aFilterData : r._aSortData;
7841
  }, 1);
7842
  });
7856
  _api_registerPlural('rows().ids()', 'row().id()', function (hash) {
7857
  var a = [];
7858
  var context = this.context;
7859
+
7860
+ // `iterator` will drop undefined values, but in this case we want them
7861
  for (var i = 0, ien = context.length; i < ien; i++) {
7862
  for (var j = 0, jen = this[i].length; j < jen; j++) {
7863
+ var id = context[i].rowIdFn(context[i].aoData[ this[i][j] ]._aData);
7864
  a.push((hash === true ? '#' : '') + id);
7865
  }
7866
  }
7873
 
7874
  this.iterator('row', function (settings, row, thatIdx) {
7875
  var data = settings.aoData;
7876
+ var rowData = data[ row ];
7877
  var i, ien, j, jen;
7878
  var loopRow, loopCells;
7879
+
7880
  data.splice(row, 1);
7881
+
7882
+ // Update the cached indexes
7883
  for (i = 0, ien = data.length; i < ien; i++) {
7884
  loopRow = data[i];
7885
  loopCells = loopRow.anCells;
7886
+
7887
  // Rows
7888
  if (loopRow.nTr !== null) {
7889
  loopRow.nTr._DT_RowIndex = i;
7890
  }
7891
+
7892
  // Cells
7893
  if (loopCells !== null) {
7894
  for (j = 0, jen = loopCells.length; j < jen; j++) {
7896
  }
7897
  }
7898
  }
7899
+
7900
  // Delete from the display arrays
7901
  _fnDeleteIndex(settings.aiDisplayMaster, row);
7902
  _fnDeleteIndex(settings.aiDisplay, row);
7903
+ _fnDeleteIndex(that[ thatIdx ], row, false); // maintain local indexes
7904
+
7905
  // Check for an 'overflow' they case for displaying the table
7906
  _fnLengthOverflow(settings);
7907
+
7908
  // Remove the row's ID reference if there is one
7909
  var id = settings.rowIdFn(rowData._aData);
7910
  if (id !== undefined) {
7911
+ delete settings.aIds[ id ];
7912
  }
7913
  });
7914
+
7915
  this.iterator('table', function (settings) {
7916
  for (var i = 0, ien = settings.aoData.length; i < ien; i++) {
7917
  settings.aoData[i].idx = i;
7918
  }
7919
  });
7920
+
7921
  return this;
7922
  });
7923
+
7924
+
7925
  _api_register('rows.add()', function (rows) {
7926
  var newRows = this.iterator('table', function (settings) {
7927
  var row, i, ien;
7928
  var out = [];
7929
+
7930
  for (i = 0, ien = rows.length; i < ien; i++) {
7931
  row = rows[i];
7932
+
7933
  if (row.nodeName && row.nodeName.toUpperCase() === 'TR') {
7934
  out.push(_fnAddTr(settings, row)[0]);
7935
  } else {
7936
  out.push(_fnAddData(settings, row));
7937
  }
7938
  }
7939
+
7940
  return out;
7941
  }, 1);
7942
+
7943
+ // Return an Api.rows() extended instance, so rows().nodes() etc can be used
7944
  var modRows = this.rows(-1);
7945
  modRows.pop();
7946
  $.merge(modRows, newRows);
7947
+
7948
  return modRows;
7949
  });
7950
+
7951
+
7952
+
7953
+
7954
+
7955
+ /**
7956
+ *
7957
+ */
7958
  _api_register('row()', function (selector, opts) {
7959
  return _selector_first(this.rows(selector, opts));
7960
  });
7961
+
7962
+
7963
  _api_register('row().data()', function (data) {
7964
  var ctx = this.context;
7965
 
7966
  if (data === undefined) {
7967
  // Get
7968
  return ctx.length && this.length ?
7969
+ ctx[0].aoData[ this[0] ]._aData :
7970
  undefined;
7971
  }
7972
+
7973
+ // Set
7974
+ ctx[0].aoData[ this[0] ]._aData = data;
7975
+
7976
+ // Automatically invalidate
7977
  _fnInvalidate(ctx[0], this[0], 'data');
7978
+
7979
  return this;
7980
  });
7981
+
7982
+
7983
  _api_register('row().node()', function () {
7984
  var ctx = this.context;
7985
 
7986
  return ctx.length && this.length ?
7987
+ ctx[0].aoData[ this[0] ].nTr || null :
7988
  null;
7989
  });
7990
+
7991
+
7992
  _api_register('row.add()', function (row) {
7993
+ // Allow a jQuery object to be passed in - only a single row is added from
7994
+ // it though - the first element in the set
7995
  if (row instanceof $ && row.length) {
7996
  row = row[0];
7997
  }
8002
  }
8003
  return _fnAddData(settings, row);
8004
  });
8005
+
8006
+ // Return an Api.rows() extended instance, with the newly added row selected
8007
  return this.row(rows[0]);
8008
  });
8009
+
8010
+
8011
+
8012
+ var __details_add = function (ctx, row, data, klass)
8013
+ {
8014
+ // Convert to array of TR elements
8015
  var rows = [];
8016
  var addRow = function (r, k) {
8017
  // Recursion to allow for arrays of jQuery objects
8022
  return;
8023
  }
8024
 
8025
+ // If we get a TR element, then just add it directly - up to the dev
8026
+ // to add the correct number of columns etc
8027
  if (r.nodeName && r.nodeName.toLowerCase() === 'tr') {
8028
  rows.push(r);
8029
  } else {
8031
  var created = $('<tr><td/></tr>').addClass(k);
8032
  $('td', created)
8033
  .addClass(k)
8034
+ .html(r)
8035
+ [0].colSpan = _fnVisbleColumns(ctx);
8036
 
8037
  rows.push(created[0]);
8038
  }
8039
  };
8040
+
8041
  addRow(data, klass);
8042
 
8043
  if (row._details) {
8044
+ row._details.detach();
8045
  }
8046
+
8047
  row._details = $(rows);
8048
+
8049
  // If the children were already shown, that state should be retained
8050
  if (row._detailsShow) {
8051
  row._details.insertAfter(row.nTr);
8052
  }
8053
  };
8054
+
8055
+
8056
+ var __details_remove = function (api, idx)
8057
+ {
8058
  var ctx = api.context;
8059
+
8060
  if (ctx.length) {
8061
+ var row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];
8062
+
8063
  if (row && row._details) {
8064
  row._details.remove();
8065
 
8068
  }
8069
  }
8070
  };
8071
+
8072
+
8073
  var __details_display = function (api, show) {
8074
  var ctx = api.context;
8075
 
8076
  if (ctx.length && api.length) {
8077
+ var row = ctx[0].aoData[ api[0] ];
8078
 
8079
  if (row._details) {
8080
  row._detailsShow = show;
8081
+
8082
  if (show) {
8083
  row._details.insertAfter(row.nTr);
8084
  } else {
8085
  row._details.detach();
8086
  }
8087
+
8088
  __details_events(ctx[0]);
8089
  }
8090
  }
8091
  };
8092
+
8093
+
8094
+ var __details_events = function (settings)
8095
+ {
8096
  var api = new _Api(settings);
8097
  var namespace = '.dt.DT_details';
8098
  var drawEvent = 'draw' + namespace;
8099
  var colvisEvent = 'column-visibility' + namespace;
8100
  var destroyEvent = 'destroy' + namespace;
8101
  var data = settings.aoData;
8102
+
8103
  api.off(drawEvent + ' ' + colvisEvent + ' ' + destroyEvent);
8104
+
8105
  if (_pluck(data, '_details').length > 0) {
8106
  // On each draw, insert the required elements into the document
8107
  api.on(drawEvent, function (e, ctx) {
8108
  if (settings !== ctx) {
8109
  return;
8110
  }
8111
+
8112
+ api.rows({page: 'current'}).eq(0).each(function (idx) {
 
8113
  // Internal data grab
8114
+ var row = data[ idx ];
8115
 
8116
  if (row._detailsShow) {
8117
  row._details.insertAfter(row.nTr);
8118
  }
8119
  });
8120
  });
8121
+
8122
  // Column visibility change - update the colspan
8123
  api.on(colvisEvent, function (e, ctx, idx, vis) {
8124
  if (settings !== ctx) {
8125
  return;
8126
  }
8127
+
8128
  // Update the colspan for the details rows (note, only if it already has
8129
  // a colspan)
8130
  var row, visible = _fnVisbleColumns(ctx);
8131
+
8132
  for (var i = 0, ien = data.length; i < ien; i++) {
8133
  row = data[i];
8134
+
8135
  if (row._details) {
8136
  row._details.children('td[colspan]').attr('colspan', visible);
8137
  }
8152
  });
8153
  }
8154
  };
8155
+
8156
  // Strings for the method names to help minification
8157
  var _emp = '';
8158
  var _child_obj = _emp + 'row().child';
8159
  var _child_mth = _child_obj + '()';
8160
 
8161
+ // data can be:
8162
+ // tr
8163
+ // string
8164
+ // jQuery or array of any of the above
8165
  _api_register(_child_mth, function (data, klass) {
8166
  var ctx = this.context;
8167
 
8168
  if (data === undefined) {
8169
  // get
8170
  return ctx.length && this.length ?
8171
+ ctx[0].aoData[ this[0] ]._details :
8172
  undefined;
8173
  } else if (data === true) {
8174
  // show
8178
  __details_remove(this);
8179
  } else if (ctx.length && this.length) {
8180
  // set
8181
+ __details_add(ctx[0], ctx[0].aoData[ this[0] ], data, klass);
8182
  }
8183
+
8184
  return this;
8185
  });
8186
+
8187
+
8188
  _api_register([
8189
  _child_obj + '.show()',
8190
  _child_mth + '.show()' // only when `child()` was called with parameters (without
8191
+ ], function (show) { // it returns an object and this method is not executed)
8192
  __details_display(this, true);
8193
  return this;
8194
  });
8195
+
8196
+
8197
  _api_register([
8198
  _child_obj + '.hide()',
8199
  _child_mth + '.hide()' // only when `child()` was called with parameters (without
8200
+ ], function () { // it returns an object and this method is not executed)
8201
  __details_display(this, false);
8202
  return this;
8203
  });
8204
+
8205
+
8206
  _api_register([
8207
  _child_obj + '.remove()',
8208
  _child_mth + '.remove()' // only when `child()` was called with parameters (without
8209
+ ], function () { // it returns an object and this method is not executed)
8210
  __details_remove(this);
8211
  return this;
8212
  });
8213
+
8214
+
8215
  _api_register(_child_obj + '.isShown()', function () {
8216
  var ctx = this.context;
8217
 
8218
  if (ctx.length && this.length) {
8219
  // _detailsShown as false or undefined will fall through to return false
8220
+ return ctx[0].aoData[ this[0] ]._detailsShow || false;
8221
  }
8222
  return false;
8223
  });
8224
+
8225
+
8226
+
8227
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
8228
+ * Columns
8229
+ *
8230
+ * {integer} - column index (>=0 count from left, <0 count from right)
8231
+ * "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
8232
+ * "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
8233
+ * "{string}:name" - column name
8234
+ * "{string}" - jQuery selector on column header nodes
8235
+ *
8236
+ */
8237
+
8238
+ // can be an array of these items, comma separated list, or an array of comma
8239
+ // separated lists
8240
+
8241
+ var __re_column_selector = /^([^:]+):(name|visIdx|visible)$/;
8242
+
8243
+
8244
+ // r1 and r2 are redundant - but it means that the parameters match for the
8245
+ // iterator callback in columns().data()
8246
  var __columnData = function (settings, column, r1, r2, rows) {
8247
  var a = [];
8248
  for (var row = 0, ien = rows.length; row < ien; row++) {
8250
  }
8251
  return a;
8252
  };
8253
+
8254
+
8255
+ var __column_selector = function (settings, selector, opts)
8256
+ {
8257
  var
8258
  columns = settings.aoColumns,
8259
  names = _pluck(columns, 'sName'),
8260
  nodes = _pluck(columns, 'nTh');
8261
+
8262
  var run = function (s) {
8263
  var selInt = _intVal(s);
8264
 
8266
  if (s === '') {
8267
  return _range(columns.length);
8268
  }
8269
+
8270
+ // Selector - index
8271
  if (selInt !== null) {
8272
  return [selInt >= 0 ?
8273
  selInt : // Count from left
8274
  columns.length + selInt // Count from right (+ because its a negative value)
8275
  ];
8276
  }
8277
+
8278
+ // Selector = function
8279
  if (typeof s === 'function') {
8280
  var rows = _selector_row_indexes(settings, opts);
8281
 
8283
  return s(
8284
  idx,
8285
  __columnData(settings, idx, 0, 0, rows),
8286
+ nodes[ idx ]
8287
  ) ? idx : null;
8288
  });
8289
  }
8290
+
8291
+ // jQuery or string selector
8292
  var match = typeof s === 'string' ?
8293
  s.match(__re_column_selector) :
8294
  '';
8295
+
8296
  if (match) {
8297
  switch (match[2]) {
8298
  case 'visIdx':
8304
  var visColumns = $.map(columns, function (col, i) {
8305
  return col.bVisible ? i : null;
8306
  });
8307
+ return [visColumns[ visColumns.length + idx ]];
8308
  }
8309
  // Counting from the left
8310
  return [_fnVisibleToColumnIndex(settings, idx)];
8319
  return [];
8320
  }
8321
  }
8322
+
8323
+ // Cell in the table body
8324
  if (s.nodeName && s._DT_CellIndex) {
8325
  return [s._DT_CellIndex.column];
8326
  }
8327
+
8328
+ // jQuery selector on the TH elements for the columns
8329
  var jqResult = $(nodes)
8330
  .filter(s)
8331
  .map(function () {
8336
  if (jqResult.length || !s.nodeName) {
8337
  return jqResult;
8338
  }
8339
+
8340
+ // Otherwise a node which might have a `dt-column` data attribute, or be
8341
+ // a child or such an element
8342
  var host = $(s).closest('*[data-dt-column]');
8343
+ return host.length ?
8344
+ [host.data('dt-column')] :
8345
+ [];
8346
  };
8347
 
8348
  return _selector_run('column', selector, run, settings, opts);
8349
  };
8350
+
8351
+
8352
  var __setColumnVis = function (settings, column, vis) {
8353
  var
8354
  cols = settings.aoColumns,
8355
+ col = cols[ column ],
8356
  data = settings.aoData,
8357
  row, cells, i, ien, tr;
8358
+
8359
+ // Get
8360
  if (vis === undefined) {
8361
  return col.bVisible;
8362
  }
8363
+
8364
+ // Set
8365
+ // No change
8366
  if (col.bVisible === vis) {
8367
  return;
8368
  }
8378
 
8379
  if (tr) {
8380
  // insertBefore can act like appendChild if 2nd arg is null
8381
+ tr.insertBefore(cells[ column ], cells[ insertBefore ] || null);
8382
  }
8383
  }
8384
  } else {
8385
  // Remove column
8386
  $(_pluck(settings.aoData, 'anCells', column)).detach();
8387
  }
8388
+
8389
  // Common actions
8390
  col.bVisible = vis;
8391
  _fnDrawHead(settings, settings.aoHeader);
8393
 
8394
  _fnSaveState(settings);
8395
  };
8396
+
8397
+
8398
  _api_register('columns()', function (selector, opts) {
8399
  // argument shifting
8400
  if (selector === undefined) {
8403
  opts = selector;
8404
  selector = '';
8405
  }
8406
+
8407
  opts = _selector_opts(opts);
8408
+
8409
  var inst = this.iterator('table', function (settings) {
8410
  return __column_selector(settings, selector, opts);
8411
  }, 1);
8412
 
8413
+ // Want argument shifting here and in _row_selector?
8414
  inst.selector.cols = selector;
8415
  inst.selector.opts = opts;
8416
 
8456
  _api_registerPlural('columns().visible()', 'column().visible()', function (vis, calc) {
8457
  var ret = this.iterator('column', function (settings, column) {
8458
  if (vis === undefined) {
8459
+ return settings.aoColumns[ column ].bVisible;
8460
  } // else
8461
  __setColumnVis(settings, column, vis);
8462
  });
8463
 
8464
+ // Group the column visibility changes
8465
  if (vis !== undefined) {
8466
  // Second loop once the first is done for events
8467
  this.iterator('column', function (settings, column) {
8472
  this.columns.adjust();
8473
  }
8474
  }
8475
+
8476
  return ret;
8477
  });
8478
 
8483
  column;
8484
  }, 1);
8485
  });
8486
+
8487
  _api_register('columns.adjust()', function () {
8488
  return this.iterator('table', function (settings) {
8489
  _fnAdjustColumnSizing(settings);
8490
  }, 1);
8491
  });
8492
+
8493
  _api_register('column.index()', function (type, idx) {
8494
  if (this.context.length !== 0) {
8495
  var ctx = this.context[0];
8501
  }
8502
  }
8503
  });
8504
+
8505
  _api_register('column()', function (selector, opts) {
8506
  return _selector_first(this.columns(selector, opts));
8507
  });
8508
 
8509
+
8510
+
8511
+ var __cell_selector = function (settings, selector, opts)
8512
+ {
8513
  var data = settings.aoData;
8514
  var rows = _selector_row_indexes(settings, opts);
8515
  var cells = _removeEmpty(_pluck_order(data, rows, 'anCells'));
8517
  var row;
8518
  var columns = settings.aoColumns.length;
8519
  var a, i, ien, j, o, host;
8520
+
8521
  var run = function (s) {
8522
  var fnSelector = typeof s === 'function';
8523
+
8524
  if (s === null || s === undefined || fnSelector) {
8525
  // All cells and function selectors
8526
  a = [];
8527
+
8528
  for (i = 0, ien = rows.length; i < ien; i++) {
8529
  row = rows[i];
8530
+
8531
  for (j = 0; j < columns; j++) {
8532
  o = {
8533
  row: row,
8534
  column: j
8535
  };
8536
+
8537
  if (fnSelector) {
8538
+ // Selector - function
8539
+ host = data[ row ];
8540
+
8541
  if (s(o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null)) {
8542
  a.push(o);
8543
  }
8544
  } else {
8545
+ // Selector - all
8546
  a.push(o);
8547
  }
8548
  }
8549
  }
8550
+
8551
  return a;
8552
  }
8553
+
8554
  // Selector - index
8555
  if ($.isPlainObject(s)) {
8556
  return [s];
8557
  }
8558
+
8559
  // Selector - jQuery filtered cells
8560
  var jqResult = allCells
8561
  .filter(s)
8566
  };
8567
  })
8568
  .toArray();
8569
+
8570
  if (jqResult.length || !s.nodeName) {
8571
  return jqResult;
8572
  }
8573
+
8574
+ // Otherwise the selector is a node, and there is one last option - the
8575
+ // element might be a child of an element which has dt-row and dt-column
8576
+ // data attributes
8577
  host = $(s).closest('*[data-dt-row]');
8578
+ return host.length ?
8579
+ [{
8580
+ row: host.data('dt-row'),
8581
+ column: host.data('dt-column')
8582
+ }] :
8583
+ [];
8584
  };
8585
+
8586
  return _selector_run('cell', selector, run, settings, opts);
8587
  };
8588
+
8589
+
8590
+
8591
+
8592
  _api_register('cells()', function (rowSelector, columnSelector, opts) {
8593
  // Argument shifting
8594
  if ($.isPlainObject(rowSelector)) {
8595
  // Indexes
8596
  if (rowSelector.row === undefined) {
8597
+ // Selector options in first parameter
8598
  opts = rowSelector;
8599
  rowSelector = null;
8600
  } else {
8607
  opts = columnSelector;
8608
  columnSelector = null;
8609
  }
8610
+
8611
+ // Cell selector
8612
  if (columnSelector === null || columnSelector === undefined) {
8613
  return this.iterator('table', function (settings) {
8614
  return __cell_selector(settings, rowSelector, _selector_opts(opts));
8615
  });
8616
  }
8617
+
8618
+ // Row + column selector
8619
  var columns = this.columns(columnSelector, opts);
8620
  var rows = this.rows(rowSelector, opts);
8621
  var a, i, ien, j, jen;
8631
  });
8632
  }
8633
  }
8634
+
8635
  return a;
8636
  }, 1);
8637
+
8638
  $.extend(cells.selector, {
8639
  cols: columnSelector,
8640
  rows: rowSelector,
8641
  opts: opts
8642
  });
8643
+
8644
  return cells;
8645
  });
8646
+
8647
+
8648
  _api_registerPlural('cells().nodes()', 'cell().node()', function () {
8649
  return this.iterator('cell', function (settings, row, column) {
8650
+ var data = settings.aoData[ row ];
8651
 
8652
  return data && data.anCells ?
8653
+ data.anCells[ column ] :
8654
  undefined;
8655
  }, 1);
8656
  });
8657
+
8658
+
8659
  _api_register('cells().data()', function () {
8660
  return this.iterator('cell', function (settings, row, column) {
8661
  return _fnGetCellData(settings, row, column);
8662
  }, 1);
8663
  });
8664
+
8665
+
8666
  _api_registerPlural('cells().cache()', 'cell().cache()', function (type) {
8667
  type = type === 'search' ? '_aFilterData' : '_aSortData';
8668
+
8669
  return this.iterator('cell', function (settings, row, column) {
8670
+ return settings.aoData[ row ][ type ][ column ];
8671
  }, 1);
8672
  });
8673
+
8674
+
8675
  _api_registerPlural('cells().render()', 'cell().render()', function (type) {
8676
  return this.iterator('cell', function (settings, row, column) {
8677
  return _fnGetCellData(settings, row, column, type);
8678
  }, 1);
8679
  });
8680
+
8681
+
8682
  _api_registerPlural('cells().indexes()', 'cell().index()', function () {
8683
  return this.iterator('cell', function (settings, row, column) {
8684
  return {
8688
  };
8689
  }, 1);
8690
  });
8691
+
8692
+
8693
  _api_registerPlural('cells().invalidate()', 'cell().invalidate()', function (src) {
8694
  return this.iterator('cell', function (settings, row, column) {
8695
  _fnInvalidate(settings, row, src, column);
8696
  });
8697
  });
8698
+
8699
+
8700
+
8701
  _api_register('cell()', function (rowSelector, columnSelector, opts) {
8702
  return _selector_first(this.cells(rowSelector, columnSelector, opts));
8703
  });
8704
+
8705
+
8706
  _api_register('cell().data()', function (data) {
8707
  var ctx = this.context;
8708
  var cell = this[0];
8713
  _fnGetCellData(ctx[0], cell[0].row, cell[0].column) :
8714
  undefined;
8715
  }
8716
+
8717
+ // Set
8718
  _fnSetCellData(ctx[0], cell[0].row, cell[0].column, data);
8719
  _fnInvalidate(ctx[0], cell[0].row, 'data', cell[0].column);
8720
 
8721
  return this;
8722
  });
8723
 
8724
+
8725
+
8726
+ /**
8727
+ * Get current ordering (sorting) that has been applied to the table.
8728
+ *
8729
+ * @returns {array} 2D array containing the sorting information for the first
8730
+ * table in the current context. Each element in the parent array represents
8731
+ * a column being sorted upon (i.e. multi-sorting with two columns would have
8732
+ * 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
8733
+ * the column index that the sorting condition applies to, the second is the
8734
+ * direction of the sort (`desc` or `asc`) and, optionally, the third is the
8735
+ * index of the sorting order from the `column.sorting` initialisation array.
8736
+ *//**
8737
+ * Set the ordering for the table.
8738
+ *
8739
+ * @param {integer} order Column index to sort upon.
8740
+ * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
8741
+ * @returns {DataTables.Api} this
8742
+ *//**
8743
+ * Set the ordering for the table.
8744
+ *
8745
+ * @param {array} order 1D array of sorting information to be applied.
8746
+ * @param {array} [...] Optional additional sorting conditions
8747
+ * @returns {DataTables.Api} this
8748
+ *//**
8749
+ * Set the ordering for the table.
8750
+ *
8751
+ * @param {array} order 2D array of sorting information to be applied.
8752
+ * @returns {DataTables.Api} this
8753
+ */
8754
  _api_register('order()', function (order, dir) {
8755
  var ctx = this.context;
8756
 
8760
  ctx[0].aaSorting :
8761
  undefined;
8762
  }
8763
+
8764
+ // set
8765
  if (typeof order === 'number') {
8766
  // Simple column / direction passed in
8767
+ order = [[order, dir]];
 
 
8768
  } else if (order.length && !$.isArray(order[0])) {
8769
  // Arguments passed in (list of 1D arrays)
8770
  order = Array.prototype.slice.call(arguments);
8771
  }
8772
+ // otherwise a 2D array was passed in
8773
+
8774
  return this.iterator('table', function (settings) {
8775
  settings.aaSorting = order.slice();
8776
  });
8777
  });
8778
+
8779
+
8780
+ /**
8781
+ * Attach a sort listener to an element for a given column
8782
+ *
8783
+ * @param {node|jQuery|string} node Identifier for the element(s) to attach the
8784
+ * listener to. This can take the form of a single DOM node, a jQuery
8785
+ * collection of nodes or a jQuery selector which will identify the node(s).
8786
+ * @param {integer} column the column that a click on this node will sort on
8787
+ * @param {function} [callback] callback function when sort is run
8788
+ * @returns {DataTables.Api} this
8789
+ */
8790
  _api_register('order.listener()', function (node, column, callback) {
8791
  return this.iterator('table', function (settings) {
8792
  _fnSortAttachListener(settings, node, column, callback);
8793
  });
8794
  });
8795
+
8796
+
8797
  _api_register('order.fixed()', function (set) {
8798
  if (!set) {
8799
  var ctx = this.context;
8801
  ctx[0].aaSortingFixed :
8802
  undefined;
8803
 
8804
+ return $.isArray(fixed) ?
8805
+ {pre: fixed} :
 
8806
  fixed;
8807
  }
8808
+
8809
  return this.iterator('table', function (settings) {
8810
  settings.aaSortingFixed = $.extend(true, {}, set);
8811
  });
8812
  });
8813
+
8814
+
8815
+ // Order by the selected column(s)
8816
  _api_register([
8817
  'columns().order()',
8818
  'column().order()'
8829
  settings.aaSorting = sort;
8830
  });
8831
  });
8832
+
8833
+
8834
+
8835
  _api_register('search()', function (input, regex, smart, caseInsen) {
8836
  var ctx = this.context;
8837
 
8842
  undefined;
8843
  }
8844
 
8845
+ // set
8846
  return this.iterator('table', function (settings) {
8847
  if (!settings.oFeatures.bFilter) {
8848
  return;
8849
  }
8850
+
8851
  _fnFilterComplete(settings, $.extend({}, settings.oPreviousSearch, {
8852
  "sSearch": input + "",
8853
  "bRegex": regex === null ? false : regex,
8856
  }), 1);
8857
  });
8858
  });
8859
+
8860
+
8861
  _api_registerPlural(
8862
  'columns().search()',
8863
  'column().search()',
8867
 
8868
  if (input === undefined) {
8869
  // get
8870
+ return preSearch[ column ].sSearch;
8871
  }
8872
+
8873
+ // set
8874
  if (!settings.oFeatures.bFilter) {
8875
  return;
8876
  }
8877
 
8878
+ $.extend(preSearch[ column ], {
8879
  "sSearch": input + "",
8880
  "bRegex": regex === null ? false : regex,
8881
  "bSmart": smart === null ? true : smart,
8886
  });
8887
  }
8888
  );
8889
+
8890
+ /*
8891
+ * State API methods
8892
+ */
8893
+
8894
  _api_register('state()', function () {
8895
  return this.context.length ?
8896
  this.context[0].oSavedState :
8897
  null;
8898
  });
8899
+
8900
+
8901
  _api_register('state.clear()', function () {
8902
  return this.iterator('table', function (settings) {
8903
  // Save an empty object
8904
  settings.fnStateSaveCallback.call(settings.oInstance, settings, {});
8905
  });
8906
  });
8907
+
8908
+
8909
  _api_register('state.loaded()', function () {
8910
  return this.context.length ?
8911
  this.context[0].oLoadedState :
8912
  null;
8913
  });
8914
+
8915
+
8916
  _api_register('state.save()', function () {
8917
  return this.iterator('table', function (settings) {
8918
  _fnSaveState(settings);
8919
  });
8920
  });
8921
 
8922
+
8923
+
8924
+ /**
8925
+ * Provide a common method for plug-ins to check the version of DataTables being
8926
+ * used, in order to ensure compatibility.
8927
+ *
8928
+ * @param {string} version Version string to check for, in the format "X.Y.Z".
8929
+ * Note that the formats "X" and "X.Y" are also acceptable.
8930
+ * @returns {boolean} true if this version of DataTables is greater or equal to
8931
+ * the required version, or false if this version of DataTales is not
8932
+ * suitable
8933
+ * @static
8934
+ * @dtopt API-Static
8935
+ *
8936
+ * @example
8937
+ * alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
8938
+ */
8939
+ DataTable.versionCheck = DataTable.fnVersionCheck = function (version)
8940
+ {
8941
  var aThis = DataTable.version.split('.');
8942
  var aThat = version.split('.');
8943
  var iThis, iThat;
8945
  for (var i = 0, iLen = aThat.length; i < iLen; i++) {
8946
  iThis = parseInt(aThis[i], 10) || 0;
8947
  iThat = parseInt(aThat[i], 10) || 0;
8948
+
8949
+ // Parts are the same, keep comparing
8950
  if (iThis === iThat) {
8951
  continue;
8952
  }
8953
+
8954
+ // Parts are different, return immediately
8955
  return iThis > iThat;
8956
  }
8957
 
8958
  return true;
8959
  };
8960
 
8961
+
8962
+ /**
8963
+ * Check if a `<table>` node is a DataTable table already or not.
8964
+ *
8965
+ * @param {node|jquery|string} table Table node, jQuery object or jQuery
8966
+ * selector for the table to test. Note that if more than more than one
8967
+ * table is passed on, only the first will be checked
8968
+ * @returns {boolean} true the table given is a DataTable, or false otherwise
8969
+ * @static
8970
+ * @dtopt API-Static
8971
+ *
8972
+ * @example
8973
+ * if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
8974
+ * $('#example').dataTable();
8975
+ * }
8976
+ */
8977
+ DataTable.isDataTable = DataTable.fnIsDataTable = function (table)
8978
+ {
8979
  var t = $(table).get(0);
8980
  var is = false;
8981
 
8982
+ if (table instanceof DataTable.Api) {
8983
+ return true;
8984
+ }
8985
+
8986
  $.each(DataTable.settings, function (i, o) {
8987
  var head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;
8988
  var foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;
8989
+
8990
  if (o.nTable === t || head === t || foot === t) {
8991
  is = true;
8992
  }
8993
  });
8994
+
8995
  return is;
8996
  };
8997
+
8998
+
8999
+ /**
9000
+ * Get all DataTable tables that have been initialised - optionally you can
9001
+ * select to get only currently visible tables.
9002
+ *
9003
+ * @param {boolean} [visible=false] Flag to indicate if you want all (default)
9004
+ * or visible tables only.
9005
+ * @returns {array} Array of `table` nodes (not DataTable instances) which are
9006
+ * DataTables
9007
+ * @static
9008
+ * @dtopt API-Static
9009
+ *
9010
+ * @example
9011
+ * $.each( $.fn.dataTable.tables(true), function () {
9012
+ * $(table).DataTable().columns.adjust();
9013
+ * } );
9014
+ */
9015
+ DataTable.tables = DataTable.fnTables = function (visible)
9016
+ {
9017
  var api = false;
9018
 
9019
  if ($.isPlainObject(visible)) {
9032
  a;
9033
  };
9034
 
9035
+
9036
+ /**
9037
+ * Convert from camel case parameters to Hungarian notation. This is made public
9038
+ * for the extensions to provide the same ability as DataTables core to accept
9039
+ * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
9040
+ * parameters.
9041
+ *
9042
+ * @param {object} src The model object which holds all parameters that can be
9043
+ * mapped.
9044
+ * @param {object} user The object to convert from camel case to Hungarian.
9045
+ * @param {boolean} force When set to `true`, properties which already have a
9046
+ * Hungarian value in the `user` object will be overwritten. Otherwise they
9047
+ * won't be.
9048
+ */
9049
  DataTable.camelToHungarian = _fnCamelToHungarian;
9050
+
9051
+
9052
+
9053
+ /**
9054
+ *
9055
+ */
9056
  _api_register('$()', function (selector, opts) {
9057
  var
9058
  rows = this.rows(opts).nodes(), // Get all rows
9064
  ));
9065
  });
9066
 
9067
+
9068
+ // jQuery functions to operate on the tables
9069
  $.each(['on', 'one', 'off'], function (i, key) {
9070
  _api_register(key + '()', function ( /* event, handler */ ) {
9071
  var args = Array.prototype.slice.call(arguments);
9072
+
9073
+ // Add the `dt` namespace automatically if it isn't already present
9074
+ args[0] = $.map(args[0].split(/\s/), function (e) {
9075
+ return !e.match(/\.dt\b/) ?
9076
+ e + '.dt' :
9077
+ e;
9078
+ }).join(' ');
9079
+
9080
  var inst = $(this.tables().nodes());
9081
  inst[key].apply(inst, args);
9082
  return this;
9083
  });
9084
  });
9085
+
9086
+
9087
  _api_register('clear()', function () {
9088
  return this.iterator('table', function (settings) {
9089
  _fnClearTable(settings);
9090
  });
9091
  });
9092
+
9093
+
9094
  _api_register('settings()', function () {
9095
  return new _Api(this.context, this.context);
9096
  });
9097
+
9098
+
9099
  _api_register('init()', function () {
9100
  var ctx = this.context;
9101
  return ctx.length ? ctx[0].oInit : null;
9102
  });
9103
+
9104
+
9105
  _api_register('data()', function () {
9106
  return this.iterator('table', function (settings) {
9107
  return _pluck(settings.aoData, '_aData');
9108
  }).flatten();
9109
  });
9110
+
9111
+
9112
  _api_register('destroy()', function (remove) {
9113
  remove = remove || false;
9114
+
9115
  return this.iterator('table', function (settings) {
9116
  var orig = settings.nTableWrapper.parentNode;
9117
  var classes = settings.oClasses;
9126
  return r.nTr;
9127
  });
9128
  var i, ien;
9129
+
9130
+ // Flag to note that the table is currently being destroyed - no action
9131
+ // should be taken
9132
  settings.bDestroying = true;
9133
+
9134
+ // Fire off the destroy callbacks for plug-ins etc
9135
  _fnCallbackFire(settings, "aoDestroyCallback", "destroy", [settings]);
9136
 
9137
+ // If not being removed from the document, make all columns visible
9138
  if (!remove) {
9139
  new _Api(settings).columns().visible(true);
9140
  }
9141
 
9142
+ // Blitz all `DT` namespaced events (these are internal events, the
9143
+ // lowercase, `dt` events are user subscribed and they are responsible
9144
+ // for removing them
9145
+ jqWrapper.off('.DT').find(':not(tbody *)').off('.DT');
9146
+ $(window).off('.DT-' + settings.sInstance);
9147
 
9148
  // When scrolling we had to break the table up - restore it
9149
  if (table != thead.parentNode) {
9181
 
9182
  // Remove the DataTables generated nodes, events and classes
9183
  var removedMethod = remove ? 'remove' : 'detach';
9184
+ jqTable[ removedMethod ]();
9185
+ jqWrapper[ removedMethod ]();
9186
 
9187
  // If we need to reattach the table to the document
9188
  if (!remove && orig) {
9189
  // insertBefore acts like appendChild if !arg[1]
9190
  orig.insertBefore(table, settings.nTableReinsertBefore);
9191
 
9192
+ // Restore the width of the original table - was read from the style property,
9193
+ // so we can restore directly to that
9194
  jqTable
9195
  .css('width', settings.sDestroyWidth)
9196
  .removeClass(classes.sTable);
9197
 
9198
+ // If the were originally stripe classes - then we add them back here.
9199
+ // Note this is not fool proof (for example if not all rows had stripe
9200
+ // classes - but it's a good effort without getting carried away
9201
  ien = settings.asDestroyStripes.length;
9202
 
9203
  if (ien) {
9207
  }
9208
  }
9209
 
9210
+ /* Remove the settings object from the settings array */
9211
  var idx = $.inArray(settings, DataTable.settings);
9212
  if (idx !== -1) {
9213
  DataTable.settings.splice(idx, 1);
9215
  });
9216
  });
9217
 
9218
+
9219
+ // Add the `every()` method for rows, columns and cells in a compact form
9220
  $.each(['column', 'row', 'cell'], function (i, type) {
9221
  _api_register(type + 's().every()', function (fn) {
9222
  var opts = this.selector.opts;
9223
  var api = this;
9224
 
9225
  return this.iterator(type, function (settings, arg1, arg2, arg3, arg4) {
9226
+ // Rows and columns:
9227
+ // arg1 - index
9228
+ // arg2 - table counter
9229
+ // arg3 - loop counter
9230
+ // arg4 - undefined
9231
+ // Cells:
9232
+ // arg1 - row index
9233
+ // arg2 - column index
9234
+ // arg3 - table counter
9235
+ // arg4 - loop counter
9236
  fn.call(
9237
+ api[ type ](
9238
  arg1,
9239
  type === 'cell' ? arg2 : opts,
9240
  type === 'cell' ? opts : undefined
9245
  });
9246
  });
9247
 
9248
+
9249
+ // i18n method for extensions to be able to use the language object from the
9250
+ // DataTable
9251
  _api_register('i18n()', function (token, def, plural) {
9252
  var ctx = this.context[0];
9253
  var resolved = _fnGetObjectDataFn(token)(ctx.oLanguage);
9257
  }
9258
 
9259
  if (plural !== undefined && $.isPlainObject(resolved)) {
9260
+ resolved = resolved[ plural ] !== undefined ?
9261
+ resolved[ plural ] :
9262
  resolved._;
9263
  }
9264
 
9265
  return resolved.replace('%d', plural); // nb: plural might be undefined,
9266
  });
9267
 
9268
+ /**
9269
+ * Version string for plug-ins to check compatibility. Allowed format is
9270
+ * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
9271
+ * only for non-release builds. See http://semver.org/ for more information.
9272
+ * @member
9273
+ * @type string
9274
+ * @default Version number
9275
+ */
9276
+ DataTable.version = "1.10.15";
9277
+
9278
+ /**
9279
+ * Private data store, containing all of the settings objects that are
9280
+ * created for the tables on a given page.
9281
+ *
9282
+ * Note that the `DataTable.settings` object is aliased to
9283
+ * `jQuery.fn.dataTableExt` through which it may be accessed and
9284
+ * manipulated, or `jQuery.fn.dataTable.settings`.
9285
+ * @member
9286
+ * @type array
9287
+ * @default []
9288
+ * @private
9289
+ */
9290
  DataTable.settings = [];
9291
 
9292
+ /**
9293
+ * Object models container, for the various models that DataTables has
9294
+ * available to it. These models define the objects that are used to hold
9295
+ * the active state and configuration of the table.
9296
+ * @namespace
9297
+ */
9298
  DataTable.models = {};
9299
 
 
9300
 
9301
+
9302
+ /**
9303
+ * Template object for the way in which DataTables holds information about
9304
+ * search information for the global filter and individual column filters.
9305
+ * @namespace
9306
+ */
9307
+ DataTable.models.oSearch = {
9308
+ /**
9309
+ * Flag to indicate if the filtering should be case insensitive or not
9310
+ * @type boolean
9311
+ * @default true
9312
+ */
9313
  "bCaseInsensitive": true,
9314
 
9315
+ /**
9316
+ * Applied search term
9317
+ * @type string
9318
+ * @default <i>Empty string</i>
9319
+ */
9320
  "sSearch": "",
9321
 
9322
+ /**
9323
+ * Flag to indicate if the search term should be interpreted as a
9324
+ * regular expression (true) or not (false) and therefore and special
9325
+ * regex characters escaped.
9326
+ * @type boolean
9327
+ * @default false
9328
+ */
9329
  "bRegex": false,
9330
 
9331
+ /**
9332
+ * Flag to indicate if DataTables is to use its smart filtering or not.
9333
+ * @type boolean
9334
+ * @default true
9335
+ */
9336
  "bSmart": true
9337
  };
9338
 
9339
+
9340
+
9341
+
9342
+ /**
9343
+ * Template object for the way in which DataTables holds information about
9344
+ * each individual row. This is the object format used for the settings
9345
+ * aoData array.
9346
+ * @namespace
9347
+ */
9348
  DataTable.models.oRow = {
9349
+ /**
9350
+ * TR element for the row
9351
+ * @type node
9352
+ * @default null
9353
+ */
9354
  "nTr": null,
9355
+
9356
+ /**
9357
+ * Array of TD elements for each row. This is null until the row has been
9358
+ * created.
9359
+ * @type array nodes
9360
+ * @default []
9361
+ */
9362
  "anCells": null,
9363
+
9364
+ /**
9365
+ * Data object from the original data source for the row. This is either
9366
+ * an array if using the traditional form of DataTables, or an object if
9367
+ * using mData options. The exact type will depend on the passed in
9368
+ * data from the data source, or will be an array if using DOM a data
9369
+ * source.
9370
+ * @type array|object
9371
+ * @default []
9372
+ */
9373
  "_aData": [],
9374
+
9375
+ /**
9376
+ * Sorting data cache - this array is ostensibly the same length as the
9377
+ * number of columns (although each index is generated only as it is
9378
+ * needed), and holds the data that is used for sorting each column in the
9379
+ * row. We do this cache generation at the start of the sort in order that
9380
+ * the formatting of the sort data need be done only once for each cell
9381
+ * per sort. This array should not be read from or written to by anything
9382
+ * other than the master sorting methods.
9383
+ * @type array
9384
+ * @default null
9385
+ * @private
9386
+ */
9387
  "_aSortData": null,
9388
+
9389
+ /**
9390
+ * Per cell filtering data cache. As per the sort data cache, used to
9391
+ * increase the performance of the filtering in DataTables
9392
+ * @type array
9393
+ * @default null
9394
+ * @private
9395
+ */
9396
  "_aFilterData": null,
9397
+
9398
+ /**
9399
+ * Filtering data cache. This is the same as the cell filtering cache, but
9400
+ * in this case a string rather than an array. This is easily computed with
9401
+ * a join on `_aFilterData`, but is provided as a cache so the join isn't
9402
+ * needed on every search (memory traded for performance)
9403
+ * @type array
9404
+ * @default null
9405
+ * @private
9406
+ */
9407
  "_sFilterRow": null,
9408
+
9409
+ /**
9410
+ * Cache of the class name that DataTables has applied to the row, so we
9411
+ * can quickly look at this variable rather than needing to do a DOM check
9412
+ * on className for the nTr property.
9413
+ * @type string
9414
+ * @default <i>Empty string</i>
9415
+ * @private
9416
+ */
9417
  "_sRowStripe": "",
9418
+
9419
+ /**
9420
+ * Denote if the original data source was from the DOM, or the data source
9421
+ * object. This is used for invalidating data, so DataTables can
9422
+ * automatically read data from the original source, unless uninstructed
9423
+ * otherwise.
9424
+ * @type string
9425
+ * @default null
9426
+ * @private
9427
+ */
9428
  "src": null,
9429
+
9430
+ /**
9431
+ * Index in the aoData array. This saves an indexOf lookup when we have the
9432
+ * object, but want to know the index
9433
+ * @type integer
9434
+ * @default -1
9435
+ * @private
9436
+ */
9437
  "idx": -1
9438
  };
9439
 
 
9440
 
9441
+ /**
9442
+ * Template object for the column information object in DataTables. This object
9443
+ * is held in the settings aoColumns array and contains all the information that
9444
+ * DataTables needs about each individual column.
9445
+ *
9446
+ * Note that this object is related to {@link DataTable.defaults.column}
9447
+ * but this one is the internal data store for DataTables's cache of columns.
9448
+ * It should NOT be manipulated outside of DataTables. Any configuration should
9449
+ * be done through the initialisation options.
9450
+ * @namespace
9451
+ */
9452
+ DataTable.models.oColumn = {
9453
+ /**
9454
+ * Column index. This could be worked out on-the-fly with $.inArray, but it
9455
+ * is faster to just hold it as a variable
9456
+ * @type integer
9457
+ * @default null
9458
+ */
9459
  "idx": null,
9460
+
9461
+ /**
9462
+ * A list of the columns that sorting should occur on when this column
9463
+ * is sorted. That this property is an array allows multi-column sorting
9464
+ * to be defined for a column (for example first name / last name columns
9465
+ * would benefit from this). The values are integers pointing to the
9466
+ * columns to be sorted on (typically it will be a single integer pointing
9467
+ * at itself, but that doesn't need to be the case).
9468
+ * @type array
9469
+ */
9470
  "aDataSort": null,
9471
+
9472
+ /**
9473
+ * Define the sorting directions that are applied to the column, in sequence
9474
+ * as the column is repeatedly sorted upon - i.e. the first value is used
9475
+ * as the sorting direction when the column if first sorted (clicked on).
9476
+ * Sort it again (click again) and it will move on to the next index.
9477
+ * Repeat until loop.
9478
+ * @type array
9479
+ */
9480
  "asSorting": null,
9481
+
9482
+ /**
9483
+ * Flag to indicate if the column is searchable, and thus should be included
9484
+ * in the filtering or not.
9485
+ * @type boolean
9486
+ */
9487
  "bSearchable": null,
9488
+
9489
+ /**
9490
+ * Flag to indicate if the column is sortable or not.
9491
+ * @type boolean
9492
+ */
9493
  "bSortable": null,
9494
+
9495
+ /**
9496
+ * Flag to indicate if the column is currently visible in the table or not
9497
+ * @type boolean
9498
+ */
9499
  "bVisible": null,
9500
+
9501
+ /**
9502
+ * Store for manual type assignment using the `column.type` option. This
9503
+ * is held in store so we can manipulate the column's `sType` property.
9504
+ * @type string
9505
+ * @default null
9506
+ * @private
9507
+ */
9508
  "_sManualType": null,
9509
+
9510
+ /**
9511
+ * Flag to indicate if HTML5 data attributes should be used as the data
9512
+ * source for filtering or sorting. True is either are.
9513
+ * @type boolean
9514
+ * @default false
9515
+ * @private
9516
+ */
9517
  "_bAttrSrc": false,
9518
 
9519
+ /**
9520
+ * Developer definable function that is called whenever a cell is created (Ajax source,
9521
+ * etc) or processed for input (DOM source). This can be used as a compliment to mRender
9522
+ * allowing you to modify the DOM element (add background colour for example) when the
9523
+ * element is available.
9524
+ * @type function
9525
+ * @param {element} nTd The TD node that has been created
9526
+ * @param {*} sData The Data for the cell
9527
+ * @param {array|object} oData The data for the whole row
9528
+ * @param {int} iRow The row index for the aoData data store
9529
+ * @default null
9530
+ */
9531
  "fnCreatedCell": null,
9532
+
9533
+ /**
9534
+ * Function to get data from a cell in a column. You should <b>never</b>
9535
+ * access data directly through _aData internally in DataTables - always use
9536
+ * the method attached to this property. It allows mData to function as
9537
+ * required. This function is automatically assigned by the column
9538
+ * initialisation method
9539
+ * @type function
9540
+ * @param {array|object} oData The data array/object for the array
9541
+ * (i.e. aoData[]._aData)
9542
+ * @param {string} sSpecific The specific data type you want to get -
9543
+ * 'display', 'type' 'filter' 'sort'
9544
+ * @returns {*} The data for the cell from the given row's data
9545
+ * @default null
9546
+ */
9547
  "fnGetData": null,
9548
+
9549
+ /**
9550
+ * Function to set data for a cell in the column. You should <b>never</b>
9551
+ * set the data directly to _aData internally in DataTables - always use
9552
+ * this method. It allows mData to function as required. This function
9553
+ * is automatically assigned by the column initialisation method
9554
+ * @type function
9555
+ * @param {array|object} oData The data array/object for the array
9556
+ * (i.e. aoData[]._aData)
9557
+ * @param {*} sValue Value to set
9558
+ * @default null
9559
+ */
9560
  "fnSetData": null,
9561
+
9562
+ /**
9563
+ * Property to read the value for the cells in the column from the data
9564
+ * source array / object. If null, then the default content is used, if a
9565
+ * function is given then the return from the function is used.
9566
+ * @type function|int|string|null
9567
+ * @default null
9568
+ */
9569
  "mData": null,
9570
+
9571
+ /**
9572
+ * Partner property to mData which is used (only when defined) to get
9573
+ * the data - i.e. it is basically the same as mData, but without the
9574
+ * 'set' option, and also the data fed to it is the result from mData.
9575
+ * This is the rendering method to match the data method of mData.
9576
+ * @type function|int|string|null
9577
+ * @default null
9578
+ */
9579
  "mRender": null,
9580
+
9581
+ /**
9582
+ * Unique header TH/TD element for this column - this is what the sorting
9583
+ * listener is attached to (if sorting is enabled.)
9584
+ * @type node
9585
+ * @default null
9586
+ */
9587
  "nTh": null,
9588
+
9589
+ /**
9590
+ * Unique footer TH/TD element for this column (if there is one). Not used
9591
+ * in DataTables as such, but can be used for plug-ins to reference the
9592
+ * footer for each column.
9593
+ * @type node
9594
+ * @default null
9595
+ */
9596
  "nTf": null,
9597
+
9598
+ /**
9599
+ * The class to apply to all TD elements in the table's TBODY for the column
9600
+ * @type string
9601
+ * @default null
9602
+ */
9603
  "sClass": null,
9604
+
9605
+ /**
9606
+ * When DataTables calculates the column widths to assign to each column,
9607
+ * it finds the longest string in each column and then constructs a
9608
+ * temporary table and reads the widths from that. The problem with this
9609
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
9610
+ * string - thus the calculation can go wrong (doing it properly and putting
9611
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
9612
+ * a "work around" we provide this option. It will append its value to the
9613
+ * text that is found to be the longest string for the column - i.e. padding.
9614
+ * @type string
9615
+ */
9616
  "sContentPadding": null,
9617
+
9618
+ /**
9619
+ * Allows a default value to be given for a column's data, and will be used
9620
+ * whenever a null data source is encountered (this can be because mData
9621
+ * is set to null, or because the data source itself is null).
9622
+ * @type string
9623
+ * @default null
9624
+ */
9625
  "sDefaultContent": null,
9626
+
9627
+ /**
9628
+ * Name for the column, allowing reference to the column by name as well as
9629
+ * by index (needs a lookup to work by name).
9630
+ * @type string
9631
+ */
9632
  "sName": null,
9633
+
9634
+ /**
9635
+ * Custom sorting data type - defines which of the available plug-ins in
9636
+ * afnSortData the custom sorting will use - if any is defined.
9637
+ * @type string
9638
+ * @default std
9639
+ */
9640
  "sSortDataType": 'std',
9641
+
9642
+ /**
9643
+ * Class to be applied to the header element when sorting on this column
9644
+ * @type string
9645
+ * @default null
9646
+ */
9647
  "sSortingClass": null,
9648
+
9649
+ /**
9650
+ * Class to be applied to the header element when sorting on this column -
9651
+ * when jQuery UI theming is used.
9652
+ * @type string
9653
+ * @default null
9654
+ */
9655
  "sSortingClassJUI": null,
9656
+
9657
+ /**
9658
+ * Title of the column - what is seen in the TH element (nTh).
9659
+ * @type string
9660
+ */
9661
  "sTitle": null,
9662
+
9663
+ /**
9664
+ * Column sorting and filtering type
9665
+ * @type string
9666
+ * @default null
9667
+ */
9668
  "sType": null,
9669
+
9670
+ /**
9671
+ * Width of the column
9672
+ * @type string
9673
+ * @default null
9674
+ */
9675
  "sWidth": null,
9676
+
9677
+ /**
9678
+ * Width of the column when it was first "encountered"
9679
+ * @type string
9680
+ * @default null
9681
+ */
9682
  "sWidthOrig": null
9683
  };
9684
+
9685
+
9686
+ /*
9687
+ * Developer note: The properties of the object below are given in Hungarian
9688
+ * notation, that was used as the interface for DataTables prior to v1.10, however
9689
+ * from v1.10 onwards the primary interface is camel case. In order to avoid
9690
+ * breaking backwards compatibility utterly with this change, the Hungarian
9691
+ * version is still, internally the primary interface, but is is not documented
9692
+ * - hence the @name tags in each doc comment. This allows a Javascript function
9693
+ * to create a map from Hungarian notation to camel case (going the other direction
9694
+ * would require each property to be listed, which would at around 3K to the size
9695
+ * of DataTables, while this method is about a 0.5K hit.
9696
+ *
9697
+ * Ultimately this does pave the way for Hungarian notation to be dropped
9698
+ * completely, but that is a massive amount of work and will break current
9699
+ * installs (therefore is on-hold until v2).
9700
+ */
9701
+
9702
+ /**
9703
+ * Initialisation options that can be given to DataTables at initialisation
9704
+ * time.
9705
+ * @namespace
9706
+ */
9707
  DataTable.defaults = {
9708
+ /**
9709
+ * An array of data to use for the table, passed in at initialisation which
9710
+ * will be used in preference to any data which is already in the DOM. This is
9711
+ * particularly useful for constructing tables purely in Javascript, for
9712
+ * example with a custom Ajax call.
9713
+ * @type array
9714
+ * @default null
9715
+ *
9716
+ * @dtopt Option
9717
+ * @name DataTable.defaults.data
9718
+ *
9719
+ * @example
9720
+ * // Using a 2D array data source
9721
+ * $(document).ready( function () {
9722
+ * $('#example').dataTable( {
9723
+ * "data": [
9724
+ * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
9725
+ * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
9726
+ * ],
9727
+ * "columns": [
9728
+ * { "title": "Engine" },
9729
+ * { "title": "Browser" },
9730
+ * { "title": "Platform" },
9731
+ * { "title": "Version" },
9732
+ * { "title": "Grade" }
9733
+ * ]
9734
+ * } );
9735
+ * } );
9736
+ *
9737
+ * @example
9738
+ * // Using an array of objects as a data source (`data`)
9739
+ * $(document).ready( function () {
9740
+ * $('#example').dataTable( {
9741
+ * "data": [
9742
+ * {
9743
+ * "engine": "Trident",
9744
+ * "browser": "Internet Explorer 4.0",
9745
+ * "platform": "Win 95+",
9746
+ * "version": 4,
9747
+ * "grade": "X"
9748
+ * },
9749
+ * {
9750
+ * "engine": "Trident",
9751
+ * "browser": "Internet Explorer 5.0",
9752
+ * "platform": "Win 95+",
9753
+ * "version": 5,
9754
+ * "grade": "C"
9755
+ * }
9756
+ * ],
9757
+ * "columns": [
9758
+ * { "title": "Engine", "data": "engine" },
9759
+ * { "title": "Browser", "data": "browser" },
9760
+ * { "title": "Platform", "data": "platform" },
9761
+ * { "title": "Version", "data": "version" },
9762
+ * { "title": "Grade", "data": "grade" }
9763
+ * ]
9764
+ * } );
9765
+ * } );
9766
+ */
9767
  "aaData": null,
9768
+
9769
+ /**
9770
+ * If ordering is enabled, then DataTables will perform a first pass sort on
9771
+ * initialisation. You can define which column(s) the sort is performed
9772
+ * upon, and the sorting direction, with this variable. The `sorting` array
9773
+ * should contain an array for each column to be sorted initially containing
9774
+ * the column's index and a direction string ('asc' or 'desc').
9775
+ * @type array
9776
+ * @default [[0,'asc']]
9777
+ *
9778
+ * @dtopt Option
9779
+ * @name DataTable.defaults.order
9780
+ *
9781
+ * @example
9782
+ * // Sort by 3rd column first, and then 4th column
9783
+ * $(document).ready( function() {
9784
+ * $('#example').dataTable( {
9785
+ * "order": [[2,'asc'], [3,'desc']]
9786
+ * } );
9787
+ * } );
9788
+ *
9789
+ * // No initial sorting
9790
+ * $(document).ready( function() {
9791
+ * $('#example').dataTable( {
9792
+ * "order": []
9793
+ * } );
9794
+ * } );
9795
+ */
9796
+ "aaSorting": [[0, 'asc']],
9797
+
9798
+ /**
9799
+ * This parameter is basically identical to the `sorting` parameter, but
9800
+ * cannot be overridden by user interaction with the table. What this means
9801
+ * is that you could have a column (visible or hidden) which the sorting
9802
+ * will always be forced on first - any sorting after that (from the user)
9803
+ * will then be performed as required. This can be useful for grouping rows
9804
+ * together.
9805
+ * @type array
9806
+ * @default null
9807
+ *
9808
+ * @dtopt Option
9809
+ * @name DataTable.defaults.orderFixed
9810
+ *
9811
+ * @example
9812
+ * $(document).ready( function() {
9813
+ * $('#example').dataTable( {
9814
+ * "orderFixed": [[0,'asc']]
9815
+ * } );
9816
+ * } )
9817
+ */
9818
  "aaSortingFixed": [],
9819
+
9820
+ /**
9821
+ * DataTables can be instructed to load data to display in the table from a
9822
+ * Ajax source. This option defines how that Ajax call is made and where to.
9823
+ *
9824
+ * The `ajax` property has three different modes of operation, depending on
9825
+ * how it is defined. These are:
9826
+ *
9827
+ * * `string` - Set the URL from where the data should be loaded from.
9828
+ * * `object` - Define properties for `jQuery.ajax`.
9829
+ * * `function` - Custom data get function
9830
+ *
9831
+ * `string`
9832
+ * --------
9833
+ *
9834
+ * As a string, the `ajax` property simply defines the URL from which
9835
+ * DataTables will load data.
9836
+ *
9837
+ * `object`
9838
+ * --------
9839
+ *
9840
+ * As an object, the parameters in the object are passed to
9841
+ * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
9842
+ * of the Ajax request. DataTables has a number of default parameters which
9843
+ * you can override using this option. Please refer to the jQuery
9844
+ * documentation for a full description of the options available, although
9845
+ * the following parameters provide additional options in DataTables or
9846
+ * require special consideration:
9847
+ *
9848
+ * * `data` - As with jQuery, `data` can be provided as an object, but it
9849
+ * can also be used as a function to manipulate the data DataTables sends
9850
+ * to the server. The function takes a single parameter, an object of
9851
+ * parameters with the values that DataTables has readied for sending. An
9852
+ * object may be returned which will be merged into the DataTables
9853
+ * defaults, or you can add the items to the object that was passed in and
9854
+ * not return anything from the function. This supersedes `fnServerParams`
9855
+ * from DataTables 1.9-.
9856
+ *
9857
+ * * `dataSrc` - By default DataTables will look for the property `data` (or
9858
+ * `aaData` for compatibility with DataTables 1.9-) when obtaining data
9859
+ * from an Ajax source or for server-side processing - this parameter
9860
+ * allows that property to be changed. You can use Javascript dotted
9861
+ * object notation to get a data source for multiple levels of nesting, or
9862
+ * it my be used as a function. As a function it takes a single parameter,
9863
+ * the JSON returned from the server, which can be manipulated as
9864
+ * required, with the returned value being that used by DataTables as the
9865
+ * data source for the table. This supersedes `sAjaxDataProp` from
9866
+ * DataTables 1.9-.
9867
+ *
9868
+ * * `success` - Should not be overridden it is used internally in
9869
+ * DataTables. To manipulate / transform the data returned by the server
9870
+ * use `ajax.dataSrc`, or use `ajax` as a function (see below).
9871
+ *
9872
+ * `function`
9873
+ * ----------
9874
+ *
9875
+ * As a function, making the Ajax call is left up to yourself allowing
9876
+ * complete control of the Ajax request. Indeed, if desired, a method other
9877
+ * than Ajax could be used to obtain the required data, such as Web storage
9878
+ * or an AIR database.
9879
+ *
9880
+ * The function is given four parameters and no return is required. The
9881
+ * parameters are:
9882
+ *
9883
+ * 1. _object_ - Data to send to the server
9884
+ * 2. _function_ - Callback function that must be executed when the required
9885
+ * data has been obtained. That data should be passed into the callback
9886
+ * as the only parameter
9887
+ * 3. _object_ - DataTables settings object for the table
9888
+ *
9889
+ * Note that this supersedes `fnServerData` from DataTables 1.9-.
9890
+ *
9891
+ * @type string|object|function
9892
+ * @default null
9893
+ *
9894
+ * @dtopt Option
9895
+ * @name DataTable.defaults.ajax
9896
+ * @since 1.10.0
9897
+ *
9898
+ * @example
9899
+ * // Get JSON data from a file via Ajax.
9900
+ * // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
9901
+ * $('#example').dataTable( {
9902
+ * "ajax": "data.json"
9903
+ * } );
9904
+ *
9905
+ * @example
9906
+ * // Get JSON data from a file via Ajax, using `dataSrc` to change
9907
+ * // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
9908
+ * $('#example').dataTable( {
9909
+ * "ajax": {
9910
+ * "url": "data.json",
9911
+ * "dataSrc": "tableData"
9912
+ * }
9913
+ * } );
9914
+ *
9915
+ * @example
9916
+ * // Get JSON data from a file via Ajax, using `dataSrc` to read data
9917
+ * // from a plain array rather than an array in an object
9918
+ * $('#example').dataTable( {
9919
+ * "ajax": {
9920
+ * "url": "data.json",
9921
+ * "dataSrc": ""
9922
+ * }
9923
+ * } );
9924
+ *
9925
+ * @example
9926
+ * // Manipulate the data returned from the server - add a link to data
9927
+ * // (note this can, should, be done using `render` for the column - this
9928
+ * // is just a simple example of how the data can be manipulated).
9929
+ * $('#example').dataTable( {
9930
+ * "ajax": {
9931
+ * "url": "data.json",
9932
+ * "dataSrc": function ( json ) {
9933
+ * for ( var i=0, ien=json.length ; i<ien ; i++ ) {
9934
+ * json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
9935
+ * }
9936
+ * return json;
9937
+ * }
9938
+ * }
9939
+ * } );
9940
+ *
9941
+ * @example
9942
+ * // Add data to the request
9943
+ * $('#example').dataTable( {
9944
+ * "ajax": {
9945
+ * "url": "data.json",
9946
+ * "data": function ( d ) {
9947
+ * return {
9948
+ * "extra_search": $('#extra').val()
9949
+ * };
9950
+ * }
9951
+ * }
9952
+ * } );
9953
+ *
9954
+ * @example
9955
+ * // Send request as POST
9956
+ * $('#example').dataTable( {
9957
+ * "ajax": {
9958
+ * "url": "data.json",
9959
+ * "type": "POST"
9960
+ * }
9961
+ * } );
9962
+ *
9963
+ * @example
9964
+ * // Get the data from localStorage (could interface with a form for
9965
+ * // adding, editing and removing rows).
9966
+ * $('#example').dataTable( {
9967
+ * "ajax": function (data, callback, settings) {
9968
+ * callback(
9969
+ * JSON.parse( localStorage.getItem('dataTablesData') )
9970
+ * );
9971
+ * }
9972
+ * } );
9973
+ */
9974
  "ajax": null,
9975
+
9976
+ /**
9977
+ * This parameter allows you to readily specify the entries in the length drop
9978
+ * down menu that DataTables shows when pagination is enabled. It can be
9979
+ * either a 1D array of options which will be used for both the displayed
9980
+ * option and the value, or a 2D array which will use the array in the first
9981
+ * position as the value, and the array in the second position as the
9982
+ * displayed options (useful for language strings such as 'All').
9983
+ *
9984
+ * Note that the `pageLength` property will be automatically set to the
9985
+ * first value given in this array, unless `pageLength` is also provided.
9986
+ * @type array
9987
+ * @default [ 10, 25, 50, 100 ]
9988
+ *
9989
+ * @dtopt Option
9990
+ * @name DataTable.defaults.lengthMenu
9991
+ *
9992
+ * @example
9993
+ * $(document).ready( function() {
9994
+ * $('#example').dataTable( {
9995
+ * "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
9996
+ * } );
9997
+ * } );
9998
+ */
9999
  "aLengthMenu": [10, 25, 50, 100],
10000
+
10001
+ /**
10002
+ * The `columns` option in the initialisation parameter allows you to define
10003
+ * details about the way individual columns behave. For a full list of
10004
+ * column options that can be set, please see
10005
+ * {@link DataTable.defaults.column}. Note that if you use `columns` to
10006
+ * define your columns, you must have an entry in the array for every single
10007
+ * column that you have in your table (these can be null if you don't which
10008
+ * to specify any options).
10009
+ * @member
10010
+ *
10011
+ * @name DataTable.defaults.column
10012
+ */
10013
  "aoColumns": null,
10014
+
10015
+ /**
10016
+ * Very similar to `columns`, `columnDefs` allows you to target a specific
10017
+ * column, multiple columns, or all columns, using the `targets` property of
10018
+ * each object in the array. This allows great flexibility when creating
10019
+ * tables, as the `columnDefs` arrays can be of any length, targeting the
10020
+ * columns you specifically want. `columnDefs` may use any of the column
10021
+ * options available: {@link DataTable.defaults.column}, but it _must_
10022
+ * have `targets` defined in each object in the array. Values in the `targets`
10023
+ * array may be:
10024
+ * <ul>
10025
+ * <li>a string - class name will be matched on the TH for the column</li>
10026
+ * <li>0 or a positive integer - column index counting from the left</li>
10027
+ * <li>a negative integer - column index counting from the right</li>
10028
+ * <li>the string "_all" - all columns (i.e. assign a default)</li>
10029
+ * </ul>
10030
+ * @member
10031
+ *
10032
+ * @name DataTable.defaults.columnDefs
10033
+ */
10034
  "aoColumnDefs": null,
10035
+
10036
+ /**
10037
+ * Basically the same as `search`, this parameter defines the individual column
10038
+ * filtering state at initialisation time. The array must be of the same size
10039
+ * as the number of columns, and each element be an object with the parameters
10040
+ * `search` and `escapeRegex` (the latter is optional). 'null' is also
10041
+ * accepted and the default will be used.
10042
+ * @type array
10043
+ * @default []
10044
+ *
10045
+ * @dtopt Option
10046
+ * @name DataTable.defaults.searchCols
10047
+ *
10048
+ * @example
10049
+ * $(document).ready( function() {
10050
+ * $('#example').dataTable( {
10051
+ * "searchCols": [
10052
+ * null,
10053
+ * { "search": "My filter" },
10054
+ * null,
10055
+ * { "search": "^[0-9]", "escapeRegex": false }
10056
+ * ]
10057
+ * } );
10058
+ * } )
10059
+ */
10060
  "aoSearchCols": [],
10061
+
10062
+ /**
10063
+ * An array of CSS classes that should be applied to displayed rows. This
10064
+ * array may be of any length, and DataTables will apply each class
10065
+ * sequentially, looping when required.
10066
+ * @type array
10067
+ * @default null <i>Will take the values determined by the `oClasses.stripe*`
10068
+ * options</i>
10069
+ *
10070
+ * @dtopt Option
10071
+ * @name DataTable.defaults.stripeClasses
10072
+ *
10073
+ * @example
10074
+ * $(document).ready( function() {
10075
+ * $('#example').dataTable( {
10076
+ * "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
10077
+ * } );
10078
+ * } )
10079
+ */
10080
  "asStripeClasses": null,
10081
+
10082
+ /**
10083
+ * Enable or disable automatic column width calculation. This can be disabled
10084
+ * as an optimisation (it takes some time to calculate the widths) if the
10085
+ * tables widths are passed in using `columns`.
10086
+ * @type boolean
10087
+ * @default true
10088
+ *
10089
+ * @dtopt Features
10090
+ * @name DataTable.defaults.autoWidth
10091
+ *
10092
+ * @example
10093
+ * $(document).ready( function () {
10094
+ * $('#example').dataTable( {
10095
+ * "autoWidth": false
10096
+ * } );
10097
+ * } );
10098
+ */
10099
  "bAutoWidth": true,
10100
+
10101
+ /**
10102
+ * Deferred rendering can provide DataTables with a huge speed boost when you
10103
+ * are using an Ajax or JS data source for the table. This option, when set to
10104
+ * true, will cause DataTables to defer the creation of the table elements for
10105
+ * each row until they are needed for a draw - saving a significant amount of
10106
+ * time.
10107
+ * @type boolean
10108
+ * @default false
10109
+ *
10110
+ * @dtopt Features
10111
+ * @name DataTable.defaults.deferRender
10112
+ *
10113
+ * @example
10114
+ * $(document).ready( function() {
10115
+ * $('#example').dataTable( {
10116
+ * "ajax": "sources/arrays.txt",
10117
+ * "deferRender": true
10118
+ * } );
10119
+ * } );
10120
+ */
10121
  "bDeferRender": false,
10122
+
10123
+ /**
10124
+ * Replace a DataTable which matches the given selector and replace it with
10125
+ * one which has the properties of the new initialisation object passed. If no
10126
+ * table matches the selector, then the new DataTable will be constructed as
10127
+ * per normal.
10128
+ * @type boolean
10129
+ * @default false
10130
+ *
10131
+ * @dtopt Options
10132
+ * @name DataTable.defaults.destroy
10133
+ *
10134
+ * @example
10135
+ * $(document).ready( function() {
10136
+ * $('#example').dataTable( {
10137
+ * "srollY": "200px",
10138
+ * "paginate": false
10139
+ * } );
10140
+ *
10141
+ * // Some time later....
10142
+ * $('#example').dataTable( {
10143
+ * "filter": false,
10144
+ * "destroy": true
10145
+ * } );
10146
+ * } );
10147
+ */
10148
  "bDestroy": false,
10149
+
10150
+ /**
10151
+ * Enable or disable filtering of data. Filtering in DataTables is "smart" in
10152
+ * that it allows the end user to input multiple words (space separated) and
10153
+ * will match a row containing those words, even if not in the order that was
10154
+ * specified (this allow matching across multiple columns). Note that if you
10155
+ * wish to use filtering in DataTables this must remain 'true' - to remove the
10156
+ * default filtering input box and retain filtering abilities, please use
10157
+ * {@link DataTable.defaults.dom}.
10158
+ * @type boolean
10159
+ * @default true
10160
+ *
10161
+ * @dtopt Features
10162
+ * @name DataTable.defaults.searching
10163
+ *
10164
+ * @example
10165
+ * $(document).ready( function () {
10166
+ * $('#example').dataTable( {
10167
+ * "searching": false
10168
+ * } );
10169
+ * } );
10170
+ */
10171
  "bFilter": true,
10172
+
10173
+ /**
10174
+ * Enable or disable the table information display. This shows information
10175
+ * about the data that is currently visible on the page, including information
10176
+ * about filtered data if that action is being performed.
10177
+ * @type boolean
10178
+ * @default true
10179
+ *
10180
+ * @dtopt Features
10181
+ * @name DataTable.defaults.info
10182
+ *
10183
+ * @example
10184
+ * $(document).ready( function () {
10185
+ * $('#example').dataTable( {
10186
+ * "info": false
10187
+ * } );
10188
+ * } );
10189
+ */
10190
  "bInfo": true,
10191
+
10192
+ /**
10193
+ * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
10194
+ * slightly different and additional mark-up from what DataTables has
10195
+ * traditionally used).
10196
+ * @type boolean
10197
+ * @default false
10198
+ *
10199
+ * @dtopt Features
10200
+ * @name DataTable.defaults.jQueryUI
10201
+ *
10202
+ * @example
10203
+ * $(document).ready( function() {
10204
+ * $('#example').dataTable( {
10205
+ * "jQueryUI": true
10206
+ * } );
10207
+ * } );
10208
+ */
10209
  "bJQueryUI": false,
10210
+
10211
+ /**
10212
+ * Allows the end user to select the size of a formatted page from a select
10213
+ * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
10214
+ * @type boolean
10215
+ * @default true
10216
+ *
10217
+ * @dtopt Features
10218
+ * @name DataTable.defaults.lengthChange
10219
+ *
10220
+ * @example
10221
+ * $(document).ready( function () {
10222
+ * $('#example').dataTable( {
10223
+ * "lengthChange": false
10224
+ * } );
10225
+ * } );
10226
+ */
10227
  "bLengthChange": true,
10228
+
10229
+ /**
10230
+ * Enable or disable pagination.
10231
+ * @type boolean
10232
+ * @default true
10233
+ *
10234
+ * @dtopt Features
10235
+ * @name DataTable.defaults.paging
10236
+ *
10237
+ * @example
10238
+ * $(document).ready( function () {
10239
+ * $('#example').dataTable( {
10240
+ * "paging": false
10241
+ * } );
10242
+ * } );
10243
+ */
10244
  "bPaginate": true,
10245
+
10246
+ /**
10247
+ * Enable or disable the display of a 'processing' indicator when the table is
10248
+ * being processed (e.g. a sort). This is particularly useful for tables with
10249
+ * large amounts of data where it can take a noticeable amount of time to sort
10250
+ * the entries.
10251
+ * @type boolean
10252
+ * @default false
10253
+ *
10254
+ * @dtopt Features
10255
+ * @name DataTable.defaults.processing
10256
+ *
10257
+ * @example
10258
+ * $(document).ready( function () {
10259
+ * $('#example').dataTable( {
10260
+ * "processing": true
10261
+ * } );
10262
+ * } );
10263
+ */
10264
  "bProcessing": false,
10265
+
10266
+ /**
10267
+ * Retrieve the DataTables object for the given selector. Note that if the
10268
+ * table has already been initialised, this parameter will cause DataTables
10269
+ * to simply return the object that has already been set up - it will not take
10270
+ * account of any changes you might have made to the initialisation object
10271
+ * passed to DataTables (setting this parameter to true is an acknowledgement
10272
+ * that you understand this). `destroy` can be used to reinitialise a table if
10273
+ * you need.
10274
+ * @type boolean
10275
+ * @default false
10276
+ *
10277
+ * @dtopt Options
10278
+ * @name DataTable.defaults.retrieve
10279
+ *
10280
+ * @example
10281
+ * $(document).ready( function() {
10282
+ * initTable();
10283
+ * tableActions();
10284
+ * } );
10285
+ *
10286
+ * function initTable ()
10287
+ * {
10288
+ * return $('#example').dataTable( {
10289
+ * "scrollY": "200px",
10290
+ * "paginate": false,
10291
+ * "retrieve": true
10292
+ * } );
10293
+ * }
10294
+ *
10295
+ * function tableActions ()
10296
+ * {
10297
+ * var table = initTable();
10298
+ * // perform API operations with oTable
10299
+ * }
10300
+ */
10301
  "bRetrieve": false,
10302
+
10303
+ /**
10304
+ * When vertical (y) scrolling is enabled, DataTables will force the height of
10305
+ * the table's viewport to the given height at all times (useful for layout).
10306
+ * However, this can look odd when filtering data down to a small data set,
10307
+ * and the footer is left "floating" further down. This parameter (when
10308
+ * enabled) will cause DataTables to collapse the table's viewport down when
10309
+ * the result set will fit within the given Y height.
10310
+ * @type boolean
10311
+ * @default false
10312
+ *
10313
+ * @dtopt Options
10314
+ * @name DataTable.defaults.scrollCollapse
10315
+ *
10316
+ * @example
10317
+ * $(document).ready( function() {
10318
+ * $('#example').dataTable( {
10319
+ * "scrollY": "200",
10320
+ * "scrollCollapse": true
10321
+ * } );
10322
+ * } );
10323
+ */
10324
  "bScrollCollapse": false,
10325
+
10326
+ /**
10327
+ * Configure DataTables to use server-side processing. Note that the
10328
+ * `ajax` parameter must also be given in order to give DataTables a
10329
+ * source to obtain the required data for each draw.
10330
+ * @type boolean
10331
+ * @default false
10332
+ *
10333
+ * @dtopt Features
10334
+ * @dtopt Server-side
10335
+ * @name DataTable.defaults.serverSide
10336
+ *
10337
+ * @example
10338
+ * $(document).ready( function () {
10339
+ * $('#example').dataTable( {
10340
+ * "serverSide": true,
10341
+ * "ajax": "xhr.php"
10342
+ * } );
10343
+ * } );
10344
+ */
10345
  "bServerSide": false,
10346
+
10347
+ /**
10348
+ * Enable or disable sorting of columns. Sorting of individual columns can be
10349
+ * disabled by the `sortable` option for each column.
10350
+ * @type boolean
10351
+ * @default true
10352
+ *
10353
+ * @dtopt Features
10354
+ * @name DataTable.defaults.ordering
10355
+ *
10356
+ * @example
10357
+ * $(document).ready( function () {
10358
+ * $('#example').dataTable( {
10359
+ * "ordering": false
10360
+ * } );
10361
+ * } );
10362
+ */
10363
  "bSort": true,
10364
+
10365
+ /**
10366
+ * Enable or display DataTables' ability to sort multiple columns at the
10367
+ * same time (activated by shift-click by the user).
10368
+ * @type boolean
10369
+ * @default true
10370
+ *
10371
+ * @dtopt Options
10372
+ * @name DataTable.defaults.orderMulti
10373
+ *
10374
+ * @example
10375
+ * // Disable multiple column sorting ability
10376
+ * $(document).ready( function () {
10377
+ * $('#example').dataTable( {
10378
+ * "orderMulti": false
10379
+ * } );
10380
+ * } );
10381
+ */
10382
  "bSortMulti": true,
10383
+
10384
+ /**
10385
+ * Allows control over whether DataTables should use the top (true) unique
10386
+ * cell that is found for a single column, or the bottom (false - default).
10387
+ * This is useful when using complex headers.
10388
+ * @type boolean
10389
+ * @default false
10390
+ *
10391
+ * @dtopt Options
10392
+ * @name DataTable.defaults.orderCellsTop
10393
+ *
10394
+ * @example
10395
+ * $(document).ready( function() {
10396
+ * $('#example').dataTable( {
10397
+ * "orderCellsTop": true
10398
+ * } );
10399
+ * } );
10400
+ */
10401
  "bSortCellsTop": false,
10402
+
10403
+ /**
10404
+ * Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
10405
+ * `sorting\_3` to the columns which are currently being sorted on. This is
10406
+ * presented as a feature switch as it can increase processing time (while
10407
+ * classes are removed and added) so for large data sets you might want to
10408
+ * turn this off.
10409
+ * @type boolean
10410
+ * @default true
10411
+ *
10412
+ * @dtopt Features
10413
+ * @name DataTable.defaults.orderClasses
10414
+ *
10415
+ * @example
10416
+ * $(document).ready( function () {
10417
+ * $('#example').dataTable( {
10418
+ * "orderClasses": false
10419
+ * } );
10420
+ * } );
10421
+ */
10422
  "bSortClasses": true,
10423
+
10424
+ /**
10425
+ * Enable or disable state saving. When enabled HTML5 `localStorage` will be
10426
+ * used to save table display information such as pagination information,
10427
+ * display length, filtering and sorting. As such when the end user reloads
10428
+ * the page the display display will match what thy had previously set up.
10429
+ *
10430
+ * Due to the use of `localStorage` the default state saving is not supported
10431
+ * in IE6 or 7. If state saving is required in those browsers, use
10432
+ * `stateSaveCallback` to provide a storage solution such as cookies.
10433
+ * @type boolean
10434
+ * @default false
10435
+ *
10436
+ * @dtopt Features
10437
+ * @name DataTable.defaults.stateSave
10438
+ *
10439
+ * @example
10440
+ * $(document).ready( function () {
10441
+ * $('#example').dataTable( {
10442
+ * "stateSave": true
10443
+ * } );
10444
+ * } );
10445
+ */
10446
  "bStateSave": false,
10447
+
10448
+ /**
10449
+ * This function is called when a TR element is created (and all TD child
10450
+ * elements have been inserted), or registered if using a DOM source, allowing
10451
+ * manipulation of the TR element (adding classes etc).
10452
+ * @type function
10453
+ * @param {node} row "TR" element for the current row
10454
+ * @param {array} data Raw data array for this row
10455
+ * @param {int} dataIndex The index of this row in the internal aoData array
10456
+ *
10457
+ * @dtopt Callbacks
10458
+ * @name DataTable.defaults.createdRow
10459
+ *
10460
+ * @example
10461
+ * $(document).ready( function() {
10462
+ * $('#example').dataTable( {
10463
+ * "createdRow": function( row, data, dataIndex ) {
10464
+ * // Bold the grade for all 'A' grade browsers
10465
+ * if ( data[4] == "A" )
10466
+ * {
10467
+ * $('td:eq(4)', row).html( '<b>A</b>' );
10468
+ * }
10469
+ * }
10470
+ * } );
10471
+ * } );
10472
+ */
10473
  "fnCreatedRow": null,
10474
+
10475
+ /**
10476
+ * This function is called on every 'draw' event, and allows you to
10477
+ * dynamically modify any aspect you want about the created DOM.
10478
+ * @type function
10479
+ * @param {object} settings DataTables settings object
10480
+ *
10481
+ * @dtopt Callbacks
10482
+ * @name DataTable.defaults.drawCallback
10483
+ *
10484
+ * @example
10485
+ * $(document).ready( function() {
10486
+ * $('#example').dataTable( {
10487
+ * "drawCallback": function( settings ) {
10488
+ * alert( 'DataTables has redrawn the table' );
10489
+ * }
10490
+ * } );
10491
+ * } );
10492
+ */
10493
  "fnDrawCallback": null,
10494
+
10495
+ /**
10496
+ * Identical to fnHeaderCallback() but for the table footer this function
10497
+ * allows you to modify the table footer on every 'draw' event.
10498
+ * @type function
10499
+ * @param {node} foot "TR" element for the footer
10500
+ * @param {array} data Full table data (as derived from the original HTML)
10501
+ * @param {int} start Index for the current display starting point in the
10502
+ * display array
10503
+ * @param {int} end Index for the current display ending point in the
10504
+ * display array
10505
+ * @param {array int} display Index array to translate the visual position
10506
+ * to the full data array
10507
+ *
10508
+ * @dtopt Callbacks
10509
+ * @name DataTable.defaults.footerCallback
10510
+ *
10511
+ * @example
10512
+ * $(document).ready( function() {
10513
+ * $('#example').dataTable( {
10514
+ * "footerCallback": function( tfoot, data, start, end, display ) {
10515
+ * tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
10516
+ * }
10517
+ * } );
10518
+ * } )
10519
+ */
10520
  "fnFooterCallback": null,
10521
+
10522
+ /**
10523
+ * When rendering large numbers in the information element for the table
10524
+ * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
10525
+ * to have a comma separator for the 'thousands' units (e.g. 1 million is
10526
+ * rendered as "1,000,000") to help readability for the end user. This
10527
+ * function will override the default method DataTables uses.
10528
+ * @type function
10529
+ * @member
10530
+ * @param {int} toFormat number to be formatted
10531
+ * @returns {string} formatted string for DataTables to show the number
10532
+ *
10533
+ * @dtopt Callbacks
10534
+ * @name DataTable.defaults.formatNumber
10535
+ *
10536
+ * @example
10537
+ * // Format a number using a single quote for the separator (note that
10538
+ * // this can also be done with the language.thousands option)
10539
+ * $(document).ready( function() {
10540
+ * $('#example').dataTable( {
10541
+ * "formatNumber": function ( toFormat ) {
10542
+ * return toFormat.toString().replace(
10543
+ * /\B(?=(\d{3})+(?!\d))/g, "'"
10544
+ * );
10545
+ * };
10546
+ * } );
10547
+ * } );
10548
+ */
10549
  "fnFormatNumber": function (toFormat) {
10550
  return toFormat.toString().replace(
10551
  /\B(?=(\d{3})+(?!\d))/g,
10552
  this.oLanguage.sThousands
10553
  );
10554
  },
10555
+
10556
+ /**
10557
+ * This function is called on every 'draw' event, and allows you to
10558
+ * dynamically modify the header row. This can be used to calculate and
10559
+ * display useful information about the table.
10560
+ * @type function
10561
+ * @param {node} head "TR" element for the header
10562
+ * @param {array} data Full table data (as derived from the original HTML)
10563
+ * @param {int} start Index for the current display starting point in the
10564
+ * display array
10565
+ * @param {int} end Index for the current display ending point in the
10566
+ * display array
10567
+ * @param {array int} display Index array to translate the visual position
10568
+ * to the full data array
10569
+ *
10570
+ * @dtopt Callbacks
10571
+ * @name DataTable.defaults.headerCallback
10572
+ *
10573
+ * @example
10574
+ * $(document).ready( function() {
10575
+ * $('#example').dataTable( {
10576
+ * "fheaderCallback": function( head, data, start, end, display ) {
10577
+ * head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
10578
+ * }
10579
+ * } );
10580
+ * } )
10581
+ */
10582
  "fnHeaderCallback": null,
10583
+
10584
+ /**
10585
+ * The information element can be used to convey information about the current
10586
+ * state of the table. Although the internationalisation options presented by
10587
+ * DataTables are quite capable of dealing with most customisations, there may
10588
+ * be times where you wish to customise the string further. This callback
10589
+ * allows you to do exactly that.
10590
+ * @type function
10591
+ * @param {object} oSettings DataTables settings object
10592
+ * @param {int} start Starting position in data for the draw
10593
+ * @param {int} end End position in data for the draw
10594
+ * @param {int} max Total number of rows in the table (regardless of
10595
+ * filtering)
10596
+ * @param {int} total Total number of rows in the data set, after filtering
10597
+ * @param {string} pre The string that DataTables has formatted using it's
10598
+ * own rules
10599
+ * @returns {string} The string to be displayed in the information element.
10600
+ *
10601
+ * @dtopt Callbacks
10602
+ * @name DataTable.defaults.infoCallback
10603
+ *
10604
+ * @example
10605
+ * $('#example').dataTable( {
10606
+ * "infoCallback": function( settings, start, end, max, total, pre ) {
10607
+ * return start +" to "+ end;
10608
+ * }
10609
+ * } );
10610
+ */
10611
  "fnInfoCallback": null,
10612
+
10613
+ /**
10614
+ * Called when the table has been initialised. Normally DataTables will
10615
+ * initialise sequentially and there will be no need for this function,
10616
+ * however, this does not hold true when using external language information
10617
+ * since that is obtained using an async XHR call.
10618
+ * @type function
10619
+ * @param {object} settings DataTables settings object
10620
+ * @param {object} json The JSON object request from the server - only
10621
+ * present if client-side Ajax sourced data is used
10622
+ *
10623
+ * @dtopt Callbacks
10624
+ * @name DataTable.defaults.initComplete
10625
+ *
10626
+ * @example
10627
+ * $(document).ready( function() {
10628
+ * $('#example').dataTable( {
10629
+ * "initComplete": function(settings, json) {
10630
+ * alert( 'DataTables has finished its initialisation.' );
10631
+ * }
10632
+ * } );
10633
+ * } )
10634
+ */
10635
  "fnInitComplete": null,
10636
+
10637
+ /**
10638
+ * Called at the very start of each table draw and can be used to cancel the
10639
+ * draw by returning false, any other return (including undefined) results in
10640
+ * the full draw occurring).
10641
+ * @type function
10642
+ * @param {object} settings DataTables settings object
10643
+ * @returns {boolean} False will cancel the draw, anything else (including no
10644
+ * return) will allow it to complete.
10645
+ *
10646
+ * @dtopt Callbacks
10647
+ * @name DataTable.defaults.preDrawCallback
10648
+ *
10649
+ * @example
10650
+ * $(document).ready( function() {
10651
+ * $('#example').dataTable( {
10652
+ * "preDrawCallback": function( settings ) {
10653
+ * if ( $('#test').val() == 1 ) {
10654
+ * return false;
10655
+ * }
10656
+ * }
10657
+ * } );
10658
+ * } );
10659
+ */
10660
  "fnPreDrawCallback": null,
10661
+
10662
+ /**
10663
+ * This function allows you to 'post process' each row after it have been
10664
+ * generated for each table draw, but before it is rendered on screen. This
10665
+ * function might be used for setting the row class name etc.
10666
+ * @type function
10667
+ * @param {node} row "TR" element for the current row
10668
+ * @param {array} data Raw data array for this row
10669
+ * @param {int} displayIndex The display index for the current table draw
10670
+ * @param {int} displayIndexFull The index of the data in the full list of
10671
+ * rows (after filtering)
10672
+ *
10673
+ * @dtopt Callbacks
10674
+ * @name DataTable.defaults.rowCallback
10675
+ *
10676
+ * @example
10677
+ * $(document).ready( function() {
10678
+ * $('#example').dataTable( {
10679
+ * "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
10680
+ * // Bold the grade for all 'A' grade browsers
10681
+ * if ( data[4] == "A" ) {
10682
+ * $('td:eq(4)', row).html( '<b>A</b>' );
10683
+ * }
10684
+ * }
10685
+ * } );
10686
+ * } );
10687
+ */
10688
  "fnRowCallback": null,
10689
+
10690
+ /**
10691
+ * __Deprecated__ The functionality provided by this parameter has now been
10692
+ * superseded by that provided through `ajax`, which should be used instead.
10693
+ *
10694
+ * This parameter allows you to override the default function which obtains
10695
+ * the data from the server so something more suitable for your application.
10696
+ * For example you could use POST data, or pull information from a Gears or
10697
+ * AIR database.
10698
+ * @type function
10699
+ * @member
10700
+ * @param {string} source HTTP source to obtain the data from (`ajax`)
10701
+ * @param {array} data A key/value pair object containing the data to send
10702
+ * to the server
10703
+ * @param {function} callback to be called on completion of the data get
10704
+ * process that will draw the data on the page.
10705
+ * @param {object} settings DataTables settings object
10706
+ *
10707
+ * @dtopt Callbacks
10708
+ * @dtopt Server-side
10709
+ * @name DataTable.defaults.serverData
10710
+ *
10711
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
10712
+ */
10713
  "fnServerData": null,
10714
+
10715
+ /**
10716
+ * __Deprecated__ The functionality provided by this parameter has now been
10717
+ * superseded by that provided through `ajax`, which should be used instead.
10718
+ *
10719
+ * It is often useful to send extra data to the server when making an Ajax
10720
+ * request - for example custom filtering information, and this callback
10721
+ * function makes it trivial to send extra information to the server. The
10722
+ * passed in parameter is the data set that has been constructed by
10723
+ * DataTables, and you can add to this or modify it as you require.
10724
+ * @type function
10725
+ * @param {array} data Data array (array of objects which are name/value
10726
+ * pairs) that has been constructed by DataTables and will be sent to the
10727
+ * server. In the case of Ajax sourced data with server-side processing
10728
+ * this will be an empty array, for server-side processing there will be a
10729
+ * significant number of parameters!
10730
+ * @returns {undefined} Ensure that you modify the data array passed in,
10731
+ * as this is passed by reference.
10732
+ *
10733
+ * @dtopt Callbacks
10734
+ * @dtopt Server-side
10735
+ * @name DataTable.defaults.serverParams
10736
+ *
10737
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
10738
+ */
10739
  "fnServerParams": null,
10740
+
10741
+ /**
10742
+ * Load the table state. With this function you can define from where, and how, the
10743
+ * state of a table is loaded. By default DataTables will load from `localStorage`
10744
+ * but you might wish to use a server-side database or cookies.
10745
+ * @type function
10746
+ * @member
10747
+ * @param {object} settings DataTables settings object
10748
+ * @param {object} callback Callback that can be executed when done. It
10749
+ * should be passed the loaded state object.
10750
+ * @return {object} The DataTables state object to be loaded
10751
+ *
10752
+ * @dtopt Callbacks
10753
+ * @name DataTable.defaults.stateLoadCallback
10754
+ *
10755
+ * @example
10756
+ * $(document).ready( function() {
10757
+ * $('#example').dataTable( {
10758
+ * "stateSave": true,
10759
+ * "stateLoadCallback": function (settings, callback) {
10760
+ * $.ajax( {
10761
+ * "url": "/state_load",
10762
+ * "dataType": "json",
10763
+ * "success": function (json) {
10764
+ * callback( json );
10765
+ * }
10766
+ * } );
10767
+ * }
10768
+ * } );
10769
+ * } );
10770
+ */
10771
  "fnStateLoadCallback": function (settings) {
10772
  try {
10773
  return JSON.parse(
10778
  } catch (e) {
10779
  }
10780
  },
10781
+
10782
+ /**
10783
+ * Callback which allows modification of the saved state prior to loading that state.
10784
+ * This callback is called when the table is loading state from the stored data, but
10785
+ * prior to the settings object being modified by the saved state. Note that for
10786
+ * plug-in authors, you should use the `stateLoadParams` event to load parameters for
10787
+ * a plug-in.
10788
+ * @type function
10789
+ * @param {object} settings DataTables settings object
10790
+ * @param {object} data The state object that is to be loaded
10791
+ *
10792
+ * @dtopt Callbacks
10793
+ * @name DataTable.defaults.stateLoadParams
10794
+ *
10795
+ * @example
10796
+ * // Remove a saved filter, so filtering is never loaded
10797
+ * $(document).ready( function() {
10798
+ * $('#example').dataTable( {
10799
+ * "stateSave": true,
10800
+ * "stateLoadParams": function (settings, data) {
10801
+ * data.oSearch.sSearch = "";
10802
+ * }
10803
+ * } );
10804
+ * } );
10805
+ *
10806
+ * @example
10807
+ * // Disallow state loading by returning false
10808
+ * $(document).ready( function() {
10809
+ * $('#example').dataTable( {
10810
+ * "stateSave": true,
10811
+ * "stateLoadParams": function (settings, data) {
10812
+ * return false;
10813
+ * }
10814
+ * } );
10815
+ * } );
10816
+ */
10817
  "fnStateLoadParams": null,
10818
+
10819
+ /**
10820
+ * Callback that is called when the state has been loaded from the state saving method
10821
+ * and the DataTables settings object has been modified as a result of the loaded state.
10822
+ * @type function
10823
+ * @param {object} settings DataTables settings object
10824
+ * @param {object} data The state object that was loaded
10825
+ *
10826
+ * @dtopt Callbacks
10827
+ * @name DataTable.defaults.stateLoaded
10828
+ *
10829
+ * @example
10830
+ * // Show an alert with the filtering value that was saved
10831
+ * $(document).ready( function() {
10832
+ * $('#example').dataTable( {
10833
+ * "stateSave": true,
10834
+ * "stateLoaded": function (settings, data) {
10835
+ * alert( 'Saved filter was: '+data.oSearch.sSearch );
10836
+ * }
10837
+ * } );
10838
+ * } );
10839
+ */
10840
  "fnStateLoaded": null,
10841
+
10842
+ /**
10843
+ * Save the table state. This function allows you to define where and how the state
10844
+ * information for the table is stored By default DataTables will use `localStorage`
10845
+ * but you might wish to use a server-side database or cookies.
10846
+ * @type function
10847
+ * @member
10848
+ * @param {object} settings DataTables settings object
10849
+ * @param {object} data The state object to be saved
10850
+ *
10851
+ * @dtopt Callbacks
10852
+ * @name DataTable.defaults.stateSaveCallback
10853
+ *
10854
+ * @example
10855
+ * $(document).ready( function() {
10856
+ * $('#example').dataTable( {
10857
+ * "stateSave": true,
10858
+ * "stateSaveCallback": function (settings, data) {
10859
+ * // Send an Ajax request to the server with the state object
10860
+ * $.ajax( {
10861
+ * "url": "/state_save",
10862
+ * "data": data,
10863
+ * "dataType": "json",
10864
+ * "method": "POST"
10865
+ * "success": function () {}
10866
+ * } );
10867
+ * }
10868
+ * } );
10869
+ * } );
10870
+ */
10871
  "fnStateSaveCallback": function (settings, data) {
10872
  try {
10873
  (settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
10877
  } catch (e) {
10878
  }
10879
  },
10880
+
10881
+ /**
10882
+ * Callback which allows modification of the state to be saved. Called when the table
10883
+ * has changed state a new state save is required. This method allows modification of
10884
+ * the state saving object prior to actually doing the save, including addition or
10885
+ * other state properties or modification. Note that for plug-in authors, you should
10886
+ * use the `stateSaveParams` event to save parameters for a plug-in.
10887
+ * @type function
10888
+ * @param {object} settings DataTables settings object
10889
+ * @param {object} data The state object to be saved
10890
+ *
10891
+ * @dtopt Callbacks
10892
+ * @name DataTable.defaults.stateSaveParams
10893
+ *
10894
+ * @example
10895
+ * // Remove a saved filter, so filtering is never saved
10896
+ * $(document).ready( function() {
10897
+ * $('#example').dataTable( {
10898
+ * "stateSave": true,
10899
+ * "stateSaveParams": function (settings, data) {
10900
+ * data.oSearch.sSearch = "";
10901
+ * }
10902
+ * } );
10903
+ * } );
10904
+ */
10905
  "fnStateSaveParams": null,
10906
+
10907
+ /**
10908
+ * Duration for which the saved state information is considered valid. After this period
10909
+ * has elapsed the state will be returned to the default.
10910
+ * Value is given in seconds.
10911
+ * @type int
10912
+ * @default 7200 <i>(2 hours)</i>
10913
+ *
10914
+ * @dtopt Options
10915
+ * @name DataTable.defaults.stateDuration
10916
+ *
10917
+ * @example
10918
+ * $(document).ready( function() {
10919
+ * $('#example').dataTable( {
10920
+ * "stateDuration": 60*60*24; // 1 day
10921
+ * } );
10922
+ * } )
10923
+ */
10924
  "iStateDuration": 7200,
10925
+
10926
+ /**
10927
+ * When enabled DataTables will not make a request to the server for the first
10928
+ * page draw - rather it will use the data already on the page (no sorting etc
10929
+ * will be applied to it), thus saving on an XHR at load time. `deferLoading`
10930
+ * is used to indicate that deferred loading is required, but it is also used
10931
+ * to tell DataTables how many records there are in the full table (allowing
10932
+ * the information element and pagination to be displayed correctly). In the case
10933
+ * where a filtering is applied to the table on initial load, this can be
10934
+ * indicated by giving the parameter as an array, where the first element is
10935
+ * the number of records available after filtering and the second element is the
10936
+ * number of records without filtering (allowing the table information element
10937
+ * to be shown correctly).
10938
+ * @type int | array
10939
+ * @default null
10940
+ *
10941
+ * @dtopt Options
10942
+ * @name DataTable.defaults.deferLoading
10943
+ *
10944
+ * @example
10945
+ * // 57 records available in the table, no filtering applied
10946
+ * $(document).ready( function() {
10947
+ * $('#example').dataTable( {
10948
+ * "serverSide": true,
10949
+ * "ajax": "scripts/server_processing.php",
10950
+ * "deferLoading": 57
10951
+ * } );
10952
+ * } );
10953
+ *
10954
+ * @example
10955
+ * // 57 records after filtering, 100 without filtering (an initial filter applied)
10956
+ * $(document).ready( function() {
10957
+ * $('#example').dataTable( {
10958
+ * "serverSide": true,
10959
+ * "ajax": "scripts/server_processing.php",
10960
+ * "deferLoading": [ 57, 100 ],
10961
+ * "search": {
10962
+ * "search": "my_filter"
10963
+ * }
10964
+ * } );
10965
+ * } );
10966
+ */
10967
  "iDeferLoading": null,
10968
+
10969
+ /**
10970
+ * Number of rows to display on a single page when using pagination. If
10971
+ * feature enabled (`lengthChange`) then the end user will be able to override
10972
+ * this to a custom setting using a pop-up menu.
10973
+ * @type int
10974
+ * @default 10
10975
+ *
10976
+ * @dtopt Options
10977
+ * @name DataTable.defaults.pageLength
10978
+ *
10979
+ * @example
10980
+ * $(document).ready( function() {
10981
+ * $('#example').dataTable( {
10982
+ * "pageLength": 50
10983
+ * } );
10984
+ * } )
10985
+ */
10986
  "iDisplayLength": 10,
10987
+
10988
+ /**
10989
+ * Define the starting point for data display when using DataTables with
10990
+ * pagination. Note that this parameter is the number of records, rather than
10991
+ * the page number, so if you have 10 records per page and want to start on
10992
+ * the third page, it should be "20".
10993
+ * @type int
10994
+ * @default 0
10995
+ *
10996
+ * @dtopt Options
10997
+ * @name DataTable.defaults.displayStart
10998
+ *
10999
+ * @example
11000
+ * $(document).ready( function() {
11001
+ * $('#example').dataTable( {
11002
+ * "displayStart": 20
11003
+ * } );
11004
+ * } )
11005
+ */
11006
  "iDisplayStart": 0,
11007
+
11008
+ /**
11009
+ * By default DataTables allows keyboard navigation of the table (sorting, paging,
11010
+ * and filtering) by adding a `tabindex` attribute to the required elements. This
11011
+ * allows you to tab through the controls and press the enter key to activate them.
11012
+ * The tabindex is default 0, meaning that the tab follows the flow of the document.
11013
+ * You can overrule this using this parameter if you wish. Use a value of -1 to
11014
+ * disable built-in keyboard navigation.
11015
+ * @type int
11016
+ * @default 0
11017
+ *
11018
+ * @dtopt Options
11019
+ * @name DataTable.defaults.tabIndex
11020
+ *
11021
+ * @example
11022
+ * $(document).ready( function() {
11023
+ * $('#example').dataTable( {
11024
+ * "tabIndex": 1
11025
+ * } );
11026
+ * } );
11027
+ */
11028
  "iTabIndex": 0,
11029
+
11030
+ /**
11031
+ * Classes that DataTables assigns to the various components and features
11032
+ * that it adds to the HTML table. This allows classes to be configured
11033
+ * during initialisation in addition to through the static
11034
+ * {@link DataTable.ext.oStdClasses} object).
11035
+ * @namespace
11036
+ * @name DataTable.defaults.classes
11037
+ */
11038
  "oClasses": {},
11039
+
11040
+ /**
11041
+ * All strings that DataTables uses in the user interface that it creates
11042
+ * are defined in this object, allowing you to modified them individually or
11043
+ * completely replace them all as required.
11044
+ * @namespace
11045
+ * @name DataTable.defaults.language
11046
+ */
11047
  "oLanguage": {
11048
+ /**
11049
+ * Strings that are used for WAI-ARIA labels and controls only (these are not
11050
+ * actually visible on the page, but will be read by screenreaders, and thus
11051
+ * must be internationalised as well).
11052
+ * @namespace
11053
+ * @name DataTable.defaults.language.aria
11054
+ */
11055
  "oAria": {
11056
+ /**
11057
+ * ARIA label that is added to the table headers when the column may be
11058
+ * sorted ascending by activing the column (click or return when focused).
11059
+ * Note that the column header is prefixed to this string.
11060
+ * @type string
11061
+ * @default : activate to sort column ascending
11062
+ *
11063
+ * @dtopt Language
11064
+ * @name DataTable.defaults.language.aria.sortAscending
11065
+ *
11066
+ * @example
11067
+ * $(document).ready( function() {
11068
+ * $('#example').dataTable( {
11069
+ * "language": {
11070
+ * "aria": {
11071
+ * "sortAscending": " - click/return to sort ascending"
11072
+ * }
11073
+ * }
11074
+ * } );
11075
+ * } );
11076
+ */
11077
  "sSortAscending": ": activate to sort column ascending",
11078
+
11079
+ /**
11080
+ * ARIA label that is added to the table headers when the column may be
11081
+ * sorted descending by activing the column (click or return when focused).
11082
+ * Note that the column header is prefixed to this string.
11083
+ * @type string
11084
+ * @default : activate to sort column ascending
11085
+ *
11086
+ * @dtopt Language
11087
+ * @name DataTable.defaults.language.aria.sortDescending
11088
+ *
11089
+ * @example
11090
+ * $(document).ready( function() {
11091
+ * $('#example').dataTable( {
11092
+ * "language": {
11093
+ * "aria": {
11094
+ * "sortDescending": " - click/return to sort descending"
11095
+ * }
11096
+ * }
11097
+ * } );
11098
+ * } );
11099
+ */
11100
  "sSortDescending": ": activate to sort column descending"
11101
  },
11102
+
11103
+ /**
11104
+ * Pagination string used by DataTables for the built-in pagination
11105
+ * control types.
11106
+ * @namespace
11107
+ * @name DataTable.defaults.language.paginate
11108
+ */
11109
  "oPaginate": {
11110
+ /**
11111
+ * Text to use when using the 'full_numbers' type of pagination for the
11112
+ * button to take the user to the first page.
11113
+ * @type string
11114
+ * @default First
11115
+ *
11116
+ * @dtopt Language
11117
+ * @name DataTable.defaults.language.paginate.first
11118
+ *
11119
+ * @example
11120
+ * $(document).ready( function() {
11121
+ * $('#example').dataTable( {
11122
+ * "language": {
11123
+ * "paginate": {
11124
+ * "first": "First page"
11125
+ * }
11126
+ * }
11127
+ * } );
11128
+ * } );
11129
+ */
11130
  "sFirst": "First",
11131
+
11132
+ /**
11133
+ * Text to use when using the 'full_numbers' type of pagination for the
11134
+ * button to take the user to the last page.
11135
+ * @type string
11136
+ * @default Last
11137
+ *
11138
+ * @dtopt Language
11139
+ * @name DataTable.defaults.language.paginate.last
11140
+ *
11141
+ * @example
11142
+ * $(document).ready( function() {
11143
+ * $('#example').dataTable( {
11144
+ * "language": {
11145
+ * "paginate": {
11146
+ * "last": "Last page"
11147
+ * }
11148
+ * }
11149
+ * } );
11150
+ * } );
11151
+ */
11152
  "sLast": "Last",
11153
+
11154
+ /**
11155
+ * Text to use for the 'next' pagination button (to take the user to the
11156
+ * next page).
11157
+ * @type string
11158
+ * @default Next
11159
+ *
11160
+ * @dtopt Language
11161
+ * @name DataTable.defaults.language.paginate.next
11162
+ *
11163
+ * @example
11164
+ * $(document).ready( function() {
11165
+ * $('#example').dataTable( {
11166
+ * "language": {
11167
+ * "paginate": {
11168
+ * "next": "Next page"
11169
+ * }
11170
+ * }
11171
+ * } );
11172
+ * } );
11173
+ */
11174
  "sNext": "Next",
11175
+
11176
+ /**
11177
+ * Text to use for the 'previous' pagination button (to take the user to
11178
+ * the previous page).
11179
+ * @type string
11180
+ * @default Previous
11181
+ *
11182
+ * @dtopt Language
11183
+ * @name DataTable.defaults.language.paginate.previous
11184
+ *
11185
+ * @example
11186
+ * $(document).ready( function() {
11187
+ * $('#example').dataTable( {
11188
+ * "language": {
11189
+ * "paginate": {
11190
+ * "previous": "Previous page"
11191
+ * }
11192
+ * }
11193
+ * } );
11194
+ * } );
11195
+ */
11196
  "sPrevious": "Previous"
11197
  },
11198
+
11199
+ /**
11200
+ * This string is shown in preference to `zeroRecords` when the table is
11201
+ * empty of data (regardless of filtering). Note that this is an optional
11202
+ * parameter - if it is not given, the value of `zeroRecords` will be used
11203
+ * instead (either the default or given value).
11204
+ * @type string
11205
+ * @default No data available in table
11206
+ *
11207
+ * @dtopt Language
11208
+ * @name DataTable.defaults.language.emptyTable
11209
+ *
11210
+ * @example
11211
+ * $(document).ready( function() {
11212
+ * $('#example').dataTable( {
11213
+ * "language": {
11214
+ * "emptyTable": "No data available in table"
11215
+ * }
11216
+ * } );
11217
+ * } );
11218
+ */
11219
  "sEmptyTable": "No data available in table",
11220
+
11221
+ /**
11222
+ * This string gives information to the end user about the information
11223
+ * that is current on display on the page. The following tokens can be
11224
+ * used in the string and will be dynamically replaced as the table
11225
+ * display updates. This tokens can be placed anywhere in the string, or
11226
+ * removed as needed by the language requires:
11227
+ *
11228
+ * * `\_START\_` - Display index of the first record on the current page
11229
+ * * `\_END\_` - Display index of the last record on the current page
11230
+ * * `\_TOTAL\_` - Number of records in the table after filtering
11231
+ * * `\_MAX\_` - Number of records in the table without filtering
11232
+ * * `\_PAGE\_` - Current page number
11233
+ * * `\_PAGES\_` - Total number of pages of data in the table
11234
+ *
11235
+ * @type string
11236
+ * @default Showing _START_ to _END_ of _TOTAL_ entries
11237
+ *
11238
+ * @dtopt Language
11239
+ * @name DataTable.defaults.language.info
11240
+ *
11241
+ * @example
11242
+ * $(document).ready( function() {
11243
+ * $('#example').dataTable( {
11244
+ * "language": {
11245
+ * "info": "Showing page _PAGE_ of _PAGES_"
11246
+ * }
11247
+ * } );
11248
+ * } );
11249
+ */
11250
  "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
11251
+
11252
+ /**
11253
+ * Display information string for when the table is empty. Typically the
11254
+ * format of this string should match `info`.
11255
+ * @type string
11256
+ * @default Showing 0 to 0 of 0 entries
11257
+ *
11258
+ * @dtopt Language
11259
+ * @name DataTable.defaults.language.infoEmpty
11260
+ *
11261
+ * @example
11262
+ * $(document).ready( function() {
11263
+ * $('#example').dataTable( {
11264
+ * "language": {
11265
+ * "infoEmpty": "No entries to show"
11266
+ * }
11267
+ * } );
11268
+ * } );
11269
+ */
11270
  "sInfoEmpty": "Showing 0 to 0 of 0 entries",
11271
+
11272
+ /**
11273
+ * When a user filters the information in a table, this string is appended
11274
+ * to the information (`info`) to give an idea of how strong the filtering
11275
+ * is. The variable _MAX_ is dynamically updated.
11276
+ * @type string
11277
+ * @default (filtered from _MAX_ total entries)
11278
+ *
11279
+ * @dtopt Language
11280
+ * @name DataTable.defaults.language.infoFiltered
11281
+ *
11282
+ * @example
11283
+ * $(document).ready( function() {
11284
+ * $('#example').dataTable( {
11285
+ * "language": {
11286
+ * "infoFiltered": " - filtering from _MAX_ records"
11287
+ * }
11288
+ * } );
11289
+ * } );
11290
+ */
11291
  "sInfoFiltered": "(filtered from _MAX_ total entries)",
11292
+
11293
+ /**
11294
+ * If can be useful to append extra information to the info string at times,
11295
+ * and this variable does exactly that. This information will be appended to
11296
+ * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
11297
+ * being used) at all times.
11298
+ * @type string
11299
+ * @default <i>Empty string</i>
11300
+ *
11301
+ * @dtopt Language
11302
+ * @name DataTable.defaults.language.infoPostFix
11303
+ *
11304
+ * @example
11305
+ * $(document).ready( function() {
11306
+ * $('#example').dataTable( {
11307
+ * "language": {
11308
+ * "infoPostFix": "All records shown are derived from real information."
11309
+ * }
11310
+ * } );
11311
+ * } );
11312
+ */
11313
  "sInfoPostFix": "",
11314
+
11315
+ /**
11316
+ * This decimal place operator is a little different from the other
11317
+ * language options since DataTables doesn't output floating point
11318
+ * numbers, so it won't ever use this for display of a number. Rather,
11319
+ * what this parameter does is modify the sort methods of the table so
11320
+ * that numbers which are in a format which has a character other than
11321
+ * a period (`.`) as a decimal place will be sorted numerically.
11322
+ *
11323
+ * Note that numbers with different decimal places cannot be shown in
11324
+ * the same table and still be sortable, the table must be consistent.
11325
+ * However, multiple different tables on the page can use different
11326
+ * decimal place characters.
11327
+ * @type string
11328
+ * @default
11329
+ *
11330
+ * @dtopt Language
11331
+ * @name DataTable.defaults.language.decimal
11332
+ *
11333
+ * @example
11334
+ * $(document).ready( function() {
11335
+ * $('#example').dataTable( {
11336
+ * "language": {
11337
+ * "decimal": ","
11338
+ * "thousands": "."
11339
+ * }
11340
+ * } );
11341
+ * } );
11342
+ */
11343
  "sDecimal": "",
11344
+
11345
+ /**
11346
+ * DataTables has a build in number formatter (`formatNumber`) which is
11347
+ * used to format large numbers that are used in the table information.
11348
+ * By default a comma is used, but this can be trivially changed to any
11349
+ * character you wish with this parameter.
11350
+ * @type string
11351
+ * @default ,
11352
+ *
11353
+ * @dtopt Language
11354
+ * @name DataTable.defaults.language.thousands
11355
+ *
11356
+ * @example
11357
+ * $(document).ready( function() {
11358
+ * $('#example').dataTable( {
11359
+ * "language": {
11360
+ * "thousands": "'"
11361
+ * }
11362
+ * } );
11363
+ * } );
11364
+ */
11365
  "sThousands": ",",
11366
+
11367
+ /**
11368
+ * Detail the action that will be taken when the drop down menu for the
11369
+ * pagination length option is changed. The '_MENU_' variable is replaced
11370
+ * with a default select list of 10, 25, 50 and 100, and can be replaced
11371
+ * with a custom select box if required.
11372
+ * @type string
11373
+ * @default Show _MENU_ entries
11374
+ *
11375
+ * @dtopt Language
11376
+ * @name DataTable.defaults.language.lengthMenu
11377
+ *
11378
+ * @example
11379
+ * // Language change only
11380
+ * $(document).ready( function() {
11381
+ * $('#example').dataTable( {
11382
+ * "language": {
11383
+ * "lengthMenu": "Display _MENU_ records"
11384
+ * }
11385
+ * } );
11386
+ * } );
11387
+ *
11388
+ * @example
11389
+ * // Language and options change
11390
+ * $(document).ready( function() {
11391
+ * $('#example').dataTable( {
11392
+ * "language": {
11393
+ * "lengthMenu": 'Display <select>'+
11394
+ * '<option value="10">10</option>'+
11395
+ * '<option value="20">20</option>'+
11396
+ * '<option value="30">30</option>'+
11397
+ * '<option value="40">40</option>'+
11398
+ * '<option value="50">50</option>'+
11399
+ * '<option value="-1">All</option>'+
11400
+ * '</select> records'
11401
+ * }
11402
+ * } );
11403
+ * } );
11404
+ */
11405
  "sLengthMenu": "Show _MENU_ entries",
11406
 
11407
+ /**
11408
+ * When using Ajax sourced data and during the first draw when DataTables is
11409
+ * gathering the data, this message is shown in an empty row in the table to
11410
+ * indicate to the end user the the data is being loaded. Note that this
11411
+ * parameter is not used when loading data by server-side processing, just
11412
+ * Ajax sourced data with client-side processing.
11413
+ * @type string
11414
+ * @default Loading...
11415
+ *
11416
+ * @dtopt Language
11417
+ * @name DataTable.defaults.language.loadingRecords
11418
+ *
11419
+ * @example
11420
+ * $(document).ready( function() {
11421
+ * $('#example').dataTable( {
11422
+ * "language": {
11423
+ * "loadingRecords": "Please wait - loading..."
11424
+ * }
11425
+ * } );
11426
+ * } );
11427
+ */
11428
  "sLoadingRecords": "Loading...",
11429
 
11430
+ /**
11431
+ * Text which is displayed when the table is processing a user action
11432
+ * (usually a sort command or similar).
11433
+ * @type string
11434
+ * @default Processing...
11435
+ *
11436
+ * @dtopt Language
11437
+ * @name DataTable.defaults.language.processing
11438
+ *
11439
+ * @example
11440
+ * $(document).ready( function() {
11441
+ * $('#example').dataTable( {
11442
+ * "language": {
11443
+ * "processing": "DataTables is currently busy"
11444
+ * }
11445
+ * } );
11446
+ * } );
11447
+ */
11448
  "sProcessing": "Processing...",
11449
 
11450
+ /**
11451
+ * Details the actions that will be taken when the user types into the
11452
+ * filtering input text box. The variable "_INPUT_", if used in the string,
11453
+ * is replaced with the HTML text box for the filtering input allowing
11454
+ * control over where it appears in the string. If "_INPUT_" is not given
11455
+ * then the input box is appended to the string automatically.
11456
+ * @type string
11457
+ * @default Search:
11458
+ *
11459
+ * @dtopt Language
11460
+ * @name DataTable.defaults.language.search
11461
+ *
11462
+ * @example
11463
+ * // Input text box will be appended at the end automatically
11464
+ * $(document).ready( function() {
11465
+ * $('#example').dataTable( {
11466
+ * "language": {
11467
+ * "search": "Filter records:"
11468
+ * }
11469
+ * } );
11470
+ * } );
11471
+ *
11472
+ * @example
11473
+ * // Specify where the filter should appear
11474
+ * $(document).ready( function() {
11475
+ * $('#example').dataTable( {
11476
+ * "language": {
11477
+ * "search": "Apply filter _INPUT_ to table"
11478
+ * }
11479
+ * } );
11480
+ * } );
11481
+ */
11482
  "sSearch": "Search:",
11483
 
11484
+ /**
11485
+ * Assign a `placeholder` attribute to the search `input` element
11486
+ * @type string
11487
+ * @default
11488
+ *
11489
+ * @dtopt Language
11490
+ * @name DataTable.defaults.language.searchPlaceholder
11491
+ */
11492
  "sSearchPlaceholder": "",
11493
 
11494
+ /**
11495
+ * All of the language information can be stored in a file on the
11496
+ * server-side, which DataTables will look up if this parameter is passed.
11497
+ * It must store the URL of the language file, which is in a JSON format,
11498
+ * and the object has the same properties as the oLanguage object in the
11499
+ * initialiser object (i.e. the above parameters). Please refer to one of
11500
+ * the example language files to see how this works in action.
11501
+ * @type string
11502
+ * @default <i>Empty string - i.e. disabled</i>
11503
+ *
11504
+ * @dtopt Language
11505
+ * @name DataTable.defaults.language.url
11506
+ *
11507
+ * @example
11508
+ * $(document).ready( function() {
11509
+ * $('#example').dataTable( {
11510
+ * "language": {
11511
+ * "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
11512
+ * }
11513
+ * } );
11514
+ * } );
11515
+ */
11516
  "sUrl": "",
11517
 
11518
+ /**
11519
+ * Text shown inside the table records when the is no information to be
11520
+ * displayed after filtering. `emptyTable` is shown when there is simply no
11521
+ * information in the table at all (regardless of filtering).
11522
+ * @type string
11523
+ * @default No matching records found
11524
+ *
11525
+ * @dtopt Language
11526
+ * @name DataTable.defaults.language.zeroRecords
11527
+ *
11528
+ * @example
11529
+ * $(document).ready( function() {
11530
+ * $('#example').dataTable( {
11531
+ * "language": {
11532
+ * "zeroRecords": "No records to display"
11533
+ * }
11534
+ * } );
11535
+ * } );
11536
+ */
11537
  "sZeroRecords": "No matching records found"
11538
  },
11539
 
11540
+ /**
11541
+ * This parameter allows you to have define the global filtering state at
11542
+ * initialisation time. As an object the `search` parameter must be
11543
+ * defined, but all other parameters are optional. When `regex` is true,
11544
+ * the search string will be treated as a regular expression, when false
11545
+ * (default) it will be treated as a straight string. When `smart`
11546
+ * DataTables will use it's smart filtering methods (to word match at
11547
+ * any point in the data), when false this will not be done.
11548
+ * @namespace
11549
+ * @extends DataTable.models.oSearch
11550
+ *
11551
+ * @dtopt Options
11552
+ * @name DataTable.defaults.search
11553
+ *
11554
+ * @example
11555
+ * $(document).ready( function() {
11556
+ * $('#example').dataTable( {
11557
+ * "search": {"search": "Initial search"}
11558
+ * } );
11559
+ * } )
11560
+ */
11561
  "oSearch": $.extend({}, DataTable.models.oSearch),
11562
 
11563
+ /**
11564
+ * __Deprecated__ The functionality provided by this parameter has now been
11565
+ * superseded by that provided through `ajax`, which should be used instead.
11566
+ *
11567
+ * By default DataTables will look for the property `data` (or `aaData` for
11568
+ * compatibility with DataTables 1.9-) when obtaining data from an Ajax
11569
+ * source or for server-side processing - this parameter allows that
11570
+ * property to be changed. You can use Javascript dotted object notation to
11571
+ * get a data source for multiple levels of nesting.
11572
+ * @type string
11573
+ * @default data
11574
+ *
11575
+ * @dtopt Options
11576
+ * @dtopt Server-side
11577
+ * @name DataTable.defaults.ajaxDataProp
11578
+ *
11579
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11580
+ */
11581
  "sAjaxDataProp": "data",
11582
 
11583
+ /**
11584
+ * __Deprecated__ The functionality provided by this parameter has now been
11585
+ * superseded by that provided through `ajax`, which should be used instead.
11586
+ *
11587
+ * You can instruct DataTables to load data from an external
11588
+ * source using this parameter (use aData if you want to pass data in you
11589
+ * already have). Simply provide a url a JSON object can be obtained from.
11590
+ * @type string
11591
+ * @default null
11592
+ *
11593
+ * @dtopt Options
11594
+ * @dtopt Server-side
11595
+ * @name DataTable.defaults.ajaxSource
11596
+ *
11597
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11598
+ */
11599
  "sAjaxSource": null,
11600
 
11601
+ /**
11602
+ * This initialisation variable allows you to specify exactly where in the
11603
+ * DOM you want DataTables to inject the various controls it adds to the page
11604
+ * (for example you might want the pagination controls at the top of the
11605
+ * table). DIV elements (with or without a custom class) can also be added to
11606
+ * aid styling. The follow syntax is used:
11607
+ * <ul>
11608
+ * <li>The following options are allowed:
11609
+ * <ul>
11610
+ * <li>'l' - Length changing</li>
11611
+ * <li>'f' - Filtering input</li>
11612
+ * <li>'t' - The table!</li>
11613
+ * <li>'i' - Information</li>
11614
+ * <li>'p' - Pagination</li>
11615
+ * <li>'r' - pRocessing</li>
11616
+ * </ul>
11617
+ * </li>
11618
+ * <li>The following constants are allowed:
11619
+ * <ul>
11620
+ * <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
11621
+ * <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
11622
+ * </ul>
11623
+ * </li>
11624
+ * <li>The following syntax is expected:
11625
+ * <ul>
11626
+ * <li>'&lt;' and '&gt;' - div elements</li>
11627
+ * <li>'&lt;"class" and '&gt;' - div with a class</li>
11628
+ * <li>'&lt;"#id" and '&gt;' - div with an ID</li>
11629
+ * </ul>
11630
+ * </li>
11631
+ * <li>Examples:
11632
+ * <ul>
11633
+ * <li>'&lt;"wrapper"flipt&gt;'</li>
11634
+ * <li>'&lt;lf&lt;t&gt;ip&gt;'</li>
11635
+ * </ul>
11636
+ * </li>
11637
+ * </ul>
11638
+ * @type string
11639
+ * @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
11640
+ * <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
11641
+ *
11642
+ * @dtopt Options
11643
+ * @name DataTable.defaults.dom
11644
+ *
11645
+ * @example
11646
+ * $(document).ready( function() {
11647
+ * $('#example').dataTable( {
11648
+ * "dom": '&lt;"top"i&gt;rt&lt;"bottom"flp&gt;&lt;"clear"&gt;'
11649
+ * } );
11650
+ * } );
11651
+ */
11652
  "sDom": "lfrtip",
11653
 
11654
+ /**
11655
+ * Search delay option. This will throttle full table searches that use the
11656
+ * DataTables provided search input element (it does not effect calls to
11657
+ * `dt-api search()`, providing a delay before the search is made.
11658
+ * @type integer
11659
+ * @default 0
11660
+ *
11661
+ * @dtopt Options
11662
+ * @name DataTable.defaults.searchDelay
11663
+ *
11664
+ * @example
11665
+ * $(document).ready( function() {
11666
+ * $('#example').dataTable( {
11667
+ * "searchDelay": 200
11668
+ * } );
11669
+ * } )
11670
+ */
11671
  "searchDelay": null,
11672
 
11673
+ /**
11674
+ * DataTables features six different built-in options for the buttons to
11675
+ * display for pagination control:
11676
+ *
11677
+ * * `numbers` - Page number buttons only
11678
+ * * `simple` - 'Previous' and 'Next' buttons only
11679
+ * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
11680
+ * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
11681
+ * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus page numbers
11682
+ * * `first_last_numbers` - 'First' and 'Last' buttons, plus page numbers
11683
+ *
11684
+ * Further methods can be added using {@link DataTable.ext.oPagination}.
11685
+ * @type string
11686
+ * @default simple_numbers
11687
+ *
11688
+ * @dtopt Options
11689
+ * @name DataTable.defaults.pagingType
11690
+ *
11691
+ * @example
11692
+ * $(document).ready( function() {
11693
+ * $('#example').dataTable( {
11694
+ * "pagingType": "full_numbers"
11695
+ * } );
11696
+ * } )
11697
+ */
11698
  "sPaginationType": "simple_numbers",
11699
 
11700
+ /**
11701
+ * Enable horizontal scrolling. When a table is too wide to fit into a
11702
+ * certain layout, or you have a large number of columns in the table, you
11703
+ * can enable x-scrolling to show the table in a viewport, which can be
11704
+ * scrolled. This property can be `true` which will allow the table to
11705
+ * scroll horizontally when needed, or any CSS unit, or a number (in which
11706
+ * case it will be treated as a pixel measurement). Setting as simply `true`
11707
+ * is recommended.
11708
+ * @type boolean|string
11709
+ * @default <i>blank string - i.e. disabled</i>
11710
+ *
11711
+ * @dtopt Features
11712
+ * @name DataTable.defaults.scrollX
11713
+ *
11714
+ * @example
11715
+ * $(document).ready( function() {
11716
+ * $('#example').dataTable( {
11717
+ * "scrollX": true,
11718
+ * "scrollCollapse": true
11719
+ * } );
11720
+ * } );
11721
+ */
11722
  "sScrollX": "",
11723
 
11724
+ /**
11725
+ * This property can be used to force a DataTable to use more width than it
11726
+ * might otherwise do when x-scrolling is enabled. For example if you have a
11727
+ * table which requires to be well spaced, this parameter is useful for
11728
+ * "over-sizing" the table, and thus forcing scrolling. This property can by
11729
+ * any CSS unit, or a number (in which case it will be treated as a pixel
11730
+ * measurement).
11731
+ * @type string
11732
+ * @default <i>blank string - i.e. disabled</i>
11733
+ *
11734
+ * @dtopt Options
11735
+ * @name DataTable.defaults.scrollXInner
11736
+ *
11737
+ * @example
11738
+ * $(document).ready( function() {
11739
+ * $('#example').dataTable( {
11740
+ * "scrollX": "100%",
11741
+ * "scrollXInner": "110%"
11742
+ * } );
11743
+ * } );
11744
+ */
11745
  "sScrollXInner": "",
11746
 
11747
+ /**
11748
+ * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
11749
+ * to the given height, and enable scrolling for any data which overflows the
11750
+ * current viewport. This can be used as an alternative to paging to display
11751
+ * a lot of data in a small area (although paging and scrolling can both be
11752
+ * enabled at the same time). This property can be any CSS unit, or a number
11753
+ * (in which case it will be treated as a pixel measurement).
11754
+ * @type string
11755
+ * @default <i>blank string - i.e. disabled</i>
11756
+ *
11757
+ * @dtopt Features
11758
+ * @name DataTable.defaults.scrollY
11759
+ *
11760
+ * @example
11761
+ * $(document).ready( function() {
11762
+ * $('#example').dataTable( {
11763
+ * "scrollY": "200px",
11764
+ * "paginate": false
11765
+ * } );
11766
+ * } );
11767
+ */
11768
  "sScrollY": "",
11769
 
11770
+ /**
11771
+ * __Deprecated__ The functionality provided by this parameter has now been
11772
+ * superseded by that provided through `ajax`, which should be used instead.
11773
+ *
11774
+ * Set the HTTP method that is used to make the Ajax call for server-side
11775
+ * processing or Ajax sourced data.
11776
+ * @type string
11777
+ * @default GET
11778
+ *
11779
+ * @dtopt Options
11780
+ * @dtopt Server-side
11781
+ * @name DataTable.defaults.serverMethod
11782
+ *
11783
+ * @deprecated 1.10. Please use `ajax` for this functionality now.
11784
+ */
11785
  "sServerMethod": "GET",
11786
 
11787
+ /**
11788
+ * DataTables makes use of renderers when displaying HTML elements for
11789
+ * a table. These renderers can be added or modified by plug-ins to
11790
+ * generate suitable mark-up for a site. For example the Bootstrap
11791
+ * integration plug-in for DataTables uses a paging button renderer to
11792
+ * display pagination buttons in the mark-up required by Bootstrap.
11793
+ *
11794
+ * For further information about the renderers available see
11795
+ * DataTable.ext.renderer
11796
+ * @type string|object
11797
+ * @default null
11798
+ *
11799
+ * @name DataTable.defaults.renderer
11800
+ *
11801
+ */
11802
  "renderer": null,
11803
 
11804
+ /**
11805
+ * Set the data property name that DataTables should use to get a row's id
11806
+ * to set as the `id` property in the node.
11807
+ * @type string
11808
+ * @default DT_RowId
11809
+ *
11810
+ * @name DataTable.defaults.rowId
11811
+ */
11812
  "rowId": "DT_RowId"
11813
  };
11814
 
11815
  _fnHungarianMap(DataTable.defaults);
11816
 
 
11817
 
11818
+
11819
+ /*
11820
+ * Developer note - See note in model.defaults.js about the use of Hungarian
11821
+ * notation and camel case.
11822
+ */
11823
+
11824
+ /**
11825
+ * Column options that can be given to DataTables at initialisation time.
11826
+ * @namespace
11827
+ */
11828
+ DataTable.defaults.column = {
11829
+ /**
11830
+ * Define which column(s) an order will occur on for this column. This
11831
+ * allows a column's ordering to take multiple columns into account when
11832
+ * doing a sort or use the data from a different column. For example first
11833
+ * name / last name columns make sense to do a multi-column sort over the
11834
+ * two columns.
11835
+ * @type array|int
11836
+ * @default null <i>Takes the value of the column index automatically</i>
11837
+ *
11838
+ * @name DataTable.defaults.column.orderData
11839
+ * @dtopt Columns
11840
+ *
11841
+ * @example
11842
+ * // Using `columnDefs`
11843
+ * $(document).ready( function() {
11844
+ * $('#example').dataTable( {
11845
+ * "columnDefs": [
11846
+ * { "orderData": [ 0, 1 ], "targets": [ 0 ] },
11847
+ * { "orderData": [ 1, 0 ], "targets": [ 1 ] },
11848
+ * { "orderData": 2, "targets": [ 2 ] }
11849
+ * ]
11850
+ * } );
11851
+ * } );
11852
+ *
11853
+ * @example
11854
+ * // Using `columns`
11855
+ * $(document).ready( function() {
11856
+ * $('#example').dataTable( {
11857
+ * "columns": [
11858
+ * { "orderData": [ 0, 1 ] },
11859
+ * { "orderData": [ 1, 0 ] },
11860
+ * { "orderData": 2 },
11861
+ * null,
11862
+ * null
11863
+ * ]
11864
+ * } );
11865
+ * } );
11866
+ */
11867
  "aDataSort": null,
11868
  "iDataSort": -1,
11869
 
11870
+ /**
11871
+ * You can control the default ordering direction, and even alter the
11872
+ * behaviour of the sort handler (i.e. only allow ascending ordering etc)
11873
+ * using this parameter.
11874
+ * @type array
11875
+ * @default [ 'asc', 'desc' ]
11876
+ *
11877
+ * @name DataTable.defaults.column.orderSequence
11878
+ * @dtopt Columns
11879
+ *
11880
+ * @example
11881
+ * // Using `columnDefs`
11882
+ * $(document).ready( function() {
11883
+ * $('#example').dataTable( {
11884
+ * "columnDefs": [
11885
+ * { "orderSequence": [ "asc" ], "targets": [ 1 ] },
11886
+ * { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
11887
+ * { "orderSequence": [ "desc" ], "targets": [ 3 ] }
11888
+ * ]
11889
+ * } );
11890
+ * } );
11891
+ *
11892
+ * @example
11893
+ * // Using `columns`
11894
+ * $(document).ready( function() {
11895
+ * $('#example').dataTable( {
11896
+ * "columns": [
11897
+ * null,
11898
+ * { "orderSequence": [ "asc" ] },
11899
+ * { "orderSequence": [ "desc", "asc", "asc" ] },
11900
+ * { "orderSequence": [ "desc" ] },
11901
+ * null
11902
+ * ]
11903
+ * } );
11904
+ * } );
11905
+ */
11906
  "asSorting": ['asc', 'desc'],
11907
 
11908
+ /**
11909
+ * Enable or disable filtering on the data in this column.
11910
+ * @type boolean
11911
+ * @default true
11912
+ *
11913
+ * @name DataTable.defaults.column.searchable
11914
+ * @dtopt Columns
11915
+ *
11916
+ * @example
11917
+ * // Using `columnDefs`
11918
+ * $(document).ready( function() {
11919
+ * $('#example').dataTable( {
11920
+ * "columnDefs": [
11921
+ * { "searchable": false, "targets": [ 0 ] }
11922
+ * ] } );
11923
+ * } );
11924
+ *
11925
+ * @example
11926
+ * // Using `columns`
11927
+ * $(document).ready( function() {
11928
+ * $('#example').dataTable( {
11929
+ * "columns": [
11930
+ * { "searchable": false },
11931
+ * null,
11932
+ * null,
11933
+ * null,
11934
+ * null
11935
+ * ] } );
11936
+ * } );
11937
+ */
11938
  "bSearchable": true,
11939
 
11940
+ /**
11941
+ * Enable or disable ordering on this column.
11942
+ * @type boolean
11943
+ * @default true
11944
+ *
11945
+ * @name DataTable.defaults.column.orderable
11946
+ * @dtopt Columns
11947
+ *
11948
+ * @example
11949
+ * // Using `columnDefs`
11950
+ * $(document).ready( function() {
11951
+ * $('#example').dataTable( {
11952
+ * "columnDefs": [
11953
+ * { "orderable": false, "targets": [ 0 ] }
11954
+ * ] } );
11955
+ * } );
11956
+ *
11957
+ * @example
11958
+ * // Using `columns`
11959
+ * $(document).ready( function() {
11960
+ * $('#example').dataTable( {
11961
+ * "columns": [
11962
+ * { "orderable": false },
11963
+ * null,
11964
+ * null,
11965
+ * null,
11966
+ * null
11967
+ * ] } );
11968
+ * } );
11969
+ */
11970
  "bSortable": true,
11971
 
11972
+ /**
11973
+ * Enable or disable the display of this column.
11974
+ * @type boolean
11975
+ * @default true
11976
+ *
11977
+ * @name DataTable.defaults.column.visible
11978
+ * @dtopt Columns
11979
+ *
11980
+ * @example
11981
+ * // Using `columnDefs`
11982
+ * $(document).ready( function() {
11983
+ * $('#example').dataTable( {
11984
+ * "columnDefs": [
11985
+ * { "visible": false, "targets": [ 0 ] }
11986
+ * ] } );
11987
+ * } );
11988
+ *
11989
+ * @example
11990
+ * // Using `columns`
11991
+ * $(document).ready( function() {
11992
+ * $('#example').dataTable( {
11993
+ * "columns": [
11994
+ * { "visible": false },
11995
+ * null,
11996
+ * null,
11997
+ * null,
11998
+ * null
11999
+ * ] } );
12000
+ * } );
12001
+ */
12002
  "bVisible": true,
12003
 
12004
+ /**
12005
+ * Developer definable function that is called whenever a cell is created (Ajax source,
12006
+ * etc) or processed for input (DOM source). This can be used as a compliment to mRender
12007
+ * allowing you to modify the DOM element (add background colour for example) when the
12008
+ * element is available.
12009
+ * @type function
12010
+ * @param {element} td The TD node that has been created
12011
+ * @param {*} cellData The Data for the cell
12012
+ * @param {array|object} rowData The data for the whole row
12013
+ * @param {int} row The row index for the aoData data store
12014
+ * @param {int} col The column index for aoColumns
12015
+ *
12016
+ * @name DataTable.defaults.column.createdCell
12017
+ * @dtopt Columns
12018
+ *
12019
+ * @example
12020
+ * $(document).ready( function() {
12021
+ * $('#example').dataTable( {
12022
+ * "columnDefs": [ {
12023
+ * "targets": [3],
12024
+ * "createdCell": function (td, cellData, rowData, row, col) {
12025
+ * if ( cellData == "1.7" ) {
12026
+ * $(td).css('color', 'blue')
12027
+ * }
12028
+ * }
12029
+ * } ]
12030
+ * });
12031
+ * } );
12032
+ */
12033
  "fnCreatedCell": null,
12034
 
12035
+ /**
12036
+ * This parameter has been replaced by `data` in DataTables to ensure naming
12037
+ * consistency. `dataProp` can still be used, as there is backwards
12038
+ * compatibility in DataTables for this option, but it is strongly
12039
+ * recommended that you use `data` in preference to `dataProp`.
12040
+ * @name DataTable.defaults.column.dataProp
12041
+ */
12042
+
12043
+
12044
+ /**
12045
+ * This property can be used to read data from any data source property,
12046
+ * including deeply nested objects / properties. `data` can be given in a
12047
+ * number of different ways which effect its behaviour:
12048
+ *
12049
+ * * `integer` - treated as an array index for the data source. This is the
12050
+ * default that DataTables uses (incrementally increased for each column).
12051
+ * * `string` - read an object property from the data source. There are
12052
+ * three 'special' options that can be used in the string to alter how
12053
+ * DataTables reads the data from the source object:
12054
+ * * `.` - Dotted Javascript notation. Just as you use a `.` in
12055
+ * Javascript to read from nested objects, so to can the options
12056
+ * specified in `data`. For example: `browser.version` or
12057
+ * `browser.name`. If your object parameter name contains a period, use
12058
+ * `\\` to escape it - i.e. `first\\.name`.
12059
+ * * `[]` - Array notation. DataTables can automatically combine data
12060
+ * from and array source, joining the data with the characters provided
12061
+ * between the two brackets. For example: `name[, ]` would provide a
12062
+ * comma-space separated list from the source array. If no characters
12063
+ * are provided between the brackets, the original array source is
12064
+ * returned.
12065
+ * * `()` - Function notation. Adding `()` to the end of a parameter will
12066
+ * execute a function of the name given. For example: `browser()` for a
12067
+ * simple function on the data source, `browser.version()` for a
12068
+ * function in a nested property or even `browser().version` to get an
12069
+ * object property if the function called returns an object. Note that
12070
+ * function notation is recommended for use in `render` rather than
12071
+ * `data` as it is much simpler to use as a renderer.
12072
+ * * `null` - use the original data source for the row rather than plucking
12073
+ * data directly from it. This action has effects on two other
12074
+ * initialisation options:
12075
+ * * `defaultContent` - When null is given as the `data` option and
12076
+ * `defaultContent` is specified for the column, the value defined by
12077
+ * `defaultContent` will be used for the cell.
12078
+ * * `render` - When null is used for the `data` option and the `render`
12079
+ * option is specified for the column, the whole data source for the
12080
+ * row is used for the renderer.
12081
+ * * `function` - the function given will be executed whenever DataTables
12082
+ * needs to set or get the data for a cell in the column. The function
12083
+ * takes three parameters:
12084
+ * * Parameters:
12085
+ * * `{array|object}` The data source for the row
12086
+ * * `{string}` The type call data requested - this will be 'set' when
12087
+ * setting data or 'filter', 'display', 'type', 'sort' or undefined
12088
+ * when gathering data. Note that when `undefined` is given for the
12089
+ * type DataTables expects to get the raw data for the object back<
12090
+ * * `{*}` Data to set when the second parameter is 'set'.
12091
+ * * Return:
12092
+ * * The return value from the function is not required when 'set' is
12093
+ * the type of call, but otherwise the return is what will be used
12094
+ * for the data requested.
12095
+ *
12096
+ * Note that `data` is a getter and setter option. If you just require
12097
+ * formatting of data for output, you will likely want to use `render` which
12098
+ * is simply a getter and thus simpler to use.
12099
+ *
12100
+ * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
12101
+ * name change reflects the flexibility of this property and is consistent
12102
+ * with the naming of mRender. If 'mDataProp' is given, then it will still
12103
+ * be used by DataTables, as it automatically maps the old name to the new
12104
+ * if required.
12105
+ *
12106
+ * @type string|int|function|null
12107
+ * @default null <i>Use automatically calculated column index</i>
12108
+ *
12109
+ * @name DataTable.defaults.column.data
12110
+ * @dtopt Columns
12111
+ *
12112
+ * @example
12113
+ * // Read table data from objects
12114
+ * // JSON structure for each row:
12115
+ * // {
12116
+ * // "engine": {value},
12117
+ * // "browser": {value},
12118
+ * // "platform": {value},
12119
+ * // "version": {value},
12120
+ * // "grade": {value}
12121
+ * // }
12122
+ * $(document).ready( function() {
12123
+ * $('#example').dataTable( {
12124
+ * "ajaxSource": "sources/objects.txt",
12125
+ * "columns": [
12126
+ * { "data": "engine" },
12127
+ * { "data": "browser" },
12128
+ * { "data": "platform" },
12129
+ * { "data": "version" },
12130
+ * { "data": "grade" }
12131
+ * ]
12132
+ * } );
12133
+ * } );
12134
+ *
12135
+ * @example
12136
+ * // Read information from deeply nested objects
12137
+ * // JSON structure for each row:
12138
+ * // {
12139
+ * // "engine": {value},
12140
+ * // "browser": {value},
12141
+ * // "platform": {
12142
+ * // "inner": {value}
12143
+ * // },
12144
+ * // "details": [
12145
+ * // {value}, {value}
12146
+ * // ]
12147
+ * // }
12148
+ * $(document).ready( function() {
12149
+ * $('#example').dataTable( {
12150
+ * "ajaxSource": "sources/deep.txt",
12151
+ * "columns": [
12152
+ * { "data": "engine" },
12153
+ * { "data": "browser" },
12154
+ * { "data": "platform.inner" },
12155
+ * { "data": "platform.details.0" },
12156
+ * { "data": "platform.details.1" }
12157
+ * ]
12158
+ * } );
12159
+ * } );
12160
+ *
12161
+ * @example
12162
+ * // Using `data` as a function to provide different information for
12163
+ * // sorting, filtering and display. In this case, currency (price)
12164
+ * $(document).ready( function() {
12165
+ * $('#example').dataTable( {
12166
+ * "columnDefs": [ {
12167
+ * "targets": [ 0 ],
12168
+ * "data": function ( source, type, val ) {
12169
+ * if (type === 'set') {
12170
+ * source.price = val;
12171
+ * // Store the computed dislay and filter values for efficiency
12172
+ * source.price_display = val=="" ? "" : "$"+numberFormat(val);
12173
+ * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
12174
+ * return;
12175
+ * }
12176
+ * else if (type === 'display') {
12177
+ * return source.price_display;
12178
+ * }
12179
+ * else if (type === 'filter') {
12180
+ * return source.price_filter;
12181
+ * }
12182
+ * // 'sort', 'type' and undefined all just use the integer
12183
+ * return source.price;
12184
+ * }
12185
+ * } ]
12186
+ * } );
12187
+ * } );
12188
+ *
12189
+ * @example
12190
+ * // Using default content
12191
+ * $(document).ready( function() {
12192
+ * $('#example').dataTable( {
12193
+ * "columnDefs": [ {
12194
+ * "targets": [ 0 ],
12195
+ * "data": null,
12196
+ * "defaultContent": "Click to edit"
12197
+ * } ]
12198
+ * } );
12199
+ * } );
12200
+ *
12201
+ * @example
12202
+ * // Using array notation - outputting a list from an array
12203
+ * $(document).ready( function() {
12204
+ * $('#example').dataTable( {
12205
+ * "columnDefs": [ {
12206
+ * "targets": [ 0 ],
12207
+ * "data": "name[, ]"
12208
+ * } ]
12209
+ * } );
12210
+ * } );
12211
+ *
12212
+ */
12213
  "mData": null,
12214
 
12215
+ /**
12216
+ * This property is the rendering partner to `data` and it is suggested that
12217
+ * when you want to manipulate data for display (including filtering,
12218
+ * sorting etc) without altering the underlying data for the table, use this
12219
+ * property. `render` can be considered to be the the read only companion to
12220
+ * `data` which is read / write (then as such more complex). Like `data`
12221
+ * this option can be given in a number of different ways to effect its
12222
+ * behaviour:
12223
+ *
12224
+ * * `integer` - treated as an array index for the data source. This is the
12225
+ * default that DataTables uses (incrementally increased for each column).
12226
+ * * `string` - read an object property from the data source. There are
12227
+ * three 'special' options that can be used in the string to alter how
12228
+ * DataTables reads the data from the source object:
12229
+ * * `.` - Dotted Javascript notation. Just as you use a `.` in
12230
+ * Javascript to read from nested objects, so to can the options
12231
+ * specified in `data`. For example: `browser.version` or
12232
+ * `browser.name`. If your object parameter name contains a period, use
12233
+ * `\\` to escape it - i.e. `first\\.name`.
12234
+ * * `[]` - Array notation. DataTables can automatically combine data
12235
+ * from and array source, joining the data with the characters provided
12236
+ * between the two brackets. For example: `name[, ]` would provide a
12237
+ * comma-space separated list from the source array. If no characters
12238
+ * are provided between the brackets, the original array source is
12239
+ * returned.
12240
+ * * `()` - Function notation. Adding `()` to the end of a parameter will
12241
+ * execute a function of the name given. For example: `browser()` for a
12242
+ * simple function on the data source, `browser.version()` for a
12243
+ * function in a nested property or even `browser().version` to get an
12244
+ * object property if the function called returns an object.
12245
+ * * `object` - use different data for the different data types requested by
12246
+ * DataTables ('filter', 'display', 'type' or 'sort'). The property names
12247
+ * of the object is the data type the property refers to and the value can
12248
+ * defined using an integer, string or function using the same rules as
12249
+ * `render` normally does. Note that an `_` option _must_ be specified.
12250
+ * This is the default value to use if you haven't specified a value for
12251
+ * the data type requested by DataTables.
12252
+ * * `function` - the function given will be executed whenever DataTables
12253
+ * needs to set or get the data for a cell in the column. The function
12254
+ * takes three parameters:
12255
+ * * Parameters:
12256
+ * * {array|object} The data source for the row (based on `data`)
12257
+ * * {string} The type call data requested - this will be 'filter',
12258
+ * 'display', 'type' or 'sort'.
12259
+ * * {array|object} The full data source for the row (not based on
12260
+ * `data`)
12261
+ * * Return:
12262
+ * * The return value from the function is what will be used for the
12263
+ * data requested.
12264
+ *
12265
+ * @type string|int|function|object|null
12266
+ * @default null Use the data source value.
12267
+ *
12268
+ * @name DataTable.defaults.column.render
12269
+ * @dtopt Columns
12270
+ *
12271
+ * @example
12272
+ * // Create a comma separated list from an array of objects
12273
+ * $(document).ready( function() {
12274
+ * $('#example').dataTable( {
12275
+ * "ajaxSource": "sources/deep.txt",
12276
+ * "columns": [
12277
+ * { "data": "engine" },
12278
+ * { "data": "browser" },
12279
+ * {
12280
+ * "data": "platform",
12281
+ * "render": "[, ].name"
12282
+ * }
12283
+ * ]
12284
+ * } );
12285
+ * } );
12286
+ *
12287
+ * @example
12288
+ * // Execute a function to obtain data
12289
+ * $(document).ready( function() {
12290
+ * $('#example').dataTable( {
12291
+ * "columnDefs": [ {
12292
+ * "targets": [ 0 ],
12293
+ * "data": null, // Use the full data source object for the renderer's source
12294
+ * "render": "browserName()"
12295
+ * } ]
12296
+ * } );
12297
+ * } );
12298
+ *
12299
+ * @example
12300
+ * // As an object, extracting different data for the different types
12301
+ * // This would be used with a data source such as:
12302
+ * // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
12303
+ * // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
12304
+ * // (which has both forms) is used for filtering for if a user inputs either format, while
12305
+ * // the formatted phone number is the one that is shown in the table.
12306
+ * $(document).ready( function() {
12307
+ * $('#example').dataTable( {
12308
+ * "columnDefs": [ {
12309
+ * "targets": [ 0 ],
12310
+ * "data": null, // Use the full data source object for the renderer's source
12311
+ * "render": {
12312
+ * "_": "phone",
12313
+ * "filter": "phone_filter",
12314
+ * "display": "phone_display"
12315
+ * }
12316
+ * } ]
12317
+ * } );
12318
+ * } );
12319
+ *
12320
+ * @example
12321
+ * // Use as a function to create a link from the data source
12322
+ * $(document).ready( function() {
12323
+ * $('#example').dataTable( {
12324
+ * "columnDefs": [ {
12325
+ * "targets": [ 0 ],
12326
+ * "data": "download_link",
12327
+ * "render": function ( data, type, full ) {
12328
+ * return '<a href="'+data+'">Download</a>';
12329
+ * }
12330
+ * } ]
12331
+ * } );
12332
+ * } );
12333
+ */
12334
  "mRender": null,
12335
 
12336
+ /**
12337
+ * Change the cell type created for the column - either TD cells or TH cells. This
12338
+ * can be useful as TH cells have semantic meaning in the table body, allowing them
12339
+ * to act as a header for a row (you may wish to add scope='row' to the TH elements).
12340
+ * @type string
12341
+ * @default td
12342
+ *
12343
+ * @name DataTable.defaults.column.cellType
12344
+ * @dtopt Columns
12345
+ *
12346
+ * @example
12347
+ * // Make the first column use TH cells
12348
+ * $(document).ready( function() {
12349
+ * $('#example').dataTable( {
12350
+ * "columnDefs": [ {
12351
+ * "targets": [ 0 ],
12352
+ * "cellType": "th"
12353
+ * } ]
12354
+ * } );
12355
+ * } );
12356
+ */
12357
  "sCellType": "td",
12358
 
12359
+ /**
12360
+ * Class to give to each cell in this column.
12361
+ * @type string
12362
+ * @default <i>Empty string</i>
12363
+ *
12364
+ * @name DataTable.defaults.column.class
12365
+ * @dtopt Columns
12366
+ *
12367
+ * @example
12368
+ * // Using `columnDefs`
12369
+ * $(document).ready( function() {
12370
+ * $('#example').dataTable( {
12371
+ * "columnDefs": [
12372
+ * { "class": "my_class", "targets": [ 0 ] }
12373
+ * ]
12374
+ * } );
12375
+ * } );
12376
+ *
12377
+ * @example
12378
+ * // Using `columns`
12379
+ * $(document).ready( function() {
12380
+ * $('#example').dataTable( {
12381
+ * "columns": [
12382
+ * { "class": "my_class" },
12383
+ * null,
12384
+ * null,
12385
+ * null,
12386
+ * null
12387
+ * ]
12388
+ * } );
12389
+ * } );
12390
+ */
12391
  "sClass": "",
12392
 
12393
+ /**
12394
+ * When DataTables calculates the column widths to assign to each column,
12395
+ * it finds the longest string in each column and then constructs a
12396
+ * temporary table and reads the widths from that. The problem with this
12397
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
12398
+ * string - thus the calculation can go wrong (doing it properly and putting
12399
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
12400
+ * a "work around" we provide this option. It will append its value to the
12401
+ * text that is found to be the longest string for the column - i.e. padding.
12402
+ * Generally you shouldn't need this!
12403
+ * @type string
12404
+ * @default <i>Empty string<i>
12405
+ *
12406
+ * @name DataTable.defaults.column.contentPadding
12407
+ * @dtopt Columns
12408
+ *
12409
+ * @example
12410
+ * // Using `columns`
12411
+ * $(document).ready( function() {
12412
+ * $('#example').dataTable( {
12413
+ * "columns": [
12414
+ * null,
12415
+ * null,
12416
+ * null,
12417
+ * {
12418
+ * "contentPadding": "mmm"
12419
+ * }
12420
+ * ]
12421
+ * } );
12422
+ * } );
12423
+ */
12424
  "sContentPadding": "",
12425
 
12426
+ /**
12427
+ * Allows a default value to be given for a column's data, and will be used
12428
+ * whenever a null data source is encountered (this can be because `data`
12429
+ * is set to null, or because the data source itself is null).
12430
+ * @type string
12431
+ * @default null
12432
+ *
12433
+ * @name DataTable.defaults.column.defaultContent
12434
+ * @dtopt Columns
12435
+ *
12436
+ * @example
12437
+ * // Using `columnDefs`
12438
+ * $(document).ready( function() {
12439
+ * $('#example').dataTable( {
12440
+ * "columnDefs": [
12441
+ * {
12442
+ * "data": null,
12443
+ * "defaultContent": "Edit",
12444
+ * "targets": [ -1 ]
12445
+ * }
12446
+ * ]
12447
+ * } );
12448
+ * } );
12449
+ *
12450
+ * @example
12451
+ * // Using `columns`
12452
+ * $(document).ready( function() {
12453
+ * $('#example').dataTable( {
12454
+ * "columns": [
12455
+ * null,
12456
+ * null,
12457
+ * null,
12458
+ * {
12459
+ * "data": null,
12460
+ * "defaultContent": "Edit"
12461
+ * }
12462
+ * ]
12463
+ * } );
12464
+ * } );
12465
+ */
12466
  "sDefaultContent": null,
12467
 
12468
+ /**
12469
+ * This parameter is only used in DataTables' server-side processing. It can
12470
+ * be exceptionally useful to know what columns are being displayed on the
12471
+ * client side, and to map these to database fields. When defined, the names
12472
+ * also allow DataTables to reorder information from the server if it comes
12473
+ * back in an unexpected order (i.e. if you switch your columns around on the
12474
+ * client-side, your server-side code does not also need updating).
12475
+ * @type string
12476
+ * @default <i>Empty string</i>
12477
+ *
12478
+ * @name DataTable.defaults.column.name
12479
+ * @dtopt Columns
12480
+ *
12481
+ * @example
12482
+ * // Using `columnDefs`
12483
+ * $(document).ready( function() {
12484
+ * $('#example').dataTable( {
12485
+ * "columnDefs": [
12486
+ * { "name": "engine", "targets": [ 0 ] },
12487
+ * { "name": "browser", "targets": [ 1 ] },
12488
+ * { "name": "platform", "targets": [ 2 ] },
12489
+ * { "name": "version", "targets": [ 3 ] },
12490
+ * { "name": "grade", "targets": [ 4 ] }
12491
+ * ]
12492
+ * } );
12493
+ * } );
12494
+ *
12495
+ * @example
12496
+ * // Using `columns`
12497
+ * $(document).ready( function() {
12498
+ * $('#example').dataTable( {
12499
+ * "columns": [
12500
+ * { "name": "engine" },
12501
+ * { "name": "browser" },
12502
+ * { "name": "platform" },
12503
+ * { "name": "version" },
12504
+ * { "name": "grade" }
12505
+ * ]
12506
+ * } );
12507
+ * } );
12508
+ */
12509
  "sName": "",
12510
 
12511
+ /**
12512
+ * Defines a data source type for the ordering which can be used to read
12513
+ * real-time information from the table (updating the internally cached
12514
+ * version) prior to ordering. This allows ordering to occur on user
12515
+ * editable elements such as form inputs.
12516
+ * @type string
12517
+ * @default std
12518
+ *
12519
+ * @name DataTable.defaults.column.orderDataType
12520
+ * @dtopt Columns
12521
+ *
12522
+ * @example
12523
+ * // Using `columnDefs`
12524
+ * $(document).ready( function() {
12525
+ * $('#example').dataTable( {
12526
+ * "columnDefs": [
12527
+ * { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
12528
+ * { "type": "numeric", "targets": [ 3 ] },
12529
+ * { "orderDataType": "dom-select", "targets": [ 4 ] },
12530
+ * { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
12531
+ * ]
12532
+ * } );
12533
+ * } );
12534
+ *
12535
+ * @example
12536
+ * // Using `columns`
12537
+ * $(document).ready( function() {
12538
+ * $('#example').dataTable( {
12539
+ * "columns": [
12540
+ * null,
12541
+ * null,
12542
+ * { "orderDataType": "dom-text" },
12543
+ * { "orderDataType": "dom-text", "type": "numeric" },
12544
+ * { "orderDataType": "dom-select" },
12545
+ * { "orderDataType": "dom-checkbox" }
12546
+ * ]
12547
+ * } );
12548
+ * } );
12549
+ */
12550
  "sSortDataType": "std",
12551
 
12552
+ /**
12553
+ * The title of this column.
12554
+ * @type string
12555
+ * @default null <i>Derived from the 'TH' value for this column in the
12556
+ * original HTML table.</i>
12557
+ *
12558
+ * @name DataTable.defaults.column.title
12559
+ * @dtopt Columns
12560
+ *
12561
+ * @example
12562
+ * // Using `columnDefs`
12563
+ * $(document).ready( function() {
12564
+ * $('#example').dataTable( {
12565
+ * "columnDefs": [
12566
+ * { "title": "My column title", "targets": [ 0 ] }
12567
+ * ]
12568
+ * } );
12569
+ * } );
12570
+ *
12571
+ * @example
12572
+ * // Using `columns`
12573
+ * $(document).ready( function() {
12574
+ * $('#example').dataTable( {
12575
+ * "columns": [
12576
+ * { "title": "My column title" },
12577
+ * null,
12578
+ * null,
12579
+ * null,
12580
+ * null
12581
+ * ]
12582
+ * } );
12583
+ * } );
12584
+ */
12585
  "sTitle": null,
12586
 
12587
+ /**
12588
+ * The type allows you to specify how the data for this column will be
12589
+ * ordered. Four types (string, numeric, date and html (which will strip
12590
+ * HTML tags before ordering)) are currently available. Note that only date
12591
+ * formats understood by Javascript's Date() object will be accepted as type
12592
+ * date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
12593
+ * 'numeric', 'date' or 'html' (by default). Further types can be adding
12594
+ * through plug-ins.
12595
+ * @type string
12596
+ * @default null <i>Auto-detected from raw data</i>
12597
+ *
12598
+ * @name DataTable.defaults.column.type
12599
+ * @dtopt Columns
12600
+ *
12601
+ * @example
12602
+ * // Using `columnDefs`
12603
+ * $(document).ready( function() {
12604
+ * $('#example').dataTable( {
12605
+ * "columnDefs": [
12606
+ * { "type": "html", "targets": [ 0 ] }
12607
+ * ]
12608
+ * } );
12609
+ * } );
12610
+ *
12611
+ * @example
12612
+ * // Using `columns`
12613
+ * $(document).ready( function() {
12614
+ * $('#example').dataTable( {
12615
+ * "columns": [
12616
+ * { "type": "html" },
12617
+ * null,
12618
+ * null,
12619
+ * null,
12620
+ * null
12621
+ * ]
12622
+ * } );
12623
+ * } );
12624
+ */
12625
  "sType": null,
12626
 
12627
+ /**
12628
+ * Defining the width of the column, this parameter may take any CSS value
12629
+ * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
12630
+ * been given a specific width through this interface ensuring that the table
12631
+ * remains readable.
12632
+ * @type string
12633
+ * @default null <i>Automatic</i>
12634
+ *
12635
+ * @name DataTable.defaults.column.width
12636
+ * @dtopt Columns
12637
+ *
12638
+ * @example
12639
+ * // Using `columnDefs`
12640
+ * $(document).ready( function() {
12641
+ * $('#example').dataTable( {
12642
+ * "columnDefs": [
12643
+ * { "width": "20%", "targets": [ 0 ] }
12644
+ * ]
12645
+ * } );
12646
+ * } );
12647
+ *
12648
+ * @example
12649
+ * // Using `columns`
12650
+ * $(document).ready( function() {
12651
+ * $('#example').dataTable( {
12652
+ * "columns": [
12653
+ * { "width": "20%" },
12654
+ * null,
12655
+ * null,
12656
+ * null,
12657
+ * null
12658
+ * ]
12659
+ * } );
12660
+ * } );
12661
+ */
12662
  "sWidth": null
12663
  };
12664
 
12665
  _fnHungarianMap(DataTable.defaults.column);
12666
 
 
12667
 
12668
+
12669
+ /**
12670
+ * DataTables settings object - this holds all the information needed for a
12671
+ * given table, including configuration, data and current application of the
12672
+ * table options. DataTables does not have a single instance for each DataTable
12673
+ * with the settings attached to that instance, but rather instances of the
12674
+ * DataTable "class" are created on-the-fly as needed (typically by a
12675
+ * $().dataTable() call) and the settings object is then applied to that
12676
+ * instance.
12677
+ *
12678
+ * Note that this object is related to {@link DataTable.defaults} but this
12679
+ * one is the internal data store for DataTables's cache of columns. It should
12680
+ * NOT be manipulated outside of DataTables. Any configuration should be done
12681
+ * through the initialisation options.
12682
+ * @namespace
12683
+ * @todo Really should attach the settings object to individual instances so we
12684
+ * don't need to create new instances on each $().dataTable() call (if the
12685
+ * table already exists). It would also save passing oSettings around and
12686
+ * into every single function. However, this is a very significant
12687
+ * architecture change for DataTables and will almost certainly break
12688
+ * backwards compatibility with older installations. This is something that
12689
+ * will be done in 2.0.
12690
+ */
12691
+ DataTable.models.oSettings = {
12692
+ /**
12693
+ * Primary features of DataTables and their enablement state.
12694
+ * @namespace
12695
+ */
12696
  "oFeatures": {
12697
+
12698
+ /**
12699
+ * Flag to say if DataTables should automatically try to calculate the
12700
+ * optimum table and columns widths (true) or not (false).
12701
+ * Note that this parameter will be set by the initialisation routine. To
12702
+ * set a default use {@link DataTable.defaults}.
12703
+ * @type boolean
12704
+ */
12705
  "bAutoWidth": null,
12706
+
12707
+ /**
12708
+ * Delay the creation of TR and TD elements until they are actually
12709
+ * needed by a driven page draw. This can give a significant speed
12710
+ * increase for Ajax source and Javascript source data, but makes no
12711
+ * difference at all fro DOM and server-side processing tables.
12712
+ * Note that this parameter will be set by the initialisation routine. To
12713
+ * set a default use {@link DataTable.defaults}.
12714
+ * @type boolean
12715
+ */
12716
  "bDeferRender": null,
12717
+
12718
+ /**
12719
+ * Enable filtering on the table or not. Note that if this is disabled
12720
+ * then there is no filtering at all on the table, including fnFilter.
12721
+ * To just remove the filtering input use sDom and remove the 'f' option.
12722
+ * Note that this parameter will be set by the initialisation routine. To
12723
+ * set a default use {@link DataTable.defaults}.
12724
+ * @type boolean
12725
+ */
12726
  "bFilter": null,
12727
+
12728
+ /**
12729
+ * Table information element (the 'Showing x of y records' div) enable
12730
+ * flag.
12731
+ * Note that this parameter will be set by the initialisation routine. To
12732
+ * set a default use {@link DataTable.defaults}.
12733
+ * @type boolean
12734
+ */
12735
  "bInfo": null,
12736
+
12737
+ /**
12738
+ * Present a user control allowing the end user to change the page size
12739
+ * when pagination is enabled.
12740
+ * Note that this parameter will be set by the initialisation routine. To
12741
+ * set a default use {@link DataTable.defaults}.
12742
+ * @type boolean
12743
+ */
12744
  "bLengthChange": null,
12745
 
12746
+ /**
12747
+ * Pagination enabled or not. Note that if this is disabled then length
12748
+ * changing must also be disabled.
12749
+ * Note that this parameter will be set by the initialisation routine. To
12750
+ * set a default use {@link DataTable.defaults}.
12751
+ * @type boolean
12752
+ */
12753
  "bPaginate": null,
12754
+
12755
+ /**
12756
+ * Processing indicator enable flag whenever DataTables is enacting a
12757
+ * user request - typically an Ajax request for server-side processing.
12758
+ * Note that this parameter will be set by the initialisation routine. To
12759
+ * set a default use {@link DataTable.defaults}.
12760
+ * @type boolean
12761
+ */
12762
  "bProcessing": null,
12763
+
12764
+ /**
12765
+ * Server-side processing enabled flag - when enabled DataTables will
12766
+ * get all data from the server for every draw - there is no filtering,
12767
+ * sorting or paging done on the client-side.
12768
+ * Note that this parameter will be set by the initialisation routine. To
12769
+ * set a default use {@link DataTable.defaults}.
12770
+ * @type boolean
12771
+ */
12772
  "bServerSide": null,
12773
+
12774
+ /**
12775
+ * Sorting enablement flag.
12776
+ * Note that this parameter will be set by the initialisation routine. To
12777
+ * set a default use {@link DataTable.defaults}.
12778
+ * @type boolean
12779
+ */
12780
  "bSort": null,
12781
+
12782
+ /**
12783
+ * Multi-column sorting
12784
+ * Note that this parameter will be set by the initialisation routine. To
12785
+ * set a default use {@link DataTable.defaults}.
12786
+ * @type boolean
12787
+ */
12788
  "bSortMulti": null,
12789
+
12790
+ /**
12791
+ * Apply a class to the columns which are being sorted to provide a
12792
+ * visual highlight or not. This can slow things down when enabled since
12793
+ * there is a lot of DOM interaction.
12794
+ * Note that this parameter will be set by the initialisation routine. To
12795
+ * set a default use {@link DataTable.defaults}.
12796
+ * @type boolean
12797
+ */
12798
  "bSortClasses": null,
12799
+
12800
+ /**
12801
+ * State saving enablement flag.
12802
+ * Note that this parameter will be set by the initialisation routine. To
12803
+ * set a default use {@link DataTable.defaults}.
12804
+ * @type boolean
12805
+ */
12806
  "bStateSave": null
12807
  },
12808
 
12809
+ /**
12810
+ * Scrolling settings for a table.
12811
+ * @namespace
12812
+ */
12813
  "oScroll": {
12814
+ /**
12815
+ * When the table is shorter in height than sScrollY, collapse the
12816
+ * table container down to the height of the table (when true).
12817
+ * Note that this parameter will be set by the initialisation routine. To
12818
+ * set a default use {@link DataTable.defaults}.
12819
+ * @type boolean
12820
+ */
12821
  "bCollapse": null,
12822
+
12823
+ /**
12824
+ * Width of the scrollbar for the web-browser's platform. Calculated
12825
+ * during table initialisation.
12826
+ * @type int
12827
+ * @default 0
12828
+ */
12829
  "iBarWidth": 0,
12830
+
12831
+ /**
12832
+ * Viewport width for horizontal scrolling. Horizontal scrolling is
12833
+ * disabled if an empty string.
12834
+ * Note that this parameter will be set by the initialisation routine. To
12835
+ * set a default use {@link DataTable.defaults}.
12836
+ * @type string
12837
+ */
12838
  "sX": null,
12839
+
12840
+ /**
12841
+ * Width to expand the table to when using x-scrolling. Typically you
12842
+ * should not need to use this.
12843
+ * Note that this parameter will be set by the initialisation routine. To
12844
+ * set a default use {@link DataTable.defaults}.
12845
+ * @type string
12846
+ * @deprecated
12847
+ */
12848
  "sXInner": null,
12849
+
12850
+ /**
12851
+ * Viewport height for vertical scrolling. Vertical scrolling is disabled
12852
+ * if an empty string.
12853
+ * Note that this parameter will be set by the initialisation routine. To
12854
+ * set a default use {@link DataTable.defaults}.
12855
+ * @type string
12856
+ */
12857
  "sY": null
12858
  },
12859
+
12860
+ /**
12861
+ * Language information for the table.
12862
+ * @namespace
12863
+ * @extends DataTable.defaults.oLanguage
12864
+ */
12865
  "oLanguage": {
12866
+ /**
12867
+ * Information callback function. See
12868
+ * {@link DataTable.defaults.fnInfoCallback}
12869
+ * @type function
12870
+ * @default null
12871
+ */
12872
  "fnInfoCallback": null
12873
  },
12874
+
12875
+ /**
12876
+ * Browser support parameters
12877
+ * @namespace
12878
+ */
12879
  "oBrowser": {
12880
+ /**
12881
+ * Indicate if the browser incorrectly calculates width:100% inside a
12882
+ * scrolling element (IE6/7)
12883
+ * @type boolean
12884
+ * @default false
12885
+ */
12886
  "bScrollOversize": false,
12887
+
12888
+ /**
12889
+ * Determine if the vertical scrollbar is on the right or left of the
12890
+ * scrolling container - needed for rtl language layout, although not
12891
+ * all browsers move the scrollbar (Safari).
12892
+ * @type boolean
12893
+ * @default false
12894
+ */
12895
  "bScrollbarLeft": false,
12896
+
12897
+ /**
12898
+ * Flag for if `getBoundingClientRect` is fully supported or not
12899
+ * @type boolean
12900
+ * @default false
12901
+ */
12902
  "bBounding": false,
12903
+
12904
+ /**
12905
+ * Browser scrollbar width
12906
+ * @type integer
12907
+ * @default 0
12908
+ */
12909
  "barWidth": 0
12910
  },
12911
+
12912
  "ajax": null,
12913
 
12914
+ /**
12915
+ * Array referencing the nodes which are used for the features. The
12916
+ * parameters of this object match what is allowed by sDom - i.e.
12917
+ * <ul>
12918
+ * <li>'l' - Length changing</li>
12919
+ * <li>'f' - Filtering input</li>
12920
+ * <li>'t' - The table!</li>
12921
+ * <li>'i' - Information</li>
12922
+ * <li>'p' - Pagination</li>
12923
+ * <li>'r' - pRocessing</li>
12924
+ * </ul>
12925
+ * @type array
12926
+ * @default []
12927
+ */
12928
  "aanFeatures": [],
12929
+
12930
+ /**
12931
+ * Store data information - see {@link DataTable.models.oRow} for detailed
12932
+ * information.
12933
+ * @type array
12934
+ * @default []
12935
+ */
12936
  "aoData": [],
12937
+
12938
+ /**
12939
+ * Array of indexes which are in the current display (after filtering etc)
12940
+ * @type array
12941
+ * @default []
12942
+ */
12943
  "aiDisplay": [],
12944
+
12945
+ /**
12946
+ * Array of indexes for display - no filtering
12947
+ * @type array
12948
+ * @default []
12949
+ */
12950
  "aiDisplayMaster": [],
12951
+
12952
+ /**
12953
+ * Map of row ids to data indexes
12954
+ * @type object
12955
+ * @default {}
12956
+ */
12957
  "aIds": {},
12958
+
12959
+ /**
12960
+ * Store information about each column that is in use
12961
+ * @type array
12962
+ * @default []
12963
+ */
12964
  "aoColumns": [],
12965
+
12966
+ /**
12967
+ * Store information about the table's header
12968
+ * @type array
12969
+ * @default []
12970
+ */
12971
  "aoHeader": [],
12972
+
12973
+ /**
12974
+ * Store information about the table's footer
12975
+ * @type array
12976
+ * @default []
12977
+ */
12978
  "aoFooter": [],
12979
+
12980
+ /**
12981
+ * Store the applied global search information in case we want to force a
12982
+ * research or compare the old search to a new one.
12983
+ * Note that this parameter will be set by the initialisation routine. To
12984
+ * set a default use {@link DataTable.defaults}.
12985
+ * @namespace
12986
+ * @extends DataTable.models.oSearch
12987
+ */
12988
  "oPreviousSearch": {},
12989
+
12990
+ /**
12991
+ * Store the applied search for each column - see
12992
+ * {@link DataTable.models.oSearch} for the format that is used for the
12993
+ * filtering information for each column.
12994
+ * @type array
12995
+ * @default []
12996
+ */
12997
  "aoPreSearchCols": [],
12998
+
12999
+ /**
13000
+ * Sorting that is applied to the table. Note that the inner arrays are
13001
+ * used in the following manner:
13002
+ * <ul>
13003
+ * <li>Index 0 - column number</li>
13004
+ * <li>Index 1 - current sorting direction</li>
13005
+ * </ul>
13006
+ * Note that this parameter will be set by the initialisation routine. To
13007
+ * set a default use {@link DataTable.defaults}.
13008
+ * @type array
13009
+ * @todo These inner arrays should really be objects
13010
+ */
13011
  "aaSorting": null,
13012
+
13013
+ /**
13014
+ * Sorting that is always applied to the table (i.e. prefixed in front of
13015
+ * aaSorting).
13016
+ * Note that this parameter will be set by the initialisation routine. To
13017
+ * set a default use {@link DataTable.defaults}.
13018
+ * @type array
13019
+ * @default []
13020
+ */
13021
  "aaSortingFixed": [],
13022
+
13023
+ /**
13024
+ * Classes to use for the striping of a table.
13025
+ * Note that this parameter will be set by the initialisation routine. To
13026
+ * set a default use {@link DataTable.defaults}.
13027
+ * @type array
13028
+ * @default []
13029
+ */
13030
  "asStripeClasses": null,
13031
+
13032
+ /**
13033
+ * If restoring a table - we should restore its striping classes as well
13034
+ * @type array
13035
+ * @default []
13036
+ */
13037
  "asDestroyStripes": [],
13038
+
13039
+ /**
13040
+ * If restoring a table - we should restore its width
13041
+ * @type int
13042
+ * @default 0
13043
+ */
13044
  "sDestroyWidth": 0,
13045
+
13046
+ /**
13047
+ * Callback functions array for every time a row is inserted (i.e. on a draw).
13048
+ * @type array
13049
+ * @default []
13050
+ */
13051
  "aoRowCallback": [],
13052
+
13053
+ /**
13054
+ * Callback functions for the header on each draw.
13055
+ * @type array
13056
+ * @default []
13057
+ */
13058
  "aoHeaderCallback": [],
13059
+
13060
+ /**
13061
+ * Callback function for the footer on each draw.
13062
+ * @type array
13063
+ * @default []
13064
+ */
13065
  "aoFooterCallback": [],
13066
+
13067
+ /**
13068
+ * Array of callback functions for draw callback functions
13069
+ * @type array
13070
+ * @default []
13071
+ */
13072
  "aoDrawCallback": [],
13073
+
13074
+ /**
13075
+ * Array of callback functions for row created function
13076
+ * @type array
13077
+ * @default []
13078
+ */
13079
  "aoRowCreatedCallback": [],
13080
+
13081
+ /**
13082
+ * Callback functions for just before the table is redrawn. A return of
13083
+ * false will be used to cancel the draw.
13084
+ * @type array
13085
+ * @default []
13086
+ */
13087
  "aoPreDrawCallback": [],
13088
+
13089
+ /**
13090
+ * Callback functions for when the table has been initialised.
13091
+ * @type array
13092
+ * @default []
13093
+ */
13094
  "aoInitComplete": [],
13095
+
13096
+ /**
13097
+ * Callbacks for modifying the settings to be stored for state saving, prior to
13098
+ * saving state.
13099
+ * @type array
13100
+ * @default []
13101
+ */
13102
  "aoStateSaveParams": [],
13103
+
13104
+ /**
13105
+ * Callbacks for modifying the settings that have been stored for state saving
13106
+ * prior to using the stored values to restore the state.
13107
+ * @type array
13108
+ * @default []
13109
+ */
13110
  "aoStateLoadParams": [],
13111
+
13112
+ /**
13113
+ * Callbacks for operating on the settings object once the saved state has been
13114
+ * loaded
13115
+ * @type array
13116
+ * @default []
13117
+ */
13118
  "aoStateLoaded": [],
13119
+
13120
+ /**
13121
+ * Cache the table ID for quick access
13122
+ * @type string
13123
+ * @default <i>Empty string</i>
13124
+ */
13125
  "sTableId": "",
13126
+
13127
+ /**
13128
+ * The TABLE node for the main table
13129
+ * @type node
13130
+ * @default null
13131
+ */
13132
  "nTable": null,
13133
+
13134
+ /**
13135
+ * Permanent ref to the thead element
13136
+ * @type node
13137
+ * @default null
13138
+ */
13139
  "nTHead": null,
13140
+
13141
+ /**
13142
+ * Permanent ref to the tfoot element - if it exists
13143
+ * @type node
13144
+ * @default null
13145
+ */
13146
  "nTFoot": null,
13147
+
13148
+ /**
13149
+ * Permanent ref to the tbody element
13150
+ * @type node
13151
+ * @default null
13152
+ */
13153
  "nTBody": null,
13154
+
13155
+ /**
13156
+ * Cache the wrapper node (contains all DataTables controlled elements)
13157
+ * @type node
13158
+ * @default null
13159
+ */
13160
  "nTableWrapper": null,
13161
+
13162
+ /**
13163
+ * Indicate if when using server-side processing the loading of data
13164
+ * should be deferred until the second draw.
13165
+ * Note that this parameter will be set by the initialisation routine. To
13166
+ * set a default use {@link DataTable.defaults}.
13167
+ * @type boolean
13168
+ * @default false
13169
+ */
13170
  "bDeferLoading": false,
13171
+
13172
+ /**
13173
+ * Indicate if all required information has been read in
13174
+ * @type boolean
13175
+ * @default false
13176
+ */
13177
  "bInitialised": false,
13178
+
13179
+ /**
13180
+ * Information about open rows. Each object in the array has the parameters
13181
+ * 'nTr' and 'nParent'
13182
+ * @type array
13183
+ * @default []
13184
+ */
13185
  "aoOpenRows": [],
13186
+
13187
+ /**
13188
+ * Dictate the positioning of DataTables' control elements - see
13189
+ * {@link DataTable.model.oInit.sDom}.
13190
+ * Note that this parameter will be set by the initialisation routine. To
13191
+ * set a default use {@link DataTable.defaults}.
13192
+ * @type string
13193
+ * @default null
13194
+ */
13195
  "sDom": null,
13196
+
13197
+ /**
13198
+ * Search delay (in mS)
13199
+ * @type integer
13200
+ * @default null
13201
+ */
13202
  "searchDelay": null,
13203
+
13204
+ /**
13205
+ * Which type of pagination should be used.
13206
+ * Note that this parameter will be set by the initialisation routine. To
13207
+ * set a default use {@link DataTable.defaults}.
13208
+ * @type string
13209
+ * @default two_button
13210
+ */
13211
  "sPaginationType": "two_button",
13212
+
13213
+ /**
13214
+ * The state duration (for `stateSave`) in seconds.
13215
+ * Note that this parameter will be set by the initialisation routine. To
13216
+ * set a default use {@link DataTable.defaults}.
13217
+ * @type int
13218
+ * @default 0
13219
+ */
13220
  "iStateDuration": 0,
13221
+
13222
+ /**
13223
+ * Array of callback functions for state saving. Each array element is an
13224
+ * object with the following parameters:
13225
+ * <ul>
13226
+ * <li>function:fn - function to call. Takes two parameters, oSettings
13227
+ * and the JSON string to save that has been thus far created. Returns
13228
+ * a JSON string to be inserted into a json object
13229
+ * (i.e. '"param": [ 0, 1, 2]')</li>
13230
+ * <li>string:sName - name of callback</li>
13231
+ * </ul>
13232
+ * @type array
13233
+ * @default []
13234
+ */
13235
  "aoStateSave": [],
13236
+
13237
+ /**
13238
+ * Array of callback functions for state loading. Each array element is an
13239
+ * object with the following parameters:
13240
+ * <ul>
13241
+ * <li>function:fn - function to call. Takes two parameters, oSettings
13242
+ * and the object stored. May return false to cancel state loading</li>
13243
+ * <li>string:sName - name of callback</li>
13244
+ * </ul>
13245
+ * @type array
13246
+ * @default []
13247
+ */
13248
  "aoStateLoad": [],
13249
+
13250
+ /**
13251
+ * State that was saved. Useful for back reference
13252
+ * @type object
13253
+ * @default null
13254
+ */
13255
  "oSavedState": null,
13256
+
13257
+ /**
13258
+ * State that was loaded. Useful for back reference
13259
+ * @type object
13260
+ * @default null
13261
+ */
13262
  "oLoadedState": null,
13263
+
13264
+ /**
13265
+ * Source url for AJAX data for the table.
13266
+ * Note that this parameter will be set by the initialisation routine. To
13267
+ * set a default use {@link DataTable.defaults}.
13268
+ * @type string
13269
+ * @default null
13270
+ */
13271
  "sAjaxSource": null,
13272
+
13273
+ /**
13274
+ * Property from a given object from which to read the table data from. This
13275
+ * can be an empty string (when not server-side processing), in which case
13276
+ * it is assumed an an array is given directly.
13277
+ * Note that this parameter will be set by the initialisation routine. To
13278
+ * set a default use {@link DataTable.defaults}.
13279
+ * @type string
13280
+ */
13281
  "sAjaxDataProp": null,
13282
+
13283
+ /**
13284
+ * Note if draw should be blocked while getting data
13285
+ * @type boolean
13286
+ * @default true
13287
+ */
13288
  "bAjaxDataGet": true,
13289
+
13290
+ /**
13291
+ * The last jQuery XHR object that was used for server-side data gathering.
13292
+ * This can be used for working with the XHR information in one of the
13293
+ * callbacks
13294
+ * @type object
13295
+ * @default null
13296
+ */
13297
  "jqXHR": null,
13298
+
13299
+ /**
13300
+ * JSON returned from the server in the last Ajax request
13301
+ * @type object
13302
+ * @default undefined
13303
+ */
13304
  "json": undefined,
13305
+
13306
+ /**
13307
+ * Data submitted as part of the last Ajax request
13308
+ * @type object
13309
+ * @default undefined
13310
+ */
13311
  "oAjaxData": undefined,
13312
+
13313
+ /**
13314
+ * Function to get the server-side data.
13315
+ * Note that this parameter will be set by the initialisation routine. To
13316
+ * set a default use {@link DataTable.defaults}.
13317
+ * @type function
13318
+ */
13319
  "fnServerData": null,
13320
+
13321
+ /**
13322
+ * Functions which are called prior to sending an Ajax request so extra
13323
+ * parameters can easily be sent to the server
13324
+ * @type array
13325
+ * @default []
13326
+ */
13327
  "aoServerParams": [],
13328
+
13329
+ /**
13330
+ * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
13331
+ * required).
13332
+ * Note that this parameter will be set by the initialisation routine. To
13333
+ * set a default use {@link DataTable.defaults}.
13334
+ * @type string
13335
+ */
13336
  "sServerMethod": null,
13337
+
13338
+ /**
13339
+ * Format numbers for display.
13340
+ * Note that this parameter will be set by the initialisation routine. To
13341
+ * set a default use {@link DataTable.defaults}.
13342
+ * @type function
13343
+ */
13344
  "fnFormatNumber": null,
13345
+
13346
+ /**
13347
+ * List of options that can be used for the user selectable length menu.
13348
+ * Note that this parameter will be set by the initialisation routine. To
13349
+ * set a default use {@link DataTable.defaults}.
13350
+ * @type array
13351
+ * @default []
13352
+ */
13353
  "aLengthMenu": null,
13354
+
13355
+ /**
13356
+ * Counter for the draws that the table does. Also used as a tracker for
13357
+ * server-side processing
13358
+ * @type int
13359
+ * @default 0
13360
+ */
13361
  "iDraw": 0,
13362
+
13363
+ /**
13364
+ * Indicate if a redraw is being done - useful for Ajax
13365
+ * @type boolean
13366
+ * @default false
13367
+ */
13368
  "bDrawing": false,
13369
+
13370
+ /**
13371
+ * Draw index (iDraw) of the last error when parsing the returned data
13372
+ * @type int
13373
+ * @default -1
13374
+ */
13375
  "iDrawError": -1,
13376
+
13377
+ /**
13378
+ * Paging display length
13379
+ * @type int
13380
+ * @default 10
13381
+ */
13382
  "_iDisplayLength": 10,
13383
+
13384
+ /**
13385
+ * Paging start point - aiDisplay index
13386
+ * @type int
13387
+ * @default 0
13388
+ */
13389
  "_iDisplayStart": 0,
13390
+
13391
+ /**
13392
+ * Server-side processing - number of records in the result set
13393
+ * (i.e. before filtering), Use fnRecordsTotal rather than
13394
+ * this property to get the value of the number of records, regardless of
13395
+ * the server-side processing setting.
13396
+ * @type int
13397
+ * @default 0
13398
+ * @private
13399
+ */
13400
  "_iRecordsTotal": 0,
13401
+
13402
+ /**
13403
+ * Server-side processing - number of records in the current display set
13404
+ * (i.e. after filtering). Use fnRecordsDisplay rather than
13405
+ * this property to get the value of the number of records, regardless of
13406
+ * the server-side processing setting.
13407
+ * @type boolean
13408
+ * @default 0
13409
+ * @private
13410
+ */
13411
  "_iRecordsDisplay": 0,
13412
+
13413
+ /**
13414
+ * Flag to indicate if jQuery UI marking and classes should be used.
13415
+ * Note that this parameter will be set by the initialisation routine. To
13416
+ * set a default use {@link DataTable.defaults}.
13417
+ * @type boolean
13418
+ */
13419
  "bJUI": null,
13420
+
13421
+ /**
13422
+ * The classes to use for the table
13423
+ * @type object
13424
+ * @default {}
13425
+ */
13426
  "oClasses": {},
13427
+
13428
+ /**
13429
+ * Flag attached to the settings object so you can check in the draw
13430
+ * callback if filtering has been done in the draw. Deprecated in favour of
13431
+ * events.
13432
+ * @type boolean
13433
+ * @default false
13434
+ * @deprecated
13435
+ */
13436
  "bFiltered": false,
13437
+
13438
+ /**
13439
+ * Flag attached to the settings object so you can check in the draw
13440
+ * callback if sorting has been done in the draw. Deprecated in favour of
13441
+ * events.
13442
+ * @type boolean
13443
+ * @default false
13444
+ * @deprecated
13445
+ */
13446
  "bSorted": false,
13447
+
13448
+ /**
13449
+ * Indicate that if multiple rows are in the header and there is more than
13450
+ * one unique cell per column, if the top one (true) or bottom one (false)
13451
+ * should be used for sorting / title by DataTables.
13452
+ * Note that this parameter will be set by the initialisation routine. To
13453
+ * set a default use {@link DataTable.defaults}.
13454
+ * @type boolean
13455
+ */
13456
  "bSortCellsTop": null,
13457
+
13458
+ /**
13459
+ * Initialisation object that is used for the table
13460
+ * @type object
13461
+ * @default null
13462
+ */
13463
  "oInit": null,
13464
+
13465
+ /**
13466
+ * Destroy callback functions - for plug-ins to attach themselves to the
13467
+ * destroy so they can clean up markup and events.
13468
+ * @type array
13469
+ * @default []
13470
+ */
13471
  "aoDestroyCallback": [],
13472
+
13473
+ /**
13474
+ * Get the number of records in the current record set, before filtering
13475
+ * @type function
13476
+ */
13477
+ "fnRecordsTotal": function ()
13478
+ {
13479
  return _fnDataSource(this) == 'ssp' ?
13480
  this._iRecordsTotal * 1 :
13481
  this.aiDisplayMaster.length;
13482
  },
13483
+
13484
+ /**
13485
+ * Get the number of records in the current record set, after filtering
13486
+ * @type function
13487
+ */
13488
+ "fnRecordsDisplay": function ()
13489
+ {
13490
  return _fnDataSource(this) == 'ssp' ?
13491
  this._iRecordsDisplay * 1 :
13492
  this.aiDisplay.length;
13493
  },
13494
+
13495
+ /**
13496
+ * Get the display end point - aiDisplay index
13497
+ * @type function
13498
+ */
13499
+ "fnDisplayEnd": function ()
13500
+ {
13501
  var
13502
  len = this._iDisplayLength,
13503
  start = this._iDisplayStart,
13516
  calc;
13517
  }
13518
  },
13519
+
13520
+ /**
13521
+ * The DataTables object for this table
13522
+ * @type object
13523
+ * @default null
13524
+ */
13525
  "oInstance": null,
13526
+
13527
+ /**
13528
+ * Unique identifier for each instance of the DataTables object. If there
13529
+ * is an ID on the table node, then it takes that value, otherwise an
13530
+ * incrementing internal counter is used.
13531
+ * @type string
13532
+ * @default null
13533
+ */
13534
  "sInstance": null,
13535
+
13536
+ /**
13537
+ * tabindex attribute value that is added to DataTables control elements, allowing
13538
+ * keyboard navigation of the table and its controls.
13539
+ */
13540
  "iTabIndex": 0,
13541
+
13542
+ /**
13543
+ * DIV container for the footer scrolling table if scrolling
13544
+ */
13545
  "nScrollHead": null,
13546
+
13547
+ /**
13548
+ * DIV container for the footer scrolling table if scrolling
13549
+ */
13550
  "nScrollFoot": null,
13551
+
13552
+ /**
13553
+ * Last applied sort
13554
+ * @type array
13555
+ * @default []
13556
+ */
13557
  "aLastSort": [],
13558
+
13559
+ /**
13560
+ * Stored plug-in instances
13561
+ * @type object
13562
+ * @default {}
13563
+ */
13564
  "oPlugins": {},
13565
+
13566
+ /**
13567
+ * Function used to get a row's id from the row's data
13568
+ * @type function
13569
+ * @default null
13570
+ */
13571
  "rowIdFn": null,
13572
+
13573
+ /**
13574
+ * Data location where to store a row's id
13575
+ * @type string
13576
+ * @default null
13577
+ */
13578
  "rowId": null
13579
  };
13580
 
13581
+ /**
13582
+ * Extension object for DataTables that is used to provide all extension
13583
+ * options.
13584
+ *
13585
+ * Note that the `DataTable.ext` object is available through
13586
+ * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
13587
+ * also aliased to `jQuery.fn.dataTableExt` for historic reasons.
13588
+ * @namespace
13589
+ * @extends DataTable.models.ext
13590
+ */
13591
+
13592
+
13593
+ /**
13594
+ * DataTables extensions
13595
+ *
13596
+ * This namespace acts as a collection area for plug-ins that can be used to
13597
+ * extend DataTables capabilities. Indeed many of the build in methods
13598
+ * use this method to provide their own capabilities (sorting methods for
13599
+ * example).
13600
+ *
13601
+ * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
13602
+ * reasons
13603
+ *
13604
+ * @namespace
13605
+ */
13606
  DataTable.ext = _ext = {
13607
+ /**
13608
+ * Buttons. For use with the Buttons extension for DataTables. This is
13609
+ * defined here so other extensions can define buttons regardless of load
13610
+ * order. It is _not_ used by DataTables core.
13611
+ *
13612
+ * @type object
13613
+ * @default {}
13614
+ */
13615
  buttons: {},
13616
+
13617
+ /**
13618
+ * Element class names
13619
+ *
13620
+ * @type object
13621
+ * @default {}
13622
+ */
13623
  classes: {},
13624
 
13625
+ /**
13626
+ * DataTables build type (expanded by the download builder)
13627
+ *
13628
+ * @type string
13629
+ */
13630
  builder: "-source-",
13631
+
13632
+ /**
13633
+ * Error reporting.
13634
+ *
13635
+ * How should DataTables report an error. Can take the value 'alert',
13636
+ * 'throw', 'none' or a function.
13637
+ *
13638
+ * @type string|function
13639
+ * @default alert
13640
+ */
13641
  errMode: "alert",
13642
 
13643
+ /**
13644
+ * Feature plug-ins.
13645
+ *
13646
+ * This is an array of objects which describe the feature plug-ins that are
13647
+ * available to DataTables. These feature plug-ins are then available for
13648
+ * use through the `dom` initialisation option.
13649
+ *
13650
+ * Each feature plug-in is described by an object which must have the
13651
+ * following properties:
13652
+ *
13653
+ * * `fnInit` - function that is used to initialise the plug-in,
13654
+ * * `cFeature` - a character so the feature can be enabled by the `dom`
13655
+ * instillation option. This is case sensitive.
13656
+ *
13657
+ * The `fnInit` function has the following input parameters:
13658
+ *
13659
+ * 1. `{object}` DataTables settings object: see
13660
+ * {@link DataTable.models.oSettings}
13661
+ *
13662
+ * And the following return is expected:
13663
+ *
13664
+ * * {node|null} The element which contains your feature. Note that the
13665
+ * return may also be void if your plug-in does not require to inject any
13666
+ * DOM elements into DataTables control (`dom`) - for example this might
13667
+ * be useful when developing a plug-in which allows table control via
13668
+ * keyboard entry
13669
+ *
13670
+ * @type array
13671
+ *
13672
+ * @example
13673
+ * $.fn.dataTable.ext.features.push( {
13674
+ * "fnInit": function( oSettings ) {
13675
+ * return new TableTools( { "oDTSettings": oSettings } );
13676
+ * },
13677
+ * "cFeature": "T"
13678
+ * } );
13679
+ */
13680
  feature: [],
13681
 
13682
+ /**
13683
+ * Row searching.
13684
+ *
13685
+ * This method of searching is complimentary to the default type based
13686
+ * searching, and a lot more comprehensive as it allows you complete control
13687
+ * over the searching logic. Each element in this array is a function
13688
+ * (parameters described below) that is called for every row in the table,
13689
+ * and your logic decides if it should be included in the searching data set
13690
+ * or not.
13691
+ *
13692
+ * Searching functions have the following input parameters:
13693
+ *
13694
+ * 1. `{object}` DataTables settings object: see
13695
+ * {@link DataTable.models.oSettings}
13696
+ * 2. `{array|object}` Data for the row to be processed (same as the
13697
+ * original format that was passed in as the data source, or an array
13698
+ * from a DOM data source
13699
+ * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
13700
+ * can be useful to retrieve the `TR` element if you need DOM interaction.
13701
+ *
13702
+ * And the following return is expected:
13703
+ *
13704
+ * * {boolean} Include the row in the searched result set (true) or not
13705
+ * (false)
13706
+ *
13707
+ * Note that as with the main search ability in DataTables, technically this
13708
+ * is "filtering", since it is subtractive. However, for consistency in
13709
+ * naming we call it searching here.
13710
+ *
13711
+ * @type array
13712
+ * @default []
13713
+ *
13714
+ * @example
13715
+ * // The following example shows custom search being applied to the
13716
+ * // fourth column (i.e. the data[3] index) based on two input values
13717
+ * // from the end-user, matching the data in a certain range.
13718
+ * $.fn.dataTable.ext.search.push(
13719
+ * function( settings, data, dataIndex ) {
13720
+ * var min = document.getElementById('min').value * 1;
13721
+ * var max = document.getElementById('max').value * 1;
13722
+ * var version = data[3] == "-" ? 0 : data[3]*1;
13723
+ *
13724
+ * if ( min == "" && max == "" ) {
13725
+ * return true;
13726
+ * }
13727
+ * else if ( min == "" && version < max ) {
13728
+ * return true;
13729
+ * }
13730
+ * else if ( min < version && "" == max ) {
13731
+ * return true;
13732
+ * }
13733
+ * else if ( min < version && version < max ) {
13734
+ * return true;
13735
+ * }
13736
+ * return false;
13737
+ * }
13738
+ * );
13739
+ */
13740
  search: [],
13741
 
13742
+ /**
13743
+ * Selector extensions
13744
+ *
13745
+ * The `selector` option can be used to extend the options available for the
13746
+ * selector modifier options (`selector-modifier` object data type) that
13747
+ * each of the three built in selector types offer (row, column and cell +
13748
+ * their plural counterparts). For example the Select extension uses this
13749
+ * mechanism to provide an option to select only rows, columns and cells
13750
+ * that have been marked as selected by the end user (`{selected: true}`),
13751
+ * which can be used in conjunction with the existing built in selector
13752
+ * options.
13753
+ *
13754
+ * Each property is an array to which functions can be pushed. The functions
13755
+ * take three attributes:
13756
+ *
13757
+ * * Settings object for the host table
13758
+ * * Options object (`selector-modifier` object type)
13759
+ * * Array of selected item indexes
13760
+ *
13761
+ * The return is an array of the resulting item indexes after the custom
13762
+ * selector has been applied.
13763
+ *
13764
+ * @type object
13765
+ */
13766
  selector: {
13767
  cell: [],
13768
  column: [],
13769
  row: []
13770
  },
13771
+
13772
+ /**
13773
+ * Internal functions, exposed for used in plug-ins.
13774
+ *
13775
+ * Please note that you should not need to use the internal methods for
13776
+ * anything other than a plug-in (and even then, try to avoid if possible).
13777
+ * The internal function may change between releases.
13778
+ *
13779
+ * @type object
13780
+ * @default {}
13781
+ */
13782
  internal: {},
13783
 
13784
+ /**
13785
+ * Legacy configuration options. Enable and disable legacy options that
13786
+ * are available in DataTables.
13787
+ *
13788
+ * @type object
13789
+ */
13790
  legacy: {
13791
+ /**
13792
+ * Enable / disable DataTables 1.9 compatible server-side processing
13793
+ * requests
13794
+ *
13795
+ * @type boolean
13796
+ * @default null
13797
+ */
13798
  ajax: null
13799
  },
13800
+
13801
+ /**
13802
+ * Pagination plug-in methods.
13803
+ *
13804
+ * Each entry in this object is a function and defines which buttons should
13805
+ * be shown by the pagination rendering method that is used for the table:
13806
+ * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
13807
+ * buttons are displayed in the document, while the functions here tell it
13808
+ * what buttons to display. This is done by returning an array of button
13809
+ * descriptions (what each button will do).
13810
+ *
13811
+ * Pagination types (the four built in options and any additional plug-in
13812
+ * options defined here) can be used through the `paginationType`
13813
+ * initialisation parameter.
13814
+ *
13815
+ * The functions defined take two parameters:
13816
+ *
13817
+ * 1. `{int} page` The current page index
13818
+ * 2. `{int} pages` The number of pages in the table
13819
+ *
13820
+ * Each function is expected to return an array where each element of the
13821
+ * array can be one of:
13822
+ *
13823
+ * * `first` - Jump to first page when activated
13824
+ * * `last` - Jump to last page when activated
13825
+ * * `previous` - Show previous page when activated
13826
+ * * `next` - Show next page when activated
13827
+ * * `{int}` - Show page of the index given
13828
+ * * `{array}` - A nested array containing the above elements to add a
13829
+ * containing 'DIV' element (might be useful for styling).
13830
+ *
13831
+ * Note that DataTables v1.9- used this object slightly differently whereby
13832
+ * an object with two functions would be defined for each plug-in. That
13833
+ * ability is still supported by DataTables 1.10+ to provide backwards
13834
+ * compatibility, but this option of use is now decremented and no longer
13835
+ * documented in DataTables 1.10+.
13836
+ *
13837
+ * @type object
13838
+ * @default {}
13839
+ *
13840
+ * @example
13841
+ * // Show previous, next and current page buttons only
13842
+ * $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
13843
+ * return [ 'previous', page, 'next' ];
13844
+ * };
13845
+ */
13846
  pager: {},
13847
+
13848
  renderer: {
13849
  pageButton: {},
13850
  header: {}
13851
  },
13852
+
13853
+ /**
13854
+ * Ordering plug-ins - custom data source
13855
+ *
13856
+ * The extension options for ordering of data available here is complimentary
13857
+ * to the default type based ordering that DataTables typically uses. It
13858
+ * allows much greater control over the the data that is being used to
13859
+ * order a column, but is necessarily therefore more complex.
13860
+ *
13861
+ * This type of ordering is useful if you want to do ordering based on data
13862
+ * live from the DOM (for example the contents of an 'input' element) rather
13863
+ * than just the static string that DataTables knows of.
13864
+ *
13865
+ * The way these plug-ins work is that you create an array of the values you
13866
+ * wish to be ordering for the column in question and then return that
13867
+ * array. The data in the array much be in the index order of the rows in
13868
+ * the table (not the currently ordering order!). Which order data gathering
13869
+ * function is run here depends on the `dt-init columns.orderDataType`
13870
+ * parameter that is used for the column (if any).
13871
+ *
13872
+ * The functions defined take two parameters:
13873
+ *
13874
+ * 1. `{object}` DataTables settings object: see
13875
+ * {@link DataTable.models.oSettings}
13876
+ * 2. `{int}` Target column index
13877
+ *
13878
+ * Each function is expected to return an array:
13879
+ *
13880
+ * * `{array}` Data for the column to be ordering upon
13881
+ *
13882
+ * @type array
13883
+ *
13884
+ * @example
13885
+ * // Ordering using `input` node values
13886
+ * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
13887
+ * {
13888
+ * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
13889
+ * return $('input', td).val();
13890
+ * } );
13891
+ * }
13892
+ */
13893
  order: {},
13894
 
13895
+ /**
13896
+ * Type based plug-ins.
13897
+ *
13898
+ * Each column in DataTables has a type assigned to it, either by automatic
13899
+ * detection or by direct assignment using the `type` option for the column.
13900
+ * The type of a column will effect how it is ordering and search (plug-ins
13901
+ * can also make use of the column type if required).
13902
+ *
13903
+ * @namespace
13904
+ */
13905
  type: {
13906
+ /**
13907
+ * Type detection functions.
13908
+ *
13909
+ * The functions defined in this object are used to automatically detect
13910
+ * a column's type, making initialisation of DataTables super easy, even
13911
+ * when complex data is in the table.
13912
+ *
13913
+ * The functions defined take two parameters:
13914
+ *
13915
+ * 1. `{*}` Data from the column cell to be analysed
13916
+ * 2. `{settings}` DataTables settings object. This can be used to
13917
+ * perform context specific type detection - for example detection
13918
+ * based on language settings such as using a comma for a decimal
13919
+ * place. Generally speaking the options from the settings will not
13920
+ * be required
13921
+ *
13922
+ * Each function is expected to return:
13923
+ *
13924
+ * * `{string|null}` Data type detected, or null if unknown (and thus
13925
+ * pass it on to the other type detection functions.
13926
+ *
13927
+ * @type array
13928
+ *
13929
+ * @example
13930
+ * // Currency type detection plug-in:
13931
+ * $.fn.dataTable.ext.type.detect.push(
13932
+ * function ( data, settings ) {
13933
+ * // Check the numeric part
13934
+ * if ( ! $.isNumeric( data.substring(1) ) ) {
13935
+ * return null;
13936
+ * }
13937
+ *
13938
+ * // Check prefixed by currency
13939
+ * if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {
13940
+ * return 'currency';
13941
+ * }
13942
+ * return null;
13943
+ * }
13944
+ * );
13945
+ */
13946
  detect: [],
13947
+
13948
+ /**
13949
+ * Type based search formatting.
13950
+ *
13951
+ * The type based searching functions can be used to pre-format the
13952
+ * data to be search on. For example, it can be used to strip HTML
13953
+ * tags or to de-format telephone numbers for numeric only searching.
13954
+ *
13955
+ * Note that is a search is not defined for a column of a given type,
13956
+ * no search formatting will be performed.
13957
+ *
13958
+ * Pre-processing of searching data plug-ins - When you assign the sType
13959
+ * for a column (or have it automatically detected for you by DataTables
13960
+ * or a type detection plug-in), you will typically be using this for
13961
+ * custom sorting, but it can also be used to provide custom searching
13962
+ * by allowing you to pre-processing the data and returning the data in
13963
+ * the format that should be searched upon. This is done by adding
13964
+ * functions this object with a parameter name which matches the sType
13965
+ * for that target column. This is the corollary of <i>afnSortData</i>
13966
+ * for searching data.
13967
+ *
13968
+ * The functions defined take a single parameter:
13969
+ *
13970
+ * 1. `{*}` Data from the column cell to be prepared for searching
13971
+ *
13972
+ * Each function is expected to return:
13973
+ *
13974
+ * * `{string|null}` Formatted string that will be used for the searching.
13975
+ *
13976
+ * @type object
13977
+ * @default {}
13978
+ *
13979
+ * @example
13980
+ * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
13981
+ * return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
13982
+ * }
13983
+ */
13984
  search: {},
13985
+
13986
+ /**
13987
+ * Type based ordering.
13988
+ *
13989
+ * The column type tells DataTables what ordering to apply to the table
13990
+ * when a column is sorted upon. The order for each type that is defined,
13991
+ * is defined by the functions available in this object.
13992
+ *
13993
+ * Each ordering option can be described by three properties added to
13994
+ * this object:
13995
+ *
13996
+ * * `{type}-pre` - Pre-formatting function
13997
+ * * `{type}-asc` - Ascending order function
13998
+ * * `{type}-desc` - Descending order function
13999
+ *
14000
+ * All three can be used together, only `{type}-pre` or only
14001
+ * `{type}-asc` and `{type}-desc` together. It is generally recommended
14002
+ * that only `{type}-pre` is used, as this provides the optimal
14003
+ * implementation in terms of speed, although the others are provided
14004
+ * for compatibility with existing Javascript sort functions.
14005
+ *
14006
+ * `{type}-pre`: Functions defined take a single parameter:
14007
+ *
14008
+ * 1. `{*}` Data from the column cell to be prepared for ordering
14009
+ *
14010
+ * And return:
14011
+ *
14012
+ * * `{*}` Data to be sorted upon
14013
+ *
14014
+ * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
14015
+ * functions, taking two parameters:
14016
+ *
14017
+ * 1. `{*}` Data to compare to the second parameter
14018
+ * 2. `{*}` Data to compare to the first parameter
14019
+ *
14020
+ * And returning:
14021
+ *
14022
+ * * `{*}` Ordering match: <0 if first parameter should be sorted lower
14023
+ * than the second parameter, ===0 if the two parameters are equal and
14024
+ * >0 if the first parameter should be sorted height than the second
14025
+ * parameter.
14026
+ *
14027
+ * @type object
14028
+ * @default {}
14029
+ *
14030
+ * @example
14031
+ * // Numeric ordering of formatted numbers with a pre-formatter
14032
+ * $.extend( $.fn.dataTable.ext.type.order, {
14033
+ * "string-pre": function(x) {
14034
+ * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
14035
+ * return parseFloat( a );
14036
+ * }
14037
+ * } );
14038
+ *
14039
+ * @example
14040
+ * // Case-sensitive string ordering, with no pre-formatting method
14041
+ * $.extend( $.fn.dataTable.ext.order, {
14042
+ * "string-case-asc": function(x,y) {
14043
+ * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14044
+ * },
14045
+ * "string-case-desc": function(x,y) {
14046
+ * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
14047
+ * }
14048
+ * } );
14049
+ */
14050
  order: {}
14051
  },
14052
+
14053
+ /**
14054
+ * Unique DataTables instance counter
14055
+ *
14056
+ * @type int
14057
+ * @private
14058
+ */
14059
  _unique: 0,
14060
+
14061
+ //
14062
+ // Depreciated
14063
+ // The following properties are retained for backwards compatiblity only.
14064
+ // The should not be used in new projects and will be removed in a future
14065
+ // version
14066
+ //
14067
+
14068
+ /**
14069
+ * Version check function.
14070
+ * @type function
14071
+ * @depreciated Since 1.10
14072
+ */
14073
  fnVersionCheck: DataTable.fnVersionCheck,
14074
+
14075
+ /**
14076
+ * Index for what 'this' index API functions should use
14077
+ * @type int
14078
+ * @deprecated Since v1.10
14079
+ */
14080
  iApiIndex: 0,
14081
+
14082
+ /**
14083
+ * jQuery UI class container
14084
+ * @type object
14085
+ * @deprecated Since v1.10
14086
+ */
14087
  oJUIClasses: {},
14088
+
14089
+ /**
14090
+ * Software version
14091
+ * @type string
14092
+ * @deprecated Since v1.10
14093
+ */
14094
  sVersion: DataTable.version
14095
  };
14096
+
14097
+
14098
+ //
14099
+ // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
14100
+ //
14101
  $.extend(_ext, {
14102
  afnFiltering: _ext.search,
14103
  aTypes: _ext.type.detect,
14110
  oPagination: _ext.pager
14111
  });
14112
 
14113
+
14114
  $.extend(DataTable.ext.classes, {
14115
  "sTable": "dataTable",
14116
  "sNoFooter": "no-footer",
14117
+
14118
+ /* Paging buttons */
14119
  "sPageButton": "paginate_button",
14120
  "sPageButtonActive": "current",
14121
  "sPageButtonDisabled": "disabled",
14122
+
14123
+ /* Striping classes */
14124
  "sStripeOdd": "odd",
14125
  "sStripeEven": "even",
14126
+
14127
+ /* Empty row */
14128
  "sRowEmpty": "dataTables_empty",
14129
+
14130
+ /* Features */
14131
  "sWrapper": "dataTables_wrapper",
14132
  "sFilter": "dataTables_filter",
14133
  "sInfo": "dataTables_info",
14134
+ "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
 
14135
  "sLength": "dataTables_length",
14136
  "sProcessing": "dataTables_processing",
14137
+
14138
+ /* Sorting */
14139
  "sSortAsc": "sorting_asc",
14140
  "sSortDesc": "sorting_desc",
14141
+ "sSortable": "sorting", /* Sortable in both directions */
 
14142
  "sSortableAsc": "sorting_asc_disabled",
14143
  "sSortableDesc": "sorting_desc_disabled",
14144
  "sSortableNone": "sorting_disabled",
14145
+ "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
14146
+
14147
+ /* Filtering */
14148
  "sFilterInput": "",
14149
+
14150
+ /* Page length */
14151
  "sLengthSelect": "",
14152
 
14153
  /* Scrolling */
14173
  "sJUIHeader": "",
14174
  "sJUIFooter": ""
14175
  });
14176
+
14177
+
14178
  (function () {
14179
+
14180
+ // Reused strings for better compression. Closure compiler appears to have a
14181
+ // weird edge case where it is trying to expand strings rather than use the
14182
+ // variable version. This results in about 200 bytes being added, for very
14183
+ // little preference benefit since it this run on script load only.
14184
  var _empty = '';
14185
  _empty = '';
14186
 
14196
 
14197
  /* Features */
14198
  "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi " +
14199
+ "ui-buttonset-multi paging_", /* Note that the type is postfixed */
14200
+
14201
+ /* Sorting */
14202
  "sSortAsc": _stateDefault + " sorting_asc",
14203
  "sSortDesc": _stateDefault + " sorting_desc",
14204
  "sSortable": _stateDefault + " sorting",
14225
  });
14226
 
14227
  }());
14228
+
14229
+
14230
+
14231
  var extPagination = DataTable.ext.pager;
14232
 
14233
  function _numbers(page, pages) {
14258
  numbers.DT_el = 'span';
14259
  return numbers;
14260
  }
14261
+
14262
+
14263
  $.extend(extPagination, {
14264
  simple: function (page, pages) {
14265
  return ['previous', 'next'];
14266
  },
14267
+
14268
  full: function (page, pages) {
14269
  return ['first', 'previous', 'next', 'last'];
14270
  },
14271
+
14272
  numbers: function (page, pages) {
14273
  return [_numbers(page, pages)];
14274
  },
14275
+
14276
  simple_numbers: function (page, pages) {
14277
  return ['previous', _numbers(page, pages), 'next'];
14278
  },
14279
+
14280
  full_numbers: function (page, pages) {
14281
  return ['first', 'previous', _numbers(page, pages), 'next', 'last'];
14282
  },
14283
+
14284
+ first_last_numbers: function (page, pages) {
14285
+ return ['first', _numbers(page, pages), 'last'];
14286
+ },
14287
+
14288
+ // For testing and plug-ins to use
14289
  _numbers: _numbers,
14290
+
14291
+ // Number of number buttons (including ellipsis) to show. _Must be odd!_
14292
  numbers_length: 7
14293
  });
14294
+
14295
+
14296
  $.extend(true, DataTable.ext.renderer, {
14297
  pageButton: {
14298
  _: function (settings, host, idx, buttons, page, pages) {
14358
  node = $('<a>', {
14359
  'class': classes.sPageButton + ' ' + btnClass,
14360
  'aria-controls': settings.sTableId,
14361
+ 'aria-label': aria[ button ],
14362
  'data-dt-idx': counter,
14363
  'tabindex': settings.iTabIndex,
14364
  'id': idx === 0 && typeof button === 'string' ?
14365
+ settings.sTableId + '_' + button :
14366
+ null
14367
  })
14368
  .html(btnDisplay)
14369
  .appendTo(container);
14370
 
14371
  _fnBindAction(
14372
+ node, {action: button}, clickHandler
 
 
14373
  );
14374
 
14375
  counter++;
14377
  }
14378
  }
14379
  };
14380
+
14381
+ // IE9 throws an 'unknown error' if document.activeElement is used
14382
+ // inside an iframe or frame. Try / catch the error. Not good for
14383
+ // accessibility, but neither are frames.
14384
  var activeEl;
14385
 
14386
  try {
14387
+ // Because this approach is destroying and recreating the paging
14388
+ // elements, focus is lost on the select button which is bad for
14389
+ // accessibility. So we want to restore focus once the draw has
14390
+ // completed
14391
  activeEl = $(host).find(document.activeElement).data('dt-idx');
14392
  } catch (e) {
14393
  }
14394
 
14395
  attach($(host).empty(), buttons);
14396
 
14397
+ if (activeEl !== undefined) {
14398
  $(host).find('[data-dt-idx=' + activeEl + ']').focus();
14399
  }
14400
  }
14401
  }
14402
  });
14403
+
14404
+
14405
+
14406
+ // Built in type detection. See model.ext.aTypes for information about
14407
+ // what is required from this methods.
14408
  $.extend(DataTable.ext.type.detect, [
14409
+ // Plain numbers - first since V8 detects some plain numbers as dates
14410
+ // e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
14411
+ function (d, settings)
14412
+ {
14413
  var decimal = settings.oLanguage.sDecimal;
14414
  return _isNumber(d, decimal) ? 'num' + decimal : null;
14415
  },
14416
+
14417
+ // Dates (only those recognised by the browser's Date.parse)
14418
+ function (d, settings)
14419
+ {
14420
+ // V8 tries _very_ hard to make a string passed into `Date.parse()`
14421
+ // valid, so we need to use a regex to restrict date formats. Use a
14422
+ // plug-in for anything other than ISO8601 style strings
14423
+ if (d && !(d instanceof Date) && !_re_date.test(d)) {
14424
  return null;
14425
  }
14426
  var parsed = Date.parse(d);
14428
  },
14429
 
14430
  // Formatted numbers
14431
+ function (d, settings)
14432
+ {
14433
  var decimal = settings.oLanguage.sDecimal;
14434
  return _isNumber(d, decimal, true) ? 'num-fmt' + decimal : null;
14435
  },
14436
 
14437
  // HTML numeric
14438
+ function (d, settings)
14439
+ {
14440
  var decimal = settings.oLanguage.sDecimal;
14441
  return _htmlNumeric(d, decimal) ? 'html-num' + decimal : null;
14442
  },
14443
 
14444
  // HTML numeric, formatted
14445
+ function (d, settings)
14446
+ {
14447
  var decimal = settings.oLanguage.sDecimal;
14448
  return _htmlNumeric(d, decimal, true) ? 'html-num-fmt' + decimal : null;
14449
  },
14450
 
14451
  // HTML (this is strict checking - there must be html)
14452
+ function (d, settings)
14453
+ {
14454
  return _empty(d) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
14455
  'html' : null;
14456
  }
14457
  ]);
14458
+
14459
+
14460
+
14461
+ // Filter formatting functions. See model.ext.ofnSearch for information about
14462
+ // what is required from these methods.
14463
+ //
14464
+ // Note that additional search methods are added for the html numbers and
14465
+ // html formatted numbers by `_addNumericSort()` when we know what the decimal
14466
+ // place is
14467
+
14468
+
14469
  $.extend(DataTable.ext.type.search, {
14470
  html: function (data) {
14471
  return _empty(data) ?
14486
  }
14487
  });
14488
 
14489
+
14490
+
14491
  var __numericReplace = function (d, decimalPlace, re1, re2) {
14492
  if (d !== 0 && (!d || d === '-')) {
14493
  return -Infinity;
14494
  }
14495
+
14496
+ // If a decimal place other than `.` is used, it needs to be given to the
14497
+ // function so we can detect it and replace with a `.` which is the only
14498
+ // decimal place Javascript recognises - it is not locale aware.
14499
  if (decimalPlace) {
14500
  d = _numToDecimal(d, decimalPlace);
14501
  }
14513
  return d * 1;
14514
  };
14515
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14516
 
14517
+ // Add the numeric 'deformatting' functions for sorting and search. This is done
14518
+ // in a function to provide an easy ability for the language options to add
14519
+ // additional methods if a non-period decimal place is used.
14520
+ function _addNumericSort(decimalPlace) {
14521
+ $.each(
14522
+ {
14523
+ // Plain numbers
14524
+ "num": function (d) {
14525
+ return __numericReplace(d, decimalPlace);
14526
+ },
14527
+
14528
+ // Formatted numbers
14529
+ "num-fmt": function (d) {
14530
+ return __numericReplace(d, decimalPlace, _re_formatted_numeric);
14531
+ },
14532
+
14533
+ // HTML numeric
14534
+ "html-num": function (d) {
14535
+ return __numericReplace(d, decimalPlace, _re_html);
14536
+ },
14537
+
14538
+ // HTML numeric, formatted
14539
+ "html-num-fmt": function (d) {
14540
+ return __numericReplace(d, decimalPlace, _re_html, _re_formatted_numeric);
14541
+ }
14542
+ },
14543
  function (key, fn) {
14544
  // Add the ordering method
14545
+ _ext.type.order[ key + decimalPlace + '-pre' ] = fn;
14546
 
14547
  // For HTML types add a search formatter that will strip the HTML
14548
  if (key.match(/^html\-/)) {
14549
+ _ext.type.search[ key + decimalPlace ] = _ext.type.search.html;
14550
  }
14551
  }
14552
  );
14553
  }
14554
+
14555
+
14556
+ // Default sort methods
14557
  $.extend(_ext.type.order, {
14558
  // Dates
14559
  "date-pre": function (d) {
14560
+ return Date.parse(d) || -Infinity;
14561
  },
14562
 
14563
  // html
14568
  a.replace(/<.*?>/g, "").toLowerCase() :
14569
  a + '';
14570
  },
14571
+
14572
+ // string
14573
  "string-pre": function (a) {
14574
+ // This is a little complex, but faster than always calling toString,
14575
+ // http://jsperf.com/tostring-v-check
14576
  return _empty(a) ?
14577
  '' :
14578
  typeof a === 'string' ?
14582
  a.toString();
14583
  },
14584
 
14585
+ // string-asc and -desc are retained only for compatibility with the old
14586
+ // sort methods
14587
  "string-asc": function (x, y) {
14588
  return ((x < y) ? -1 : ((x > y) ? 1 : 0));
14589
  },
14593
  }
14594
  });
14595
 
14596
+
14597
+ // Numeric sorting types - order doesn't matter here
14598
  _addNumericSort('');
14599
 
14600
+
14601
  $.extend(true, DataTable.ext.renderer, {
14602
  header: {
14603
  _: function (settings, cell, column, classes) {
14604
+ // No additional mark-up required
14605
+ // Attach a sort listener to update on sort - note that using the
14606
+ // `DT` namespace will allow the event to be removed automatically
14607
+ // on destroy, while the `dt` namespaced event is the one we are
14608
+ // listening for
14609
  $(settings.nTable).on('order.dt.DT', function (e, ctx, sorting, columns) {
14610
  if (settings !== ctx) { // need to check this this is the host
14611
+ return; // table, not a nested one
14612
  }
14613
 
14614
  var colIdx = column.idx;
14619
  classes.sSortAsc + ' ' +
14620
  classes.sSortDesc
14621
  )
14622
+ .addClass(columns[ colIdx ] == 'asc' ?
14623
+ classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14624
  classes.sSortDesc :
14625
  column.sSortingClass
14626
  );
14646
 
14647
  cell
14648
  .removeClass(classes.sSortAsc + " " + classes.sSortDesc)
14649
+ .addClass(columns[ colIdx ] == 'asc' ?
14650
+ classes.sSortAsc : columns[ colIdx ] == 'desc' ?
14651
  classes.sSortDesc :
14652
  column.sSortingClass
14653
  );
14661
  classes.sSortJUIAscAllowed + " " +
14662
  classes.sSortJUIDescAllowed
14663
  )
14664
+ .addClass(columns[ colIdx ] == 'asc' ?
14665
+ classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
14666
  classes.sSortJUIDesc :
14667
  column.sSortingClassJUI
14668
  );
14670
  }
14671
  }
14672
  });
14673
+
14674
+ /*
14675
+ * Public helper functions. These aren't used internally by DataTables, or
14676
+ * called by any of the options passed into DataTables, but they can be used
14677
+ * externally by developers working with DataTables. They are helper functions
14678
+ * to make working with DataTables a little bit easier.
14679
+ */
14680
+
14681
  var __htmlEscapeEntities = function (d) {
14682
  return typeof d === 'string' ?
14683
  d.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') :
14684
  d;
14685
  };
14686
 
14687
+ /**
14688
+ * Helpers for `columns.render`.
14689
+ *
14690
+ * The options defined here can be used with the `columns.render` initialisation
14691
+ * option to provide a display renderer. The following functions are defined:
14692
+ *
14693
+ * * `number` - Will format numeric data (defined by `columns.data`) for
14694
+ * display, retaining the original unformatted data for sorting and filtering.
14695
+ * It takes 5 parameters:
14696
+ * * `string` - Thousands grouping separator
14697
+ * * `string` - Decimal point indicator
14698
+ * * `integer` - Number of decimal points to show
14699
+ * * `string` (optional) - Prefix.
14700
+ * * `string` (optional) - Postfix (/suffix).
14701
+ * * `text` - Escape HTML to help prevent XSS attacks. It has no optional
14702
+ * parameters.
14703
+ *
14704
+ * @example
14705
+ * // Column definition using the number renderer
14706
+ * {
14707
+ * data: "salary",
14708
+ * render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
14709
+ * }
14710
+ *
14711
+ * @namespace
14712
+ */
14713
  DataTable.render = {
14714
  number: function (thousands, decimal, precision, prefix, postfix) {
14715
  return {
14721
  var negative = d < 0 ? '-' : '';
14722
  var flo = parseFloat(d);
14723
 
14724
+ // If NaN then there isn't much formatting that we can do - just
14725
+ // return immediately, escaping any HTML (this was supposed to
14726
+ // be a number after all)
14727
  if (isNaN(flo)) {
14728
  return __htmlEscapeEntities(d);
14729
  }
14730
 
14731
+ flo = flo.toFixed(precision);
14732
  d = Math.abs(flo);
14733
 
14734
  var intPart = parseInt(d, 10);
14753
  }
14754
  };
14755
 
14756
+
14757
+ /*
14758
+ * This is really a good bit rubbish this method of exposing the internal methods
14759
+ * publicly... - To be fixed in 2.0 using methods on the prototype
14760
+ */
14761
+
14762
+
14763
+ /**
14764
+ * Create a wrapper function for exporting an internal functions to an external API.
14765
+ * @param {string} fn API function name
14766
+ * @returns {function} wrapped function
14767
+ * @memberof DataTable#internal
14768
+ */
14769
+ function _fnExternApiFunc(fn)
14770
+ {
14771
  return function () {
14772
  var args = [_fnSettingsFromNode(this[DataTable.ext.iApiIndex])].concat(
14773
  Array.prototype.slice.call(arguments)
14775
  return DataTable.ext.internal[fn].apply(this, args);
14776
  };
14777
  }
14778
+
14779
+
14780
+ /**
14781
+ * Reference to internal functions for use by plug-in developers. Note that
14782
+ * these methods are references to internal functions and are considered to be
14783
+ * private. If you use these methods, be aware that they are liable to change
14784
+ * between versions.
14785
+ * @namespace
14786
+ */
14787
  $.extend(DataTable.ext.internal, {
14788
  _fnExternApiFunc: _fnExternApiFunc,
14789
  _fnBuildAjax: _fnBuildAjax,
14874
  _fnDataSource: _fnDataSource,
14875
  _fnRowAttributes: _fnRowAttributes,
14876
  _fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
14877
+ // in 1.10, so this dead-end function is
14878
+ // added to prevent errors
14879
  });
14880
 
14881
+
14882
+ // jQuery access
14883
  $.fn.dataTable = DataTable;
14884
 
14885
  // Provide access to the host jQuery object (circular reference)
14898
  // All properties that are available to $.fn.dataTable should also be
14899
  // available on $.fn.DataTable
14900
  $.each(DataTable, function (prop, val) {
14901
+ $.fn.DataTable[ prop ] = val;
14902
  });
14903
 
14904
+
14905
+ // Information about events fired by DataTables - for documentation.
14906
+ /**
14907
+ * Draw event, fired whenever the table is redrawn on the page, at the same
14908
+ * point as fnDrawCallback. This may be useful for binding events or
14909
+ * performing calculations when the table is altered at all.
14910
+ * @name DataTable#draw.dt
14911
+ * @event
14912
+ * @param {event} e jQuery event object
14913
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14914
+ */
14915
+
14916
+ /**
14917
+ * Search event, fired when the searching applied to the table (using the
14918
+ * built-in global search, or column filters) is altered.
14919
+ * @name DataTable#search.dt
14920
+ * @event
14921
+ * @param {event} e jQuery event object
14922
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14923
+ */
14924
+
14925
+ /**
14926
+ * Page change event, fired when the paging of the table is altered.
14927
+ * @name DataTable#page.dt
14928
+ * @event
14929
+ * @param {event} e jQuery event object
14930
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14931
+ */
14932
+
14933
+ /**
14934
+ * Order event, fired when the ordering applied to the table is altered.
14935
+ * @name DataTable#order.dt
14936
+ * @event
14937
+ * @param {event} e jQuery event object
14938
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
14939
+ */
14940
+
14941
+ /**
14942
+ * DataTables initialisation complete event, fired when the table is fully
14943
+ * drawn, including Ajax data loaded, if Ajax data is required.
14944
+ * @name DataTable#init.dt
14945
+ * @event
14946
+ * @param {event} e jQuery event object
14947
+ * @param {object} oSettings DataTables settings object
14948
+ * @param {object} json The JSON object request from the server - only
14949
+ * present if client-side Ajax sourced data is used</li></ol>
14950
+ */
14951
+
14952
+ /**
14953
+ * State save event, fired when the table has changed state a new state save
14954
+ * is required. This event allows modification of the state saving object
14955
+ * prior to actually doing the save, including addition or other state
14956
+ * properties (for plug-ins) or modification of a DataTables core property.
14957
+ * @name DataTable#stateSaveParams.dt
14958
+ * @event
14959
+ * @param {event} e jQuery event object
14960
+ * @param {object} oSettings DataTables settings object
14961
+ * @param {object} json The state information to be saved
14962
+ */
14963
+
14964
+ /**
14965
+ * State load event, fired when the table is loading state from the stored
14966
+ * data, but prior to the settings object being modified by the saved state
14967
+ * - allowing modification of the saved state is required or loading of
14968
+ * state for a plug-in.
14969
+ * @name DataTable#stateLoadParams.dt
14970
+ * @event
14971
+ * @param {event} e jQuery event object
14972
+ * @param {object} oSettings DataTables settings object
14973
+ * @param {object} json The saved state information
14974
+ */
14975
+
14976
+ /**
14977
+ * State loaded event, fired when state has been loaded from stored data and
14978
+ * the settings object has been modified by the loaded data.
14979
+ * @name DataTable#stateLoaded.dt
14980
+ * @event
14981
+ * @param {event} e jQuery event object
14982
+ * @param {object} oSettings DataTables settings object
14983
+ * @param {object} json The saved state information
14984
+ */
14985
+
14986
+ /**
14987
+ * Processing event, fired when DataTables is doing some kind of processing
14988
+ * (be it, order, searcg or anything else). It can be used to indicate to
14989
+ * the end user that there is something happening, or that something has
14990
+ * finished.
14991
+ * @name DataTable#processing.dt
14992
+ * @event
14993
+ * @param {event} e jQuery event object
14994
+ * @param {object} oSettings DataTables settings object
14995
+ * @param {boolean} bShow Flag for if DataTables is doing processing or not
14996
+ */
14997
+
14998
+ /**
14999
+ * Ajax (XHR) event, fired whenever an Ajax request is completed from a
15000
+ * request to made to the server for new data. This event is called before
15001
+ * DataTables processed the returned data, so it can also be used to pre-
15002
+ * process the data returned from the server, if needed.
15003
+ *
15004
+ * Note that this trigger is called in `fnServerData`, if you override
15005
+ * `fnServerData` and which to use this event, you need to trigger it in you
15006
+ * success function.
15007
+ * @name DataTable#xhr.dt
15008
+ * @event
15009
+ * @param {event} e jQuery event object
15010
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15011
+ * @param {object} json JSON returned from the server
15012
+ *
15013
+ * @example
15014
+ * // Use a custom property returned from the server in another DOM element
15015
+ * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15016
+ * $('#status').html( json.status );
15017
+ * } );
15018
+ *
15019
+ * @example
15020
+ * // Pre-process the data returned from the server
15021
+ * $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
15022
+ * for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
15023
+ * json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
15024
+ * }
15025
+ * // Note no return - manipulate the data directly in the JSON object.
15026
+ * } );
15027
+ */
15028
+
15029
+ /**
15030
+ * Destroy event, fired when the DataTable is destroyed by calling fnDestroy
15031
+ * or passing the bDestroy:true parameter in the initialisation object. This
15032
+ * can be used to remove bound events, added DOM nodes, etc.
15033
+ * @name DataTable#destroy.dt
15034
+ * @event
15035
+ * @param {event} e jQuery event object
15036
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15037
+ */
15038
+
15039
+ /**
15040
+ * Page length change event, fired when number of records to show on each
15041
+ * page (the length) is changed.
15042
+ * @name DataTable#length.dt
15043
+ * @event
15044
+ * @param {event} e jQuery event object
15045
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15046
+ * @param {integer} len New length
15047
+ */
15048
+
15049
+ /**
15050
+ * Column sizing has changed.
15051
+ * @name DataTable#column-sizing.dt
15052
+ * @event
15053
+ * @param {event} e jQuery event object
15054
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15055
+ */
15056
+
15057
+ /**
15058
+ * Column visibility has changed.
15059
+ * @name DataTable#column-visibility.dt
15060
+ * @event
15061
+ * @param {event} e jQuery event object
15062
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
15063
+ * @param {int} column Column index
15064
+ * @param {bool} vis `false` if column now hidden, or `true` if visible
15065
+ */
15066
+
15067
  return $.fn.dataTable;
15068
  }));
15069
 
15070
+
15071
  (function (window, document, undefined) {
15072
 
15073
  var factory = function ($, DataTable) {
assets/global/plugins/jqueryFileTree/jqueryFileTree.css CHANGED
@@ -2,90 +2,225 @@ UL.jqueryFileTree {
2
  font-family: Verdana, sans-serif;
3
  font-size: 11px;
4
  line-height: 18px;
5
- padding: 0px;
6
- margin: 0px;
 
7
  }
8
-
9
  UL.jqueryFileTree LI {
10
  list-style: none;
11
- padding: 0px;
12
  padding-left: 20px;
13
- margin: 0px;
14
  white-space: nowrap;
15
  }
16
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  UL.jqueryFileTree A {
18
  color: #333;
19
  text-decoration: none;
20
- display: block;
21
- padding: 0px 2px;
 
22
  }
23
-
24
  UL.jqueryFileTree A:hover {
25
  background: #BDF;
26
  }
27
-
28
- /* Core Styles */
29
- .jqueryFileTree LI.directory { background: url(images/directory.png) left top no-repeat; }
30
- .jqueryFileTree LI.expanded { background: url(images/folder_open.png) left top no-repeat; }
31
- .jqueryFileTree LI.file { background: url(images/file.png) left top no-repeat; }
32
- .jqueryFileTree LI.wait { background: url(images/spinner.gif) left top no-repeat; }
33
- /* File Extensions*/
34
- .jqueryFileTree LI.ext_3gp { background: url(images/film.png) left top no-repeat; }
35
- .jqueryFileTree LI.ext_afp { background: url(images/code.png) left top no-repeat; }
36
- .jqueryFileTree LI.ext_afpa { background: url(images/code.png) left top no-repeat; }
37
- .jqueryFileTree LI.ext_asp { background: url(images/code.png) left top no-repeat; }
38
- .jqueryFileTree LI.ext_aspx { background: url(images/code.png) left top no-repeat; }
39
- .jqueryFileTree LI.ext_avi { background: url(images/film.png) left top no-repeat; }
40
- .jqueryFileTree LI.ext_bat { background: url(images/application.png) left top no-repeat; }
41
- .jqueryFileTree LI.ext_bmp { background: url(images/picture.png) left top no-repeat; }
42
- .jqueryFileTree LI.ext_c { background: url(images/code.png) left top no-repeat; }
43
- .jqueryFileTree LI.ext_cfm { background: url(images/code.png) left top no-repeat; }
44
- .jqueryFileTree LI.ext_cgi { background: url(images/code.png) left top no-repeat; }
45
- .jqueryFileTree LI.ext_com { background: url(images/application.png) left top no-repeat; }
46
- .jqueryFileTree LI.ext_cpp { background: url(images/code.png) left top no-repeat; }
47
- .jqueryFileTree LI.ext_css { background: url(images/css.png) left top no-repeat; }
48
- .jqueryFileTree LI.ext_doc { background: url(images/doc.png) left top no-repeat; }
49
- .jqueryFileTree LI.ext_exe { background: url(images/application.png) left top no-repeat; }
50
- .jqueryFileTree LI.ext_gif { background: url(images/picture.png) left top no-repeat; }
51
- .jqueryFileTree LI.ext_fla { background: url(images/flash.png) left top no-repeat; }
52
- .jqueryFileTree LI.ext_h { background: url(images/code.png) left top no-repeat; }
53
- .jqueryFileTree LI.ext_htm { background: url(images/html.png) left top no-repeat; }
54
- .jqueryFileTree LI.ext_html { background: url(images/html.png) left top no-repeat; }
55
- .jqueryFileTree LI.ext_jar { background: url(images/java.png) left top no-repeat; }
56
- .jqueryFileTree LI.ext_jpg { background: url(images/picture.png) left top no-repeat; }
57
- .jqueryFileTree LI.ext_jpeg { background: url(images/picture.png) left top no-repeat; }
58
- .jqueryFileTree LI.ext_js { background: url(images/script.png) left top no-repeat; }
59
- .jqueryFileTree LI.ext_lasso { background: url(images/code.png) left top no-repeat; }
60
- .jqueryFileTree LI.ext_log { background: url(images/txt.png) left top no-repeat; }
61
- .jqueryFileTree LI.ext_m4p { background: url(images/music.png) left top no-repeat; }
62
- .jqueryFileTree LI.ext_mov { background: url(images/film.png) left top no-repeat; }
63
- .jqueryFileTree LI.ext_mp3 { background: url(images/music.png) left top no-repeat; }
64
- .jqueryFileTree LI.ext_mp4 { background: url(images/film.png) left top no-repeat; }
65
- .jqueryFileTree LI.ext_mpg { background: url(images/film.png) left top no-repeat; }
66
- .jqueryFileTree LI.ext_mpeg { background: url(images/film.png) left top no-repeat; }
67
- .jqueryFileTree LI.ext_ogg { background: url(images/music.png) left top no-repeat; }
68
- .jqueryFileTree LI.ext_pcx { background: url(images/picture.png) left top no-repeat; }
69
- .jqueryFileTree LI.ext_pdf { background: url(images/pdf.png) left top no-repeat; }
70
- .jqueryFileTree LI.ext_php { background: url(images/php.png) left top no-repeat; }
71
- .jqueryFileTree LI.ext_png { background: url(images/picture.png) left top no-repeat; }
72
- .jqueryFileTree LI.ext_ppt { background: url(images/ppt.png) left top no-repeat; }
73
- .jqueryFileTree LI.ext_psd { background: url(images/psd.png) left top no-repeat; }
74
- .jqueryFileTree LI.ext_pl { background: url(images/script.png) left top no-repeat; }
75
- .jqueryFileTree LI.ext_py { background: url(images/script.png) left top no-repeat; }
76
- .jqueryFileTree LI.ext_rb { background: url(images/ruby.png) left top no-repeat; }
77
- .jqueryFileTree LI.ext_rbx { background: url(images/ruby.png) left top no-repeat; }
78
- .jqueryFileTree LI.ext_rhtml { background: url(images/ruby.png) left top no-repeat; }
79
- .jqueryFileTree LI.ext_rpm { background: url(images/linux.png) left top no-repeat; }
80
- .jqueryFileTree LI.ext_ruby { background: url(images/ruby.png) left top no-repeat; }
81
- .jqueryFileTree LI.ext_sql { background: url(images/db.png) left top no-repeat; }
82
- .jqueryFileTree LI.ext_swf { background: url(images/flash.png) left top no-repeat; }
83
- .jqueryFileTree LI.ext_tif { background: url(images/picture.png) left top no-repeat; }
84
- .jqueryFileTree LI.ext_tiff { background: url(images/picture.png) left top no-repeat; }
85
- .jqueryFileTree LI.ext_txt { background: url(images/txt.png) left top no-repeat; }
86
- .jqueryFileTree LI.ext_vb { background: url(images/code.png) left top no-repeat; }
87
- .jqueryFileTree LI.ext_wav { background: url(images/music.png) left top no-repeat; }
88
- .jqueryFileTree LI.ext_wmv { background: url(images/film.png) left top no-repeat; }
89
- .jqueryFileTree LI.ext_xls { background: url(images/xls.png) left top no-repeat; }
90
- .jqueryFileTree LI.ext_xml { background: url(images/code.png) left top no-repeat; }
91
- .jqueryFileTree LI.ext_zip { background: url(images/zip.png) left top no-repeat; }
2
  font-family: Verdana, sans-serif;
3
  font-size: 11px;
4
  line-height: 18px;
5
+ padding: 0;
6
+ margin: 0;
7
+ display: none;
8
  }
 
9
  UL.jqueryFileTree LI {
10
  list-style: none;
11
+ padding: 0;
12
  padding-left: 20px;
13
+ margin: 0;
14
  white-space: nowrap;
15
  }
16
+ UL.jqueryFileTree LI.directory {
17
+ background: url(images/directory.png) left top no-repeat;
18
+ }
19
+ UL.jqueryFileTree LI.directory-locked {
20
+ background: url(images/directory-lock.png) left top no-repeat;
21
+ }
22
+ UL.jqueryFileTree LI.expanded {
23
+ background: url(images/folder_open.png) left top no-repeat;
24
+ }
25
+ UL.jqueryFileTree LI.file {
26
+ background: url(images/file.png) left top no-repeat;
27
+ }
28
+ UL.jqueryFileTree LI.file-locked {
29
+ background: url(images/file-lock.png) left top no-repeat !important;
30
+ }
31
+ UL.jqueryFileTree LI.wait {
32
+ background: url(images/spinner.gif) left top no-repeat;
33
+ }
34
+ UL.jqueryFileTree LI.selected > a {
35
+ font-weight: bold;
36
+ }
37
+ UL.jqueryFileTree LI.ext_3gp {
38
+ background: url(images/film.png) left top no-repeat;
39
+ }
40
+ UL.jqueryFileTree LI.ext_afp {
41
+ background: url(images/code.png) left top no-repeat;
42
+ }
43
+ UL.jqueryFileTree LI.ext_afpa {
44
+ background: url(images/code.png) left top no-repeat;
45
+ }
46
+ UL.jqueryFileTree LI.ext_asp {
47
+ background: url(images/code.png) left top no-repeat;
48
+ }
49
+ UL.jqueryFileTree LI.ext_aspx {
50
+ background: url(images/code.png) left top no-repeat;
51
+ }
52
+ UL.jqueryFileTree LI.ext_avi {
53
+ background: url(images/film.png) left top no-repeat;
54
+ }
55
+ UL.jqueryFileTree LI.ext_bat {
56
+ background: url(images/application.png) left top no-repeat;
57
+ }
58
+ UL.jqueryFileTree LI.ext_bmp {
59
+ background: url(images/picture.png) left top no-repeat;
60
+ }
61
+ UL.jqueryFileTree LI.ext_c {
62
+ background: url(images/code.png) left top no-repeat;
63
+ }
64
+ UL.jqueryFileTree LI.ext_cfm {
65
+ background: url(images/code.png) left top no-repeat;
66
+ }
67
+ UL.jqueryFileTree LI.ext_cgi {
68
+ background: url(images/code.png) left top no-repeat;
69
+ }
70
+ UL.jqueryFileTree LI.ext_com {
71
+ background: url(images/application.png) left top no-repeat;
72
+ }
73
+ UL.jqueryFileTree LI.ext_cpp {
74
+ background: url(images/code.png) left top no-repeat;
75
+ }
76
+ UL.jqueryFileTree LI.ext_css {
77
+ background: url(images/css.png) left top no-repeat;
78
+ }
79
+ UL.jqueryFileTree LI.ext_doc {
80
+ background: url(images/doc.png) left top no-repeat;
81
+ }
82
+ UL.jqueryFileTree LI.ext_exe {
83
+ background: url(images/application.png) left top no-repeat;
84
+ }
85
+ UL.jqueryFileTree LI.ext_gif {
86
+ background: url(images/picture.png) left top no-repeat;
87
+ }
88
+ UL.jqueryFileTree LI.ext_fla {
89
+ background: url(images/flash.png) left top no-repeat;
90
+ }
91
+ UL.jqueryFileTree LI.ext_h {
92
+ background: url(images/code.png) left top no-repeat;
93
+ }
94
+ UL.jqueryFileTree LI.ext_htm {
95
+ background: url(images/html.png) left top no-repeat;
96
+ }
97
+ UL.jqueryFileTree LI.ext_html {
98
+ background: url(images/html.png) left top no-repeat;
99
+ }
100
+ UL.jqueryFileTree LI.ext_jar {
101
+ background: url(images/java.png) left top no-repeat;
102
+ }
103
+ UL.jqueryFileTree LI.ext_jpg {
104
+ background: url(images/picture.png) left top no-repeat;
105
+ }
106
+ UL.jqueryFileTree LI.ext_jpeg {
107
+ background: url(images/picture.png) left top no-repeat;
108
+ }
109
+ UL.jqueryFileTree LI.ext_js {
110
+ background: url(images/script.png) left top no-repeat;
111
+ }
112
+ UL.jqueryFileTree LI.ext_lasso {
113
+ background: url(images/code.png) left top no-repeat;
114
+ }
115
+ UL.jqueryFileTree LI.ext_log {
116
+ background: url(images/txt.png) left top no-repeat;
117
+ }
118
+ UL.jqueryFileTree LI.ext_m4p {
119
+ background: url(images/music.png) left top no-repeat;
120
+ }
121
+ UL.jqueryFileTree LI.ext_mov {
122
+ background: url(images/film.png) left top no-repeat;
123
+ }
124
+ UL.jqueryFileTree LI.ext_mp3 {
125
+ background: url(images/music.png) left top no-repeat;
126
+ }
127
+ UL.jqueryFileTree LI.ext_mp4 {
128
+ background: url(images/film.png) left top no-repeat;
129
+ }
130
+ UL.jqueryFileTree LI.ext_mpg {
131
+ background: url(images/film.png) left top no-repeat;
132
+ }
133
+ UL.jqueryFileTree LI.ext_mpeg {
134
+ background: url(images/film.png) left top no-repeat;
135
+ }
136
+ UL.jqueryFileTree LI.ext_ogg {
137
+ background: url(images/music.png) left top no-repeat;
138
+ }
139
+ UL.jqueryFileTree LI.ext_ogv {
140
+ background: url(images/film.png) left top no-repeat;
141
+ }
142
+ UL.jqueryFileTree LI.ext_pcx {
143
+ background: url(images/picture.png) left top no-repeat;
144
+ }
145
+ UL.jqueryFileTree LI.ext_pdf {
146
+ background: url(images/pdf.png) left top no-repeat;
147
+ }
148
+ UL.jqueryFileTree LI.ext_php {
149
+ background: url(images/php.png) left top no-repeat;
150
+ }
151
+ UL.jqueryFileTree LI.ext_png {
152
+ background: url(images/picture.png) left top no-repeat;
153
+ }
154
+ UL.jqueryFileTree LI.ext_ppt {
155
+ background: url(images/ppt.png) left top no-repeat;
156
+ }
157
+ UL.jqueryFileTree LI.ext_psd {
158
+ background: url(images/psd.png) left top no-repeat;
159
+ }
160
+ UL.jqueryFileTree LI.ext_pl {
161
+ background: url(images/script.png) left top no-repeat;
162
+ }
163
+ UL.jqueryFileTree LI.ext_py {
164
+ background: url(images/script.png) left top no-repeat;
165
+ }
166
+ UL.jqueryFileTree LI.ext_rb {
167
+ background: url(images/ruby.png) left top no-repeat;
168
+ }
169
+ UL.jqueryFileTree LI.ext_rbx {
170
+ background: url(images/ruby.png) left top no-repeat;
171
+ }
172
+ UL.jqueryFileTree LI.ext_rhtml {
173
+ background: url(images/ruby.png) left top no-repeat;
174
+ }
175
+ UL.jqueryFileTree LI.ext_rpm {
176
+ background: url(images/linux.png) left top no-repeat;
177
+ }
178
+ UL.jqueryFileTree LI.ext_ruby {
179
+ background: url(images/ruby.png) left top no-repeat;
180
+ }
181
+ UL.jqueryFileTree LI.ext_sql {
182
+ background: url(images/db.png) left top no-repeat;
183
+ }
184
+ UL.jqueryFileTree LI.ext_swf {
185
+ background: url(images/flash.png) left top no-repeat;
186
+ }
187
+ UL.jqueryFileTree LI.ext_tif {
188
+ background: url(images/picture.png) left top no-repeat;
189
+ }
190
+ UL.jqueryFileTree LI.ext_tiff {
191
+ background: url(images/picture.png) left top no-repeat;
192
+ }
193
+ UL.jqueryFileTree LI.ext_txt {
194
+ background: url(images/txt.png) left top no-repeat;
195
+ }
196
+ UL.jqueryFileTree LI.ext_vb {
197
+ background: url(images/code.png) left top no-repeat;
198
+ }
199
+ UL.jqueryFileTree LI.ext_wav {
200
+ background: url(images/music.png) left top no-repeat;
201
+ }
202
+ UL.jqueryFileTree LI.ext_webm {
203
+ background: url(images/film.png) left top no-repeat;
204
+ }
205
+ UL.jqueryFileTree LI.ext_wmv {
206
+ background: url(images/film.png) left top no-repeat;
207
+ }
208
+ UL.jqueryFileTree LI.ext_xls {
209
+ background: url(images/xls.png) left top no-repeat;
210
+ }
211
+ UL.jqueryFileTree LI.ext_xml {
212
+ background: url(images/code.png) left top no-repeat;
213
+ }
214
+ UL.jqueryFileTree LI.ext_zip {
215
+ background: url(images/zip.png) left top no-repeat;
216
+ }
217
  UL.jqueryFileTree A {
218
  color: #333;
219
  text-decoration: none;
220
+ display: inline-block;
221
+ padding: 0 2px;
222
+ cursor: pointer;
223
  }
 
224
  UL.jqueryFileTree A:hover {
225
  background: #BDF;
226
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/global/plugins/jqueryFileTree/jqueryFileTree.js CHANGED
@@ -1,115 +1,223 @@
1
- // jQuery File Tree Plugin
2
- //
3
- // Version 1.01
4
- //
5
- // Cory S.N. LaViska
6
- // A Beautiful Site (http://abeautifulsite.net/)
7
- // 24 March 2008
8
- //
9
- // Visit http://abeautifulsite.net/notebook.php?article=58 for more information
10
- //
11
- // Usage: $('.fileTreeDemo').fileTree( options, callback )
12
- //
13
- // Options: root - root folder to display; default = /
14
- // script - location of the serverside AJAX file to use; default = jqueryFileTree.php
15
- // folderEvent - event to trigger expand/collapse; default = click
16
- // expandSpeed - default = 500 (ms); use -1 for no animation
17
- // collapseSpeed - default = 500 (ms); use -1 for no animation
18
- // expandEasing - easing function to use on expand (optional)
19
- // collapseEasing - easing function to use on collapse (optional)
20
- // multiFolder - whether or not to limit the browser to one subfolder at a time
21
- // loadMessage - Message to display while initial tree loads (can be HTML)
22
- //
23
- // History:
24
- //
25
- // 1.01 - updated to work with foreign characters in directory/file names (12 April 2008)
26
- // 1.00 - released (24 March 2008)
27
- //
28
- // TERMS OF USE
29
- //
30
- // This plugin is dual-licensed under the GNU General Public License and the MIT License and
31
- // is copyright 2008 A Beautiful Site, LLC.
32
- //
33
- if (jQuery)
34
- (function ($) {
35
 
36
- $.extend($.fn, {
37
- fileTree: function (o, h) {
38
- // Defaults
39
- if (!o)
40
- var o = {};
41
- if (o.root == undefined)
42
- o.root = '/';
43
- if (o.script == undefined)
44
- o.script = 'jqueryFileTree.php';
45
- if (o.folderEvent == undefined)
46
- o.folderEvent = 'click';
47
- if (o.expandSpeed == undefined)
48
- o.expandSpeed = -1;
49
- if (o.collapseSpeed == undefined)
50
- o.collapseSpeed = -1;
51
- if (o.expandEasing == undefined)
52
- o.expandEasing = null;
53
- if (o.collapseEasing == undefined)
54
- o.collapseEasing = null;
55
- if (o.multiFolder == undefined)
56
- o.multiFolder = true;
57
- if (o.loadMessage == undefined)
58
- o.loadMessage = 'Loading...';
59
-
60
- $(this).each(function () {
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- function showTree(c, t) {
63
- $(c).addClass('wait');
64
- $(".jqueryFileTree.start").remove();
65
- $.post(o.script, {dir: t}, function (data) {
66
- $(c).find('.start').html('');
67
- $(c).removeClass('wait').append(data);
68
- if (o.root == t)
69
- $(c).find('UL:hidden').show();
70
- else
71
- $(c).find('UL:hidden').slideDown({duration: o.expandSpeed, easing: o.expandEasing});
72
- bindTree(c);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
 
 
 
 
 
75
 
76
- function bindTree(t) {
77
- $(t).find('LI A').bind(o.folderEvent, function () {
78
- if ($(this).parent().hasClass('directory')) {
79
- if ($(this).parent().hasClass('collapsed')) {
80
- // Expand
81
- if (!o.multiFolder) {
82
- $(this).parent().parent().find('UL').slideUp({duration: o.collapseSpeed, easing: o.collapseEasing});
83
- $(this).parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
84
- }
85
- $(this).parent().find('UL').remove(); // cleanup
86
- showTree($(this).parent(), escape($(this).attr('rel').match(/.*\//)));
87
- $(this).parent().removeClass('collapsed').addClass('expanded');
88
- } else {
89
- // Collapse
90
- $(this).parent().find('UL').slideUp({duration: o.collapseSpeed, easing: o.collapseEasing});
91
- $(this).parent().removeClass('expanded').addClass('collapsed');
92
- }
93
- } else {
94
- h($(this).attr('rel'));
95
- }
96
- return false;
97
- });
98
- // Prevent A from triggering the # on non-click events
99
- if (o.folderEvent.toLowerCase != 'click')
100
- $(t).find('LI A').bind('click', function () {
101
- h($(this).attr('rel'));
102
- //$(this).parents('#ux_wp_dir_browser').find('.active').removeClass('active');
103
- //$(this).parent().addClass('active');
104
- return false;
105
- });
106
  }
107
- // Loading message
108
- $(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
109
- // Get the initial file list
110
- showTree($(this), escape(o.root));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  });
112
  }
113
- });
 
 
 
 
 
 
 
 
114
 
115
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQueryFileTree Plugin
3
+ *
4
+ * @author - Cory S.N. LaViska - A Beautiful Site (http://abeautifulsite.net/) - 24 March 2008
5
+ * @author - Dave Rogers - (https://github.com/daverogers/)
6
+ *
7
+ * Usage: $('.fileTreeDemo').fileTree({ options }, callback )
8
+ *
9
+ * TERMS OF USE
10
+ *
11
+ * This plugin is dual-licensed under the GNU General Public License and the MIT License and
12
+ * is copyright 2008 A Beautiful Site, LLC.
13
+ */
14
+ var bind = function (fn, me) {
15
+ return function () {
16
+ return fn.apply(me, arguments);
17
+ };
18
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ (function ($, window) {
21
+ var FileTree;
22
+ FileTree = (function () {
23
+ function FileTree(el, args, callback) {
24
+ this.onEvent = bind(this.onEvent, this);
25
+ var $el, _this, defaults;
26
+ $el = $(el);
27
+ _this = this;
28
+ defaults = {
29
+ root: '/',
30
+ script: '/files/filetree',
31
+ folderEvent: 'click',
32
+ expandSpeed: 500,
33
+ collapseSpeed: 500,
34
+ expandEasing: 'swing',
35
+ collapseEasing: 'swing',
36
+ multiFolder: true,
37
+ loadMessage: 'Loading...',
38
+ errorMessage: 'Unable to get file tree information',
39
+ multiSelect: false,
40
+ onlyFolders: false,
41
+ onlyFiles: false
42
+ };
43
+ this.jqft = {
44
+ container: $el
45
+ };
46
+ this.options = $.extend(defaults, args);
47
+ this.callback = callback;
48
+ this.data = {};
49
+ $el.html('<ul class="jqueryFileTree start"><li class="wait">' + this.options.loadMessage + '<li></ul>');
50
+ _this.showTree($el, escape(this.options.root), function () {
51
+ return _this._trigger('filetreeinitiated', {
52
+ options: _this.options
53
+ });
54
+ });
55
+ $el.delegate("li a", this.options.folderEvent, _this.onEvent);
56
+ }
57
 
58
+ FileTree.prototype.onEvent = function (event) {
59
+ var $ev, _this, callback, jqft, options, ref, prevent;
60
+ $ev = $(event.target);
61
+ options = this.options;
62
+ jqft = this.jqft;
63
+ _this = this;
64
+ callback = this.callback;
65
+ _this.data = {};
66
+ _this.data.li = $ev.closest('li');
67
+ _this.data.type = (ref = _this.data.li.hasClass('directory')) != null ? ref : {
68
+ 'directory': 'file'
69
+ };
70
+ _this.data.value = $ev.text();
71
+ _this.data.rel = $ev.prop('rel');
72
+ _this.data.container = jqft.container;
73
+ _this.data.options = _this.options;
74
+ prevent = _this._trigger('filetreeclick', _this.data);
75
+ if (prevent === true) {
76
+ return false;
77
+ }
78
+ if ($ev.parent().hasClass('directory')) {
79
+ if ($ev.parent().hasClass('collapsed')) {
80
+ if (!options.multiFolder) {
81
+ $ev.parent().parent().find('UL').slideUp({
82
+ duration: options.collapseSpeed,
83
+ easing: options.collapseEasing
84
  });
85
+ $ev.parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
86
+ }
87
+ $ev.parent().removeClass('collapsed').addClass('expanded');
88
+ $ev.parent().find('UL').remove();
89
+ return _this.showTree($ev.parent(), $ev.attr('rel'), function () {
90
+ _this._trigger('filetreeexpanded', _this.data);
91
+ return callback != null;
92
+ });
93
+ } else {
94
+ return $ev.parent().find('UL').slideUp({
95
+ duration: options.collapseSpeed,
96
+ easing: options.collapseEasing,
97
+ start: function () {
98
+ return _this._trigger('filetreecollapse', _this.data);
99
+ },
100
+ complete: function () {
101
+ $ev.parent().removeClass('expanded').addClass('collapsed');
102
+ _this._trigger('filetreecollapsed', _this.data);
103
+ return callback != null;
104
+ }
105
+ });
106
+ }
107
+ } else {
108
+ if (!options.multiSelect) {
109
+ jqft.container.find('li').removeClass('selected');
110
+ $ev.parent().addClass('selected');
111
+ } else {
112
+ if ($ev.parent().find('input').is(':checked')) {
113
+ $ev.parent().find('input').prop('checked', false);
114
+ $ev.parent().removeClass('selected');
115
+ } else {
116
+ $ev.parent().find('input').prop('checked', true);
117
+ $ev.parent().addClass('selected');
118
  }
119
+ }
120
+ _this._trigger('filetreeclicked', _this.data);
121
+ return typeof callback === "function" ? callback($ev.attr('rel')) : void 0;
122
+ }
123
+ };
124
 
125
+ FileTree.prototype.showTree = function (el, dir, finishCallback) {
126
+ var $el, _this, data, handleFail, handleResult, options, result;
127
+ $el = $(el);
128
+ options = this.options;
129
+ _this = this;
130
+ $el.addClass('wait');
131
+ $(".jqueryFileTree.start").remove();
132
+ data = {
133
+ dir: dir,
134
+ onlyFolders: options.onlyFolders,
135
+ onlyFiles: options.onlyFiles,
136
+ multiSelect: options.multiSelect
137
+ };
138
+ handleResult = function (result) {
139
+ var li;
140
+ $el.find('.start').html('');
141
+ $el.removeClass('wait').append(result);
142
+ if (options.root === dir) {
143
+ $el.find('UL:hidden').show();
144
+ finishCallback();
145
+ } else {
146
+ if (jQuery.easing[options.expandEasing] === void 0) {
147
+ console.log('Easing library not loaded. Include jQueryUI or 3rd party lib.');
148
+ options.expandEasing = 'swing';
 
 
 
 
 
 
149
  }
150
+ $el.find('UL:hidden').slideDown({
151
+ duration: options.expandSpeed,
152
+ easing: options.expandEasing,
153
+ start: function () {
154
+ return _this._trigger('filetreeexpand', _this.data);
155
+ },
156
+ complete: finishCallback
157
+ });
158
+ }
159
+ li = $('[rel="' + decodeURIComponent(dir) + '"]').parent();
160
+ if (options.multiSelect && li.children('input').is(':checked')) {
161
+ li.find('ul li input').each(function () {
162
+ $(this).prop('checked', true);
163
+ return $(this).parent().addClass('selected');
164
+ });
165
+ }
166
+ return false;
167
+ };
168
+ handleFail = function () {
169
+ $el.find('.start').html('');
170
+ $el.removeClass('wait');
171
+ if (options.errorMessage) {
172
+ $el.append("<p>" + options.errorMessage + "</p>");
173
+ } else {
174
+ $el.removeClass('expanded').addClass('collapsed');
175
+ }
176
+ return false;
177
+ };
178
+ if (typeof options.script === 'function') {
179
+ result = options.script(data);
180
+ if (typeof result === 'string' || result instanceof jQuery) {
181
+ return handleResult(result);
182
+ } else {
183
+ return handleFail();
184
+ }
185
+ } else {
186
+ return $.ajax({
187
+ url: options.script,
188
+ type: 'POST',
189
+ dataType: 'HTML',
190
+ data: data
191
+ }).done(function (result) {
192
+ return handleResult(result);
193
+ }).fail(function () {
194
+ return handleFail();
195
  });
196
  }
197
+ };
198
+
199
+ FileTree.prototype._trigger = function (eventType, data) {
200
+ var $el;
201
+ $el = this.jqft.container;
202
+ return $el.triggerHandler(eventType, data);
203
+ };
204
+
205
+ return FileTree;
206
 
207
+ })();
208
+ return $.fn.extend({
209
+ fileTree: function (args, callback) {
210
+ return this.each(function () {
211
+ var $this, data;
212
+ $this = $(this);
213
+ data = $this.data('fileTree');
214
+ if (!data) {
215
+ $this.data('fileTree', (data = new FileTree(this, args, callback)));
216
+ }
217
+ if (typeof args === 'string') {
218
+ return data[option].apply(data);
219
+ }
220
+ });
221
+ }
222
+ });
223
+ })(window.jQuery, window);
assets/global/plugins/validation/jquery.validate.js CHANGED
@@ -1,9 +1,9 @@
1
  /*!
2
- * jQuery Validation Plugin v1.16.0
3
  *
4
- * http://jqueryvalidation.org/
5
  *
6
- * Copyright (c) 2016 Jörn Zaefferer
7
  * Released under the MIT license
8
  */
9
  (function (factory) {
@@ -18,7 +18,7 @@
18
 
19
  $.extend($.fn, {
20
 
21
- // http://jqueryvalidation.org/validate/
22
  validate: function (options) {
23
 
24
  // If nothing is selected, return nothing; can't chain anyway
@@ -44,9 +44,10 @@
44
  if (validator.settings.onsubmit) {
45
 
46
  this.on("click.validate", ":submit", function (event) {
47
- if (validator.settings.submitHandler) {
48
- validator.submitButton = event.target;
49
- }
 
50
 
51
  // Allow suppressing validation by adding a cancel class to the submit button
52
  if ($(this).hasClass("cancel")) {
@@ -68,17 +69,22 @@
68
  }
69
  function handle() {
70
  var hidden, result;
71
- if (validator.settings.submitHandler) {
72
- if (validator.submitButton) {
73
 
74
- // Insert a hidden input as a replacement for the missing submit button
75
- hidden = $("<input type='hidden'/>")
76
- .attr("name", validator.submitButton.name)
77
- .val($(validator.submitButton).val())
78
- .appendTo(validator.currentForm);
79
- }
 
 
 
 
 
 
 
80
  result = validator.settings.submitHandler.call(validator, validator.currentForm, event);
81
- if (validator.submitButton) {
82
 
83
  // And clean up afterwards; thanks to no-block-scope, hidden can be referenced
84
  hidden.remove();
@@ -112,7 +118,7 @@
112
  return validator;
113
  },
114
 
115
- // http://jqueryvalidation.org/valid/
116
  valid: function () {
117
  var valid, validator, errorList;
118
 
@@ -133,13 +139,22 @@
133
  return valid;
134
  },
135
 
136
- // http://jqueryvalidation.org/rules/
137
  rules: function (command, argument) {
138
  var element = this[ 0 ],
139
  settings, staticRules, existingRules, data, param, filtered;
140
 
141
  // If nothing is selected, return empty object; can't chain anyway
142
- if (element == null || element.form == null) {
 
 
 
 
 
 
 
 
 
143
  return;
144
  }
145
 
@@ -167,9 +182,6 @@
167
  $.each(argument.split(/\s/), function (index, method) {
168
  filtered[ method ] = existingRules[ method ];
169
  delete existingRules[ method ];
170
- if (method === "required") {
171
- $(element).removeAttr("aria-required");
172
- }
173
  });
174
  return filtered;
175
  }
@@ -189,7 +201,6 @@
189
  param = data.required;
190
  delete data.required;
191
  data = $.extend({required: param}, data);
192
- $(element).attr("aria-required", "true");
193
  }
194
 
195
  // Make sure remote is at back
@@ -206,18 +217,18 @@
206
  // Custom selectors
207
  $.extend($.expr.pseudos || $.expr[ ":" ], {// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
208
 
209
- // http://jqueryvalidation.org/blank-selector/
210
  blank: function (a) {
211
  return !$.trim("" + $(a).val());
212
  },
213
 
214
- // http://jqueryvalidation.org/filled-selector/
215
  filled: function (a) {
216
  var val = $(a).val();
217
  return val !== null && !!$.trim("" + val);
218
  },
219
 
220
- // http://jqueryvalidation.org/unchecked-selector/
221
  unchecked: function (a) {
222
  return !$(a).prop("checked");
223
  }
@@ -230,7 +241,7 @@
230
  this.init();
231
  };
232
 
233
- // http://jqueryvalidation.org/jQuery.validator.format/
234
  $.validator.format = function (source, params) {
235
  if (arguments.length === 1) {
236
  return function () {
@@ -343,7 +354,7 @@
343
  }
344
  },
345
 
346
- // http://jqueryvalidation.org/jQuery.validator.setDefaults/
347
  setDefaults: function (settings) {
348
  $.extend($.validator.defaults, settings);
349
  },
@@ -402,6 +413,7 @@
402
  // Set form expando on contenteditable
403
  if (!this.form && this.hasAttribute("contenteditable")) {
404
  this.form = $(this).closest("form")[ 0 ];
 
405
  }
406
 
407
  var validator = $.data(this.form, "validator"),
@@ -426,13 +438,9 @@
426
  if (this.settings.invalidHandler) {
427
  $(this.currentForm).on("invalid-form.validate", this.settings.invalidHandler);
428
  }
429
-
430
- // Add aria-required to any Static/Data/Class required fields before first validation
431
- // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
432
- $(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required", "true");
433
  },
434
 
435
- // http://jqueryvalidation.org/Validator.form/
436
  form: function () {
437
  this.checkForm();
438
  $.extend(this.submitted, this.errorMap);
@@ -452,7 +460,7 @@
452
  return this.valid();
453
  },
454
 
455
- // http://jqueryvalidation.org/Validator.element/
456
  element: function (element) {
457
  var cleanElement = this.clean(element),
458
  checkElement = this.validationTargetFor(cleanElement),
@@ -503,7 +511,7 @@
503
  return result;
504
  },
505
 
506
- // http://jqueryvalidation.org/Validator.showErrors/
507
  showErrors: function (errors) {
508
  if (errors) {
509
  var validator = this;
@@ -529,7 +537,7 @@
529
  }
530
  },
531
 
532
- // http://jqueryvalidation.org/Validator.resetForm/
533
  resetForm: function () {
534
  if ($.fn.resetForm) {
535
  $(this.currentForm).resetForm();
@@ -570,7 +578,10 @@
570
  var count = 0,
571
  i;
572
  for (i in obj) {
573
- if (obj[ i ]) {
 
 
 
574
  count++;
575
  }
576
  }
@@ -635,6 +646,7 @@
635
  // Set form expando on contenteditable
636
  if (this.hasAttribute("contenteditable")) {
637
  this.form = $(this).closest("form")[ 0 ];
 
638
  }
639
 
640
  // Select only the first element for each name, and only those with rules specified
@@ -735,21 +747,27 @@
735
  }).length,
736
  dependencyMismatch = false,
737
  val = this.elementValue(element),
738
- result, method, rule;
739
 
740
- // If a normalizer is defined for this element, then
741
- // call it to retreive the changed value instead
 
 
 
 
 
 
 
742
  // of using the real one.
743
  // Note that `this` in the normalizer is `element`.
744
- if (typeof rules.normalizer === "function") {
745
- val = rules.normalizer.call(element, val);
746
 
747
  if (typeof val !== "string") {
748
  throw new TypeError("The normalizer should return a string value.");
749
  }
750
 
751
- // Delete the normalizer from rules to avoid treating
752
- // it as a pre-defined method.
753
  delete rules.normalizer;
754
  }
755
 
@@ -1088,6 +1106,15 @@
1088
  $(element).removeClass(this.settings.pendingClass);
1089
  if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form()) {
1090
  $(this.currentForm).submit();
 
 
 
 
 
 
 
 
 
1091
  this.formSubmitted = false;
1092
  } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
1093
  $(this.currentForm).triggerHandler("invalid-form", [this]);
@@ -1315,7 +1342,7 @@
1315
  return data;
1316
  },
1317
 
1318
- // http://jqueryvalidation.org/jQuery.validator.addMethod/
1319
  addMethod: function (name, method, message) {
1320
  $.validator.methods[ name ] = method;
1321
  $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
@@ -1324,10 +1351,10 @@
1324
  }
1325
  },
1326
 
1327
- // http://jqueryvalidation.org/jQuery.validator.methods/
1328
  methods: {
1329
 
1330
- // http://jqueryvalidation.org/required-method/
1331
  required: function (value, element, param) {
1332
 
1333
  // Check if dependency is met
@@ -1346,7 +1373,7 @@
1346
  return value.length > 0;
1347
  },
1348
 
1349
- // http://jqueryvalidation.org/email-method/
1350
  email: function (value, element) {
1351
 
1352
  // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
@@ -1356,7 +1383,7 @@
1356
  return this.optional(element) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
1357
  },
1358
 
1359
- // http://jqueryvalidation.org/url-method/
1360
  url: function (value, element) {
1361
 
1362
  // Copyright (c) 2010-2013 Diego Perini, MIT licensed
@@ -1366,60 +1393,60 @@
1366
  return this.optional(element) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
1367
  },
1368
 
1369
- // http://jqueryvalidation.org/date-method/
1370
  date: function (value, element) {
1371
  return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1372
  },
1373
 
1374
- // http://jqueryvalidation.org/dateISO-method/
1375
  dateISO: function (value, element) {
1376
  return this.optional(element) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value);
1377
  },
1378
 
1379
- // http://jqueryvalidation.org/number-method/
1380
  number: function (value, element) {
1381
  return this.optional(element) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1382
  },
1383
 
1384
- // http://jqueryvalidation.org/digits-method/
1385
  digits: function (value, element) {
1386
  return this.optional(element) || /^\d+$/.test(value);
1387
  },
1388
 
1389
- // http://jqueryvalidation.org/minlength-method/
1390
  minlength: function (value, element, param) {
1391
  var length = $.isArray(value) ? value.length : this.getLength(value, element);
1392
  return this.optional(element) || length >= param;
1393
  },
1394
 
1395
- // http://jqueryvalidation.org/maxlength-method/
1396
  maxlength: function (value, element, param) {
1397
  var length = $.isArray(value) ? value.length : this.getLength(value, element);
1398
  return this.optional(element) || length <= param;
1399
  },
1400
 
1401
- // http://jqueryvalidation.org/rangelength-method/
1402
  rangelength: function (value, element, param) {
1403
  var length = $.isArray(value) ? value.length : this.getLength(value, element);
1404
  return this.optional(element) || (length >= param[ 0 ] && length <= param[ 1 ]);
1405
  },
1406
 
1407
- // http://jqueryvalidation.org/min-method/
1408
  min: function (value, element, param) {
1409
  return this.optional(element) || value >= param;
1410
  },
1411
 
1412
- // http://jqueryvalidation.org/max-method/
1413
  max: function (value, element, param) {
1414
  return this.optional(element) || value <= param;
1415
  },
1416
 
1417
- // http://jqueryvalidation.org/range-method/
1418
  range: function (value, element, param) {
1419
  return this.optional(element) || (value >= param[ 0 ] && value <= param[ 1 ]);
1420
  },
1421
 
1422
- // http://jqueryvalidation.org/step-method/
1423
  step: function (value, element, param) {
1424
  var type = $(element).attr("type"),
1425
  errorMessage = "Step attribute on input type " + type + " is not supported.",
@@ -1457,7 +1484,7 @@
1457
  return this.optional(element) || valid;
1458
  },
1459
 
1460
- // http://jqueryvalidation.org/equalTo-method/
1461
  equalTo: function (value, element, param) {
1462
 
1463
  // Bind to the blur event of the target in order to revalidate whenever the target field is updated
@@ -1470,7 +1497,7 @@
1470
  return value === target.val();
1471
  },
1472
 
1473
- // http://jqueryvalidation.org/remote-method/
1474
  remote: function (value, element, param, method) {
1475
  if (this.optional(element)) {
1476
  return "dependency-mismatch";
1
  /*!
2
+ * jQuery Validation Plugin v1.17.0
3
  *
4
+ * https://jqueryvalidation.org/
5
  *
6
+ * Copyright (c) 2017 Jörn Zaefferer
7
  * Released under the MIT license
8
  */
9
  (function (factory) {
18
 
19
  $.extend($.fn, {
20
 
21
+ // https://jqueryvalidation.org/validate/
22
  validate: function (options) {
23
 
24
  // If nothing is selected, return nothing; can't chain anyway
44
  if (validator.settings.onsubmit) {
45
 
46
  this.on("click.validate", ":submit", function (event) {
47
+
48
+ // Track the used submit button to properly handle scripted
49
+ // submits later.
50
+ validator.submitButton = event.currentTarget;
51
 
52
  // Allow suppressing validation by adding a cancel class to the submit button
53
  if ($(this).hasClass("cancel")) {
69
  }
70
  function handle() {
71
  var hidden, result;
 
 
72
 
73
+ // Insert a hidden input as a replacement for the missing submit button
74
+ // The hidden input is inserted in two cases:
75
+ // - A user defined a `submitHandler`
76
+ // - There was a pending request due to `remote` method and `stopRequest()`
77
+ // was called to submit the form in case it's valid
78
+ if (validator.submitButton && (validator.settings.submitHandler || validator.formSubmitted)) {
79
+ hidden = $("<input type='hidden'/>")
80
+ .attr("name", validator.submitButton.name)
81
+ .val($(validator.submitButton).val())
82
+ .appendTo(validator.currentForm);
83
+ }
84
+
85
+ if (validator.settings.submitHandler) {
86
  result = validator.settings.submitHandler.call(validator, validator.currentForm, event);
87
+ if (hidden) {
88
 
89
  // And clean up afterwards; thanks to no-block-scope, hidden can be referenced
90
  hidden.remove();
118
  return validator;
119
  },
120
 
121
+ // https://jqueryvalidation.org/valid/
122
  valid: function () {
123
  var valid, validator, errorList;
124
 
139
  return valid;
140
  },
141
 
142
+ // https://jqueryvalidation.org/rules/
143
  rules: function (command, argument) {
144
  var element = this[ 0 ],
145
  settings, staticRules, existingRules, data, param, filtered;
146
 
147
  // If nothing is selected, return empty object; can't chain anyway
148
+ if (element == null) {
149
+ return;
150
+ }
151
+
152
+ if (!element.form && element.hasAttribute("contenteditable")) {
153
+ element.form = this.closest("form")[ 0 ];
154
+ element.name = this.attr("name");
155
+ }
156
+
157
+ if (element.form == null) {
158
  return;
159
  }
160
 
182
  $.each(argument.split(/\s/), function (index, method) {
183
  filtered[ method ] = existingRules[ method ];
184
  delete existingRules[ method ];
 
 
 
185
  });
186
  return filtered;
187
  }
201
  param = data.required;
202
  delete data.required;
203
  data = $.extend({required: param}, data);
 
204
  }
205
 
206
  // Make sure remote is at back
217
  // Custom selectors
218
  $.extend($.expr.pseudos || $.expr[ ":" ], {// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
219
 
220
+ // https://jqueryvalidation.org/blank-selector/
221
  blank: function (a) {
222
  return !$.trim("" + $(a).val());
223
  },
224
 
225
+ // https://jqueryvalidation.org/filled-selector/
226
  filled: function (a) {
227
  var val = $(a).val();
228
  return val !== null && !!$.trim("" + val);
229
  },
230
 
231
+ // https://jqueryvalidation.org/unchecked-selector/
232
  unchecked: function (a) {
233
  return !$(a).prop("checked");
234
  }
241
  this.init();
242
  };
243
 
244
+ // https://jqueryvalidation.org/jQuery.validator.format/
245
  $.validator.format = function (source, params) {
246
  if (arguments.length === 1) {
247
  return function () {
354
  }
355
  },
356
 
357
+ // https://jqueryvalidation.org/jQuery.validator.setDefaults/
358
  setDefaults: function (settings) {
359
  $.extend($.validator.defaults, settings);
360
  },
413
  // Set form expando on contenteditable
414
  if (!this.form && this.hasAttribute("contenteditable")) {
415
  this.form = $(this).closest("form")[ 0 ];
416
+ this.name = $(this).attr("name");
417
  }
418
 
419
  var validator = $.data(this.form, "validator"),
438
  if (this.settings.invalidHandler) {
439
  $(this.currentForm).on("invalid-form.validate", this.settings.invalidHandler);
440
  }
 
 
 
 
441
  },
442
 
443
+ // https://jqueryvalidation.org/Validator.form/
444
  form: function () {
445
  this.checkForm();
446
  $.extend(this.submitted, this.errorMap);
460
  return this.valid();
461
  },
462
 
463
+ // https://jqueryvalidation.org/Validator.element/
464
  element: function (element) {
465
  var cleanElement = this.clean(element),
466
  checkElement = this.validationTargetFor(cleanElement),
511
  return result;
512
  },
513
 
514
+ // https://jqueryvalidation.org/Validator.showErrors/
515
  showErrors: function (errors) {
516
  if (errors) {
517
  var validator = this;
537
  }
538
  },
539
 
540
+ // https://jqueryvalidation.org/Validator.resetForm/
541
  resetForm: function () {
542
  if ($.fn.resetForm) {
543
  $(this.currentForm).resetForm();
578
  var count = 0,
579
  i;
580
  for (i in obj) {
581
+
582
+ // This check allows counting elements with empty error
583
+ // message as invalid elements
584
+ if (obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false) {
585
  count++;
586
  }
587
  }
646
  // Set form expando on contenteditable
647
  if (this.hasAttribute("contenteditable")) {
648
  this.form = $(this).closest("form")[ 0 ];
649
+ this.name = name;
650
  }
651
 
652
  // Select only the first element for each name, and only those with rules specified
747
  }).length,
748
  dependencyMismatch = false,
749
  val = this.elementValue(element),
750
+ result, method, rule, normalizer;
751
 
752
+ // Prioritize the local normalizer defined for this element over the global one
753
+ // if the former exists, otherwise user the global one in case it exists.
754
+ if (typeof rules.normalizer === "function") {
755
+ normalizer = rules.normalizer;
756
+ } else if (typeof this.settings.normalizer === "function") {
757
+ normalizer = this.settings.normalizer;
758
+ }
759
+
760
+ // If normalizer is defined, then call it to retreive the changed value instead
761
  // of using the real one.
762
  // Note that `this` in the normalizer is `element`.
763
+ if (normalizer) {
764
+ val = normalizer.call(element, val);
765
 
766
  if (typeof val !== "string") {
767
  throw new TypeError("The normalizer should return a string value.");
768
  }
769
 
770
+ // Delete the normalizer from rules to avoid treating it as a pre-defined method.
 
771
  delete rules.normalizer;
772
  }
773
 
1106
  $(element).removeClass(this.settings.pendingClass);
1107
  if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form()) {
1108
  $(this.currentForm).submit();
1109
+
1110
+ // Remove the hidden input that was used as a replacement for the
1111
+ // missing submit button. The hidden input is added by `handle()`
1112
+ // to ensure that the value of the used submit button is passed on
1113
+ // for scripted submits triggered by this method
1114
+ if (this.submitButton) {
1115
+ $("input:hidden[name='" + this.submitButton.name + "']", this.currentForm).remove();
1116
+ }
1117
+
1118
  this.formSubmitted = false;
1119
  } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
1120
  $(this.currentForm).triggerHandler("invalid-form", [this]);
1342
  return data;
1343
  },
1344
 
1345
+ // https://jqueryvalidation.org/jQuery.validator.addMethod/
1346
  addMethod: function (name, method, message) {
1347
  $.validator.methods[ name ] = method;
1348
  $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
1351
  }
1352
  },
1353
 
1354
+ // https://jqueryvalidation.org/jQuery.validator.methods/
1355
  methods: {
1356
 
1357
+ // https://jqueryvalidation.org/required-method/
1358
  required: function (value, element, param) {
1359
 
1360
  // Check if dependency is met
1373
  return value.length > 0;
1374
  },
1375
 
1376
+ // https://jqueryvalidation.org/email-method/
1377
  email: function (value, element) {
1378
 
1379
  // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
1383
  return this.optional(element) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value);
1384
  },
1385
 
1386
+ // https://jqueryvalidation.org/url-method/
1387
  url: function (value, element) {
1388
 
1389
  // Copyright (c) 2010-2013 Diego Perini, MIT licensed
1393
  return this.optional(element) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
1394
  },
1395
 
1396
+ // https://jqueryvalidation.org/date-method/
1397
  date: function (value, element) {
1398
  return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1399
  },
1400
 
1401
+ // https://jqueryvalidation.org/dateISO-method/
1402
  dateISO: function (value, element) {
1403
  return this.optional(element) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value);
1404
  },
1405
 
1406
+ // https://jqueryvalidation.org/number-method/
1407
  number: function (value, element) {
1408
  return this.optional(element) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1409
  },
1410
 
1411
+ // https://jqueryvalidation.org/digits-method/
1412
  digits: function (value, element) {
1413
  return this.optional(element) || /^\d+$/.test(value);
1414
  },
1415
 
1416
+ // https://jqueryvalidation.org/minlength-method/
1417
  minlength: function (value, element, param) {
1418
  var length = $.isArray(value) ? value.length : this.getLength(value, element);
1419
  return this.optional(element) || length >= param;
1420
  },
1421
 
1422
+ // https://jqueryvalidation.org/maxlength-method/
1423
  maxlength: function (value, element, param) {
1424
  var length = $.isArray(value) ? value.length : this.getLength(value, element);
1425
  return this.optional(element) || length <= param;
1426
  },
1427
 
1428
+ // https://jqueryvalidation.org/rangelength-method/
1429
  rangelength: function (value, element, param) {
1430
  var length = $.isArray(value) ? value.length : this.getLength(value, element);
1431
  return this.optional(element) || (length >= param[ 0 ] && length <= param[ 1 ]);
1432
  },
1433
 
1434
+ // https://jqueryvalidation.org/min-method/
1435
  min: function (value, element, param) {
1436
  return this.optional(element) || value >= param;
1437
  },
1438
 
1439
+ // https://jqueryvalidation.org/max-method/
1440
  max: function (value, element, param) {
1441
  return this.optional(element) || value <= param;
1442
  },
1443
 
1444
+ // https://jqueryvalidation.org/range-method/
1445
  range: function (value, element, param) {
1446
  return this.optional(element) || (value >= param[ 0 ] && value <= param[ 1 ]);
1447
  },
1448
 
1449
+ // https://jqueryvalidation.org/step-method/
1450
  step: function (value, element, param) {
1451
  var type = $(element).attr("type"),
1452
  errorMessage = "Step attribute on input type " + type + " is not supported.",
1484
  return this.optional(element) || valid;
1485
  },
1486
 
1487
+ // https://jqueryvalidation.org/equalTo-method/
1488
  equalTo: function (value, element, param) {
1489
 
1490
  // Bind to the blur event of the target in order to revalidate whenever the target field is updated
1497
  return value === target.val();
1498
  },
1499
 
1500
+ // https://jqueryvalidation.org/remote-method/
1501
  remote: function (value, element, param, method) {
1502
  if (this.optional(element)) {
1503
  return "dependency-mismatch";
gallery-bank.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Photo Gallery Plugin for WordPress. Creates elegant responsive gallery widget, image gallery, media gallery, portfolio gallery and albums.
6
  * Author: Tech Banker
7
  * Author URI: https://gallery-bank.tech-banker.com
8
- * Version: 4.0.9
9
  * License: GPLv3
10
  * Text Domain: gallery-bank
11
  * Domain Path: /languages
@@ -528,12 +528,14 @@ if ($version == "4.0") {
528
  $content = trim(do_shortcode(shortcode_unautop($content)));
529
 
530
  /* Remove '' from the start of the string. */
531
- if (substr($content, 0, 4) == '')
532
  $content = substr($content, 4);
 
533
 
534
  /* Remove '' from the end of the string. */
535
- if (substr($content, -3, 3) == '')
536
  $content = substr($content, 0, -3);
 
537
 
538
  /* Remove any instances of ''. */
539
  $content = str_replace(array('<p></p>'), '', $content);
5
  * Description: Photo Gallery Plugin for WordPress. Creates elegant responsive gallery widget, image gallery, media gallery, portfolio gallery and albums.
6
  * Author: Tech Banker
7
  * Author URI: https://gallery-bank.tech-banker.com
8
+ * Version: 4.0.10
9
  * License: GPLv3
10
  * Text Domain: gallery-bank
11
  * Domain Path: /languages
528
  $content = trim(do_shortcode(shortcode_unautop($content)));
529
 
530
  /* Remove '' from the start of the string. */
531
+ if (substr($content, 0, 4) == '') {
532
  $content = substr($content, 4);
533
+ }
534
 
535
  /* Remove '' from the end of the string. */
536
+ if (substr($content, -3, 3) == '') {
537
  $content = substr($content, 0, -3);
538
+ }
539
 
540
  /* Remove any instances of ''. */
541
  $content = str_replace(array('<p></p>'), '', $content);
includes/footer.php CHANGED
@@ -701,7 +701,7 @@ if (!is_user_logged_in()) {
701
  {
702
  if (jQuery("#" + id).hasClass("tag"))
703
  {
704
- if (jQuery("#" + id).prop("selected") == true)
705
  {
706
  jQuery("#" + id).prop("selected", false);
707
  }
@@ -786,7 +786,7 @@ if (!is_user_logged_in()) {
786
  });
787
  }
788
  });
789
-
790
  jQuery(document).ready(function ()
791
  {
792
  jQuery("#cboxTitle").remove();
@@ -897,7 +897,7 @@ if (!is_user_logged_in()) {
897
  jQuery("#ux_wp_dir_browser a").each(function ()
898
  {
899
  jQuery(this).removeClass("custom-selected-folder");
900
- })
901
  jQuery("#ux_wp_dir_browser a[rel=\"" + file + "\"]").addClass("custom-selected-folder");
902
  jQuery("#ux_txt_ftp_path").val(file);
903
  });
@@ -1274,7 +1274,8 @@ if (!is_user_logged_in()) {
1274
  case "gb_add_tag":
1275
  ?>
1276
  jQuery("#ux_li_tags").addClass("active");
1277
- "<?php echo isset($_REQUEST["id "]); ?>" ? jQuery("#ux_li_manage_tags").addClass("active") : jQuery("#ux_li_add_tag").addClass("active");
 
1278
  <?php
1279
  if (tags_gallery_bank == "1") {
1280
  ?>
701
  {
702
  if (jQuery("#" + id).hasClass("tag"))
703
  {
704
+ if (jQuery("#" + id).prop("selected") === true)
705
  {
706
  jQuery("#" + id).prop("selected", false);
707
  }
786
  });
787
  }
788
  });
789
+
790
  jQuery(document).ready(function ()
791
  {
792
  jQuery("#cboxTitle").remove();
897
  jQuery("#ux_wp_dir_browser a").each(function ()
898
  {
899
  jQuery(this).removeClass("custom-selected-folder");
900
+ });
901
  jQuery("#ux_wp_dir_browser a[rel=\"" + file + "\"]").addClass("custom-selected-folder");
902
  jQuery("#ux_txt_ftp_path").val(file);
903
  });
1274
  case "gb_add_tag":
1275
  ?>
1276
  jQuery("#ux_li_tags").addClass("active");
1277
+ var page_id = "<?php echo isset($_REQUEST["id "]); ?>";
1278
+ page_id === "" ? jQuery("#ux_li_manage_tags").addClass("active") : jQuery("#ux_li_add_tag").addClass("active");
1279
  <?php
1280
  if (tags_gallery_bank == "1") {
1281
  ?>
includes/translations.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /**
3
- This file is used for translating strings.
4
  *
5
  * @author Tech Banker
6
  * @package gallery-bank/includes
1
  <?php
2
  /**
3
+ This file is used for translating strings.
4
  *
5
  * @author Tech Banker
6
  * @package gallery-bank/includes
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Gallery - Photo Gallery - Image Gallery - Photo Albums - WordPress Gallery Plugin ===
2
  Contributors: gallery-bank, contact-banker
3
  Donate link: https://gallery-bank.tech-banker.com/
4
- Tags: album, gallery, gallery widget, image gallery, images, masonry gallery, media gallery, photo album, photo gallery, portfolio, responsive gallery, wordpress gallery, wordpress gallery plugin, gallery lightbox, masonry gallery
5
  Requires at least: 3.3
6
- Tested up to: 4.8
7
  Stable tag: trunk
8
  License: GPLv3 or later
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -12,7 +12,7 @@ Responsive Gallery Plugin. Gallery Widget, Image Gallery, Grid Gallery, Media Ga
12
 
13
  == Description ==
14
 
15
- ### #1 WordPress Photo Gallery Plugin - Gallery Bank
16
 
17
  #### [Gallery Bank is the Most Advanced and Powerful WordPress Gallery Plugin to create attractive photo galleries and gallery images.](https://gallery-bank.tech-banker.com/)
18
 
@@ -25,7 +25,7 @@ Whether you specialize in photography, creative designs, or a journalistic explo
25
  > <strong>Gallery Bank Premium Editions</strong><br />
26
  > This plugin is the lite version of the very popular Gallery Bank Plugin that comes with all the gallery features you will ever need including photo albums, tags, gallery layouts, deeplinking, pagination, watermarking, image proofing, different gallery lightboxes and tons more. <a href="https://gallery-bank.tech-banker.com/" rel="friend" title="Gallery Bank">Click here to purchase the best premium WordPress gallery plugin now!</a>
27
 
28
- #### This plugin is the ideal solution for creating portfolios, galleries, albums, gallery lightbox, showcases or teasers.
29
 
30
  * **[Gallery Bank - Responsive Image Gallery Plugin](https://gallery-bank.tech-banker.com/)**
31
  * **[Detailed Features - Responsive Photo Gallery Plugin](http://gallery-bank.tech-banker.com/features/detailed-features/)**
@@ -2479,6 +2479,14 @@ The following set of lists are the minimum requirements for installing Gallery B
2479
 
2480
  == Changelog ==
2481
 
 
 
 
 
 
 
 
 
2482
  = 4.0.9 =
2483
 
2484
  * TWEAK: Tabs Removed from Add/Edit Gallery Page
1
  === Gallery - Photo Gallery - Image Gallery - Photo Albums - WordPress Gallery Plugin ===
2
  Contributors: gallery-bank, contact-banker
3
  Donate link: https://gallery-bank.tech-banker.com/
4
+ Tags: album, fancy gallery, fullscreen gallery, gallery, gallery lightbox, gallery plugin, gallery widget, grid gallery, image gallery, images, masonry gallery, media gallery, mosaic gallery, photo album, photo gallery, portfolio gallery, responsive gallery, thumbnail gallery, wordpress gallery, wordpress gallery plugin
5
  Requires at least: 3.3
6
+ Tested up to: 4.9
7
  Stable tag: trunk
8
  License: GPLv3 or later
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
12
 
13
  == Description ==
14
 
15
+ ### WordPress Photo Gallery Plugin + WordPress Photo Albums Plugin = Gallery Bank
16
 
17
  #### [Gallery Bank is the Most Advanced and Powerful WordPress Gallery Plugin to create attractive photo galleries and gallery images.](https://gallery-bank.tech-banker.com/)
18
 
25
  > <strong>Gallery Bank Premium Editions</strong><br />
26
  > This plugin is the lite version of the very popular Gallery Bank Plugin that comes with all the gallery features you will ever need including photo albums, tags, gallery layouts, deeplinking, pagination, watermarking, image proofing, different gallery lightboxes and tons more. <a href="https://gallery-bank.tech-banker.com/" rel="friend" title="Gallery Bank">Click here to purchase the best premium WordPress gallery plugin now!</a>
27
 
28
+ #### This plugin is the ideal solution for creating portfolio gallery, media gallery, albums, gallery lightbox, gallery widgets, fullscreen galleries and albums.
29
 
30
  * **[Gallery Bank - Responsive Image Gallery Plugin](https://gallery-bank.tech-banker.com/)**
31
  * **[Detailed Features - Responsive Photo Gallery Plugin](http://gallery-bank.tech-banker.com/features/detailed-features/)**
2479
 
2480
  == Changelog ==
2481
 
2482
+ = 4.0.10 =
2483
+
2484
+ * TWEAK: PL Uploader updated to 2.3.1
2485
+ * TWEAK: jQUery Datatables updated to 1.10.15
2486
+ * TWEAK: jQUery Filtree updated to 2.1.5
2487
+ * TWEAK: jQUery Clip Board updated to 1.7.1
2488
+ * FIX: Footer File Bugs
2489
+
2490
  = 4.0.9 =
2491
 
2492
  * TWEAK: Tabs Removed from Add/Edit Gallery Page
user-views/layouts/compact-album-layout/compact-album-layout.php CHANGED
@@ -23,35 +23,34 @@ if (!defined("ABSPATH")) {
23
  <img src="<?php echo GALLERY_BANK_THUMBS_CROPPED_URL . esc_attr($gallery["gallery_cover_image"]); ?>"/>
24
  </div>
25
  </a>
26
- <?php
27
- if($gallery["gallery_title"] != "" || $gallery["gallery_description"] != "")
28
- {
29
- ?>
30
- <div id="grid_content_item_album" class="compact_album_grid_content_item">
31
- <?php
32
- if ($gallery_title == "show" && $gallery["gallery_title"] != "") {
33
- ?>
34
- <a href="<?php echo $redirect_url; ?>" id="grid_album_single_text_title_<?php echo $random . "_" . $gallery["id"]; ?>" class="compact_album_grid_single_text_title">
35
- <<?php echo isset($compact_album_layout_settings["compact_album_layout_gallery_title_html_tag"]) ? esc_attr($compact_album_layout_settings["compact_album_layout_gallery_title_html_tag"]) : "h3"; ?>>
36
- <?php echo isset($gallery["gallery_title"]) ? htmlspecialchars_decode($gallery["gallery_title"]) : ""; ?>
37
- </<?php echo isset($compact_album_layout_settings["compact_album_layout_gallery_title_html_tag"]) ? esc_attr($compact_album_layout_settings["compact_album_layout_gallery_title_html_tag"]) : "h3"; ?>>
38
- </a>
39
- <?php
40
- }
41
- if ($gallery_description == "show" && $gallery["gallery_description"] != "") {
42
- ?>
43
- <a href="<?php echo $redirect_url; ?>" id="grid_album_single_text_desc_<?php echo $random . "_" . $gallery["id"]; ?>" class="compact_album_grid_single_text_desc">
44
- <<?php echo isset($compact_album_layout_settings["compact_album_layout_gallery_description_html_tag"]) ? esc_attr($compact_album_layout_settings["compact_album_layout_gallery_description_html_tag"]) : "p"; ?>>
45
- <?php echo isset($gallery["gallery_description"]) ? htmlspecialchars_decode($gallery["gallery_description"]) : ""; ?>
46
- </<?php echo isset($compact_album_layout_settings["compact_album_layout_gallery_description_html_tag"]) ? esc_attr($compact_album_layout_settings["compact_album_layout_gallery_description_html_tag"]) : "p"; ?>>
47
- </a>
48
- <?php
49
- }
50
- ?>
51
- </div>
52
- <?php
53
- }
54
- ?>
55
  </div>
56
  <?php
57
  }
23
  <img src="<?php echo GALLERY_BANK_THUMBS_CROPPED_URL . esc_attr($gallery["gallery_cover_image"]); ?>"/>
24
  </div>
25
  </a>
26
+ <?php
27
+ if ($gallery["gallery_title"] != "" || $gallery["gallery_description"] != "") {
28
+ ?>
29
+ <div id="grid_content_item_album" class="compact_album_grid_content_item">
30
+ <?php
31
+ if ($gallery_title == "show" && $gallery["gallery_title"] != "") {
32
+ ?>
33
+ <a href="<?php echo $redirect_url; ?>" id="grid_album_single_text_title_<?php echo $random . "_" . $gallery["id"]; ?>" class="compact_album_grid_single_text_title">
34
+ <<?php echo isset($compact_album_layout_settings["compact_album_layout_gallery_title_html_tag"]) ? esc_attr($compact_album_layout_settings["compact_album_layout_gallery_title_html_tag"]) : "h3"; ?>>
35
+ <?php echo isset($gallery["gallery_title"]) ? htmlspecialchars_decode($gallery["gallery_title"]) : ""; ?>
36
+ </<?php echo isset($compact_album_layout_settings["compact_album_layout_gallery_title_html_tag"]) ? esc_attr($compact_album_layout_settings["compact_album_layout_gallery_title_html_tag"]) : "h3"; ?>>
37
+ </a>
38
+ <?php
39
+ }
40
+ if ($gallery_description == "show" && $gallery["gallery_description"] != "") {
41
+ ?>
42
+ <a href="<?php echo $redirect_url; ?>" id="grid_album_single_text_desc_<?php echo $random . "_" . $gallery["id"]; ?>" class="compact_album_grid_single_text_desc">
43
+ <<?php echo isset($compact_album_layout_settings["compact_album_layout_gallery_description_html_tag"]) ? esc_attr($compact_album_layout_settings["compact_album_layout_gallery_description_html_tag"]) : "p"; ?>>
44
+ <?php echo isset($gallery["gallery_description"]) ? htmlspecialchars_decode($gallery["gallery_description"]) : ""; ?>
45
+ </<?php echo isset($compact_album_layout_settings["compact_album_layout_gallery_description_html_tag"]) ? esc_attr($compact_album_layout_settings["compact_album_layout_gallery_description_html_tag"]) : "p"; ?>>
46
+ </a>
47
+ <?php
48
+ }
49
+ ?>
50
+ </div>
51
+ <?php
52
+ }
53
+ ?>
 
54
  </div>
55
  <?php
56
  }
user-views/layouts/masonry-layout/masonry-layout.php CHANGED
@@ -58,34 +58,33 @@ if (!defined("ABSPATH")) {
58
  </a>
59
  </div>
60
  <?php
61
- if($pic["image_title"] != "" || $pic["image_description"] != "")
62
- {
63
- ?>
64
- <div id="grid_content_item" class="masonry_grid_content_item">
65
- <?php
66
- if ($thumbnail_title == "show" && $pic["image_title"] != "") {
67
- ?>
68
- <div id="grid_single_text_title_<?php echo $random . "_" . $pic["id"]; ?>" class="masonry_grid_single_text_title">
69
- <<?php echo isset($masonry_layout_settings["masonry_layout_thumbnail_title_html_tag"]) ? esc_attr($masonry_layout_settings["masonry_layout_thumbnail_title_html_tag"]) : "h3"; ?>>
70
- <?php echo isset($pic["image_title"]) ? htmlspecialchars_decode($pic["image_title"]) : ""; ?>
71
- </<?php echo isset($masonry_layout_settings["masonry_layout_thumbnail_title_html_tag"]) ? esc_attr($masonry_layout_settings["masonry_layout_thumbnail_title_html_tag"]) : "h3"; ?>>
72
- </div>
73
- <?php
74
- }
75
- if ($thumbnail_description == "show" && $pic["image_description"] != "") {
76
- ?>
77
- <div id="grid_single_text_desc_<?php echo $random . "_" . $pic["id"]; ?>" class="masonry_grid_single_text_desc">
78
- <<?php echo isset($masonry_layout_settings["masonry_layout_thumbnail_description_html_tag"]) ? esc_attr($masonry_layout_settings["masonry_layout_thumbnail_description_html_tag"]) : "p"; ?>>
79
- <?php echo isset($pic["image_description"]) ? htmlspecialchars_decode($pic["image_description"]) : ""; ?>
80
- </<?php echo isset($masonry_layout_settings["masonry_layout_thumbnail_description_html_tag"]) ? esc_attr($masonry_layout_settings["masonry_layout_thumbnail_description_html_tag"]) : "p"; ?>>
81
- </div>
82
- <?php
83
- }
84
- ?>
85
- </div>
86
- <?php
87
- }
88
- ?>
89
  </div>
90
  <?php
91
  }
58
  </a>
59
  </div>
60
  <?php
61
+ if ($pic["image_title"] != "" || $pic["image_description"] != "") {
62
+ ?>
63
+ <div id="grid_content_item" class="masonry_grid_content_item">
64
+ <?php
65
+ if ($thumbnail_title == "show" && $pic["image_title"] != "") {
66
+ ?>
67
+ <div id="grid_single_text_title_<?php echo $random . "_" . $pic["id"]; ?>" class="masonry_grid_single_text_title">
68
+ <<?php echo isset($masonry_layout_settings["masonry_layout_thumbnail_title_html_tag"]) ? esc_attr($masonry_layout_settings["masonry_layout_thumbnail_title_html_tag"]) : "h3"; ?>>
69
+ <?php echo isset($pic["image_title"]) ? htmlspecialchars_decode($pic["image_title"]) : ""; ?>
70
+ </<?php echo isset($masonry_layout_settings["masonry_layout_thumbnail_title_html_tag"]) ? esc_attr($masonry_layout_settings["masonry_layout_thumbnail_title_html_tag"]) : "h3"; ?>>
71
+ </div>
72
+ <?php
73
+ }
74
+ if ($thumbnail_description == "show" && $pic["image_description"] != "") {
75
+ ?>
76
+ <div id="grid_single_text_desc_<?php echo $random . "_" . $pic["id"]; ?>" class="masonry_grid_single_text_desc">
77
+ <<?php echo isset($masonry_layout_settings["masonry_layout_thumbnail_description_html_tag"]) ? esc_attr($masonry_layout_settings["masonry_layout_thumbnail_description_html_tag"]) : "p"; ?>>
78
+ <?php echo isset($pic["image_description"]) ? htmlspecialchars_decode($pic["image_description"]) : ""; ?>
79
+ </<?php echo isset($masonry_layout_settings["masonry_layout_thumbnail_description_html_tag"]) ? esc_attr($masonry_layout_settings["masonry_layout_thumbnail_description_html_tag"]) : "p"; ?>>
80
+ </div>
81
+ <?php
82
+ }
83
+ ?>
84
+ </div>
85
+ <?php
86
+ }
87
+ ?>
 
88
  </div>
89
  <?php
90
  }
user-views/layouts/thumbnail-layout/thumbnail-layout.php CHANGED
@@ -57,36 +57,34 @@ if (!defined("ABSPATH")) {
57
  <img src="<?php echo GALLERY_BANK_THUMBS_CROPPED_URL . esc_attr($pic["image_name"]); ?>" image_full_path="<?php echo $pic["file_type"] ?>" alt="<?php echo esc_attr($pic["alt_text"]); ?>" id="ux_gb_file" name= "ux_gb_file_<?php echo $random . "_" . $pic["id"]; ?>"/>
58
  </div>
59
  </a>
60
- <?php
61
- if($pic["image_title"] != "" || $pic["image_description"] != "")
62
- {
63
- ?>
64
- <div id="grid_content_item" class="grid_content_item">
65
- <?php
66
- if ($thumbnail_title == "show" && $pic["image_title"] != "") {
67
- ?>
68
- <div id="grid_single_text_title_<?php echo $random . "_" . $pic["id"]; ?>" class="grid_single_text_title">
69
- <<?php echo isset($thumbnail_layout_settings["thumbnail_layout_thumbnail_title_html_tag"]) ? esc_attr($thumbnail_layout_settings["thumbnail_layout_thumbnail_title_html_tag"]) : "h3"; ?>>
70
- <?php echo isset($pic["image_title"]) ? htmlspecialchars_decode($pic["image_title"]) : ""; ?>
71
- </<?php echo isset($thumbnail_layout_settings["thumbnail_layout_thumbnail_title_html_tag"]) ? esc_attr($thumbnail_layout_settings["thumbnail_layout_thumbnail_title_html_tag"]) : "h3"; ?>>
72
- </div>
73
- <?php
74
- }
75
- if ($thumbnail_description == "show" && $pic["image_description"] != "") {
76
- ?>
77
- <div id="grid_single_text_desc_<?php echo $random; ?>" class="grid_single_text_desc">
78
- <<?php echo isset($thumbnail_layout_settings["thumbnail_layout_thumbnail_description_html_tag"]) ? esc_attr($thumbnail_layout_settings["thumbnail_layout_thumbnail_description_html_tag"]) : "p"; ?>>
79
- <?php echo isset($pic["image_description"]) ? htmlspecialchars_decode($pic["image_description"]) : ""; ?>
80
- </<?php echo isset($thumbnail_layout_settings["thumbnail_layout_thumbnail_description_html_tag"]) ? esc_attr($thumbnail_layout_settings["thumbnail_layout_thumbnail_description_html_tag"]) : "p"; ?>>
81
- </div>
82
- <?php
83
- }
84
- ?>
85
- </div>
86
- <?php
87
-
88
- }
89
- ?>
90
  </div>
91
  <?php
92
  }
57
  <img src="<?php echo GALLERY_BANK_THUMBS_CROPPED_URL . esc_attr($pic["image_name"]); ?>" image_full_path="<?php echo $pic["file_type"] ?>" alt="<?php echo esc_attr($pic["alt_text"]); ?>" id="ux_gb_file" name= "ux_gb_file_<?php echo $random . "_" . $pic["id"]; ?>"/>
58
  </div>
59
  </a>
60
+ <?php
61
+ if ($pic["image_title"] != "" || $pic["image_description"] != "") {
62
+ ?>
63
+ <div id="grid_content_item" class="grid_content_item">
64
+ <?php
65
+ if ($thumbnail_title == "show" && $pic["image_title"] != "") {
66
+ ?>
67
+ <div id="grid_single_text_title_<?php echo $random . "_" . $pic["id"]; ?>" class="grid_single_text_title">
68
+ <<?php echo isset($thumbnail_layout_settings["thumbnail_layout_thumbnail_title_html_tag"]) ? esc_attr($thumbnail_layout_settings["thumbnail_layout_thumbnail_title_html_tag"]) : "h3"; ?>>
69
+ <?php echo isset($pic["image_title"]) ? htmlspecialchars_decode($pic["image_title"]) : ""; ?>
70
+ </<?php echo isset($thumbnail_layout_settings["thumbnail_layout_thumbnail_title_html_tag"]) ? esc_attr($thumbnail_layout_settings["thumbnail_layout_thumbnail_title_html_tag"]) : "h3"; ?>>
71
+ </div>
72
+ <?php
73
+ }
74
+ if ($thumbnail_description == "show" && $pic["image_description"] != "") {
75
+ ?>
76
+ <div id="grid_single_text_desc_<?php echo $random; ?>" class="grid_single_text_desc">
77
+ <<?php echo isset($thumbnail_layout_settings["thumbnail_layout_thumbnail_description_html_tag"]) ? esc_attr($thumbnail_layout_settings["thumbnail_layout_thumbnail_description_html_tag"]) : "p"; ?>>
78
+ <?php echo isset($pic["image_description"]) ? htmlspecialchars_decode($pic["image_description"]) : ""; ?>
79
+ </<?php echo isset($thumbnail_layout_settings["thumbnail_layout_thumbnail_description_html_tag"]) ? esc_attr($thumbnail_layout_settings["thumbnail_layout_thumbnail_description_html_tag"]) : "p"; ?>>
80
+ </div>
81
+ <?php
82
+ }
83
+ ?>
84
+ </div>
85
+ <?php
86
+ }
87
+ ?>
 
 
88
  </div>
89
  <?php
90
  }
views/galleries/add-gallery.php CHANGED
@@ -7,537 +7,537 @@
7
  * @version 4.0.0
8
  */
9
  if (!defined("ABSPATH")) {
10
- exit;
11
  } // Exit if accessed directly
12
  if (!is_user_logged_in()) {
13
- return;
14
  } else {
15
- $access_granted = false;
16
- foreach ($user_role_permission as $permission) {
17
- if (current_user_can($permission)) {
18
- $access_granted = true;
19
- break;
20
- }
21
- }
22
- if (!$access_granted) {
23
- return;
24
- } else if (galleries_gallery_bank == "1") {
25
- global $wp_version;
26
- $gallery_images_effect_nonce = wp_create_nonce("gallery_images_effect_nonce");
27
- $watermark_image_nonce = wp_create_nonce("watermark_image_nonce");
28
- $save_image_detail_nonce = wp_create_nonce("save_image_detail_nonce");
29
- $get_previous_image_nonce = wp_create_nonce("get_previous_image_nonce");
30
- $generate_edited_image_thumbs_nonce = wp_create_nonce("generate_edited_image_thumbs_nonce");
31
- $scale_image_nonce = wp_create_nonce("scale_image_nonce");
32
- $get_original_image_dimension_nonce = wp_create_nonce("get_original_image_dimension_nonce");
33
- $crop_gallery_image_nonce = wp_create_nonce("crop_gallery_image_nonce");
34
- $gallery_images_restore_nonce = wp_create_nonce("gallery_images_restore_nonce");
35
- $gallery_images_rotate_nonce = wp_create_nonce("gallery_images_rotate_nonce");
36
- $gallery_images_flip_nonce = wp_create_nonce("gallery_images_flip_nonce");
37
- $gallery_images_move_nonce = wp_create_nonce("gallery_images_move_nonce");
38
- $gallery_images_copy_nonce = wp_create_nonce("gallery_images_copy_nonce");
39
- $gallery_update_data_nonce = wp_create_nonce("gallery_update_data_nonce");
40
- $gallery_images_delete_nonce = wp_create_nonce("gallery_images_delete_nonce");
41
- $upload_local_system_files_nonce = wp_create_nonce("upload_local_system_files_nonce");
42
- $gallery_upload_images_nonce = wp_create_nonce("gallery_upload_images_nonce");
43
- $gb_delete_uploaded_image_nonce = wp_create_nonce("gb_delete_uploaded_image_nonce");
44
- $gb_check_id_nonce = wp_create_nonce("gb_check_id_nonce");
45
- $ftp_uploader_nonce = wp_create_nonce("ftp_uploader_nonce");
46
- $ftp_upload = wp_create_nonce("ftp_upload");
47
- ?>
48
- <div class="page-bar">
49
- <ul class="page-breadcrumb">
50
- <li>
51
- <i class="icon-custom-home"></i>
52
- <a href="admin.php?page=gallery_bank">
53
- <?php echo $gallery_bank; ?>
54
- </a>
55
- <span>></span>
56
- </li>
57
- <li>
58
- <a href="admin.php?page=gallery_bank">
59
- <?php echo $gb_galleries; ?>
60
- </a>
61
- <span>></span>
62
- </li>
63
- <li>
64
- <span>
65
- <?php echo isset($_REQUEST["mode"]) && esc_attr($_REQUEST["mode"]) == "edit" ? $gb_update_gallery : $gb_add_gallery; ?>
66
- </span>
67
- </li>
68
- </ul>
69
- </div>
70
- <div class="row">
71
- <div class="col-md-12">
72
- <div class="portlet box vivid-green">
73
- <div class="portlet-title">
74
- <div class="caption">
75
- <i class="icon <?php echo isset($_REQUEST["mode"]) && esc_attr($_REQUEST["mode"]) == "edit" ? "icon-custom-note" : "icon-custom-plus"; ?>"></i>
76
- <?php echo isset($_REQUEST["mode"]) && esc_attr($_REQUEST["mode"]) == "edit" ? $gb_update_gallery : $gb_add_gallery; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  </div>
78
- <p class="premium-editions">
79
- <?php echo $gb_upgrade_need_help ?><a href="<?php echo tech_banker_gallery_url; ?>" target="_blank" class="premium-editions-documentation"><?php echo $gb_documentation ?></a><?php echo $gb_read_and_check; ?><a href="<?php echo tech_banker_gallery_url; ?>frontend-demos/" target="_blank" class="premium-editions-documentation"><?php echo $gb_demos_section; ?></a>
80
- </p>
81
- </div>
82
- <div class="portlet-body form">
83
- <form id="ux_frm_add_gallery">
84
- <div class="form-body">
85
- <div class="note note-warning">
86
- <?php
87
- if ($gb_message_translate_help != "") {
88
- ?>
89
- <h4 class="block">
90
- <?php echo $gb_important_disclaimer; ?>
91
- </h4>
92
- <p><strong><?php echo $gb_message_translate_help; ?> <a href="javascript:void(0);" data-popup-open="ux_open_popup_translator" class="custom_links_feature" onclick="show_pop_up_gallery_bank();"><?php echo $gb_message_translate_here; ?></a></strong></p>
93
- <?php
94
- }
95
- ?>
96
- <h4 class="block">
97
- <?php echo $gb_take_galleries_further; ?>
98
- </h4>
99
- <p>
100
- <?php echo $gb_galleries_upgrade_message; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  </p>
102
- <a href="<?php echo tech_banker_gallery_url; ?>" target="_blank" class="btn vivid-green-upgrade"><?php echo $gb_click_here_to_upgrade; ?></a>
103
- </div>
104
- <div class="form-actions">
105
- <div class="pull-right">
106
- <input type="submit" class="btn vivid-green" name="ux_btn_save_changes" id="ux_btn_save_changes" value="<?php echo $gb_save_changes; ?>">
107
- </div>
108
- </div>
109
- <div class="line-separator"></div>
110
- <div class="form-group">
111
- <label class="control-label">
112
- <?php echo $gb_gallery_title; ?> :
113
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_title_tooltip; ?>" data-placement="right"></i>
114
- <span class="required" aria-required="true">*</span>
115
- </label>
116
- <textarea rows="1" class="form-control" name="ux_txt_gallery_title" id="ux_txt_gallery_title" placeholder="<?php echo $gb_add_gallery_title_placeholder; ?>"><?php echo isset($get_gallery_meta_data_unserialize["gallery_title"]) ? esc_html($get_gallery_meta_data_unserialize["gallery_title"]) : ""; ?></textarea>
117
- </div>
118
- <div class="form-group">
119
- <label class="control-label">
120
- <?php echo $gb_gallery_description_title; ?> :
121
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_description_tooltip; ?>" data-placement="right"></i>
 
 
 
 
122
  </label>
123
- <?php
124
- $gallery_description = isset($get_gallery_meta_data_unserialize["gallery_description"]) ? htmlspecialchars_decode($get_gallery_meta_data_unserialize["gallery_description"]) : "";
125
- wp_editor($gallery_description, $id = "ux_heading_content", array("media_buttons" => false, "textarea_rows" => 6, "tabindex" => 4));
126
- ?>
127
- <textarea name="ux_txtarea_gallery_heading_content" id="ux_txtarea_gallery_heading_content" style="display:none;"></textarea>
128
- </div>
129
- <div class="tabbable-custom">
130
- <ul class="nav nav-tabs">
131
- <li class="active">
132
- <a aria-expanded="true" href="#local_system" data-toggle="tab">
133
- <?php echo $gb_add_gallery_local_system; ?>
134
- </a>
135
- </li>
136
- <li class="">
137
- <a aria-expanded="false" href="#wp_media" data-toggle="tab">
138
- <?php echo $gb_add_gallery_wp_media_manager; ?>
139
- </a>
140
- </li>
141
- <li class="">
142
- <a aria-expanded="false" href="#upload_ftp" data-toggle="tab">
143
- <?php echo $gb_add_gallery_upload_from_ftp; ?>
144
- </a>
145
- </li>
146
- <li class="">
147
- <a aria-expanded="false" href="#upload_videos" data-toggle="tab">
148
- <?php echo $gb_add_gallery_upload_videos; ?>
149
- </a>
150
- </li>
151
- </ul>
152
- <div class="tab-content">
153
- <div class="tab-pane active" id="local_system">
154
- <div id="local_file_upload">
155
- <p><?php echo $gb_add_gallery_local_system_notification; ?></p>
156
- </div>
157
- </div>
158
- <div class="tab-pane" id="wp_media" style="text-align:center">
159
- <div class="form-group">
160
- <h4><?php echo $gb_add_gallery_wp_media_guide_title; ?></h4>
161
- </div>
162
- <div class="form-group">
163
- <a class="btn vivid-green" id="wp_media_upload_button" onclick="premium_edition_notification_gallery_bank();">
164
- <?php echo $gb_add_gallery_upload_thumbnail; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  </a>
166
- <p id="wp_media_upload_error_message" style="display:none;">
167
- <?php echo $gb_add_gallery_wp_media_notification; ?>
168
- </p>
169
- </div>
170
- </div>
171
- <div class="tab-pane" id="upload_ftp" style="text-align:left">
172
- <div class="form-group">
173
- <h4><?php echo $gb_add_gallery_select_folder_import; ?></h4>
174
- </div>
175
- <div class="form-group" id="ux_wp_dir_browser">
176
- </div>
177
- <div class="form-group">
178
- <label><?php echo WP_CONTENT_DIR; ?></label>
179
- <input type="text" disabled="disabled" id="ux_txt_ftp_path" name="ux_txt_ftp_path" class="form-control input-inline custom-gallery-type" placeholder="<?php echo $gb_add_gallery_directory_path_placeholder; ?>" value="">
180
- </div>
181
- <div class="form-group">
182
- <button class="btn vivid-green" type="button" onclick="premium_edition_notification_gallery_bank();"><?php echo $gb_add_gallery_import_images; ?></button>
183
- </div>
184
- </div>
185
- <div class="tab-pane" id="upload_videos">
186
- <div class="form-group">
187
- <h4>Give the URL to upload video</h4>
188
- </div>
189
- <div class="form-group">
190
- <label><?php echo $gb_add_gallery_videos_url; ?> :
191
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_video_url_tooltip; ?>" data-placement="right"></i>
192
- <span class="required" aria-required="true">* <?php echo " ( " . $gb_premium_edition . " )"; ?></span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  </label>
194
- <input type="text" id="ux_text_videos_url" name="ux_text_videos_url" class="form-control" placeholder="<?php echo $gb_add_gallery_videos_url_placeholder; ?>" value="">
195
- </div>
196
- <div class="form-group" style="text-align:right">
197
- <input type="button" class="btn vivid-green" value="<?php echo $gb_add_gallery_embed_video; ?>" onclick="premium_edition_notification_gallery_bank();">
198
- </div>
199
- </div>
200
- </div>
201
- </div>
202
- <div id="ux_div_seperator" class="line-separator"></div>
203
- <div class="form-actions tabbable-custom" id="ux_div_bind_data">
204
- <div class="table-top-margin">
205
- <select name="ux_ddl_add_gallery" id="ux_ddl_add_gallery">
206
- <option value=""><?php echo $gb_bulk_action; ?></option>
207
- <option value="delete" style="color:red;"><?php echo $gb_add_gallery_option_delete_images . " (" . $gb_premium_edition . " )"; ?></option>
208
- <option value="copy" style="color:red;"><?php echo $gb_add_gallery_option_copy_images . " (" . $gb_premium_edition . " )"; ?></option>
209
- <option value="move" style="color:red;"><?php echo $gb_add_gallery_option_move_images . " (" . $gb_premium_edition . " )"; ?></option>
210
- <option value="rotate_clockwise" style="color:red;"><?php echo $gb_add_gallery_option_rotate_clockwise_images . " (" . $gb_premium_edition . " )"; ?></option>
211
- <option value="rotate_anticlockwise" style="color:red;"><?php echo $gb_add_gallery_option_rotate_anti_clockwise_images . " (" . $gb_premium_edition . " )"; ?></option>
212
- <option value="flip_vertically" style="color:red;"><?php echo $gb_add_gallery_option_flip_images_vertically . " (" . $gb_premium_edition . " )"; ?></option>
213
- <option value="flip_horizontally" style="color:red;"><?php echo $gb_add_gallery_option_flip_images_horizontally . " (" . $gb_premium_edition . " )"; ?></option>
214
- <option value="restore_image" style="color:red;"><?php echo $gb_add_gallery_option_restore_image . " (" . $gb_premium_edition . " )"; ?></option>
215
- <option value="watermark_image" style="color:red;"><?php echo $gb_add_gallery_option_apply_watermark . " (" . $gb_premium_edition . " )"; ?></option>
216
- </select>
217
- <input type="button" class="btn vivid-green" name="ux_btn_bulk_action" id="ux_btn_bulk_action" value="<?php echo $gb_apply; ?>" onclick="premium_edition_notification_gallery_bank();">
218
- </div>
219
- <div id="ux_div_clone" style="display:none;">
220
- <table class="table table-striped table-bordered table-hover table-margin-top" id="ux_tbl_add_gallery_clone">
221
- <thead>
222
- <tr>
223
- <th class="chk-action">
224
- <input type="checkbox" name="ux_chk_add_gallery" id="ux_chk_add_gallery">
225
- </th>
226
- <th>
227
- <label class="control-label">
228
- <?php echo $gb_add_gallery_table_thumbnail; ?>
229
- </label>
230
- </th>
231
- <th>
232
- <label class="control-label">
233
- <?php echo $gb_add_gallery_table_file_details; ?>
234
- </label>
235
- </th>
236
- </tr>
237
- </thead>
238
- <tbody>
239
- <tr id="ux_dynamic_tr_0" style="display:none;">
240
- <td>
241
- <input type="checkbox" id="ux_chk_select_items_" name="ux_chk_select_items_" value="" onclick="">
242
- </td>
243
- <td>
244
- <div class="image-style">
245
- <img file_type="" src="" id="ux_gb_file_" name="ux_gb_file_"/>
246
- </div>
247
- <div class="custom-div-gap">
248
- <input type="radio" name="ux_rdl_set_cover_image" id="ux_rdl_set_cover_image_" value="1" />
249
- <?php echo $gb_add_gallery_cover_image_title; ?>
250
- </div>
251
- <div class="custom-div-gap">
252
- <input type="checkbox" id="ux_exclude_image_" name="ux_exclude_image_" value="" />
253
- <?php echo $gb_add_gallery_exclude_title; ?>
254
- </div>
255
- <div class="custom-div-gap">
256
- <?php
257
- if ($wp_version >= "4.0") {
258
- ?>
259
- <a href="javascript:void(0);" class="tooltips" data-original-title="<?php echo $gb_add_gallery_edit_tooltip; ?>" data-placement="right" onclick="premium_edition_notification_gallery_bank();">
260
- <i class="icon-custom-note" ></i>
261
- <?php echo $gb_edit_tooltip; ?>
262
- </a>
263
- <label>|</label>
264
- <?php
265
- }
266
- ?>
267
- <a href="javascript:void(0);" class="tooltips" data-original-title="<?php echo $gb_add_gallery_delete_tooltip; ?>" data-placement="right" onclick="delete_upload_image_gallery_bank(this)" control_id="">
268
- <i class="icon-custom-trash" ></i>
269
- <?php echo $gb_delete; ?>
270
- </a>
271
- </div>
272
- </td>
273
- <td>
274
- <div class="row">
275
- <div class="col-md-6">
276
- <div class="form-group">
277
- <label class="control-label">
278
- <?php echo $gb_add_gallery_image_title; ?> :
279
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_tooltip; ?>" data-placement="right"></i>
280
- </label>
281
- <div class="input-icon right">
282
- <input type="text" placeholder="<?php echo $gb_add_gallery_image_placeholder; ?>" class="form-control" name="ux_txt_img_title_" id="ux_txt_img_title_" value="">
283
- </div>
284
- </div>
285
- </div>
286
- <div class="col-md-6">
287
- <div class="form-group">
288
- <label class="control-label">
289
- <?php echo $gb_add_gallery_image_alt_text_title; ?> :
290
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_alt_text_tooltip; ?>" data-placement="right"></i>
291
- </label>
292
- <div class="input-icon right">
293
- <input type="text" placeholder="<?php echo $gb_add_gallery_image_alt_text_placeholder; ?>" class="form-control" name="ux_img_alt_text_" id="ux_img_alt_text_" value="">
294
- </div>
295
- </div>
296
- </div>
297
- </div>
298
- <div class="form-group">
299
- <label class="control-label">
300
- <?php echo $gb_add_gallery_image_description_title; ?> :
301
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_description_tooltip; ?>" data-placement="right"></i>
302
- </label>
303
- <div class="input-icon right">
304
- <textarea placeholder="<?php echo $gb_add_gallery_image_description_placeholder; ?>" class="form-control" name="ux_txt_img_desc_" id="ux_txt_img_desc_"></textarea>
305
- </div>
306
- </div>
307
- <div class="form-group">
308
- <label class="control-label">
309
- <?php echo $gb_tags; ?> :
310
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_tag_tooltip; ?>" data-placement="right"></i>
311
- </label>
312
- <div class="input-icon right">
313
- <select id="ux_ddl_tags_" name="ux_ddl_tags_" class="form-control" multiple>
314
- <?php
315
- if (isset($tag_data_unserialize) && count($tag_data_unserialize) > 0) {
316
- foreach ($tag_data_unserialize as $value) {
317
- ?>
318
- <option value="<?php echo intval($value["id"]) ?>"><?php echo esc_attr($value["tag_name"]) ?></option>
319
- <?php
320
- }
321
- }
322
- ?>
323
- </select>
324
- </div>
325
- </div>
326
- <div class="form-group">
327
- <label class="control-label">
328
- <?php echo $gb_add_gallery_enable_url_title; ?> :
329
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_enable_url_tooltip; ?>" data-placement="right"></i>
330
- </label>
331
- <div class="input-group">
332
- <label>
333
- <input type="radio" name="ux_rdl_redirect_" id="ux_rdl_enable_redirect_" value="1" onclick="">
334
- <?php echo $gb_enable; ?>
335
- </label>
336
- <label style="margin-left:15px;">
337
- <input type="radio" checked="checked" name="ux_rdl_redirect_" id="ux_rdl_disable_redirect_" value="0" onclick="">
338
- <?php echo $gb_disable; ?>
339
- </label>
340
- </div>
341
- </div>
342
- <div class="form-group" id="ux_div_url_redirect_" style="display:none;">
343
- <label class="control-label"><?php echo $gb_add_gallery_url_link_title; ?> :
344
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_url_link_tooltip; ?>" data-placement="right"></i>
345
- </label>
346
- <div class="input-icon right">
347
- <input placeholder="<?php echo $gb_add_gallery_url_link_placeholder; ?>" class="form-control" type="text" name="ux_txt_img_url_" id="ux_txt_img_url_" value="http://">
348
- </div>
349
- </div>
350
- </td>
351
- </tr>
352
- </tbody>
353
- </table>
354
- </div>
355
- <table class="table table-striped table-bordered table-hover table-margin-top" id="ux_tbl_add_gallery">
356
- <thead>
357
- <tr>
358
- <th class="custom-checkbox chk-action">
359
- <input type="checkbox" class="custom-chkbox-operation" name="ux_chk_all_gallery" id="ux_chk_all_gallery">
360
- </th>
361
- <th class="custom-gallery-title">
362
- <label class="control-label">
363
- <?php echo $gb_add_gallery_table_thumbnail; ?>
364
- </label>
365
- </th>
366
- <th>
367
- <label class="control-label">
368
- <?php echo $gb_add_gallery_table_file_details; ?>
369
- </label>
370
- </th>
371
- </tr>
372
- </thead>
373
- <tbody>
374
- <?php
375
- if (isset($get_gallery_image_meta_data_unserialize) && count($get_gallery_image_meta_data_unserialize) > 0) {
376
- foreach ($get_gallery_image_meta_data_unserialize as $pic) {
377
- ?>
378
- <tr id="ux_dynamic_tr_<?php echo intval($pic["id"]); ?>">
379
- <td style="width:5%;text-align:center">
380
- <input type="checkbox" file_type="<?php echo esc_attr($pic["file_type"]); ?>" id="ux_chk_select_items_<?php echo intval($pic["id"]); ?>" onclick="check_value_checkbox_gallery_bank();" name="ux_chk_select_items_<?php echo intval($pic["id"]); ?>" value="<?php echo intval($pic["id"]); ?>"/>
381
- </td>
382
- <td style="width:20%">
383
- <div class="image-style">
384
- <img file_type="<?php echo esc_attr($pic["file_type"]); ?>" src="<?php echo GALLERY_BANK_THUMBS_NON_CROPPED_URL . esc_attr($pic["image_name"]); ?>" img_name="<?php echo esc_attr($pic["image_name"]); ?>" id="ux_gb_file_<?php echo intval($pic["id"]); ?>" name="ux_gb_file_<?php echo intval($pic["id"]); ?>" style="width: 100%;display: block;"/>
385
- </div>
386
- <div class="custom-div-gap">
387
- <input type="radio" name="ux_rdl_set_cover_image" onclick="set_cover_image_dynamically_gallery_bank(<?php echo $pic["id"]; ?>);" <?php echo intval($pic["gallery_cover_image"]) == 1 ? "checked=\"checked\"" : ""; ?> id="ux_rdl_set_cover_image_<?php echo intval($pic["id"]); ?>" value="1" image_data="<?php echo intval($pic["id"]); ?>"/> <?php echo $gb_add_gallery_cover_image_title; ?>
388
- </div>
389
- <div class="custom-div-gap">
390
- <input type="checkbox" id="ux_exclude_image_<?php echo intval($pic["id"]); ?>" <?php echo intval($pic["exclude_image"]) == 1 ? "checked=\"checked\"" : ""; ?> name="ux_exclude_image_<?php echo intval($pic["id"]); ?>" /><?php echo $gb_add_gallery_exclude_title; ?>
391
- </div>
392
- <div class="custom-div-gap">
393
- <?php
394
- if ($wp_version >= "4.0") {
395
- ?>
396
- <a href="javascript:void(0);" class="tooltips" data-original-title="<?php echo $gb_add_gallery_edit_tooltip; ?>" data-placement="right" id="ux_a_edit_<?php echo intval($pic["id"]); ?>" onclick="premium_edition_notification_gallery_bank();" control_id="<?php echo intval($pic["id"]); ?>">
397
- <i class="icon-custom-note" ></i> <?php echo $gb_edit_tooltip; ?>
398
- </a><label>|</label>
399
- <?php
400
- }
401
- ?>
402
- <a href="javascript:void(0);" class="tooltips" data-original-title="<?php echo $gb_add_gallery_delete_tooltip; ?>" data-placement="right" onclick="delete_upload_image_gallery_bank(this)" control_id="<?php echo intval($pic["id"]); ?>">
403
- <i class="icon-custom-trash" ></i> <?php echo $gb_delete; ?>
404
- </a>
405
- </div>
406
- </td>
407
- <td>
408
- <div class="row">
409
- <div class="col-md-6">
410
- <div class="form-group">
411
- <label class="control-label"><?php echo $gb_add_gallery_image_title; ?> :
412
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_tooltip; ?>" data-placement="right"></i>
413
- </label>
414
- <div class="input-icon right">
415
- <input type="text" placeholder="<?php echo $gb_add_gallery_image_placeholder; ?>" class="form-control edit" name="ux_txt_img_title_<?php echo intval($pic["id"]); ?>" id="ux_txt_img_title_<?php echo intval($pic["id"]); ?>" value="<?php echo esc_attr($pic["image_title"]); ?>"/>
416
- </div>
417
- </div>
418
- </div>
419
- <div class="col-md-6">
420
- <div class="form-group">
421
- <label class="control-label"><?php echo $gb_add_gallery_image_alt_text_title; ?> :
422
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_alt_text_tooltip; ?>" data-placement="right"></i>
423
- </label>
424
- <div class="input-icon right">
425
- <input type="text" placeholder="<?php echo $gb_add_gallery_image_alt_text_placeholder; ?>" class="form-control edit" name="ux_img_alt_text_<?php echo intval($pic["id"]); ?>" id="ux_img_alt_text_<?php echo intval($pic["id"]); ?>" value="<?php echo esc_attr(stripcslashes(urldecode($pic["alt_text"]))); ?>"/>
426
- </div>
427
- </div>
428
- </div>
429
- </div>
430
- <div class="form-group">
431
- <label class="control-label"><?php echo $gb_add_gallery_image_description_title; ?> :
432
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_description_tooltip; ?>" data-placement="right"></i>
433
- </label>
434
- <div class="input-icon right">
435
- <textarea placeholder="<?php echo $gb_add_gallery_image_description_placeholder; ?>" class="form-control" rows="3" name="ux_txt_img_desc_<?php echo intval($pic["id"]); ?>" id="ux_txt_img_desc_<?php echo intval($pic["id"]); ?>"><?php echo stripcslashes(urldecode($pic["image_description"])); ?></textarea>
436
- </div>
437
- </div>
438
- <div class="form-group">
439
- <label class="control-label"><?php echo $gb_tags; ?> :
440
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_tag_tooltip; ?>" data-placement="right"></i>
441
- </label>
442
- <div class="input-icon right">
443
- <select name="ux_ddl_tags_<?php echo intval($pic["id"]); ?>[]" id="ux_ddl_tags_<?php echo intval($pic["id"]); ?>" class="form-control" multiple>
444
- <?php
445
- $tag_array = isset($pic["tags"]) ? (is_array($pic["tags"]) ? $pic["tags"] : array()) : "";
446
- if (isset($tag_data_unserialize) && count($tag_data_unserialize) > 0) {
447
- foreach ($tag_data_unserialize as $value) {
448
- ?>
449
- <option onclick="remove_selected_attr_gallery_bank(this.id)" id="ux_tag_<?php echo intval($value["id"]) . "_" . intval($pic["id"]); ?>" value="<?php echo $value["id"] ?>" class="<?php echo in_array($value["id"], $tag_array) == true ? "tag" : ""; ?>" <?php echo in_array($value["id"], $tag_array) == true ? "selected" : ""; ?>><?php echo $value["tag_name"] ?></option>
450
- <?php
451
- }
452
- }
453
- ?>
454
- </select>
455
- </div>
456
- </div>
457
- <div class="form-group">
458
- <label class="control-label"> <?php echo $gb_add_gallery_enable_url_title; ?> :
459
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_enable_url_tooltip; ?>" data-placement="right"></i>
460
- </label>
461
- <div class="input-group">
462
- <label>
463
- <input type="radio" <?php echo intval($pic["enable_redirect"]) == 1 ? "checked=\"checked\"" : ""; ?> name="ux_rdl_redirect_<?php echo intval($pic["id"]); ?>" id="ux_rdl_enable_redirect_<?php echo intval($pic["id"]); ?>" value="1" onclick="show_image_url_redirect_gallery_bank(<?php echo intval($pic["id"]); ?>);"><?php echo $gb_enable; ?>
464
- </label>
465
- <label style="margin-left:15px;">
466
- <input type="radio" <?php echo intval($pic["enable_redirect"]) == 0 ? "checked=\"checked\"" : ""; ?> name="ux_rdl_redirect_<?php echo intval($pic["id"]); ?>" id="ux_rdl_disable_redirect_<?php echo intval($pic["id"]); ?>" value="0" onclick="show_image_url_redirect_gallery_bank(<?php echo intval($pic["id"]); ?>);"><?php echo $gb_disable; ?>
467
- </label>
468
- </div>
469
- </div>
470
- <div class="form-group" id="ux_div_url_redirect_<?php echo intval($pic["id"]); ?>" style="display: none;">
471
- <label class="control-label"><?php echo $gb_add_gallery_url_link_title; ?> :
472
- <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_url_link_tooltip; ?>" data-placement="right"></i>
473
- </label>
474
- <div class="input-icon right">
475
- <input placeholder="<?php echo $gb_add_gallery_url_link_placeholder; ?>" class="form-control" type="text" name="ux_txt_img_url_<?php echo intval($pic["id"]); ?>" id="ux_txt_img_url_<?php echo intval($pic["id"]); ?>" value="<?php echo esc_attr($pic["redirect_url"]); ?>"/>
476
- </div>
477
- </div>
478
- </td>
479
- </tr>
480
- <?php
481
  }
482
- }
483
- ?>
484
- </tbody>
485
- </table>
486
- </div>
487
- <div class="line-separator"></div>
488
- <div class="form-actions">
489
- <div class="pull-right">
490
- <input type="submit" class="btn vivid-green" name="ux_btn_save_changes" id="ux_btn_save_changes" value="<?php echo $gb_save_changes; ?>">
491
- </div>
492
- </div>
493
- </div>
494
- </form>
495
- </div>
496
- </div>
497
- </div>
498
- </div>
499
- <?php
500
- } else {
501
- ?>
502
- <div class="page-bar">
503
- <ul class="page-breadcrumb">
504
- <li>
505
- <i class="icon-custom-home"></i>
506
- <a href="admin.php?page=gallery_bank">
507
- <?php echo $gallery_bank; ?>
508
- </a>
509
- <span>></span>
510
- </li>
511
- <li>
512
- <a href="admin.php?page=gallery_bank">
513
- <?php echo $gb_galleries; ?>
514
- </a>
515
- <span>></span>
516
- </li>
517
- <li>
518
- <span>
519
- <?php echo isset($_REQUEST["mode"]) && esc_attr($_REQUEST["mode"]) == "edit" ? $gb_update_gallery : $gb_add_gallery; ?>
520
- </span>
521
- </li>
522
- </ul>
523
- </div>
524
- <div class="row">
525
- <div class="col-md-12">
526
- <div class="portlet box vivid-green">
527
- <div class="portlet-title">
528
- <div class="caption">
529
- <i class="icon icon-custom-plus"></i>
530
- <?php echo $gb_add_gallery; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
531
  </div>
532
- </div>
533
- <div class="portlet-body form">
534
- <div class="form-body">
535
- <strong><?php echo $gb_user_access_message; ?></strong>
 
536
  </div>
537
- </div>
538
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
  </div>
540
- </div>
541
- <?php
542
- }
 
543
  }
7
  * @version 4.0.0
8
  */
9
  if (!defined("ABSPATH")) {
10
+ exit;
11
  } // Exit if accessed directly
12
  if (!is_user_logged_in()) {
13
+ return;
14
  } else {
15
+ $access_granted = false;
16
+ foreach ($user_role_permission as $permission) {
17
+ if (current_user_can($permission)) {
18
+ $access_granted = true;
19
+ break;
20
+ }
21
+ }
22
+ if (!$access_granted) {
23
+ return;
24
+ } else if (galleries_gallery_bank == "1") {
25
+ global $wp_version;
26
+ $gallery_images_effect_nonce = wp_create_nonce("gallery_images_effect_nonce");
27
+ $watermark_image_nonce = wp_create_nonce("watermark_image_nonce");
28
+ $save_image_detail_nonce = wp_create_nonce("save_image_detail_nonce");
29
+ $get_previous_image_nonce = wp_create_nonce("get_previous_image_nonce");
30
+ $generate_edited_image_thumbs_nonce = wp_create_nonce("generate_edited_image_thumbs_nonce");
31
+ $scale_image_nonce = wp_create_nonce("scale_image_nonce");
32
+ $get_original_image_dimension_nonce = wp_create_nonce("get_original_image_dimension_nonce");
33
+ $crop_gallery_image_nonce = wp_create_nonce("crop_gallery_image_nonce");
34
+ $gallery_images_restore_nonce = wp_create_nonce("gallery_images_restore_nonce");
35
+ $gallery_images_rotate_nonce = wp_create_nonce("gallery_images_rotate_nonce");
36
+ $gallery_images_flip_nonce = wp_create_nonce("gallery_images_flip_nonce");
37
+ $gallery_images_move_nonce = wp_create_nonce("gallery_images_move_nonce");
38
+ $gallery_images_copy_nonce = wp_create_nonce("gallery_images_copy_nonce");
39
+ $gallery_update_data_nonce = wp_create_nonce("gallery_update_data_nonce");
40
+ $gallery_images_delete_nonce = wp_create_nonce("gallery_images_delete_nonce");
41
+ $upload_local_system_files_nonce = wp_create_nonce("upload_local_system_files_nonce");
42
+ $gallery_upload_images_nonce = wp_create_nonce("gallery_upload_images_nonce");
43
+ $gb_delete_uploaded_image_nonce = wp_create_nonce("gb_delete_uploaded_image_nonce");
44
+ $gb_check_id_nonce = wp_create_nonce("gb_check_id_nonce");
45
+ $ftp_uploader_nonce = wp_create_nonce("ftp_uploader_nonce");
46
+ $ftp_upload = wp_create_nonce("ftp_upload");
47
+ ?>
48
+ <div class="page-bar">
49
+ <ul class="page-breadcrumb">
50
+ <li>
51
+ <i class="icon-custom-home"></i>
52
+ <a href="admin.php?page=gallery_bank">
53
+ <?php echo $gallery_bank; ?>
54
+ </a>
55
+ <span>></span>
56
+ </li>
57
+ <li>
58
+ <a href="admin.php?page=gallery_bank">
59
+ <?php echo $gb_galleries; ?>
60
+ </a>
61
+ <span>></span>
62
+ </li>
63
+ <li>
64
+ <span>
65
+ <?php echo isset($_REQUEST["mode"]) && esc_attr($_REQUEST["mode"]) == "edit" ? $gb_update_gallery : $gb_add_gallery; ?>
66
+ </span>
67
+ </li>
68
+ </ul>
69
+ </div>
70
+ <div class="row">
71
+ <div class="col-md-12">
72
+ <div class="portlet box vivid-green">
73
+ <div class="portlet-title">
74
+ <div class="caption">
75
+ <i class="icon <?php echo isset($_REQUEST["mode"]) && esc_attr($_REQUEST["mode"]) == "edit" ? "icon-custom-note" : "icon-custom-plus"; ?>"></i>
76
+ <?php echo isset($_REQUEST["mode"]) && esc_attr($_REQUEST["mode"]) == "edit" ? $gb_update_gallery : $gb_add_gallery; ?>
77
+ </div>
78
+ <p class="premium-editions">
79
+ <?php echo $gb_upgrade_need_help ?><a href="<?php echo tech_banker_gallery_url; ?>" target="_blank" class="premium-editions-documentation"><?php echo $gb_documentation ?></a><?php echo $gb_read_and_check; ?><a href="<?php echo tech_banker_gallery_url; ?>frontend-demos/" target="_blank" class="premium-editions-documentation"><?php echo $gb_demos_section; ?></a>
80
+ </p>
81
+ </div>
82
+ <div class="portlet-body form">
83
+ <form id="ux_frm_add_gallery">
84
+ <div class="form-body">
85
+ <div class="note note-warning">
86
+ <?php
87
+ if ($gb_message_translate_help != "") {
88
+ ?>
89
+ <h4 class="block">
90
+ <?php echo $gb_important_disclaimer; ?>
91
+ </h4>
92
+ <p><strong><?php echo $gb_message_translate_help; ?> <a href="javascript:void(0);" data-popup-open="ux_open_popup_translator" class="custom_links_feature" onclick="show_pop_up_gallery_bank();"><?php echo $gb_message_translate_here; ?></a></strong></p>
93
+ <?php
94
+ }
95
+ ?>
96
+ <h4 class="block">
97
+ <?php echo $gb_take_galleries_further; ?>
98
+ </h4>
99
+ <p>
100
+ <?php echo $gb_galleries_upgrade_message; ?>
101
+ </p>
102
+ <a href="<?php echo tech_banker_gallery_url; ?>" target="_blank" class="btn vivid-green-upgrade"><?php echo $gb_click_here_to_upgrade; ?></a>
103
  </div>
104
+ <div class="form-actions">
105
+ <div class="pull-right">
106
+ <input type="submit" class="btn vivid-green" name="ux_btn_save_changes" id="ux_btn_save_changes" value="<?php echo $gb_save_changes; ?>">
107
+ </div>
108
+ </div>
109
+ <div class="line-separator"></div>
110
+ <div class="form-group">
111
+ <label class="control-label">
112
+ <?php echo $gb_gallery_title; ?> :
113
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_title_tooltip; ?>" data-placement="right"></i>
114
+ <span class="required" aria-required="true">*</span>
115
+ </label>
116
+ <textarea rows="1" class="form-control" name="ux_txt_gallery_title" id="ux_txt_gallery_title" placeholder="<?php echo $gb_add_gallery_title_placeholder; ?>"><?php echo isset($get_gallery_meta_data_unserialize["gallery_title"]) ? esc_html($get_gallery_meta_data_unserialize["gallery_title"]) : ""; ?></textarea>
117
+ </div>
118
+ <div class="form-group">
119
+ <label class="control-label">
120
+ <?php echo $gb_gallery_description_title; ?> :
121
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_description_tooltip; ?>" data-placement="right"></i>
122
+ </label>
123
+ <?php
124
+ $gallery_description = isset($get_gallery_meta_data_unserialize["gallery_description"]) ? htmlspecialchars_decode($get_gallery_meta_data_unserialize["gallery_description"]) : "";
125
+ wp_editor($gallery_description, $id = "ux_heading_content", array("media_buttons" => false, "textarea_rows" => 6, "tabindex" => 4));
126
+ ?>
127
+ <textarea name="ux_txtarea_gallery_heading_content" id="ux_txtarea_gallery_heading_content" style="display:none;"></textarea>
128
+ </div>
129
+ <div class="tabbable-custom">
130
+ <ul class="nav nav-tabs">
131
+ <li class="active">
132
+ <a aria-expanded="true" href="#local_system" data-toggle="tab">
133
+ <?php echo $gb_add_gallery_local_system; ?>
134
+ </a>
135
+ </li>
136
+ <li class="">
137
+ <a aria-expanded="false" href="#wp_media" data-toggle="tab">
138
+ <?php echo $gb_add_gallery_wp_media_manager; ?>
139
+ </a>
140
+ </li>
141
+ <li class="">
142
+ <a aria-expanded="false" href="#upload_ftp" data-toggle="tab">
143
+ <?php echo $gb_add_gallery_upload_from_ftp; ?>
144
+ </a>
145
+ </li>
146
+ <li class="">
147
+ <a aria-expanded="false" href="#upload_videos" data-toggle="tab">
148
+ <?php echo $gb_add_gallery_upload_videos; ?>
149
+ </a>
150
+ </li>
151
+ </ul>
152
+ <div class="tab-content">
153
+ <div class="tab-pane active" id="local_system">
154
+ <div id="local_file_upload">
155
+ <p><?php echo $gb_add_gallery_local_system_notification; ?></p>
156
+ </div>
157
+ </div>
158
+ <div class="tab-pane" id="wp_media" style="text-align:center">
159
+ <div class="form-group">
160
+ <h4><?php echo $gb_add_gallery_wp_media_guide_title; ?></h4>
161
+ </div>
162
+ <div class="form-group">
163
+ <a class="btn vivid-green" id="wp_media_upload_button" onclick="premium_edition_notification_gallery_bank();">
164
+ <?php echo $gb_add_gallery_upload_thumbnail; ?>
165
+ </a>
166
+ <p id="wp_media_upload_error_message" style="display:none;">
167
+ <?php echo $gb_add_gallery_wp_media_notification; ?>
168
  </p>
169
+ </div>
170
+ </div>
171
+ <div class="tab-pane" id="upload_ftp" style="text-align:left">
172
+ <div class="form-group">
173
+ <h4><?php echo $gb_add_gallery_select_folder_import; ?></h4>
174
+ </div>
175
+ <div class="form-group" id="ux_wp_dir_browser">
176
+ </div>
177
+ <div class="form-group">
178
+ <label><?php echo WP_CONTENT_DIR; ?></label>
179
+ <input type="text" disabled="disabled" id="ux_txt_ftp_path" name="ux_txt_ftp_path" class="form-control input-inline custom-gallery-type" placeholder="<?php echo $gb_add_gallery_directory_path_placeholder; ?>" value="">
180
+ </div>
181
+ <div class="form-group">
182
+ <button class="btn vivid-green" type="button" onclick="premium_edition_notification_gallery_bank();"><?php echo $gb_add_gallery_import_images; ?></button>
183
+ </div>
184
+ </div>
185
+ <div class="tab-pane" id="upload_videos">
186
+ <div class="form-group">
187
+ <h4>Give the URL to upload video</h4>
188
+ </div>
189
+ <div class="form-group">
190
+ <label><?php echo $gb_add_gallery_videos_url; ?> :
191
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_video_url_tooltip; ?>" data-placement="right"></i>
192
+ <span class="required" aria-required="true">* <?php echo " ( " . $gb_premium_edition . " )"; ?></span>
193
  </label>
194
+ <input type="text" id="ux_text_videos_url" name="ux_text_videos_url" class="form-control" placeholder="<?php echo $gb_add_gallery_videos_url_placeholder; ?>" value="">
195
+ </div>
196
+ <div class="form-group" style="text-align:right">
197
+ <input type="button" class="btn vivid-green" value="<?php echo $gb_add_gallery_embed_video; ?>" onclick="premium_edition_notification_gallery_bank();">
198
+ </div>
199
+ </div>
200
+ </div>
201
+ </div>
202
+ <div id="ux_div_seperator" class="line-separator"></div>
203
+ <div class="form-actions tabbable-custom" id="ux_div_bind_data">
204
+ <div class="table-top-margin">
205
+ <select name="ux_ddl_add_gallery" id="ux_ddl_add_gallery">
206
+ <option value=""><?php echo $gb_bulk_action; ?></option>
207
+ <option value="delete" style="color:red;"><?php echo $gb_add_gallery_option_delete_images . " (" . $gb_premium_edition . " )"; ?></option>
208
+ <option value="copy" style="color:red;"><?php echo $gb_add_gallery_option_copy_images . " (" . $gb_premium_edition . " )"; ?></option>
209
+ <option value="move" style="color:red;"><?php echo $gb_add_gallery_option_move_images . " (" . $gb_premium_edition . " )"; ?></option>
210
+ <option value="rotate_clockwise" style="color:red;"><?php echo $gb_add_gallery_option_rotate_clockwise_images . " (" . $gb_premium_edition . " )"; ?></option>
211
+ <option value="rotate_anticlockwise" style="color:red;"><?php echo $gb_add_gallery_option_rotate_anti_clockwise_images . " (" . $gb_premium_edition . " )"; ?></option>
212
+ <option value="flip_vertically" style="color:red;"><?php echo $gb_add_gallery_option_flip_images_vertically . " (" . $gb_premium_edition . " )"; ?></option>
213
+ <option value="flip_horizontally" style="color:red;"><?php echo $gb_add_gallery_option_flip_images_horizontally . " (" . $gb_premium_edition . " )"; ?></option>
214
+ <option value="restore_image" style="color:red;"><?php echo $gb_add_gallery_option_restore_image . " (" . $gb_premium_edition . " )"; ?></option>
215
+ <option value="watermark_image" style="color:red;"><?php echo $gb_add_gallery_option_apply_watermark . " (" . $gb_premium_edition . " )"; ?></option>
216
+ </select>
217
+ <input type="button" class="btn vivid-green" name="ux_btn_bulk_action" id="ux_btn_bulk_action" value="<?php echo $gb_apply; ?>" onclick="premium_edition_notification_gallery_bank();">
218
+ </div>
219
+ <div id="ux_div_clone" style="display:none;">
220
+ <table class="table table-striped table-bordered table-hover table-margin-top" id="ux_tbl_add_gallery_clone">
221
+ <thead>
222
+ <tr>
223
+ <th class="chk-action">
224
+ <input type="checkbox" name="ux_chk_add_gallery" id="ux_chk_add_gallery">
225
+ </th>
226
+ <th>
227
+ <label class="control-label">
228
+ <?php echo $gb_add_gallery_table_thumbnail; ?>
229
+ </label>
230
+ </th>
231
+ <th>
232
+ <label class="control-label">
233
+ <?php echo $gb_add_gallery_table_file_details; ?>
234
+ </label>
235
+ </th>
236
+ </tr>
237
+ </thead>
238
+ <tbody>
239
+ <tr id="ux_dynamic_tr_0" style="display:none;">
240
+ <td>
241
+ <input type="checkbox" id="ux_chk_select_items_" name="ux_chk_select_items_" value="" onclick="">
242
+ </td>
243
+ <td>
244
+ <div class="image-style">
245
+ <img file_type="" src="" id="ux_gb_file_" name="ux_gb_file_"/>
246
+ </div>
247
+ <div class="custom-div-gap">
248
+ <input type="radio" name="ux_rdl_set_cover_image" id="ux_rdl_set_cover_image_" value="1" />
249
+ <?php echo $gb_add_gallery_cover_image_title; ?>
250
+ </div>
251
+ <div class="custom-div-gap">
252
+ <input type="checkbox" id="ux_exclude_image_" name="ux_exclude_image_" value="" />
253
+ <?php echo $gb_add_gallery_exclude_title; ?>
254
+ </div>
255
+ <div class="custom-div-gap">
256
+ <?php
257
+ if ($wp_version >= "4.0") {
258
+ ?>
259
+ <a href="javascript:void(0);" class="tooltips" data-original-title="<?php echo $gb_add_gallery_edit_tooltip; ?>" data-placement="right" onclick="premium_edition_notification_gallery_bank();">
260
+ <i class="icon-custom-note" ></i>
261
+ <?php echo $gb_edit_tooltip; ?>
262
  </a>
263
+ <label>|</label>
264
+ <?php
265
+ }
266
+ ?>
267
+ <a href="javascript:void(0);" class="tooltips" data-original-title="<?php echo $gb_add_gallery_delete_tooltip; ?>" data-placement="right" onclick="delete_upload_image_gallery_bank(this)" control_id="">
268
+ <i class="icon-custom-trash" ></i>
269
+ <?php echo $gb_delete; ?>
270
+ </a>
271
+ </div>
272
+ </td>
273
+ <td>
274
+ <div class="row">
275
+ <div class="col-md-6">
276
+ <div class="form-group">
277
+ <label class="control-label">
278
+ <?php echo $gb_add_gallery_image_title; ?> :
279
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_tooltip; ?>" data-placement="right"></i>
280
+ </label>
281
+ <div class="input-icon right">
282
+ <input type="text" placeholder="<?php echo $gb_add_gallery_image_placeholder; ?>" class="form-control" name="ux_txt_img_title_" id="ux_txt_img_title_" value="">
283
+ </div>
284
+ </div>
285
+ </div>
286
+ <div class="col-md-6">
287
+ <div class="form-group">
288
+ <label class="control-label">
289
+ <?php echo $gb_add_gallery_image_alt_text_title; ?> :
290
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_alt_text_tooltip; ?>" data-placement="right"></i>
291
+ </label>
292
+ <div class="input-icon right">
293
+ <input type="text" placeholder="<?php echo $gb_add_gallery_image_alt_text_placeholder; ?>" class="form-control" name="ux_img_alt_text_" id="ux_img_alt_text_" value="">
294
+ </div>
295
+ </div>
296
+ </div>
297
+ </div>
298
+ <div class="form-group">
299
+ <label class="control-label">
300
+ <?php echo $gb_add_gallery_image_description_title; ?> :
301
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_description_tooltip; ?>" data-placement="right"></i>
302
+ </label>
303
+ <div class="input-icon right">
304
+ <textarea placeholder="<?php echo $gb_add_gallery_image_description_placeholder; ?>" class="form-control" name="ux_txt_img_desc_" id="ux_txt_img_desc_"></textarea>
305
+ </div>
306
+ </div>
307
+ <div class="form-group">
308
+ <label class="control-label">
309
+ <?php echo $gb_tags; ?> :
310
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_tag_tooltip; ?>" data-placement="right"></i>
311
+ </label>
312
+ <div class="input-icon right">
313
+ <select id="ux_ddl_tags_" name="ux_ddl_tags_" class="form-control" multiple>
314
+ <?php
315
+ if (isset($tag_data_unserialize) && count($tag_data_unserialize) > 0) {
316
+ foreach ($tag_data_unserialize as $value) {
317
+ ?>
318
+ <option value="<?php echo intval($value["id"]) ?>"><?php echo esc_attr($value["tag_name"]) ?></option>
319
+ <?php
320
+ }
321
+ }
322
+ ?>
323
+ </select>
324
+ </div>
325
+ </div>
326
+ <div class="form-group">
327
+ <label class="control-label">
328
+ <?php echo $gb_add_gallery_enable_url_title; ?> :
329
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_enable_url_tooltip; ?>" data-placement="right"></i>
330
+ </label>
331
+ <div class="input-group">
332
+ <label>
333
+ <input type="radio" name="ux_rdl_redirect_" id="ux_rdl_enable_redirect_" value="1" onclick="">
334
+ <?php echo $gb_enable; ?>
335
  </label>
336
+ <label style="margin-left:15px;">
337
+ <input type="radio" checked="checked" name="ux_rdl_redirect_" id="ux_rdl_disable_redirect_" value="0" onclick="">
338
+ <?php echo $gb_disable; ?>
339
+ </label>
340
+ </div>
341
+ </div>
342
+ <div class="form-group" id="ux_div_url_redirect_" style="display:none;">
343
+ <label class="control-label"><?php echo $gb_add_gallery_url_link_title; ?> :
344
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_url_link_tooltip; ?>" data-placement="right"></i>
345
+ </label>
346
+ <div class="input-icon right">
347
+ <input placeholder="<?php echo $gb_add_gallery_url_link_placeholder; ?>" class="form-control" type="text" name="ux_txt_img_url_" id="ux_txt_img_url_" value="http://">
348
+ </div>
349
+ </div>
350
+ </td>
351
+ </tr>
352
+ </tbody>
353
+ </table>
354
+ </div>
355
+ <table class="table table-striped table-bordered table-hover table-margin-top" id="ux_tbl_add_gallery">
356
+ <thead>
357
+ <tr>
358
+ <th class="custom-checkbox chk-action">
359
+ <input type="checkbox" class="custom-chkbox-operation" name="ux_chk_all_gallery" id="ux_chk_all_gallery">
360
+ </th>
361
+ <th class="custom-gallery-title">
362
+ <label class="control-label">
363
+ <?php echo $gb_add_gallery_table_thumbnail; ?>
364
+ </label>
365
+ </th>
366
+ <th>
367
+ <label class="control-label">
368
+ <?php echo $gb_add_gallery_table_file_details; ?>
369
+ </label>
370
+ </th>
371
+ </tr>
372
+ </thead>
373
+ <tbody>
374
+ <?php
375
+ if (isset($get_gallery_image_meta_data_unserialize) && count($get_gallery_image_meta_data_unserialize) > 0) {
376
+ foreach ($get_gallery_image_meta_data_unserialize as $pic) {
377
+ ?>
378
+ <tr id="ux_dynamic_tr_<?php echo intval($pic["id"]); ?>">
379
+ <td style="width:5%;text-align:center">
380
+ <input type="checkbox" file_type="<?php echo esc_attr($pic["file_type"]); ?>" id="ux_chk_select_items_<?php echo intval($pic["id"]); ?>" onclick="check_value_checkbox_gallery_bank();" name="ux_chk_select_items_<?php echo intval($pic["id"]); ?>" value="<?php echo intval($pic["id"]); ?>"/>
381
+ </td>
382
+ <td style="width:20%">
383
+ <div class="image-style">
384
+ <img file_type="<?php echo esc_attr($pic["file_type"]); ?>" src="<?php echo GALLERY_BANK_THUMBS_NON_CROPPED_URL . esc_attr($pic["image_name"]); ?>" img_name="<?php echo esc_attr($pic["image_name"]); ?>" id="ux_gb_file_<?php echo intval($pic["id"]); ?>" name="ux_gb_file_<?php echo intval($pic["id"]); ?>" style="width: 100%;display: block;"/>
385
+ </div>
386
+ <div class="custom-div-gap">
387
+ <input type="radio" name="ux_rdl_set_cover_image" onclick="set_cover_image_dynamically_gallery_bank(<?php echo $pic["id"]; ?>);" <?php echo intval($pic["gallery_cover_image"]) == 1 ? "checked=\"checked\"" : ""; ?> id="ux_rdl_set_cover_image_<?php echo intval($pic["id"]); ?>" value="1" image_data="<?php echo intval($pic["id"]); ?>"/> <?php echo $gb_add_gallery_cover_image_title; ?>
388
+ </div>
389
+ <div class="custom-div-gap">
390
+ <input type="checkbox" id="ux_exclude_image_<?php echo intval($pic["id"]); ?>" <?php echo intval($pic["exclude_image"]) == 1 ? "checked=\"checked\"" : ""; ?> name="ux_exclude_image_<?php echo intval($pic["id"]); ?>" /><?php echo $gb_add_gallery_exclude_title; ?>
391
+ </div>
392
+ <div class="custom-div-gap">
393
+ <?php
394
+ if ($wp_version >= "4.0") {
395
+ ?>
396
+ <a href="javascript:void(0);" class="tooltips" data-original-title="<?php echo $gb_add_gallery_edit_tooltip; ?>" data-placement="right" id="ux_a_edit_<?php echo intval($pic["id"]); ?>" onclick="premium_edition_notification_gallery_bank();" control_id="<?php echo intval($pic["id"]); ?>">
397
+ <i class="icon-custom-note" ></i> <?php echo $gb_edit_tooltip; ?>
398
+ </a><label>|</label>
399
+ <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  }
401
+ ?>
402
+ <a href="javascript:void(0);" class="tooltips" data-original-title="<?php echo $gb_add_gallery_delete_tooltip; ?>" data-placement="right" onclick="delete_upload_image_gallery_bank(this)" control_id="<?php echo intval($pic["id"]); ?>">
403
+ <i class="icon-custom-trash" ></i> <?php echo $gb_delete; ?>
404
+ </a>
405
+ </div>
406
+ </td>
407
+ <td>
408
+ <div class="row">
409
+ <div class="col-md-6">
410
+ <div class="form-group">
411
+ <label class="control-label"><?php echo $gb_add_gallery_image_title; ?> :
412
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_tooltip; ?>" data-placement="right"></i>
413
+ </label>
414
+ <div class="input-icon right">
415
+ <input type="text" placeholder="<?php echo $gb_add_gallery_image_placeholder; ?>" class="form-control edit" name="ux_txt_img_title_<?php echo intval($pic["id"]); ?>" id="ux_txt_img_title_<?php echo intval($pic["id"]); ?>" value="<?php echo esc_attr($pic["image_title"]); ?>"/>
416
+ </div>
417
+ </div>
418
+ </div>
419
+ <div class="col-md-6">
420
+ <div class="form-group">
421
+ <label class="control-label"><?php echo $gb_add_gallery_image_alt_text_title; ?> :
422
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_alt_text_tooltip; ?>" data-placement="right"></i>
423
+ </label>
424
+ <div class="input-icon right">
425
+ <input type="text" placeholder="<?php echo $gb_add_gallery_image_alt_text_placeholder; ?>" class="form-control edit" name="ux_img_alt_text_<?php echo intval($pic["id"]); ?>" id="ux_img_alt_text_<?php echo intval($pic["id"]); ?>" value="<?php echo esc_attr(stripcslashes(urldecode($pic["alt_text"]))); ?>"/>
426
+ </div>
427
+ </div>
428
+ </div>
429
+ </div>
430
+ <div class="form-group">
431
+ <label class="control-label"><?php echo $gb_add_gallery_image_description_title; ?> :
432
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_image_description_tooltip; ?>" data-placement="right"></i>
433
+ </label>
434
+ <div class="input-icon right">
435
+ <textarea placeholder="<?php echo $gb_add_gallery_image_description_placeholder; ?>" class="form-control" rows="3" name="ux_txt_img_desc_<?php echo intval($pic["id"]); ?>" id="ux_txt_img_desc_<?php echo intval($pic["id"]); ?>"><?php echo stripcslashes(urldecode($pic["image_description"])); ?></textarea>
436
+ </div>
437
+ </div>
438
+ <div class="form-group">
439
+ <label class="control-label"><?php echo $gb_tags; ?> :
440
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_tag_tooltip; ?>" data-placement="right"></i>
441
+ </label>
442
+ <div class="input-icon right">
443
+ <select name="ux_ddl_tags_<?php echo intval($pic["id"]); ?>[]" id="ux_ddl_tags_<?php echo intval($pic["id"]); ?>" class="form-control" multiple>
444
+ <?php
445
+ $tag_array = isset($pic["tags"]) ? (is_array($pic["tags"]) ? $pic["tags"] : array()) : "";
446
+ if (isset($tag_data_unserialize) && count($tag_data_unserialize) > 0) {
447
+ foreach ($tag_data_unserialize as $value) {
448
+ ?>
449
+ <option onclick="remove_selected_attr_gallery_bank(this.id)" id="ux_tag_<?php echo intval($value["id"]) . "_" . intval($pic["id"]); ?>" value="<?php echo $value["id"] ?>" class="<?php echo in_array($value["id"], $tag_array) == true ? "tag" : ""; ?>" <?php echo in_array($value["id"], $tag_array) == true ? "selected" : ""; ?>><?php echo $value["tag_name"] ?></option>
450
+ <?php
451
+ }
452
+ }
453
+ ?>
454
+ </select>
455
+ </div>
456
+ </div>
457
+ <div class="form-group">
458
+ <label class="control-label"> <?php echo $gb_add_gallery_enable_url_title; ?> :
459
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_enable_url_tooltip; ?>" data-placement="right"></i>
460
+ </label>
461
+ <div class="input-group">
462
+ <label>
463
+ <input type="radio" <?php echo intval($pic["enable_redirect"]) == 1 ? "checked=\"checked\"" : ""; ?> name="ux_rdl_redirect_<?php echo intval($pic["id"]); ?>" id="ux_rdl_enable_redirect_<?php echo intval($pic["id"]); ?>" value="1" onclick="show_image_url_redirect_gallery_bank(<?php echo intval($pic["id"]); ?>);"><?php echo $gb_enable; ?>
464
+ </label>
465
+ <label style="margin-left:15px;">
466
+ <input type="radio" <?php echo intval($pic["enable_redirect"]) == 0 ? "checked=\"checked\"" : ""; ?> name="ux_rdl_redirect_<?php echo intval($pic["id"]); ?>" id="ux_rdl_disable_redirect_<?php echo intval($pic["id"]); ?>" value="0" onclick="show_image_url_redirect_gallery_bank(<?php echo intval($pic["id"]); ?>);"><?php echo $gb_disable; ?>
467
+ </label>
468
+ </div>
469
+ </div>
470
+ <div class="form-group" id="ux_div_url_redirect_<?php echo intval($pic["id"]); ?>" style="display: none;">
471
+ <label class="control-label"><?php echo $gb_add_gallery_url_link_title; ?> :
472
+ <i class="icon-custom-question tooltips" data-original-title="<?php echo $gb_add_gallery_url_link_tooltip; ?>" data-placement="right"></i>
473
+ </label>
474
+ <div class="input-icon right">
475
+ <input placeholder="<?php echo $gb_add_gallery_url_link_placeholder; ?>" class="form-control" type="text" name="ux_txt_img_url_<?php echo intval($pic["id"]); ?>" id="ux_txt_img_url_<?php echo intval($pic["id"]); ?>" value="<?php echo esc_attr($pic["redirect_url"]); ?>"/>
476
+ </div>
477
+ </div>
478
+ </td>
479
+ </tr>
480
+ <?php
481
+ }
482
+ }
483
+ ?>
484
+ </tbody>
485
+ </table>
486
  </div>
487
+ <div class="line-separator"></div>
488
+ <div class="form-actions">
489
+ <div class="pull-right">
490
+ <input type="submit" class="btn vivid-green" name="ux_btn_save_changes" id="ux_btn_save_changes" value="<?php echo $gb_save_changes; ?>">
491
+ </div>
492
  </div>
493
+ </div>
494
+ </form>
495
+ </div>
496
+ </div>
497
+ </div>
498
+ </div>
499
+ <?php
500
+ } else {
501
+ ?>
502
+ <div class="page-bar">
503
+ <ul class="page-breadcrumb">
504
+ <li>
505
+ <i class="icon-custom-home"></i>
506
+ <a href="admin.php?page=gallery_bank">
507
+ <?php echo $gallery_bank; ?>
508
+ </a>
509
+ <span>></span>
510
+ </li>
511
+ <li>
512
+ <a href="admin.php?page=gallery_bank">
513
+ <?php echo $gb_galleries; ?>
514
+ </a>
515
+ <span>></span>
516
+ </li>
517
+ <li>
518
+ <span>
519
+ <?php echo isset($_REQUEST["mode"]) && esc_attr($_REQUEST["mode"]) == "edit" ? $gb_update_gallery : $gb_add_gallery; ?>
520
+ </span>
521
+ </li>
522
+ </ul>
523
+ </div>
524
+ <div class="row">
525
+ <div class="col-md-12">
526
+ <div class="portlet box vivid-green">
527
+ <div class="portlet-title">
528
+ <div class="caption">
529
+ <i class="icon icon-custom-plus"></i>
530
+ <?php echo $gb_add_gallery; ?>
531
+ </div>
532
+ </div>
533
+ <div class="portlet-body form">
534
+ <div class="form-body">
535
+ <strong><?php echo $gb_user_access_message; ?></strong>
536
+ </div>
537
+ </div>
538
  </div>
539
+ </div>
540
+ </div>
541
+ <?php
542
+ }
543
  }
views/wizard/wizard.php CHANGED
@@ -96,7 +96,7 @@ if (!is_user_logged_in()) {
96
  </ul>
97
  <div class="tab-content">
98
  <div class="tab-pane active" id="video_tutorials">
99
- <div class="portlet box vivid-green" style="margin-top:5px;">
100
  <div class="portlet-title" onclick="show_hide_text_field_options('ux_div_add_images_gallery');">
101
  <div class="caption">
102
  <i class="icon-custom-plus"></i>
@@ -110,7 +110,7 @@ if (!is_user_logged_in()) {
110
  </div>
111
  </div>
112
  </div>
113
- <div class="portlet box vivid-green" style="margin-top:5px;">
114
  <div class="portlet-title" onclick="show_hide_text_field_options('ux_div_embed_shortcode_gallery');">
115
  <div class="caption">
116
  <i class="icon-custom-plus"></i>
96
  </ul>
97
  <div class="tab-content">
98
  <div class="tab-pane active" id="video_tutorials">
99
+ <div class="portlet box vivid-green" style="margin-top:5px;">
100
  <div class="portlet-title" onclick="show_hide_text_field_options('ux_div_add_images_gallery');">
101
  <div class="caption">
102
  <i class="icon-custom-plus"></i>
110
  </div>
111
  </div>
112
  </div>
113
+ <div class="portlet box vivid-green" style="margin-top:5px;">
114
  <div class="portlet-title" onclick="show_hide_text_field_options('ux_div_embed_shortcode_gallery');">
115
  <div class="caption">
116
  <i class="icon-custom-plus"></i>