slickgrid 2.4.5 → 2.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,12 +24,12 @@
24
24
  var lastPage = pagingInfo.totalPages - 1;
25
25
 
26
26
  return {
27
- canGotoFirst: !cannotLeaveEditMode && pagingInfo.pageSize != 0 && pagingInfo.pageNum > 0,
28
- canGotoLast: !cannotLeaveEditMode && pagingInfo.pageSize != 0 && pagingInfo.pageNum != lastPage,
29
- canGotoPrev: !cannotLeaveEditMode && pagingInfo.pageSize != 0 && pagingInfo.pageNum > 0,
30
- canGotoNext: !cannotLeaveEditMode && pagingInfo.pageSize != 0 && pagingInfo.pageNum < lastPage,
27
+ canGotoFirst: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum > 0,
28
+ canGotoLast: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum !== lastPage,
29
+ canGotoPrev: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum > 0,
30
+ canGotoNext: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum < lastPage,
31
31
  pagingInfo: pagingInfo
32
- }
32
+ };
33
33
  }
34
34
 
35
35
  function setPageSize(n) {
@@ -78,7 +78,7 @@
78
78
 
79
79
  $settings.find("a[data]").click(function (e) {
80
80
  var pagesize = $(e.target).attr("data");
81
- if (pagesize != undefined) {
81
+ if (pagesize !== undefined) {
82
82
  if (pagesize == -1) {
83
83
  var vp = grid.getViewport();
84
84
  setPageSize(vp.bottom - vp.top);
@@ -93,7 +93,7 @@
93
93
 
94
94
  $(icon_prefix + "ui-icon-lightbulb" + icon_suffix)
95
95
  .click(function () {
96
- $(".slick-pager-settings-expanded").toggle()
96
+ $(".slick-pager-settings-expanded").toggle();
97
97
  })
98
98
  .appendTo($settings);
99
99
 
@@ -139,7 +139,7 @@
139
139
  $container.find(".ui-icon-seek-prev").addClass("ui-state-disabled");
140
140
  }
141
141
 
142
- if (pagingInfo.pageSize == 0) {
142
+ if (pagingInfo.pageSize === 0) {
143
143
  $status.text(_options.showAllText.replace('{rowCount}', pagingInfo.totalRows + "").replace('{pageCount}', pagingInfo.totalPages + ""));
144
144
  } else {
145
145
  $status.text(_options.showPageText.replace('{pageNum}', pagingInfo.pageNum + 1 + "").replace('{pageCount}', pagingInfo.totalPages + ""));
@@ -16,7 +16,7 @@
16
16
  "Group": Group,
17
17
  "GroupTotals": GroupTotals,
18
18
  "EditorLock": EditorLock,
19
-
19
+
20
20
  /***
21
21
  * A global singleton editor lock.
22
22
  * @class GlobalEditorLock
@@ -44,10 +44,46 @@
44
44
  UP: 38,
45
45
  A: 65
46
46
  },
47
- "preClickClassName" : "slick-edit-preclick"
47
+ "preClickClassName" : "slick-edit-preclick",
48
+
49
+ "GridAutosizeColsMode": {
50
+ None: 'NOA',
51
+ LegacyOff: 'LOF',
52
+ LegacyForceFit: 'LFF',
53
+ IgnoreViewport: 'IGV',
54
+ FitColsToViewport: 'FCV',
55
+ FitViewportToCols: 'FVC'
56
+ },
57
+
58
+ "ColAutosizeMode": {
59
+ Locked: 'LCK',
60
+ Guide: 'GUI',
61
+ Content: 'CON',
62
+ ContentIntelligent: 'CTI'
63
+ },
64
+
65
+ "RowSelectionMode": {
66
+ FirstRow: 'FS1',
67
+ FirstNRows: 'FSN',
68
+ AllRows: 'ALL',
69
+ LastRow: 'LS1'
70
+ },
71
+
72
+ "ValueFilterMode": {
73
+ None: 'NONE',
74
+ DeDuplicate: 'DEDP',
75
+ GetGreatestAndSub: 'GR8T',
76
+ GetLongestTextAndSub: 'LNSB',
77
+ GetLongestText: 'LNSC'
78
+ },
79
+
80
+ "WidthEvalMode": {
81
+ CanvasTextSize: 'CANV',
82
+ HTML: 'HTML'
83
+ }
48
84
  }
49
85
  });
50
-
86
+
51
87
  /***
52
88
  * An event object for passing data to event handlers and letting them control propagation.
53
89
  * <p>This is pretty much identical to how W3C and jQuery implement events.</p>
@@ -90,7 +126,7 @@
90
126
  */
91
127
  this.isImmediatePropagationStopped = function () {
92
128
  return isImmediatePropagationStopped;
93
- }
129
+ };
94
130
  }
95
131
 
96
132
  /***
@@ -186,7 +222,7 @@
186
222
  handlers = [];
187
223
 
188
224
  return this; // allow chaining
189
- }
225
+ };
190
226
  }
191
227
 
192
228
  /***
@@ -270,7 +306,7 @@
270
306
  else {
271
307
  return "(" + this.fromRow + ":" + this.fromCell + " - " + this.toRow + ":" + this.toCell + ")";
272
308
  }
273
- }
309
+ };
274
310
  }
275
311
 
276
312
 
@@ -660,7 +696,7 @@
660
696
  return ids.map(function (id) {
661
697
  return columnsById[id];
662
698
  });
663
- }
699
+ };
664
700
  }
665
701
  })(jQuery);
666
702
 
@@ -7,7 +7,8 @@
7
7
  Avg: AvgAggregator,
8
8
  Min: MinAggregator,
9
9
  Max: MaxAggregator,
10
- Sum: SumAggregator
10
+ Sum: SumAggregator,
11
+ Count: CountAggregator
11
12
  }
12
13
  }
13
14
  }
@@ -186,7 +187,7 @@
186
187
  sortComparer = null;
187
188
  var oldToString = Object.prototype.toString;
188
189
  Object.prototype.toString = (typeof field == "function") ? field : function () {
189
- return this[field]
190
+ return this[field];
190
191
  };
191
192
  // an extra reversal for descending sort keeps the sort stable
192
193
  // (assuming a stable native sort implementation, which isn't true in some cases)
@@ -708,7 +709,9 @@
708
709
  }
709
710
 
710
711
  function getFunctionInfo(fn) {
711
- var fnRegex = /^function[^(]*\(([^)]*)\)\s*{([\s\S]*)}$/;
712
+ var fnStr = fn.toString();
713
+ var usingEs5 = fnStr.indexOf('function') >= 0; // with ES6, the word function is not present
714
+ var fnRegex = usingEs5 ? /^function[^(]*\(([^)]*)\)\s*{([\s\S]*)}$/ : /^[^(]*\(([^)]*)\)\s*{([\s\S]*)}$/;
712
715
  var matches = fn.toString().match(fnRegex);
713
716
  return {
714
717
  params: matches[1].split(","),
@@ -717,16 +720,23 @@
717
720
  }
718
721
 
719
722
  function compileAccumulatorLoop(aggregator) {
720
- var accumulatorInfo = getFunctionInfo(aggregator.accumulate);
721
- var fn = new Function(
722
- "_items",
723
- "for (var " + accumulatorInfo.params[0] + ", _i=0, _il=_items.length; _i<_il; _i++) {" +
724
- accumulatorInfo.params[0] + " = _items[_i]; " +
725
- accumulatorInfo.body +
726
- "}"
727
- );
728
- fn.displayName = fn.name = "compiledAccumulatorLoop";
729
- return fn;
723
+ if(aggregator.accumulate) {
724
+ var accumulatorInfo = getFunctionInfo(aggregator.accumulate);
725
+ var fn = new Function(
726
+ "_items",
727
+ "for (var " + accumulatorInfo.params[0] + ", _i=0, _il=_items.length; _i<_il; _i++) {" +
728
+ accumulatorInfo.params[0] + " = _items[_i]; " +
729
+ accumulatorInfo.body +
730
+ "}"
731
+ );
732
+ var fnName = "compiledAccumulatorLoop";
733
+ fn.displayName = fnName;
734
+ fn.name = setFunctionName(fn, fnName);
735
+ return fn;
736
+ } else {
737
+ return function noAccumulator() {
738
+ }
739
+ }
730
740
  }
731
741
 
732
742
  function compileFilter() {
@@ -762,7 +772,9 @@
762
772
  tpl = tpl.replace(/\$args\$/gi, filterInfo.params[1]);
763
773
 
764
774
  var fn = new Function("_items,_args", tpl);
765
- fn.displayName = fn.name = "compiledFilter";
775
+ var fnName = "compiledFilter";
776
+ fn.displayName = fnName;
777
+ fn.name = setFunctionName(fn, fnName);
766
778
  return fn;
767
779
  }
768
780
 
@@ -803,10 +815,30 @@
803
815
  tpl = tpl.replace(/\$args\$/gi, filterInfo.params[1]);
804
816
 
805
817
  var fn = new Function("_items,_args,_cache", tpl);
806
- fn.displayName = fn.name = "compiledFilterWithCaching";
818
+ var fnName = "compiledFilterWithCaching";
819
+ fn.displayName = fnName;
820
+ fn.name = setFunctionName(fn, fnName);
807
821
  return fn;
808
822
  }
809
823
 
824
+ /**
825
+ * In ES5 we could set the function name on the fly but in ES6 this is forbidden and we need to set it through differently
826
+ * We can use Object.defineProperty and set it the property to writable, see MDN for reference
827
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
828
+ * @param {string} fn
829
+ * @param {string} fnName
830
+ */
831
+ function setFunctionName(fn, fnName) {
832
+ try {
833
+ Object.defineProperty(fn, 'name', {
834
+ writable: true,
835
+ value: fnName
836
+ });
837
+ } catch(err) {
838
+ fn.name = fnName;
839
+ }
840
+ }
841
+
810
842
  function uncompiledFilter(items, args) {
811
843
  var retval = [], idx = 0;
812
844
 
@@ -873,7 +905,7 @@
873
905
 
874
906
  function getRowDiffs(rows, newRows) {
875
907
  var item, r, eitherIsNonData, diff = [];
876
- var from = 0, to = newRows.length;
908
+ var from = 0, to = Math.max(newRows.length,rows.length);
877
909
 
878
910
  if (refreshHints && refreshHints.ignoreDiffsBefore) {
879
911
  from = Math.max(0,
@@ -892,7 +924,7 @@
892
924
  item = newRows[i];
893
925
  r = rows[i];
894
926
 
895
- if ((groupingInfos.length && (eitherIsNonData = (item.__nonDataRow) || (r.__nonDataRow)) &&
927
+ if (!item || (groupingInfos.length && (eitherIsNonData = (item.__nonDataRow) || (r.__nonDataRow)) &&
896
928
  item.__group !== r.__group ||
897
929
  item.__group && !item.equals(r))
898
930
  || (eitherIsNonData &&
@@ -969,8 +1001,10 @@
969
1001
  onRowsChanged.notify({rows: diff, dataView: self, calledOnRowCountChanged: (countBefore !== rows.length)}, null, self);
970
1002
  }
971
1003
  if (countBefore !== rows.length || diff.length > 0) {
972
- onRowsOrCountChanged.notify({rowsDiff: diff, previousRowCount: countBefore, currentRowCount: rows.length,
973
- rowCountChanged: countBefore !== rows.length, rowsChanged: diff.length > 0, dataView: self}, null, self);
1004
+ onRowsOrCountChanged.notify({
1005
+ rowsDiff: diff, previousRowCount: countBefore, currentRowCount: rows.length,
1006
+ rowCountChanged: countBefore !== rows.length, rowsChanged: diff.length > 0, dataView: self
1007
+ }, null, self);
974
1008
  }
975
1009
  }
976
1010
 
@@ -1167,7 +1201,7 @@
1167
1201
  if (!groupTotals.avg) {
1168
1202
  groupTotals.avg = {};
1169
1203
  }
1170
- if (this.nonNullCount_ != 0) {
1204
+ if (this.nonNullCount_ !== 0) {
1171
1205
  groupTotals.avg[this.field_] = this.sum_ / this.nonNullCount_;
1172
1206
  }
1173
1207
  };
@@ -1194,7 +1228,7 @@
1194
1228
  groupTotals.min = {};
1195
1229
  }
1196
1230
  groupTotals.min[this.field_] = this.min_;
1197
- }
1231
+ };
1198
1232
  }
1199
1233
 
1200
1234
  function MaxAggregator(field) {
@@ -1218,7 +1252,7 @@
1218
1252
  groupTotals.max = {};
1219
1253
  }
1220
1254
  groupTotals.max[this.field_] = this.max_;
1221
- }
1255
+ };
1222
1256
  }
1223
1257
 
1224
1258
  function SumAggregator(field) {
@@ -1240,9 +1274,23 @@
1240
1274
  groupTotals.sum = {};
1241
1275
  }
1242
1276
  groupTotals.sum[this.field_] = this.sum_;
1243
- }
1277
+ };
1244
1278
  }
1245
1279
 
1280
+ function CountAggregator(field) {
1281
+ this.field_ = field;
1282
+
1283
+ this.init = function () {
1284
+ };
1285
+
1286
+ this.storeResult = function (groupTotals) {
1287
+ if (!groupTotals.count) {
1288
+ groupTotals.count = {};
1289
+ }
1290
+ groupTotals.count[this.field_] = groupTotals.group.rows.length;
1291
+ };
1292
+ }
1293
+
1246
1294
  // TODO: add more built-in aggregators
1247
1295
  // TODO: merge common aggregators in one to prevent needles iterating
1248
1296
 
@@ -67,7 +67,7 @@
67
67
  };
