onKeydown()

in BismNormalizer/AlmToolkit/html-resources/src/app/grid/grid.component.ts [373:628]


  onKeydown(event: any) {

    this.showContextMenu = false;
    document.getElementById('comparison-table-container').style.overflowY = 'auto';
    let siblingRow;
    let eventRow;
    let columnType;
    let nodeSelected: ComparisonNode;
    eventRow = event.target.parentElement;
    columnType = document.getElementById(event.target.id).getAttribute('data-column-type');

    if (event.ctrlKey && event.which === 83) {
      this.gridService.saveOrCompare('save');
      return;
    }

    if (event.ctrlKey && event.altKey && event.which === 67) {
      this.gridService.saveOrCompare('compare');
      return;
    }

    // Remove the transparent background color from existing cells
    const transparentCells = document.querySelectorAll('.transparent-cell');
    for (let iTransparentCellCounter = 0; iTransparentCellCounter < transparentCells.length; iTransparentCellCounter += 1) {
      transparentCells[iTransparentCellCounter].classList.remove('transparent-cell');
    }

    // Handle up arrow, down arrow, Shift+Up, Shift+Down
    if (event.which === 38 || event.which === 40) {
      event.preventDefault();
      event.stopPropagation();
      if (!event.ctrlKey) {
        // If shift key is not pressed its a single select
        if (!event.shiftKey) {
          // Checking if the column in focus is dropdown
          // If yes, change the option else empty the selected list and select the current row
          if (columnType === 'action-dropdown') {
            let dropdownElement: HTMLSelectElement;
            dropdownElement = <HTMLSelectElement>document.getElementById(event.target.id).firstElementChild;
            nodeSelected = this.comparisonDataToDisplay
              .find(comparisonNode => comparisonNode.Id === parseInt(event.target.id.split('node-')[1], 10));
            const selectedOption = dropdownElement.selectedOptions[0];
            const oldOption = selectedOption.innerHTML;
            if (event.which === 38) {
              siblingRow = this.getSiblingElement(true, selectedOption.id);
            } else {
              siblingRow = this.getSiblingElement(false, selectedOption.id);
            }
            if (siblingRow) {
              if (event.which === 38) {
                dropdownElement.selectedIndex = dropdownElement.selectedIndex - 1;
              } else {
                dropdownElement.selectedIndex = dropdownElement.selectedIndex + 1;
              }
              const option = dropdownElement.selectedOptions[0].innerHTML;
              if (option !== oldOption) {
                this.gridService.sendChange(nodeSelected.Id, option, oldOption);
                this.getDataToDisplay(true);
              }
            }
          } else {
            this.selectedNodes = [];
            const selectedRows = document.querySelectorAll('.selected-row');
            for (let iRowCounter = 0; iRowCounter < selectedRows.length; iRowCounter++) {
              selectedRows[iRowCounter].classList.remove('selected-row');
            }
          }
        }

        // Select previous/next row (Up, Down, Shift+Up, Shift+Down)
        if (columnType !== 'action-dropdown') {
          // Find the sibling based on the key pressed
          if (event.which === 38) {
            this.direction = 'up';
            siblingRow = this.getSiblingElement(true, eventRow.id);
          } else {
            this.direction = 'down';
            siblingRow = this.getSiblingElement(false, eventRow.id);
          }
          let deselectNextRow = true;

          let rowId = eventRow.id;
          rowId = rowId.split('node-')[1];
          nodeSelected = this.comparisonDataToDisplay.find(comparisonNode => comparisonNode.Id === parseInt(rowId, 10));

          if (this.oldDirection && this.oldDirection !== this.direction && this.selectedNodes.length > 1) {
            if (this.selectedNodes.indexOf(nodeSelected.Id) > -1) {
              eventRow.classList.remove('selected-row');
              this.selectedNodes.splice(this.selectedNodes.indexOf(nodeSelected.Id), 1);
              deselectNextRow = false;
            }
          } else if (this.selectedNodes.length === 0 || this.selectedNodes.length === 1) {
            this.oldDirection = this.direction;
          }

          if (!(siblingRow && siblingRow.classList.contains('grid-data-row'))) {
            siblingRow = eventRow;
            deselectNextRow = false;
          }

          // Select the current row
          rowId = siblingRow.id;
          document.getElementById(rowId + '-' + columnType).focus();

          // Set this as current object so that editor can be refreshed
          rowId = rowId.split('node-')[1];
          nodeSelected = this.comparisonDataToDisplay.find(comparisonNode => comparisonNode.Id === parseInt(rowId, 10));

          if (this.selectedNodes.indexOf(nodeSelected.Id) === -1) {
            siblingRow.classList.add('selected-row');
            this.selectedNodes.push(nodeSelected.Id);
            this.lastSelectedRow = siblingRow;
          } else if (deselectNextRow) {
            siblingRow.classList.remove('selected-row');
            this.selectedNodes.splice(this.selectedNodes.indexOf(nodeSelected.Id), 1);
          }

          this.selectedObject = nodeSelected;
        }
      } else {
        // This is for Ctrl+Shift+Up and Ctrl+Shift+Down
        if (event.shiftKey) {
          let isSiblingAvailable = true;
          let prev = true;
          let rowId;
          let comparisonTable;
          let firstRow;
          let lastRow;
          // Decide if previous elements are to be fetched or next elements
          if (event.which === 38) {
            this.direction = 'up';
            prev = true;
          } else {
            this.direction = 'down';
            prev = false;
          }

          // If last selected row exists, get its ID
          if (this.lastSelectedRow) {
            rowId = this.lastSelectedRow.id;
            nodeSelected = this.comparisonDataToDisplay
              .find(comparisonNode => comparisonNode.Id === parseInt(rowId.split('node-')[1], 10));
          }

          // If the direction changes and lastSelectedRow is not same as
          if (this.oldDirection && this.oldDirection !== this.direction
            && this.lastSelectedRow && this.lastSelectedRow !== eventRow) {
            if (this.selectedNodes.indexOf(nodeSelected.Id) > -1) {
              this.lastSelectedRow.classList.remove('selected-row');
              this.selectedNodes.splice(this.selectedNodes.indexOf(nodeSelected.Id), 1);
            } else {
              this.lastSelectedRow.classList.add('selected-row');
              this.selectedNodes.push(nodeSelected.Id);
            }
          }
          comparisonTable = document.getElementById('comparison-grid');
          firstRow = this.getSiblingElement(false, comparisonTable.firstElementChild.firstElementChild.id);
          lastRow = comparisonTable.firstElementChild.lastElementChild;
          rowId = eventRow.id;
          nodeSelected = this.comparisonDataToDisplay
            .find(comparisonNode => comparisonNode.Id === parseInt(rowId.split('node-')[1], 10));
          if (this.oldDirection && this.oldDirection !== this.direction
            && (firstRow === eventRow || lastRow === eventRow)) {
            if (this.selectedNodes.indexOf(nodeSelected.Id) > -1) {
              eventRow.classList.remove('selected-row');
              this.selectedNodes.splice(this.selectedNodes.indexOf(nodeSelected.Id), 1);
            } else {
              eventRow.classList.add('selected-row');
              this.selectedNodes.push(nodeSelected.Id);
            }
          }
          this.oldDirection = this.direction;
          // Find all elements above or below this row and select them as well
          while (isSiblingAvailable) {
            siblingRow = this.getSiblingElement(prev, rowId);
            if (siblingRow && siblingRow.classList && siblingRow.classList.contains('grid-data-row')) {
              rowId = siblingRow.id;
              document.getElementById(rowId + '-' + columnType).focus();
              nodeSelected = this.comparisonDataToDisplay
                .find(comparisonNode => comparisonNode.Id === parseInt(rowId.split('node-')[1], 10));
              this.selectedObject = nodeSelected;

              if (this.selectedNodes.indexOf(nodeSelected.Id) === -1) {
                siblingRow.classList.add('selected-row');
                this.selectedNodes.push(nodeSelected.Id);
              } else {
                siblingRow.classList.remove('selected-row');
                this.selectedNodes.splice(this.selectedNodes.indexOf(nodeSelected.Id), 1);
              }

              siblingRow.focus();
              siblingRow = this.getSiblingElement(prev, rowId);
            } else {
              isSiblingAvailable = false;
            }
          }
        }
      }
    } else if ((event.which === 37 || event.which === 39 || event.which === 9 || (event.shiftKey && event.which === 9)) && !event.ctrlKey) {

      event.preventDefault();
      event.stopPropagation();
      // To handle left and right keys, tab and Shift+Tab
      let prev = true;
      let rowChild;
      let comparisonTable;
      let firstRow;
      let lastRow;
      comparisonTable = document.getElementById('comparison-grid');
      firstRow = this.getSiblingElement(false, comparisonTable.firstElementChild.firstElementChild.id);
      lastRow = comparisonTable.firstElementChild.lastElementChild;
      if (event.which === 39 || (event.which === 9 && !event.shiftKey)) {
        prev = false;
      }
      siblingRow = this.getSiblingElement(prev, event.target.id);
      if (!siblingRow) {
        columnType = document.getElementById(event.target.id).getAttribute('data-column-type');
        if (!((eventRow === firstRow && columnType === 'node-type') || (eventRow === lastRow && columnType === 'action-dropdown'))) {
          eventRow.classList.remove('selected-row');
          nodeSelected = this.comparisonDataToDisplay
            .find(comparisonNode => comparisonNode.Id === parseInt(eventRow.id.split('node-')[1], 10));
          if (this.selectedNodes.indexOf(nodeSelected.Id) > -1) {
            this.selectedNodes.splice(this.selectedNodes.indexOf(nodeSelected.Id), 1);
          }

          siblingRow = this.getSiblingElement(prev, eventRow.id);
          nodeSelected = this.comparisonDataToDisplay
            .find(comparisonNode => comparisonNode.Id === parseInt(siblingRow.id.split('node-')[1], 10));
          this.selectedObject = nodeSelected;
          if (this.selectedNodes.indexOf(nodeSelected.Id) === -1) {
            siblingRow.classList.add('selected-row');
            this.selectedNodes.push(nodeSelected.Id);
          } else {
            siblingRow.classList.remove('selected-row');
            this.selectedNodes.splice(this.selectedNodes.indexOf(nodeSelected.Id), 1);
          }

          if (prev) {
            rowChild = document.getElementById(siblingRow.id).lastElementChild;
          } else {
            rowChild = document.getElementById(siblingRow.id).firstElementChild;
          }
          document.getElementById(rowChild.id).focus();
        }
      } else {
        siblingRow.focus();
      }
    }

    // Get the greyed out cells in the selected row to make them transparent
    const greyedOutCells = document.querySelectorAll('.selected-row .greyed-out-cell');

    for (let iCellCounter = 0; iCellCounter < greyedOutCells.length; iCellCounter += 1) {
      greyedOutCells[iCellCounter].classList.add('transparent-cell');
    }
  }