private initSelectionListener()

in tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts [539:638]


  private initSelectionListener(row: HTMLTableRowElement): void {
    let clickElement: HTMLTableRowElement | HTMLTableCellElement;

    if (this.columnSelector && this.columnSelector.disabled) {
      return;
    } else if (this.columnSelector && this.columnSelector.rowElement(row)
        && this.columnSelector.rowElement(row).disabled) {
      return;
    } else if ([Selectable.single, Selectable.singleOrNone, Selectable.multi].includes(this.selectable)) {
      clickElement = row;
    } else if (this.selectable === Selectable.none && this.columnSelector
        && [Selectable.single, Selectable.singleOrNone, Selectable.multi].includes(this.columnSelector.selectable)
        && !row.classList.contains(Css.TOBAGO_COLUMN_PANEL)) {
      clickElement = row.querySelector("td:first-child");
      clickElement.addEventListener("click", (event) => event.stopPropagation()); //TOBAGO-2276
    } else if (this.columnSelector && this.columnSelector.selectable === Selectable.none) {
      const rowElement = this.columnSelector.rowElement(row);
      if (rowElement) {
        rowElement.addEventListener("click", (event) => event.preventDefault());
      }
    }

    if (clickElement) {
      clickElement.addEventListener("mousedown", (event: MouseEvent) => {
        this.mousedownOnRowData = {
          x: event.clientX,
          y: event.clientY
        };
      });

      clickElement.addEventListener("click", (event: MouseEvent) => {
        const row: HTMLTableRowElement = (event.currentTarget as HTMLElement).closest("tr");

        if (this.mousedownOnRowData) { // integration test: mousedownOnRowData may be 'null'
          if (Math.abs(this.mousedownOnRowData.x - event.clientX)
              + Math.abs(this.mousedownOnRowData.y - event.clientY) > 5) {
            // The user has moved the mouse. We assume, the user want to select some text inside the sheet,
            // so we don't select the row.
            return;
          }
        }

        const selectable = this.columnSelector ? this.columnSelector.selectable : this.selectable;
        const ctrlPressed = event.ctrlKey || event.metaKey;
        const shiftPressed = event.shiftKey && this.lastClickedRowIndex > -1;

        /* eslint-disable max-len */
        // @formatter:off
        const selectMode: SelectMode
        = !this.columnSelector && selectable === Selectable.single                                 ? SelectMode.singleMode
        : !this.columnSelector && selectable === Selectable.singleOrNone && !ctrlPressed           ? SelectMode.singleMode
        : !this.columnSelector && selectable === Selectable.singleOrNone && ctrlPressed            ? SelectMode.ctrlMode_singleOrNone
        : !this.columnSelector && selectable === Selectable.multi && !ctrlPressed && !shiftPressed ? SelectMode.singleMode
        : !this.columnSelector && selectable === Selectable.multi && ctrlPressed                   ? SelectMode.ctrlMode_multi
        : !this.columnSelector && selectable === Selectable.multi && shiftPressed                  ? SelectMode.shiftMode
        : this.columnSelector  && selectable === Selectable.single                                 ? SelectMode.singleMode
        : this.columnSelector  && selectable === Selectable.singleOrNone                           ? SelectMode.ctrlMode_singleOrNone
        : this.columnSelector  && selectable === Selectable.multi && !shiftPressed                 ? SelectMode.ctrlMode_multi
        : this.columnSelector  && selectable === Selectable.multi && shiftPressed                  ? SelectMode.shiftMode
        : SelectMode.none;
        // @formatter:on
        /* eslint-enable max-len */

        const selected = this.selected;
        const rowIndex = Number(row.classList.contains(Css.TOBAGO_COLUMN_PANEL)
            ? row.getAttribute("name") : row.getAttribute("row-index"));

        switch (selectMode) {
          case SelectMode.singleMode:
            selected.clear();
            selected.add(rowIndex);
            break;
          case SelectMode.ctrlMode_singleOrNone:
            if (selected.has(rowIndex)) {
              selected.delete(rowIndex);
            } else {
              selected.clear();
              selected.add(rowIndex);
            }
            break;
          case SelectMode.ctrlMode_multi:
            if (selected.has(rowIndex)) {
              selected.delete(rowIndex);
            } else {
              selected.add(rowIndex);
            }
            break;
          case SelectMode.shiftMode:
            for (let i = Math.min(rowIndex, this.lastClickedRowIndex);
                 i <= Math.max(rowIndex, this.lastClickedRowIndex); i++) {
              selected.add(i);
            }
            break;
        }

        this.lastClickedRowIndex = rowIndex;
        this.selected = selected;
      });
    }
  }