68
68
 
69
69
  this.isValueChanged = function () {
70
- return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
70
+ return (!($input.val() === "" && defaultValue == null)) && ($input.val() != defaultValue);
71
71
  };
72
72
 
73
73
  this.validate = function () {
@@ -125,7 +125,7 @@
125
125
  };
126
126
 
127
127
  this.isValueChanged = function () {
128
- return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
128
+ return (!($input.val() === "" && defaultValue == null)) && ($input.val() != defaultValue);
129
129
  };
130
130
 
131
131
  this.validate = function () {
@@ -221,7 +221,7 @@
221
221
  };
222
222
 
223
223
  this.isValueChanged = function () {
224
- return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
224
+ return (!($input.val() === "" && defaultValue == null)) && ($input.val() != defaultValue);
225
225
  };
226
226
 
227
227
  this.validate = function () {
@@ -265,10 +265,10 @@
265
265
  showOn: "button",
266
266
  buttonImageOnly: true,
267
267
  beforeShow: function () {
268
- calendarOpen = true
268
+ calendarOpen = true;
269
269
  },
270
270
  onClose: function () {
271
- calendarOpen = false
271
+ calendarOpen = false;
272
272
  }
273
273
  });
274
274
  $input.width($input.width() - 18);
@@ -322,7 +322,7 @@
322
322
  };
323
323
 
324
324
  this.isValueChanged = function () {
325
- return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
325
+ return (!($input.val() === "" && defaultValue == null)) && ($input.val() != defaultValue);
326
326
  };
327
327
 
328
328
  this.validate = function () {
@@ -464,14 +464,14 @@
464
464
  range: "min",
465
465
  value: defaultValue,
466
466
  slide: function (event, ui) {
467
- $input.val(ui.value)
467
+ $input.val(ui.value);
468
468
  }
469
469
  });
470
470
 
471
471
  $picker.find(".editor-percentcomplete-buttons button").on("click", function (e) {
472
472
  $input.val($(this).attr("val"));
473
473
  $picker.find(".editor-percentcomplete-slider").slider("value", $(this).attr("val"));
474
- })
474
+ });
475
475
  };
476
476
 
477
477
  this.destroy = function () {
@@ -497,7 +497,7 @@
497
497
  };
498
498
 
499
499
  this.isValueChanged = function () {
500
- return (!($input.val() == "" && defaultValue == null)) && ((parseInt($input.val(), 10) || 0) != defaultValue);
500
+ return (!($input.val() === "" && defaultValue == null)) && ((parseInt($input.val(), 10) || 0) != defaultValue);
501
501
  };
502
502
 
