slickgrid 2.4.5 → 2.4.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,