@refinitiv-ui/efx-grid 6.0.107 → 6.0.109

Sign up to get free protection for your applications and to get access to all the features.
@@ -321,7 +321,7 @@ let Grid = function(placeholder, config) {
321
321
  t._snapshotFillerDataChanged = t._snapshotFillerDataChanged.bind(t);
322
322
  t._onPollingInterval = t._onPollingInterval.bind(t);
323
323
 
324
- t._onKeyDown = t._onKeyDown.bind(t);
324
+ t._onTabNavigation = t._onTabNavigation.bind(t);
325
325
  t._requestScroll = t._requestScroll.bind(t);
326
326
  t._onVScroll = t._onVScroll.bind(t);
327
327
  t._selfScrollToRow = t._selfScrollToRow.bind(t);
@@ -404,10 +404,9 @@ let Grid = function(placeholder, config) {
404
404
  t._grid.listen("postSectionDataBinding", t._onPostSectionDataBinding);
405
405
  t._grid.listen("firstRendered", t._dispatch.bind(t, "firstRendered"));
406
406
  t._grid.listen("afterContentBinding", t._dispatch.bind(t, "afterContentBinding"));
407
- t._grid.listen("keydown", t._onKeyDown);
407
+ t._grid.listen("tabNavigation", t._onTabNavigation);
408
408
 
409
409
  t._grid.getVScrollbar().listen("scroll", t._onVScroll);
410
- t._hiddenInput = t._grid.getHiddenInput();
411
410
 
412
411
  t._grid.enableRowHighlighting(true);
413
412
 
@@ -634,8 +633,10 @@ Grid.prototype.dispose = function() {
634
633
  this._subs = null;
635
634
  }
636
635
 
637
- if(this._focusingArgs && this._focusingArgs.id) {
638
- clearTimeout(this._focusingArgs.id);
636
+ if(this._focusingArgs) {
637
+ if(this._focusingArgs.id) {
638
+ clearTimeout(this._focusingArgs.id);
639
+ }
639
640
  this._focusingArgs = null;
640
641
  }
641
642
  };
@@ -4123,16 +4124,11 @@ Grid.prototype.getVScrollView = function () {
4123
4124
  * @param {Element} el
4124
4125
  * @return {boolean}
4125
4126
  */
4126
- function isValidInput(el) {
4127
- return el && el.tagName !== "SPAN" && !el.disabled;
4128
- }
4129
- /** @private
4130
- * @param {Element} el
4131
- * @param {Element} hiddenInput
4132
- * @return {boolean}
4133
- */
4134
- function isValidTarget(el, hiddenInput) {
4135
- return !el.classList.contains("valigner") && el !== hiddenInput;
4127
+ function isFocusableContent(el) {
4128
+ if(el) {
4129
+ return (el.tagName !== "SPAN" && !el.disabled);
4130
+ }
4131
+ return false;
4136
4132
  }
4137
4133
  /** @private
4138
4134
  * @param {Object} cell
@@ -4141,7 +4137,7 @@ function isValidTarget(el, hiddenInput) {
4141
4137
  function focusCell(cell) {
4142
4138
  if(cell) {
4143
4139
  let cellContent = cell.getContent();
4144
- if(cellContent && isValidInput(cellContent)) {
4140
+ if(cellContent && isFocusableContent(cellContent)) {
4145
4141
  cellContent.focus();
4146
4142
  return true;
4147
4143
  }
@@ -4152,18 +4148,15 @@ function focusCell(cell) {
4152
4148
  */
4153
4149
  Grid.prototype._onVScroll = function() {
4154
4150
  let args = this._focusingArgs;
4155
- if(!args) { return; }
4156
-
4157
- this._focusingArgs = null;
4158
- let event = args.event;
4159
- let cell = args.section.getCell(args.colIndex, args.rowIndex);
4160
- if(focusCell(cell)) {
4161
- event.preventDefault();
4162
- } else {
4163
- if(event.shiftKey) {
4164
- this._findPrevFocusableCell(event, args.colIndex, args.rowIndex, args.focusableColIndices);
4165
- } else {
4166
- this._findNextFocusableCell(event, args.colIndex, args.rowIndex, args.focusableColIndices);
4151
+ if(args) {
4152
+ this._focusingArgs = null;
4153
+ let cell = this._grid.getCell("content", args.colIndex, args.rowIndex);
4154
+ if(!focusCell(cell)) {
4155
+ if(args.shiftKey) {
4156
+ this._focusPrevCellContent(args);
4157
+ } else {
4158
+ this._focusNextCellContent(args);
4159
+ }
4167
4160
  }
4168
4161
  }
4169
4162
  };
@@ -4171,89 +4164,108 @@ Grid.prototype._onVScroll = function() {
4171
4164
  */
4172
4165
  Grid.prototype._selfScrollToRow = function() {
4173
4166
  let args = this._focusingArgs;
4174
- if(!args) { return; }
4175
- args.id = 0;
4176
- this.scrollToRow(args.rowIndex);
4167
+ if(args) {
4168
+ args.id = 0;
4169
+ this.scrollToRow(args.rowIndex);
4170
+ }
4177
4171
  };
4178
4172
  /** @private
4179
- * @param {Object} e
4173
+ * @param {Object} args
4180
4174
  * @param {number} colIndex
4181
4175
  * @param {number} rowIndex
4182
- * @param {Array} focusableColIndices
4183
- * @param {Object} section
4184
4176
  */
4185
- Grid.prototype._requestScroll = function(e, colIndex, rowIndex, focusableColIndices, section) {
4186
- let args = this._focusingArgs;
4187
- if(args) { return; }
4188
- if(this._scrolledRow === rowIndex) { return; } // Avoid infinite loop
4189
-
4190
- this._scrolledRow = rowIndex;
4191
- args = this._focusingArgs = {
4192
- event: e,
4193
- colIndex: colIndex,
4194
- rowIndex: rowIndex,
4195
- focusableColIndices: focusableColIndices,
4196
- section: section
4197
- };
4177
+ Grid.prototype._requestScroll = function(args, colIndex, rowIndex) {
4178
+ if(this._focusingArgs || this._scrolledRow === args.rowIndex) {
4179
+ return; // Avoid infinite loop
4180
+ }
4198
4181
 
4182
+ this._scrolledRow = args.rowIndex;
4183
+ this._focusingArgs = args;
4184
+ args.colIndex = colIndex;
4185
+ args.rowIndex = rowIndex;
4186
+ args.event = null; // The event is invalid after the scroll
4199
4187
  args.id = setTimeout(this._selfScrollToRow); // Avoid event loop protection
4200
4188
  };
4201
4189
  /** @private
4202
- * @param {Object} e
4203
- * @param {number} colIndex
4204
- * @param {number} rowIndex
4205
- * @param {Array} focusableColIndices
4206
- * @param {Element=} content
4190
+ * @param {Object} args
4207
4191
  */
4208
- Grid.prototype._findNextFocusableCell = function(e, colIndex, rowIndex, focusableColIndices, content) {
4209
- let startIdx = focusableColIndices.indexOf(colIndex);
4192
+ Grid.prototype._focusNextCellContent = function(args) {
4193
+ let colIndex = args.colIndex;
4194
+ let rowIndex = args.rowIndex;
4195
+ if(rowIndex < 0 || rowIndex == null) {
4196
+ return;
4197
+ }
4210
4198
 
4211
- // Calculate starting row and column index
4212
- if(!isValidTarget(e.target, this._hiddenInput) || startIdx < 0) {
4213
- rowIndex = 0;
4214
- startIdx = 0;
4215
- } else if(isValidInput(content) && startIdx >= 0) {
4199
+ let focusableColIndices = args.focusableColIndices;
4200
+ let len = focusableColIndices.length;
4201
+ let startIdx = 0;
4202
+ let i;
4203
+ if(colIndex >= 0) {
4204
+ for(i = 1; i < len; i++) {
4205
+ if(colIndex < focusableColIndices[i]) {
4206
+ break;
4207
+ }
4208
+ startIdx = i;
4209
+ }
4210
+ }
4211
+ // If the current focus is on a valid content, starts on the next cell
4212
+ if(args.event && args.validContent) {
4216
4213
  startIdx++;
4217
4214
  }
4215
+
4218
4216
  let grid = this._grid;
4219
4217
  let section = grid.getSection("content");
4220
4218
  let viewInfo = grid.getVerticalViewInfo();
4221
4219
  let bottomRowIndex = viewInfo.bottomRowIndex;
4222
4220
  let rowCount = this.getRowCount();
4223
4221
  for(let r = rowIndex; r < rowCount; r++) {
4224
- for(let i = startIdx; i < focusableColIndices.length; i++) {
4222
+ for(i = startIdx; i < len; i++) {
4225
4223
  let c = focusableColIndices[i];
4226
4224
  if(r > bottomRowIndex) {
4227
- this._requestScroll(e, c, r, focusableColIndices, section);
4225
+ this._requestScroll(args, c, r);
4228
4226
  return;
4229
4227
  } else {
4230
4228
  let cell = section.getCell(c, r);
4231
4229
  if(focusCell(cell)) {
4232
- e.preventDefault();
4230
+ if(args.event) {
4231
+ args.event.preventDefault();
4232
+ }
4233
4233
  return;
4234
4234
  }
4235
4235
  }
4236
4236
  }
4237
4237
  startIdx = 0;
4238
4238
  }
4239
+
4240
+ if(args.validContent) { // The current focus on the last focusable content
4241
+ this._grid.getHiddenInput().focus();
4242
+ }
4239
4243
  };
4240
4244
  /** @private
4241
- * @param {Object} e
4242
- * @param {number} colIndex
4243
- * @param {number} rowIndex
4244
- * @param {Array} focusableColIndices
4245
- * @param {Element=} content
4245
+ * @param {Object} args
4246
4246
  */
4247
- Grid.prototype._findPrevFocusableCell = function(e, colIndex, rowIndex, focusableColIndices, content) {
4248
- let startIdx = focusableColIndices.indexOf(colIndex);
4249
- let len = focusableColIndices.length;
4247
+ Grid.prototype._focusPrevCellContent = function(args) {
4248
+ let colIndex = args.colIndex;
4249
+ let rowIndex = args.rowIndex;
4250
+ if(rowIndex < 0 || rowIndex == null) {
4251
+ return;
4252
+ }
4250
4253
 
4251
- // Calculate starting row and column index
4252
- if(!isValidTarget(e.target, this._hiddenInput) || startIdx < 0) {
4253
- rowIndex = 0;
4254
- startIdx = 0;
4255
- } else if(isValidInput(content) && startIdx >= 0) {
4256
- startIdx--;
4254
+ let focusableColIndices = args.focusableColIndices;
4255
+ let len = focusableColIndices.length;
4256
+ let startIdx = len - 1;
4257
+ let i;
4258
+ if(colIndex >= 0) {
4259
+ for(i = len - 1; --i >= 0;) {
4260
+ if(colIndex > focusableColIndices[i]) {
4261
+ break;
4262
+ }
4263
+ startIdx = i;
4264
+ }
4265
+ }
4266
+ // If the current focus is on a valid content, starts on the next cell
4267
+ if(args.event && args.validContent) {
4268
+ --startIdx;
4257
4269
  }
4258
4270
 
4259
4271
  let grid = this._grid;
@@ -4261,32 +4273,33 @@ Grid.prototype._findPrevFocusableCell = function(e, colIndex, rowIndex, focusabl
4261
4273
  let viewInfo = grid.getVerticalViewInfo();
4262
4274
  let topRowIndex = viewInfo.topRowIndex;
4263
4275
  for(let r = rowIndex; r >= 0; r--) {
4264
- for(let i = startIdx; i >= 0; i--) {
4276
+ for(i = startIdx; i >= 0; i--) {
4265
4277
  let c = focusableColIndices[i];
4266
4278
  if(r < topRowIndex) {
4267
- this._requestScroll(e, c, r, focusableColIndices, section);
4279
+ this._requestScroll(args, c, r);
4268
4280
  return;
4269
4281
  } else {
4270
4282
  let cell = section.getCell(c, r);
4271
4283
  if(focusCell(cell)) {
4272
- e.preventDefault();
4284
+ if(args.event) {
4285
+ args.event.preventDefault();
4286
+ }
4273
4287
  return;
4274
4288
  }
4275
4289
  }
4276
4290
  }
4277
4291
  startIdx = len - 1;
4278
4292
  }
4293
+
4294
+ if(args.validContent) { // The current focus on the last focusable content
4295
+ this._grid.getHiddenInput(true).focus();
4296
+ }
4279
4297
  };
4280
4298
 
4281
4299
  /** @private
4282
4300
  * @param {Object} e
4283
4301
  */
4284
- Grid.prototype._onKeyDown = function(e) {
4285
- if (e.keyCode !== 9 || e.ctrlKey || e.altKey || e.metaKey) {
4286
- return;
4287
- }
4288
-
4289
- // Find next focusable cell
4302
+ Grid.prototype._onTabNavigation = function(e) {
4290
4303
  let colDefs = this.getColumnDefinitions();
4291
4304
  let colCount = colDefs.length;
4292
4305
 
@@ -4302,13 +4315,36 @@ Grid.prototype._onKeyDown = function(e) {
4302
4315
  }
4303
4316
 
4304
4317
  this._scrolledRow = -1; // Reset the scroll loop protector
4305
- let pos = this.getRelativePosition(e);
4306
- let content = pos["cell"] ? pos["cell"].getContent() : null;
4318
+ let keyEvt = e.event;
4319
+ let pos = this.getRelativePosition(keyEvt);
4320
+ let validContent = true;
4321
+ let activeElement = e.activeElement;
4322
+ if(activeElement) {
4323
+ validContent = !activeElement.classList.contains("valigner");
4324
+ }
4325
+
4326
+ if(validContent) {
4327
+ let content = pos["cell"] ? pos["cell"].getContent() : null;
4328
+ validContent = isFocusableContent(content);
4329
+ }
4330
+ let startingRowIndex = pos["rowIndex"];
4331
+ if(e.onTheEdge) {
4332
+ let viewInfo = this._grid.getVScrollView();
4333
+ startingRowIndex = keyEvt.shiftKey ? viewInfo.lastFullRow : viewInfo.firstFullRow;
4334
+ }
4335
+ let args = {
4336
+ event: keyEvt,
4337
+ shiftKey: keyEvt.shiftKey,
4338
+ colIndex: pos["colIndex"],
4339
+ rowIndex: startingRowIndex,
4340
+ focusableColIndices: focusableColIndices,
4341
+ validContent: validContent
4342
+ };
4307
4343
 
4308
- if(e.shiftKey) {
4309
- this._findPrevFocusableCell(e, pos["colIndex"], pos["rowIndex"], focusableColIndices, content);
4344
+ if(keyEvt.shiftKey) {
4345
+ this._focusPrevCellContent(args);
4310
4346
  } else {
4311
- this._findNextFocusableCell(e, pos["colIndex"], pos["rowIndex"], focusableColIndices, content);
4347
+ this._focusNextCellContent(args);
4312
4348
  }
4313
4349
  };
4314
4350