503
503
  this.validate = function () {
@@ -594,7 +594,7 @@
594
594
  this.position = function (position) {
595
595
  $wrapper
596
596
  .css("top", position.top - 5)
597
- .css("left", position.left - 5)
597
+ .css("left", position.left - 5);
598
598
  };
599
599
 
600
600
  this.destroy = function () {
@@ -619,7 +619,7 @@
619
619
  };
620
620
 
621
621
  this.isValueChanged = function () {
622
- return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
622
+ return (!($input.val() === "" && defaultValue == null)) && ($input.val() != defaultValue);
623
623
  };
624
624
 
625
625
  this.validate = function () {
@@ -29,6 +29,8 @@ if (typeof Slick === "undefined") {
29
29
 
30
30
 
31
31
  (function ($) {
32
+ "use strict";
33
+
32
34
  // Slick.Grid
33
35
  $.extend(true, window, {
34
36
  Slick: {
@@ -76,6 +78,7 @@ if (typeof Slick === "undefined") {
76
78
  asyncPostRenderCleanupDelay: 40,
77
79
  autoHeight: false,
78
80
  editorLock: Slick.GlobalEditorLock,
81
+ showColumnHeader: true,
79
82
  showHeaderRow: false,
80
83
  headerRowHeight: 25,
81
84
  createFooterRow: false,
@@ -110,7 +113,13 @@ if (typeof Slick === "undefined") {
110
113
  minRowBuffer: 3,
111
114
  emulatePagingWhenScrolling: true, // when scrolling off bottom of viewport, place new row at top of viewport
112
115
  editorCellNavOnLRKeys: false,
113
- doPaging: true
116
+ doPaging: true,
117
+ autosizeColsMode: Slick.GridAutosizeColsMode.LegacyOff,
118
+ autosizeColPaddingPx: 4,
119
+ autosizeTextAvgToMWidthRatio: 0.75,
120
+ viewportSwitchToScrollModeWidthPercent: undefined,
121
+ viewportMinWidthPx: undefined,
122
+ viewportMaxWidthPx: undefined
114
123
  };
115
124
 
116
125
  var columnDefaults = {
@@ -118,11 +127,28 @@ if (typeof Slick === "undefined") {
118
127
  resizable: true,
119
128
  sortable: false,
120
129
  minWidth: 30,
130
+ maxWidth: undefined,
121
131
  rerenderOnResize: false,
122
132
  headerCssClass: null,
123
133
  defaultSortAsc: true,
124
134
  focusable: true,
125
- selectable: true
135
+ selectable: true,
136
+ };
137
+
138
+ var columnAutosizeDefaults = {
139
+ ignoreHeaderText: false,
140
+ colValueArray: undefined,
141
+ allowAddlPercent: undefined,
142
+ formatterOverride: undefined,
143
+ autosizeMode: Slick.ColAutosizeMode.ContentIntelligent,
144
+ rowSelectionModeOnInit: undefined,
145
+ rowSelectionMode: Slick.RowSelectionMode.FirstNRows,
146
+ rowSelectionCount: 100,
147
+ valueFilterMode: Slick.ValueFilterMode.None,
148
+ widthEvalMode: Slick.WidthEvalMode.CanvasTextSize,
149
+ sizeToRemaining: undefined,
150
+ widthPx: undefined,
151
+ colDataTypeOf: undefined
126
152
  };
127
153
 
128
154
  // scroller
@@ -148,6 +174,7 @@ if (typeof Slick === "undefined") {
148
174
  var $headerRow, $headerRowScroller, $headerRowSpacerL, $headerRowSpacerR;
149
175
  var $footerRow, $footerRowScroller, $footerRowSpacerL, $footerRowSpacerR;
150
176
  var $preHeaderPanel, $preHeaderPanelScroller, $preHeaderPanelSpacer;
177
+ var $preHeaderPanelR, $preHeaderPanelScrollerR, $preHeaderPanelSpacerR;
151
178
  var $topPanelScroller;
152
179
  var $topPanel;
153
180
  var $viewport;
@@ -314,7 +341,7 @@ if (typeof Slick === "undefined") {
314
341
  columns = treeColumns.extractColumns();
315
342
 
316
343
  updateColumnProps();
317
-
344
+
318
345
  // validate loaded JavaScript modules against requested options
319
346
  if (options.enableColumnReorder && !$.fn.sortable) {
320
347
  throw new Error("SlickGrid's 'enableColumnReorder = true' option requires jquery-ui.sortable module to be loaded");
@@ -333,7 +360,7 @@ if (typeof Slick === "undefined") {
333
360
  .addClass("ui-widget");
334
361
 
335
362
  // set up a positioning container if needed
336
- if (!/relative|absolute|fixed/.test($container.css("position"))) {
363
+ if (!(/relative|absolute|fixed/).test($container.css("position"))) {
337
364
  $container.css("position", "relative");
338
365
  }
339
366
 
@@ -353,8 +380,14 @@ if (typeof Slick === "undefined") {
353
380
  $preHeaderPanelSpacer = $("<div style='display:block;height:1px;position:absolute;top:0;left:0;'></div>")
354
381
  .appendTo($preHeaderPanelScroller);
355
382
 
383
+ $preHeaderPanelScrollerR = $("<div class='slick-preheader-panel ui-state-default' style='overflow:hidden;position:relative;' />").appendTo($paneHeaderR);
384
+ $preHeaderPanelR = $("<div />").appendTo($preHeaderPanelScrollerR);
385
+ $preHeaderPanelSpacerR = $("<div style='display:block;height:1px;position:absolute;top:0;left:0;'></div>")
386
+ .appendTo($preHeaderPanelScrollerR);
387
+
356
388
  if (!options.showPreHeaderPanel) {
357
389
  $preHeaderPanelScroller.hide();
390
+ $preHeaderPanelScrollerR.hide();
358
391
  }
359
392
  }
360
393
 
@@ -366,7 +399,8 @@ if (typeof Slick === "undefined") {
366
399
  $headerScroller = $().add($headerScrollerL).add($headerScrollerR);
367
400
 
368
401
  if (treeColumns.hasDepth()) {
369
- $groupHeadersL = [], $groupHeadersR = [];
402
+ $groupHeadersL = [];
403
+ $groupHeadersR = [];
370
404
  for (var index = 0; index < treeColumns.getDepth() - 1; index++) {
371
405
  $groupHeadersL[index] = $("<div class='slick-group-header-columns slick-group-header-columns-left' style='left:-1000px' />").appendTo($headerScrollerL);
372
406
  $groupHeadersR[index] = $("<div class='slick-group-header-columns slick-group-header-columns-right' style='left:-1000px' />").appendTo($headerScrollerR);
@@ -410,6 +444,10 @@ if (typeof Slick === "undefined") {
410
444
 
411
445
  $topPanel = $().add($topPanelL).add($topPanelR);
412
446
 
447
+ if (!options.showColumnHeader) {
448
+ $headerScroller.hide();
449
+ }
450
+
413
451
  if (!options.showTopPanel) {
414
452
  $topPanelScroller.hide();
415
453
  }
@@ -543,6 +581,10 @@ if (typeof Slick === "undefined") {
543
581
  .on("scroll", handleHeaderRowScroll);
544
582
 
545
583
  if (options.createFooterRow) {
584
+ $footerRow
585
+ .on("contextmenu", handleFooterContextMenu)
586
+ .on("click", handleFooterClick);
587
+
546
588
  $footerRowScroller
547
589
  .on("scroll", handleFooterRowScroll);
548
590
  }
@@ -616,7 +658,7 @@ if (typeof Slick === "undefined") {
616
658
  }
617
659
 
618
660
  function getPluginByName(name) {
619
- for (var i = plugins.length; i >= 0; i--) {
661
+ for (var i = plugins.length-1; i >= 0; i--) {
620
662
  if (plugins[i].pluginName === name) {
621
663
  return plugins[i];
622
664
  }
@@ -646,10 +688,10 @@ if (typeof Slick === "undefined") {
646
688
  function getCanvasNode(columnIdOrIdx, rowIndex) {
647
689
  if (!columnIdOrIdx) { columnIdOrIdx = 0; }
648
690
  if (!rowIndex) { rowIndex = 0; }
649
-
691
+
650
692
  var idx = (typeof columnIdOrIdx === "number" ? columnIdOrIdx : getColumnIndex(columnIdOrIdx));
651
-
652
- return (hasFrozenRows && rowIndex >= actualFrozenRow + (options.frozenBottom ? 0 : 1) )
693
+
694
+ return (hasFrozenRows && rowIndex >= actualFrozenRow + (options.frozenBottom ? 0 : 1) )
653
695
  ? ((hasFrozenColumns() && idx > options.frozenColumn) ? $canvasBottomR[0] : $canvasBottomL[0])
654
696
  : ((hasFrozenColumns() && idx > options.frozenColumn) ? $canvasTopR[0] : $canvasTopL[0])
655
697
  ;
@@ -1013,6 +1055,10 @@ if (typeof Slick === "undefined") {
1013
1055
  return $preHeaderPanel[0];
1014
1056
  }
1015
1057
 
1058
+ function getPreHeaderPanelRight() {
1059
+ return $preHeaderPanelR[0];
1060
+ }
1061
+
1016
1062
  function getHeaderRowColumn(columnIdOrIdx) {
1017
1063
  var idx = (typeof columnIdOrIdx === "number" ? columnIdOrIdx : getColumnIndex(columnIdOrIdx));
1018
1064
 
@@ -1050,7 +1096,7 @@ if (typeof Slick === "undefined") {
1050
1096
  $footerRowTarget = $footerRowL;
1051
1097
  }
1052
1098
 
1053
- var $footer = $footerRowTarget.children().eq(idx);
1099
+ var $footer = $footerRowTarget && $footerRowTarget.children().eq(idx);
1054
1100
  return $footer && $footer[0];
1055
1101
  }
1056
1102
 
@@ -1107,7 +1153,7 @@ if (typeof Slick === "undefined") {
1107
1153
 
1108
1154
  columnsLength += m.extractColumns().length;
1109
1155
 
1110
- if (hasFrozenColumns() && index == 0 && (columnsLength-1) === options.frozenColumn)
1156
+ if (hasFrozenColumns() && index === 0 && (columnsLength-1) === options.frozenColumn)
1111
1157
  frozenColumnsValid = true;
1112
1158
 
1113
1159
  $("<div class='ui-state-default slick-group-header-column' />")
@@ -1120,7 +1166,7 @@ if (typeof Slick === "undefined") {
1120
1166
  .appendTo(hasFrozenColumns() && (columnsLength - 1) > options.frozenColumn? $groupHeadersR[index]: $groupHeadersL[index]);
1121
1167
  }
1122
1168
 
1123
- if (hasFrozenColumns() && index == 0 && !frozenColumnsValid) {
1169
+ if (hasFrozenColumns() && index === 0 && !frozenColumnsValid) {
1124
1170
  $groupHeadersL[index].empty();
1125
1171
  $groupHeadersR[index].empty();
1126
1172
  alert("All columns of group should to be grouped!");
@@ -1227,6 +1273,14 @@ if (typeof Slick === "undefined") {
1227
1273
  .on('mouseleave', onMouseLeave);
1228
1274
  }
1229
1275
 
1276
+ if(m.hasOwnProperty('headerCellAttrs') && m.headerCellAttrs instanceof Object) {
1277
+ for (var key in m.headerCellAttrs) {
1278
+ if (m.headerCellAttrs.hasOwnProperty(key)) {
1279
+ header.attr(key, m.headerCellAttrs[key]);
1280
+ }
1281
+ }
1282
+ }
1283
+
1230
1284
  if (m.sortable) {
1231
1285
  header.addClass("slick-header-sortable");
1232
1286
  header.append("<span class='slick-sort-indicator"
@@ -1336,7 +1390,7 @@ if (typeof Slick === "undefined") {
1336
1390
  if (!sortColumn) {
1337
1391
  sortColumn = { columnId: column.id, sortAsc: column.defaultSortAsc };
1338
1392
  sortColumns.push(sortColumn);
1339
- } else if (sortColumns.length == 0) {
1393
+ } else if (sortColumns.length === 0) {
1340
1394
  sortColumns.push(sortColumn);
1341
1395
  }
1342
1396
  }
@@ -1403,7 +1457,7 @@ if (typeof Slick === "undefined") {
1403
1457
  start: startLimit,
1404
1458
  end: endLimit,
1405
1459
  group: groupColumnOfPreviousPosition
1406
- }
1460
+ };
1407
1461
  }
1408
1462
 
1409
1463
  function remove(arr, elem) {
@@ -1512,7 +1566,7 @@ if (typeof Slick === "undefined") {
1512
1566
  function getImpactedColumns( limit ) {
1513
1567
  var impactedColumns = [];
1514
1568
 
1515
- if( limit != undefined ) {
1569
+ if( limit ) {
1516
1570
 
1517
1571
  for( var i = limit.start; i <= limit.end; i++ ) {
1518
1572
  impactedColumns.push( columns[i] );
@@ -1613,11 +1667,11 @@ if (typeof Slick === "undefined") {
1613
1667
  .on("drag", function (e, dd) {
1614
1668
  columnResizeDragging = true;
1615
1669
  var actualMinWidth, d = Math.min(maxPageX, Math.max(minPageX, e.pageX)) - pageX, x;
1670
+ var newCanvasWidthL = 0, newCanvasWidthR = 0;
1671
+
1616
1672
  if (d < 0) { // shrink column
1617
1673
  x = d;
1618
1674
 
1619
- var newCanvasWidthL = 0, newCanvasWidthR = 0;
1620
-
1621
1675
  for (j = i; j >= 0; j--) {
1622
1676
  c = columns[j];
1623
1677
  if (c.resizable) {
@@ -1692,7 +1746,8 @@ if (typeof Slick === "undefined") {
1692
1746
  } else { // stretch column
1693
1747
  x = d;
1694
1748
 
1695
- var newCanvasWidthL = 0, newCanvasWidthR = 0;
1749
+ newCanvasWidthL = 0;
1750
+ newCanvasWidthR = 0;
1696
1751
 
1697
1752
  for (j = i; j >= 0; j--) {
1698
1753
  c = columns[j];
@@ -1775,7 +1830,7 @@ if (typeof Slick === "undefined") {
1775
1830
  }
1776
1831
  updateCanvasWidth(true);
1777
1832
  render();
1778
- trigger(self.onColumnsResized, {});
1833
+ trigger(self.onColumnsResized, {triggeredByColumn: $(this).parent().attr("id").replace(uid, "")});
1779
1834
  setTimeout(function () { columnResizeDragging = false; }, 300);
1780
1835
  });
1781
1836
  });
@@ -2027,30 +2082,382 @@ if (typeof Slick === "undefined") {
2027
2082
  $container.empty().removeClass(uid);
2028
2083
  }
2029
2084
 
2030
-
2031
2085
  //////////////////////////////////////////////////////////////////////////////////////////////
2032
- // General
2086
+ // Column Autosizing
2087
+ //////////////////////////////////////////////////////////////////////////////////////////////
2033
2088
 
2034
- function trigger(evt, args, e) {
2035
- e = e || new Slick.EventData();
2036
- args = args || {};
2037
- args.grid = self;
2038
- return evt.notify(args, e, self);
2089
+ var canvas = null;
2090
+ var canvas_context = null;
2091
+
2092
+ function autosizeColumn(columnOrIndexOrId, isInit) {
2093
+ var c = columnOrIndexOrId;
2094
+ if (typeof columnOrIndexOrId === 'number') {
2095
+ c = columns[columnOrIndexOrId];
2096
+ }
2097
+ else if (typeof columnOrIndexOrId === 'string') {
2098
+ for (i = 0; i < columns.length; i++) {
2099
+ if (columns[i].Id === columnOrIndexOrId) { c = columns[i]; }
2100
+ }
2101
+ }
2102
+ var $gridCanvas = $(getCanvasNode(0, 0));
2103
+ getColAutosizeWidth(c, $gridCanvas, isInit);
2039
2104
  }
2105
+
2106
+ function autosizeColumns(autosizeMode, isInit) {
2107
+ //LogColWidths();
2040
2108
 
2041
- function getEditorLock() {
2042
- return options.editorLock;
2109
+ autosizeMode = autosizeMode || options.autosizeColsMode;
2110
+ if (autosizeMode === Slick.GridAutosizeColsMode.LegacyForceFit
2111
+ || autosizeMode === Slick.GridAutosizeColsMode.LegacyOff) {
2112
+ legacyAutosizeColumns();
2113
+ return;
2114
+ }
2115
+
2116
+ if (autosizeMode === Slick.GridAutosizeColsMode.None) {
2117
+ return;
2118
+ }
2119
+
2120
+ // test for brower canvas support, canvas_context!=null if supported
2121
+ canvas = document.createElement("canvas");
2122
+ if (canvas && canvas.getContext) { canvas_context = canvas.getContext("2d"); }
2123
+
2124
+ // pass in the grid canvas
2125
+ var $gridCanvas = $(getCanvasNode(0, 0));
2126
+ var viewportWidth = viewportHasVScroll ? viewportW - scrollbarDimensions.width : viewportW;
2127
+
2128
+ // iterate columns to get autosizes
2129
+ var i, c, colWidth, reRender, totalWidth = 0, totalWidthLessSTR = 0, strColsMinWidth = 0, totalMinWidth = 0, totalLockedColWidth = 0;
2130
+ for (i = 0; i < columns.length; i++) {
2131
+ c = columns[i];
2132
+ getColAutosizeWidth(c, $gridCanvas, isInit);
2133
+ totalLockedColWidth += (c.autoSize.autosizeMode === Slick.ColAutosizeMode.Locked ? c.width : 0);
2134
+ totalMinWidth += (c.autoSize.autosizeMode === Slick.ColAutosizeMode.Locked ? c.width : c.minWidth);
2135
+ totalWidth += c.autoSize.widthPx;
2136
+ totalWidthLessSTR += (c.autoSize.sizeToRemaining ? 0 : c.autoSize.widthPx);
2137
+ strColsMinWidth += (c.autoSize.sizeToRemaining ? c.minWidth || 0 : 0);
2138
+ }
2139
+ var strColTotalGuideWidth = totalWidth - totalWidthLessSTR;
2140
+
2141
+ if (autosizeMode === Slick.GridAutosizeColsMode.FitViewportToCols) {
2142
+ // - if viewport with is outside MinViewportWidthPx and MaxViewportWidthPx, then the viewport is set to
2143
+ // MinViewportWidthPx or MaxViewportWidthPx and the FitColsToViewport algorithm is used
2144
+ // - viewport is resized to fit columns
2145
+ var setWidth = totalWidth + scrollbarDimensions.width;
2146
+ autosizeMode = Slick.GridAutosizeColsMode.IgnoreViewport;
2147
+
2148
+ if (options.viewportMaxWidthPx && setWidth > options.viewportMaxWidthPx) {
2149
+ setWidth = options.viewportMaxWidthPx;
2150
+ autosizeMode = Slick.GridAutosizeColsMode.FitColsToViewport;
2151
+ } else if (options.viewportMinWidthPx && setWidth < options.viewportMinWidthPx) {
2152
+ setWidth = options.viewportMinWidthPx;
2153
+ autosizeMode = Slick.GridAutosizeColsMode.FitColsToViewport;
2154
+ } else {
2155
+ // falling back to IgnoreViewport will size the columns as-is, with render checking
2156
+ //for (i = 0; i < columns.length; i++) { columns[i].width = columns[i].autoSize.widthPx; }
2157
+ }
2158
+ $container.width(setWidth);
2159
+ }
2160
+
2161
+ if (autosizeMode === Slick.GridAutosizeColsMode.FitColsToViewport) {
2162
+ if (strColTotalGuideWidth > 0 && totalWidthLessSTR < viewportWidth - strColsMinWidth) {
2163
+ // if addl space remains in the viewport and there are SizeToRemaining cols, just the SizeToRemaining cols expand proportionally to fill viewport
2164
+ for (i = 0; i < columns.length; i++) {
2165
+ c = columns[i];
2166
+ var totalSTRViewportWidth = viewportWidth - totalWidthLessSTR;
2167
+ if (c.autoSize.sizeToRemaining) {
2168
+ colWidth = totalSTRViewportWidth * c.autoSize.widthPx / strColTotalGuideWidth;
2169
+ } else {
2170
+ colWidth = c.autoSize.widthPx;
2171
+ }
2172
+ if (c.rerenderOnResize && c.width != colWidth) { reRender = true; }
2173
+ c.width = colWidth;
2174
+ }
2175
+ } else if ((options.viewportSwitchToScrollModeWidthPercent && totalWidthLessSTR + strColsMinWidth > viewportWidth * options.viewportSwitchToScrollModeWidthPercent / 100)
2176
+ || (totalMinWidth > viewportWidth)) {
2177
+ // if the total columns width is wider than the viewport by switchToScrollModeWidthPercent, switch to IgnoreViewport mode
2178
+ autosizeMode = Slick.GridAutosizeColsMode.IgnoreViewport;
2179
+ } else {
2180
+ // otherwise (ie. no SizeToRemaining cols or viewport smaller than columns) all cols other than 'Locked' scale in proportion to fill viewport
2181
+ // and SizeToRemaining get minWidth
2182
+ var unallocatedColWidth = totalWidthLessSTR - totalLockedColWidth;
2183
+ var unallocatedViewportWidth = viewportWidth - totalLockedColWidth - strColsMinWidth;
2184
+ for (i = 0; i < columns.length; i++) {
2185
+ c = columns[i];
2186
+ colWidth = c.width;
2187
+ if (c.autoSize.autosizeMode !== Slick.ColAutosizeMode.Locked) {
2188
+ if (c.autoSize.sizeToRemaining) {
2189
+ colWidth = c.minWidth;
2190
+ } else {
2191
+ // size width proportionally to free space (we know we have enough room due to the earlier calculations)
2192
+ colWidth = unallocatedViewportWidth / unallocatedColWidth * c.autoSize.widthPx;
2193
+ if (colWidth < c.minWidth) { colWidth = c.minWidth; }
2194
+
2195
+ // remove the just allocated widths from the allocation pool
2196
+ unallocatedColWidth -= c.autoSize.widthPx;
2197
+ unallocatedViewportWidth -= colWidth;
2198
+ }
2199
+ }
2200
+ if (c.rerenderOnResize && c.width != colWidth) { reRender = true; }
2201
+ c.width = colWidth;
2202
+ }
2203
+ }
2204
+ }
2205
+
2206
+ if (autosizeMode === Slick.GridAutosizeColsMode.IgnoreViewport) {
2207
+ // just size columns as-is
2208
+ for (i = 0; i < columns.length; i++) {
2209
+ colWidth = columns[i].autoSize.widthPx;
2210
+ if (columns[i].rerenderOnResize && columns[i].width != colWidth) {
2211
+ reRender = true;
2212
+ }
2213
+ columns[i].width = colWidth;
2214
+ }
2215
+ }
2216
+
2217
+ //LogColWidths();
2218
+ reRenderColumns(reRender);
2043
2219
  }
2044
2220
 
2045
- function getEditController() {
2046
- return editController;
2221
+ function LogColWidths () {
2222
+ var s = "Col Widths:";
2223
+ for (i = 0; i < columns.length; i++) { s += ' ' + columns[i].width; }
2224
+ console.log(s);
2047
2225
  }
2048
2226
 
2049
- function getColumnIndex(id) {
2050
- return columnsById[id];
2227
+ function getColAutosizeWidth(columnDef, $gridCanvas, isInit) {
2228
+ var autoSize = columnDef.autoSize;
2229
+
2230
+ // set to width as default
2231
+ autoSize.widthPx = columnDef.width;
2232
+ if (autoSize.autosizeMode === Slick.ColAutosizeMode.Locked
2233
+ || autoSize.autosizeMode === Slick.ColAutosizeMode.Guide) {
2234
+ return;
2235
+ }
2236
+
2237
+ var dl = getDataLength(); //getDataItem();
2238
+
2239
+ // ContentIntelligent takes settings from column data type
2240
+ if (autoSize.autosizeMode === Slick.ColAutosizeMode.ContentIntelligent) {
2241
+ // default to column colDataTypeOf (can be used if initially there are no data rows)
2242
+ var colDataTypeOf = autoSize.colDataTypeOf;
2243
+ var colDataItem;
2244
+ if (dl > 0) {
2245
+ var tempRow = getDataItem(0);
2246
+ if (tempRow) {
2247
+ colDataItem = tempRow[columnDef.field];
2248
+ colDataTypeOf = typeof colDataItem;
2249
+ if (colDataTypeOf === 'object') {
2250
+ if (colDataItem instanceof Date) { colDataTypeOf = "date"; }
2251
+ if (typeof moment!=='undefined' && colDataItem instanceof moment) { colDataTypeOf = "moment"; }
2252
+ }
2253
+ }
2254
+ }
2255
+ if (colDataTypeOf === 'boolean') {
2256
+ autoSize.colValueArray = [ true, false ];
2257
+ }
2258
+ if (colDataTypeOf === 'number') {
2259
+ autoSize.valueFilterMode = Slick.ValueFilterMode.GetGreatestAndSub;
2260
+ autoSize.rowSelectionMode = Slick.RowSelectionMode.AllRows;
2261
+ }
2262
+ if (colDataTypeOf === 'string') {
2263
+ autoSize.valueFilterMode = Slick.ValueFilterMode.GetLongestText;
2264
+ autoSize.rowSelectionMode = Slick.RowSelectionMode.AllRows;
2265
+ autoSize.allowAddlPercent = 5;
2266
+ }
2267
+ if (colDataTypeOf === 'date') {
2268
+ autoSize.colValueArray = [ new Date(2009, 8, 30, 12, 20, 20) ]; // Sep 30th 2009, 12:20:20 AM
2269
+ }
2270
+ if (colDataTypeOf === 'moment' && typeof moment!=='undefined') {
2271
+ autoSize.colValueArray = [ moment([2009, 8, 30, 12, 20, 20]) ]; // Sep 30th 2009, 12:20:20 AM
2272
+ }
2273
+ }
2274
+
2275
+ // at this point, the autosizeMode is effectively 'Content', so proceed to get size
2276
+ var colWidth = getColContentSize(columnDef, $gridCanvas, isInit);
2277
+
2278
+ var addlPercentMultiplier = (autoSize.allowAddlPercent ? (1 + autoSize.allowAddlPercent/100) : 1);
2279
+ colWidth = colWidth * addlPercentMultiplier + options.autosizeColPaddingPx;
2280
+ if (columnDef.minWidth && colWidth < columnDef.minWidth) { colWidth = columnDef.minWidth; }
2281
+ if (columnDef.maxWidth && colWidth > columnDef.maxWidth) { colWidth = columnDef.maxWidth; }
2282
+
2283
+ autoSize.widthPx = colWidth;
2051
2284
  }
2052
2285
 
2053
- function autosizeColumns() {
2286
+ function getColContentSize(columnDef, $gridCanvas, isInit) {
2287
+ var autoSize = columnDef.autoSize;
2288
+ var widthAdjustRatio = 1;
2289
+
2290
+ // at this point, the autosizeMode is effectively 'Content', so proceed to get size
2291
+
2292
+ // get header width, if we are taking notice of it
2293
+ var i, ii;
2294
+ var maxColWidth = 0;
2295
+ var headerWidth = 0;
2296
+ if (!autoSize.ignoreHeaderText) {
2297
+ headerWidth = getColHeaderWidth(columnDef);
2298
+ }
2299
+
2300
+ if (autoSize.colValueArray) {
2301
+ // if an array of values are specified, just pass them in instead of data
2302
+ maxColWidth = getColWidth(columnDef, $gridCanvas, autoSize.colValueArray);
2303
+ return Math.max(headerWidth, maxColWidth);
2304
+ }
2305
+
2306
+ // select rows to evaluate using rowSelectionMode and rowSelectionCount
2307
+ var rows = getData();
2308
+ if (rows.getItems) { rows = rows.getItems(); }
2309
+
2310
+ var rowSelectionMode = (isInit ? autoSize.rowSelectionModeOnInit : undefined) || autoSize.rowSelectionMode;
2311
+
2312
+ if (rowSelectionMode === Slick.RowSelectionMode.FirstRow) { rows = rows.slice(0,1); }
2313
+ if (rowSelectionMode === Slick.RowSelectionMode.LastRow) { rows = rows.slice(rows.length -1, rows.length); }
2314
+ if (rowSelectionMode === Slick.RowSelectionMode.FirstNRows) { rows = rows.slice(0, autoSize.rowSelectionCount); }
2315
+
2316
+ // now use valueFilterMode to further filter selected rows
2317
+ if (autoSize.valueFilterMode === Slick.ValueFilterMode.DeDuplicate) {
2318
+ var rowsDict = {};
2319
+ for (i = 0, ii = rows.length; i < ii; i++) {
2320
+ rowsDict[rows[i][columnDef.field]] = true;
2321
+ }
2322
+ if (Object.keys) {
2323
+ rows = Object.keys(rowsDict);
2324
+ } else {
2325
+ rows = [];
2326
+ for (var i in rowsDict) rows.push(i);
2327
+ }
2328
+ }
2329
+
2330
+ if (autoSize.valueFilterMode === Slick.ValueFilterMode.GetGreatestAndSub) {
2331
+ // get greatest abs value in data
2332
+ var tempVal, maxVal, maxAbsVal = 0;
2333
+ for (i = 0, ii = rows.length; i < ii; i++) {
2334
+ tempVal = rows[i][columnDef.field];
2335
+ if (Math.abs(tempVal) > maxAbsVal) { maxVal = tempVal; maxAbsVal = Math.abs(tempVal); }
2336
+ }
2337
+ // now substitute a '9' for all characters (to get widest width) and convert back to a number
2338
+ maxVal = '' + maxVal;
2339
+ maxVal = Array(maxVal.length + 1).join("9");
2340
+ maxVal = +maxVal;
2341
+
2342
+ rows = [ maxVal ];
2343
+ }
2344
+
2345
+ if (autoSize.valueFilterMode === Slick.ValueFilterMode.GetLongestTextAndSub) {
2346
+ // get greatest abs value in data
2347
+ var tempVal, maxLen = 0, maxIndex;
2348
+ for (i = 0, ii = rows.length; i < ii; i++) {
2349
+ tempVal = rows[i][columnDef.field];
2350
+ if ((tempVal || '').length > maxLen) { maxLen = tempVal.length; maxIndex = i; }
2351
+ }
2352
+ // now substitute a 'c' for all characters
2353
+ tempVal = Array(maxLen + 1).join("m");
2354
+ widthAdjustRatio = options.autosizeTextAvgToMWidthRatio;
2355
+
2356
+ rows = [ tempVal ];
2357
+ }
2358
+
2359
+ if (autoSize.valueFilterMode === Slick.ValueFilterMode.GetLongestText) {
2360
+ // get greatest abs value in data
2361
+ var tempVal, maxLen = 0, maxIndex;
2362
+ for (i = 0, ii = rows.length; i < ii; i++) {
2363
+ tempVal = rows[i][columnDef.field];
2364
+ if ((tempVal || '').length > maxLen) { maxLen = tempVal.length; maxIndex = i; }
2365
+ }
2366
+ // now substitute a 'c' for all characters
2367
+ tempVal = rows[maxIndex][columnDef.field];
2368
+ rows = [ tempVal ];
2369
+ }
2370
+
2371
+ maxColWidth = getColWidth(columnDef, $gridCanvas, rows) * widthAdjustRatio;
2372
+ return Math.max(headerWidth, maxColWidth);
2373
+ }
2374
+
2375
+ function getColWidth(columnDef, $gridCanvas, data) {
2376
+ var colIndex = getColumnIndex(columnDef.id);
2377
+
2378
+ var $rowEl = $('<div class="slick-row ui-widget-content"></div>');
2379
+ var $cellEl = $('<div class="slick-cell"></div>');
2380
+ $cellEl.css({
2381
+ "position": "absolute",
2382
+ "visibility": "hidden",
2383
+ "text-overflow": "initial",
2384
+ "white-space": "nowrap"
2385
+ });
2386
+ $rowEl.append($cellEl);
2387
+
2388
+ $gridCanvas.append($rowEl);
2389
+
2390
+ var len, max = 0, text, maxText, formatterResult, maxWidth = 0, val;
2391
+
2392
+ // use canvas - very fast, but text-only
2393
+ if (canvas_context && columnDef.autoSize.widthEvalMode === Slick.WidthEvalMode.CanvasTextSize) {
2394
+ canvas_context.font = $cellEl.css("font-size") + " " + $cellEl.css("font-family");
2395
+ $(data).each(function (index, row) {
2396
+ // row is either an array or values or a single value
2397
+ val = (Array.isArray(row) ? row[columnDef.field] : row);
2398
+ text = '' + val;
2399
+ len = text ? canvas_context.measureText(text).width : 0;
2400
+ if (len > max) { max = len; maxText = text; }
2401
+ });
2402
+
2403
+ $cellEl.html(maxText);
2404
+ len = $cellEl.outerWidth();
2405
+
2406
+ $rowEl.remove();
2407
+ return len;
2408
+ }
2409
+
2410
+ $(data).each(function (index, row) {
2411
+ val = (Array.isArray(row) ? row[columnDef.field] : row);
2412
+ if (columnDef.formatterOverride) {
2413
+ // use formatterOverride as first preference
2414
+ formatterResult = columnDef.formatterOverride(index, colIndex, val, columnDef, row);
2415
+ } else if (columnDef.formatter) {
2416
+ // otherwise, use formatter
2417
+ formatterResult = columnDef.formatter(index, colIndex, val, columnDef, row);
2418
+ } else {
2419
+ // otherwise, use plain text
2420
+ formatterResult = '' + val;
2421
+ }
2422
+ applyFormatResultToCellNode(formatterResult, $cellEl[0]);
2423
+ len = $cellEl.outerWidth();
2424
+ if (len > max) { max = len; }
2425
+ });
2426
+
2427
+ $rowEl.remove();
2428
+ return max;
2429
+ }
2430
+
2431
+ function getColHeaderWidth(columnDef) {
2432
+ var width = 0;
2433
+ //if (columnDef && (!columnDef.resizable || columnDef._autoCalcWidth === true)) return;
2434
+ var headerColElId = getUID() + columnDef.id;
2435
+ var headerColEl = document.getElementById(headerColElId);
2436
+ var dummyHeaderColElId = headerColElId + "_";
2437
+ if (headerColEl) {
2438
+ // headers have been created, use clone technique
2439
+ var clone = headerColEl.cloneNode(true);
2440
+ clone.id = dummyHeaderColElId;
2441
+ clone.style.cssText = 'position: absolute; visibility: hidden;right: auto;text-overflow: initial;white-space: nowrap;';
2442
+ headerColEl.parentNode.insertBefore(clone, headerColEl);
2443
+ width = clone.offsetWidth;
2444
+ clone.parentNode.removeChild(clone);
2445
+ } else {
2446
+ // headers have not yet been created, create a new node
2447
+ var header = getHeader(columnDef);
2448
+ headerColEl = $("<div class='ui-state-default slick-header-column' />")
2449
+ .html("<span class='slick-column-name'>" + columnDef.name + "</span>")
2450
+ .attr("id", dummyHeaderColElId)
2451
+ .css({ "position": "absolute", "visibility": "hidden", "right": "auto", "text-overflow:": "initial", "white-space": "nowrap" })
2452
+ .addClass(columnDef.headerCssClass || "")
2453
+ .appendTo(header);
2454
+ width = headerColEl[0].offsetWidth;
2455
+ header[0].removeChild(headerColEl[0]);
2456
+ }
2457
+ return width;
2458
+ }
2459
+
2460
+ function legacyAutosizeColumns() {
2054
2461
  var i, c,
2055
2462
  widths = [],
2056
2463
  shrinkLeeway = 0,
@@ -2120,7 +2527,11 @@ if (typeof Slick === "undefined") {
2120
2527
  }
2121
2528
  columns[i].width = widths[i];
2122
2529
  }
2530
+
2531
+ reRenderColumns(reRender);
2532
+ }
2123
2533
 
2534
+ function reRenderColumns(reRender) {
2124
2535
  applyColumnHeaderWidths();
2125
2536
  applyColumnGroupHeaderWidths();
2126
2537
  updateCanvasWidth(true);
@@ -2133,6 +2544,29 @@ if (typeof Slick === "undefined") {
2133
2544
  }
2134
2545
  }
2135
2546
 
2547
+ //////////////////////////////////////////////////////////////////////////////////////////////
2548
+ // General
2549
+ //////////////////////////////////////////////////////////////////////////////////////////////
2550
+
2551
+ function trigger(evt, args, e) {
2552
+ e = e || new Slick.EventData();
2553
+ args = args || {};
2554
+ args.grid = self;
2555
+ return evt.notify(args, e, self);
2556
+ }
2557
+
2558
+ function getEditorLock() {
2559
+ return options.editorLock;
2560
+ }
2561
+
2562
+ function getEditController() {
2563
+ return editController;
2564
+ }
2565
+
2566
+ function getColumnIndex(id) {
2567
+ return columnsById[id];
2568
+ }
2569
+
2136
2570
  function applyColumnGroupHeaderWidths() {
2137
2571
  if (!treeColumns.hasDepth())
2138
2572
  return;
@@ -2145,7 +2579,7 @@ if (typeof Slick === "undefined") {
2145
2579
  var $groupHeader = $(this),
2146
2580
  currentColumnIndex = 0;
2147
2581
 
2148
- $groupHeader.width(i == 0? getHeadersWidthL(): getHeadersWidthR());
2582
+ $groupHeader.width(i === 0? getHeadersWidthL(): getHeadersWidthR());
2149
2583
 
2150
2584
  $groupHeader.children().each(function() {
2151
2585
  var $groupHeaderColumn = $(this);
@@ -2157,13 +2591,13 @@ if (typeof Slick === "undefined") {
2157
2591
  m.columns.forEach(function() {
2158
2592
  var $headerColumn = $groupHeader.next().children(':eq(' + (currentColumnIndex++) + ')');
2159
2593
  m.width += $headerColumn.outerWidth();
2160
- })
2594
+ });
2161
2595
 
2162
2596
  $groupHeaderColumn.width(m.width - headerColumnWidthDiff);
2163
2597
 
2164
2598
  });
2165
2599
 
2166
- })
2600
+ });
2167
2601
 
2168
2602
  }
2169
2603
  }
@@ -2301,8 +2735,10 @@ if (typeof Slick === "undefined") {
2301
2735
  columnsById = {};
2302
2736
  for (var i = 0; i < columns.length; i++) {
2303
2737
  if (columns[i].width) { columns[i].widthRequest = columns[i].width; }
2304
-
2738
+
2305
2739
  var m = columns[i] = $.extend({}, columnDefaults, columns[i]);
2740
+ m.autoSize = $.extend({}, columnAutosizeDefaults, m.autoSize);
2741
+
2306
2742
  columnsById[m.id] = i;
2307
2743
  if (m.minWidth && m.width < m.minWidth) {
2308
2744
  m.width = m.minWidth;
@@ -2310,9 +2746,13 @@ if (typeof Slick === "undefined") {
2310
2746
  if (m.maxWidth && m.width > m.maxWidth) {
2311
2747
  m.width = m.maxWidth;
2312
2748
  }
2313
- }
2749
+ if (!m.resizable) {
2750
+ // there is difference between user resizable and autoWidth resizable
2751
+ //m.autoSize.autosizeMode = Slick.ColAutosizeMode.Locked;
2752
+ }
2753
+ }
2314
2754
  }
2315
-
2755
+
2316
2756
  function setColumns(columnDefinitions) {
2317
2757
  var _treeColumns = new Slick.TreeColumns(columnDefinitions);
2318
2758
  if (_treeColumns.hasDepth()) {
@@ -2337,6 +2777,7 @@ if (typeof Slick === "undefined") {
2337
2777
  createCssRules();
2338
2778
  resizeCanvas();
2339
2779
  updateCanvasWidth();
2780
+ applyColumnHeaderWidths();
2340
2781
  applyColumnWidths();
2341
2782
  handleScroll();
2342
2783
  }
@@ -2353,6 +2794,10 @@ if (typeof Slick === "undefined") {
2353
2794
 
2354
2795
  makeActiveCellNormal();
2355
2796
 
2797
+ if (args.showColumnHeader !== undefined) {
2798
+ setColumnHeaderVisibility(args.showColumnHeader);
2799
+ }
2800
+
2356
2801
  if (options.enableAddRow !== args.enableAddRow) {
2357
2802
  invalidateRow(getDataLength());
2358
2803
  }
@@ -2374,6 +2819,10 @@ if (typeof Slick === "undefined") {
2374
2819
  if (options.autoHeight) {
2375
2820
  options.leaveSpaceForNewRows = false;
2376
2821
  }
2822
+ if (options.forceFitColumns) {
2823
+ options.autosizeColsMode = Slick.GridAutosizeColsMode.LegacyForceFit;
2824
+ console.log("forceFitColumns option is deprecated - use autosizeColsMode");
2825
+ }
2377
2826
  }
2378
2827
 
2379
2828
  function setData(newData, scrollToTop) {
@@ -2437,6 +2886,27 @@ if (typeof Slick === "undefined") {
2437
2886
  }
2438
2887
  }
2439
2888
 
2889
+ function setColumnHeaderVisibility(visible, animate) {
2890
+ if (options.showColumnHeader != visible) {
2891
+ options.showColumnHeader = visible;
2892
+ if (visible) {
2893
+ if (animate) {
2894
+ $headerScroller.slideDown("fast", resizeCanvas);
2895
+ } else {
2896
+ $headerScroller.show();
2897
+ resizeCanvas();
2898
+ }
2899
+ } else {
2900
+ if (animate) {
2901
+ $headerScroller.slideUp("fast", resizeCanvas);
2902
+ } else {
2903
+ $headerScroller.hide();
2904
+ resizeCanvas();
2905
+ }
2906
+ }
2907
+ }
2908
+ }
2909
+
2440
2910
  function setFooterRowVisibility(visible) {
2441
2911
  if (options.showFooterRow != visible) {
2442
2912
  options.showFooterRow = visible;
@@ -2680,7 +3150,16 @@ if (typeof Slick === "undefined") {
2680
3150
  addlCssClasses += (formatterResult && formatterResult.addClasses ? (addlCssClasses ? ' ' : '') + formatterResult.addClasses : '');
2681
3151
  var toolTip = formatterResult && formatterResult.toolTip ? "title='" + formatterResult.toolTip + "'" : '';
2682
3152
 
2683
- stringArray.push("<div class='" + cellCss + (addlCssClasses ? ' ' + addlCssClasses : '') + "' " + toolTip + ">");
3153
+ var customAttrStr = '';
3154
+ if(m.hasOwnProperty('cellAttrs') && m.cellAttrs instanceof Object) {
3155
+ for (var key in m.cellAttrs) {
3156
+ if (m.cellAttrs.hasOwnProperty(key)) {
3157
+ customAttrStr += ' ' + key + '="' + m.cellAttrs[key] + '" ';
3158
+ }
3159
+ }
3160
+ }
3161
+
3162
+ stringArray.push("<div class='" + cellCss + (addlCssClasses ? ' ' + addlCssClasses : '') + "' " + toolTip + customAttrStr + ">");
2684
3163
 
2685
3164
  // if there is a corresponding row (if not, this is the Add New row or this data hasn't been loaded yet)
2686
3165
  if (item) {
@@ -2882,25 +3361,27 @@ if (typeof Slick === "undefined") {
2882
3361
  }
2883
3362
 
2884
3363
  function getViewportHeight() {
2885
- var fullHeight = $paneHeaderL.outerHeight();
2886
- fullHeight += ( options.showHeaderRow ) ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0;
2887
- fullHeight += ( options.showFooterRow ) ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0;
2888
-
2889
3364
  if (options.autoHeight) {
3365
+ var fullHeight = $paneHeaderL.outerHeight();
3366
+ fullHeight += ( options.showHeaderRow ) ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0;
3367
+ fullHeight += ( options.showFooterRow ) ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0;
3368
+ fullHeight += (getCanvasWidth() > viewportW) ? scrollbarDimensions.height : 0;
3369
+
2890
3370
  viewportH = options.rowHeight
2891
3371
  * getDataLengthIncludingAddNew()
2892
3372
  + ( ( options.frozenColumn == -1 ) ? fullHeight : 0 );
2893
3373
  } else {
3374
+ var columnNamesH = ( options.showColumnHeader ) ? parseFloat($.css($headerScroller[0], "height"))
3375
+ + getVBoxDelta($headerScroller) : 0;
2894
3376
  topPanelH = ( options.showTopPanel ) ? options.topPanelHeight + getVBoxDelta($topPanelScroller) : 0;
2895
3377
  headerRowH = ( options.showHeaderRow ) ? options.headerRowHeight + getVBoxDelta($headerRowScroller) : 0;
2896
3378
  footerRowH = ( options.showFooterRow ) ? options.footerRowHeight + getVBoxDelta($footerRowScroller) : 0;
2897
- preHeaderH = (options.createPreHeaderPanel && options.showPreHeaderPanel) ? options.preHeaderPanelHeight + getVBoxDelta($preHeaderPanelScroller) : 0;
3379
+ var preHeaderH = (options.createPreHeaderPanel && options.showPreHeaderPanel) ? options.preHeaderPanelHeight + getVBoxDelta($preHeaderPanelScroller) : 0;
2898
3380
 
2899
3381
  viewportH = parseFloat($.css($container[0], "height", true))
2900
3382
  - parseFloat($.css($container[0], "paddingTop", true))
2901
3383
  - parseFloat($.css($container[0], "paddingBottom", true))
2902
- - parseFloat($.css($headerScroller[0], "height"))
2903
- - getVBoxDelta($headerScroller)
3384
+ - columnNamesH
2904
3385
  - topPanelH
2905
3386
  - headerRowH
2906
3387
  - footerRowH
@@ -2917,9 +3398,9 @@ if (typeof Slick === "undefined") {
2917
3398
 
2918
3399
  function resizeCanvas() {
2919
3400
  if (!initialized) { return; }
2920
- paneTopH = 0
2921
- paneBottomH = 0
2922
- viewportTopH = 0
3401
+ paneTopH = 0;
3402
+ paneBottomH = 0;
3403
+ viewportTopH = 0;
2923
3404
  viewportBottomH = 0;
2924
3405
 
2925
3406
  getViewportWidth();
@@ -2966,7 +3447,9 @@ if (typeof Slick === "undefined") {
2966
3447
  var paneBottomTop = $paneTopL.position().top
2967
3448
  + paneTopH;
2968
3449
 
2969
- $viewportTopL.height(viewportTopH);
3450
+ if (!options.autoHeight) {
3451
+ $viewportTopL.height(viewportTopH);
3452
+ }
2970
3453
 
2971
3454
  if (hasFrozenColumns()) {
2972
3455
  $paneTopR.css({
@@ -3020,7 +3503,7 @@ if (typeof Slick === "undefined") {
3020
3503
  scrollbarDimensions = measureScrollbar();
3021
3504
  }
3022
3505
 
3023
- if (options.forceFitColumns) {
3506
+ if (options.autosizeColsMode === Slick.GridAutosizeColsMode.LegacyForceFit) {
3024
3507
  autosizeColumns();
3025
3508
  }
3026
3509
 
@@ -3071,18 +3554,23 @@ if (typeof Slick === "undefined") {
3071
3554
  resetActiveCell();
3072
3555
  }
3073
3556
 
3074
- th = Math.max(options.rowHeight * numberOfRows, tempViewportH - scrollbarDimensions.height);
3075
- if (th < maxSupportedCssHeight) {
3076
- // just one page
3077
- h = ph = th;
3078
- n = 1;
3079
- cj = 0;
3557
+ var oldH = h;
3558
+ if (options.autoHeight) {
3559
+ h = options.rowHeight * numberOfRows;
3080
3560
  } else {
3081
- // break into pages
3082
- h = maxSupportedCssHeight;
3083
- ph = h / 100;
3084
- n = Math.floor(th / ph);
3085
- cj = (th - h) / (n - 1);
3561
+ th = Math.max(options.rowHeight * numberOfRows, tempViewportH - scrollbarDimensions.height);
3562
+ if (th < maxSupportedCssHeight) {
3563
+ // just one page
3564
+ h = ph = th;
3565
+ n = 1;
3566
+ cj = 0;
3567
+ } else {
3568
+ // break into pages
3569
+ h = maxSupportedCssHeight;
3570
+ ph = h / 100;
3571
+ n = Math.floor(th / ph);
3572
+ cj = (th - h) / (n - 1);
3573
+ }
3086
3574
  }
3087
3575
 
3088
3576
  if (h !== oldH) {
@@ -3116,7 +3604,7 @@ if (typeof Slick === "undefined") {
3116
3604
  resizeCanvas();
3117
3605
  }
3118
3606
 
3119
- if (options.forceFitColumns && oldViewportHasVScroll != viewportHasVScroll) {
3607
+ if (options.autosizeColsMode === Slick.GridAutosizeColsMode.LegacyForceFit && oldViewportHasVScroll != viewportHasVScroll) {
3120
3608
  autosizeColumns();
3121
3609
  }
3122
3610
  updateCanvasWidth(false);
@@ -3178,7 +3666,7 @@ if (typeof Slick === "undefined") {
3178
3666
  $lastNode = $lastNode.prev();
3179
3667
 
3180
3668
  // Hack to retrieve the frozen columns because
3181
- if ($lastNode.length == 0) {
3669
+ if ($lastNode.length === 0) {
3182
3670
  $lastNode = $(cacheEntry.rowNode[0]).children().last();
3183
3671
  }
3184
3672
  }
@@ -3313,20 +3801,19 @@ if (typeof Slick === "undefined") {
3313
3801
  x.innerHTML = stringArray.join("");
3314
3802
 
3315
3803
  var processedRow;
3316
- var $node;
3804
+ var node;
3317
3805
  while ((processedRow = processedRows.pop()) != null) {
3318
3806
  cacheEntry = rowsCache[processedRow];
3319
3807
  var columnIdx;
3320
3808
  while ((columnIdx = cacheEntry.cellRenderQueue.pop()) != null) {
3321
- $node = $(x).children().last();
3809
+ node = x.lastChild;
3322
3810
 
3323
- if (hasFrozenColumns() && ( columnIdx > options.frozenColumn )) {
3324
- $(cacheEntry.rowNode[1]).append($node);
3811
+ if (hasFrozenColumns() && (columnIdx > options.frozenColumn)) {
3812
+ cacheEntry.rowNode[1].appendChild(node);
3325
3813
  } else {
3326
- $(cacheEntry.rowNode[0]).append($node);
3814
+ cacheEntry.rowNode[0].appendChild(node);
3327
3815
  }
3328
-
3329
- cacheEntry.cellNodesByColumnIdx[columnIdx] = $node;
3816
+ cacheEntry.cellNodesByColumnIdx[columnIdx] = $(node);
3330
3817
  }
3331
3818
  }
3332
3819
  }
@@ -3433,7 +3920,8 @@ if (typeof Slick === "undefined") {
3433
3920
 
3434
3921
  function updateRowPositions() {
3435
3922
  for (var row in rowsCache) {
3436
- rowsCache[row].rowNode.style.top = getRowTop(row) + "px";
3923
+ var rowNumber = row ? parseInt(row) : 0;
3924
+ rowsCache[rowNumber].rowNode[0].style.top = getRowTop(rowNumber) + "px";
3437
3925
  }
3438
3926
  }
3439
3927
 
@@ -3560,7 +4048,11 @@ if (typeof Slick === "undefined") {
3560
4048
  $footerRowScrollContainer[0].scrollLeft = scrollLeft;
3561
4049
  }
3562
4050
  if (options.createPreHeaderPanel) {
3563
- $preHeaderPanelScroller[0].scrollLeft = scrollLeft;
4051
+ if (hasFrozenColumns()) {
4052
+ $preHeaderPanelScrollerR[0].scrollLeft = scrollLeft;
4053
+ } else {
4054
+ $preHeaderPanelScroller[0].scrollLeft = scrollLeft;
4055
+ }
3564
4056
  }
3565
4057
 
3566
4058
  if (hasFrozenColumns()) {
@@ -3669,7 +4161,7 @@ if (typeof Slick === "undefined") {
3669
4161
  return {
3670
4162
  enqueue: enqueue,
3671
4163
  dequeue: dequeue
3672
- }
4164
+ };
3673
4165
  }
3674
4166
 
3675
4167
  function asyncPostProcessRows() {
@@ -3800,23 +4292,24 @@ if (typeof Slick === "undefined") {
3800
4292
 
3801
4293
  function flashCell(row, cell, speed) {
3802
4294
  speed = speed || 100;
3803
- if (rowsCache[row]) {
3804
- var $cell = $(getCellNode(row, cell));
3805
4295
 
3806
- function toggleCellClass(times) {
3807
- if (!times) {
3808
- return;
3809
- }
3810
- setTimeout(function () {
3811
- $cell.queue(function () {
3812
- $cell.toggleClass(options.cellFlashingCssClass).dequeue();
3813
- toggleCellClass(times - 1);
3814
- });
3815
- },
3816
- speed);
4296
+ function toggleCellClass($cell, times) {
4297
+ if (!times) {
4298
+ return;
3817
4299
  }
3818
4300
 
3819
- toggleCellClass(4);
4301
+ setTimeout(function () {
4302
+ $cell.queue(function () {
4303
+ $cell.toggleClass(options.cellFlashingCssClass).dequeue();
4304
+ toggleCellClass($cell, times - 1);
4305
+ });
4306
+ }, speed);
4307
+ }
4308
+
4309
+ if (rowsCache[row]) {
4310
+ var $cell = $(getCellNode(row, cell));
4311
+
4312
+ toggleCellClass($cell, 4);
3820
4313
  }
3821
4314
  }
3822
4315
 
@@ -3997,7 +4490,7 @@ if (typeof Slick === "undefined") {
3997
4490
 
3998
4491
  var preClickModeOn = (e.target && e.target.className === Slick.preClickClassName);
3999
4492
  var column = columns[cell.cell];
4000
- var suppressActiveCellChangedEvent = (options.editable && column && column.editor && options.suppressActiveCellChangeOnEdit) ? true : false;
4493
+ var suppressActiveCellChangedEvent = !!(options.editable && column && column.editor && options.suppressActiveCellChangeOnEdit);
4001
4494
  setActiveCellInternal(getCellNode(cell.row, cell.cell), null, preClickModeOn, suppressActiveCellChangedEvent, e);
4002
4495
  }
4003
4496
  }
@@ -4062,6 +4555,18 @@ if (typeof Slick === "undefined") {
4062
4555
  }
4063
4556
  }
4064
4557
 
4558
+ function handleFooterContextMenu(e) {
4559
+ var $footer = $(e.target).closest(".slick-footerrow-column", ".slick-footerrow-columns");
4560
+ var column = $footer && $footer.data("column");
4561
+ trigger(self.onFooterContextMenu, {column: column}, e);
4562
+ }
4563
+
4564
+ function handleFooterClick(e) {
4565
+ var $footer = $(e.target).closest(".slick-footerrow-column", ".slick-footerrow-columns");
4566
+ var column = $footer && $footer.data("column");
4567
+ trigger(self.onFooterClick, {column: column}, e);
4568
+ }
4569
+
4065
4570
  function handleMouseEnter(e) {
4066
4571
  trigger(self.onMouseEnter, {}, e);
4067
4572
  }
@@ -4104,7 +4609,7 @@ if (typeof Slick === "undefined") {
4104
4609
  for (var row in rowsCache) {
4105
4610
  for (var i in rowsCache[row].rowNode) {
4106
4611
  if (rowsCache[row].rowNode[i] === rowNode)
4107
- return row | 0;
4612
+ return (row ? parseInt(row) : 0);
4108
4613
  }
4109
4614
  }
4110
4615
  return null;
@@ -4258,7 +4763,7 @@ if (typeof Slick === "undefined") {
4258
4763
  : frozenRowsHeight;
4259
4764
  }
4260
4765
 
4261
- cell = getCellFromPoint($activeCellOffset.left, Math.ceil($activeCellOffset.top) - rowOffset);
4766
+ var cell = getCellFromPoint($activeCellOffset.left, Math.ceil($activeCellOffset.top) - rowOffset);
4262
4767
 
4263
4768
  activeRow = cell.row;
4264
4769
  activeCell = activePosX = activeCell = activePosX = getCellFromNode(activeCellNode);
@@ -4451,7 +4956,8 @@ if (typeof Slick === "undefined") {
4451
4956
  right: 0,
4452
4957
  width: $(elem).outerWidth(),
4453
4958
  height: $(elem).outerHeight(),
4454
- visible: true};
4959
+ visible: true
4960
+ };
4455
4961
  box.bottom = box.top + box.height;
4456
4962
  box.right = box.left + box.width;
4457
4963
 
@@ -4489,7 +4995,7 @@ if (typeof Slick === "undefined") {
4489
4995
  }
4490
4996
 
4491
4997
  function getGridPosition() {
4492
- return absBox($container[0])
4998
+ return absBox($container[0]);
4493
4999
  }
4494
5000
 
4495
5001
  function handleActiveCellPositionChange() {
@@ -4974,7 +5480,12 @@ if (typeof Slick === "undefined") {
4974
5480
  if (rowsCache[row]) {
4975
5481
  ensureCellNodesInRowsCache(row);
4976
5482
  try {
4977
- return rowsCache[row].cellNodesByColumnIdx[cell][0];
5483
+ if (rowsCache[row].cellNodesByColumnIdx.length > cell) {
5484
+ return rowsCache[row].cellNodesByColumnIdx[cell][0];
5485
+ }
5486
+ else {
5487
+ return null;
5488
+ }
4978
5489
  } catch (e) {
4979
5490
  return rowsCache[row].cellNodesByColumnIdx[cell];
4980
5491
  }
@@ -5051,7 +5562,9 @@ if (typeof Slick === "undefined") {
5051
5562
  var newCell = getCellNode(row, cell);
5052
5563
 
5053
5564
  // if selecting the 'add new' row, start editing right away
5054
- setActiveCellInternal(newCell, (forceEdit || (row === getDataLength()) || options.autoEdit), null, options.editable, e);
5565
+ var column = columns[cell];
5566
+ var suppressActiveCellChangedEvent = !!(options.editable && column && column.editor && options.suppressActiveCellChangeOnEdit);
5567
+ setActiveCellInternal(newCell, (forceEdit || (row === getDataLength()) || options.autoEdit), null, suppressActiveCellChangedEvent, e);
5055
5568
 
5056
5569
  // if no editor was created, set the focus back on the grid
5057
5570
  if (!currentEditor) {
@@ -5200,7 +5713,7 @@ if (typeof Slick === "undefined") {
5200
5713
  // Public API
5201
5714
 
5202
5715
  $.extend(this, {
5203
- "slickGridVersion": "2.4.5",
5716
+ "slickGridVersion": "2.4.14",
5204
5717
 
5205
5718
  // Events
5206
5719
  "onScroll": new Slick.Event(),
@@ -5213,6 +5726,8 @@ if (typeof Slick === "undefined") {
5213
5726
  "onBeforeHeaderCellDestroy": new Slick.Event(),
5214
5727
  "onHeaderRowCellRendered": new Slick.Event(),
5215
5728
  "onFooterRowCellRendered": new Slick.Event(),
5729
+ "onFooterContextMenu": new Slick.Event(),
5730
+ "onFooterClick": new Slick.Event(),
5216
5731
  "onBeforeHeaderRowCellDestroy": new Slick.Event(),
5217
5732
  "onBeforeFooterRowCellDestroy": new Slick.Event(),
5218
5733
  "onMouseEnter": new Slick.Event(),
@@ -5254,6 +5769,7 @@ if (typeof Slick === "undefined") {
5254
5769
  "setSortColumns": setSortColumns,
5255
5770
  "getSortColumns": getSortColumns,
5256
5771
  "autosizeColumns": autosizeColumns,
5772
+ "autosizeColumn": autosizeColumn,
5257
5773
  "getOptions": getOptions,
5258
5774
  "setOptions": setOptions,
5259
5775
  "getData": getData,
@@ -5267,7 +5783,7 @@ if (typeof Slick === "undefined") {
5267
5783
  "getContainerNode": getContainerNode,
5268
5784
  "updatePagingStatusFromView": updatePagingStatusFromView,
5269
5785
  "applyFormatResultToCellNode": applyFormatResultToCellNode,
5270
-
5786
+
5271
5787
  "render": render,
5272
5788
  "invalidate": invalidate,
5273
5789
  "invalidateRow": invalidateRow,
@@ -5327,6 +5843,8 @@ if (typeof Slick === "undefined") {
5327
5843
  "getTopPanel": getTopPanel,
5328
5844
  "setTopPanelVisibility": setTopPanelVisibility,
5329
5845
  "getPreHeaderPanel": getPreHeaderPanel,
5846
+ "getPreHeaderPanelLeft": getPreHeaderPanel,
5847
+ "getPreHeaderPanelRight": getPreHeaderPanelRight,
5330
5848
  "setPreHeaderPanelVisibility": setPreHeaderPanelVisibility,
5331
5849
  "getHeader": getHeader,
5332
5850
  "getHeaderColumn": getHeaderColumn,
@@ -5343,6 +5861,7 @@ if (typeof Slick === "undefined") {
5343
5861
  "removeCellCssStyles": removeCellCssStyles,
5344
5862
  "getCellCssStyles": getCellCssStyles,
5345
5863
  "getFrozenRowOffset": getFrozenRowOffset,
5864
+ "setColumnHeaderVisibility": setColumnHeaderVisibility,
5346
5865
 
5347
5866
  "init": finishInitialization,
5348
5867
  "destroy": destroy,