Example #1
0
      rangeEach(index, index + amount - 1, function (i) {
        var isChild = false;
        var translated = _this4.collapsingUI.translateTrimmedRow(i);
        var currentDataObj = _this4.dataManager.getDataObject(translated);

        if (_this4.dataManager.hasChildren(currentDataObj)) {
          lastParents.push(currentDataObj);

          arrayEach(lastParents, function (elem) {
            if (elem.__children.indexOf(currentDataObj) > -1) {
              isChild = true;
              return false;
            }
          });

          if (!isChild) {
            childrenCount += _this4.dataManager.countChildren(currentDataObj);
          }
        }

        isChild = false;
        arrayEach(lastParents, function (elem) {
          if (elem.__children.indexOf(currentDataObj) > -1) {
            isChild = true;
            return false;
          }
        });

        if (isChild) {
          childrenCount--;
        }
      });
Example #2
0
  /**
   * Build DOM structure.
   */
  build() {
    const registerEvent = (element, eventName) => {
      this.eventManager.addEventListener(element, eventName, (event) => this.runLocalHooks(eventName, event, this));
    };

    if (!this.buildState) {
      this.buildState = STATE_BUILDING;
    }
    if (this.options.className) {
      addClass(this._element, this.options.className);
    }
    if (this.options.children.length) {
      arrayEach(this.options.children, (element) => this._element.appendChild(element.element));

    } else if (this.options.wrapIt) {
      const element = document.createElement(this.options.tagName);

      objectEach(this.options, (value, key) => {
        if (element[key] !== void 0 && key !== 'className' && key !== 'tagName' && key !== 'children') {
          element[key] = value;
        }
      });

      this._element.appendChild(element);

      arrayEach(EVENTS_TO_REGISTER, (eventName) => registerEvent(element, eventName));

    } else {
      arrayEach(EVENTS_TO_REGISTER, (eventName) => registerEvent(this._element, eventName));
    }
  }
Example #3
0
  /**
   * Calculate week structure within defined months.
   *
   * @private
   */
  calculateWeekStructure() {
    this.monthList = this.calculateMonthData();

    const firstWeekDay = this.getFirstWeekDay();
    const monthList = this.getMonthList();
    const currentYear = this.getYear();
    const mixedMonthToAdd = [];
    let weekOffset = 0;
    let weekSectionCount = 0;

    if (firstWeekDay === 'monday') {
      weekOffset = 1;
    }

    arrayEach(monthList, (currentMonth, monthIndex) => {
      let firstMonthDay = new Date(currentYear, monthIndex, 1).getDay();
      let mixedMonthsAdded = 0;
      let mixedMonthName = null;

      currentMonth.daysBeforeFullWeeks = (7 - firstMonthDay + weekOffset) % 7;

      if (!this.allowSplitWeeks && currentMonth.daysBeforeFullWeeks) {
        mixedMonthName = getMixedMonthName(monthIndex, monthList);

        mixedMonthToAdd.push(getMixedMonthObject(mixedMonthName, monthIndex));

        mixedMonthsAdded++;
      }

      currentMonth.fullWeeks = Math.floor((currentMonth.days - currentMonth.daysBeforeFullWeeks) / 7);
      currentMonth.daysAfterFullWeeks = currentMonth.days - currentMonth.daysBeforeFullWeeks - (7 * currentMonth.fullWeeks);

      if (!this.allowSplitWeeks) {
        if (monthIndex === monthList.length - 1 && currentMonth.daysAfterFullWeeks) {
          mixedMonthName = getMixedMonthName(monthIndex, monthList);

          mixedMonthToAdd.push(getMixedMonthObject(mixedMonthName, null));

          mixedMonthsAdded++;
        }

        weekSectionCount += currentMonth.fullWeeks + mixedMonthsAdded;

      } else {
        weekSectionCount += currentMonth.fullWeeks + (currentMonth.daysBeforeFullWeeks ? 1 : 0) + (currentMonth.daysAfterFullWeeks ? 1 : 0);
      }
    });

    arrayEach(mixedMonthToAdd, (monthObject, monthIndex) => {
      const index = monthObject.index;

      delete monthObject.index;

      this.addMixedMonth(index === null ? index : monthIndex + index, monthObject);
    });

    this.weekSectionCount = weekSectionCount;
  }
Example #4
0
    value: function restore() {
      var _sheet2 = this.sheet,
          matrix = _sheet2.matrix,
          dataProvider = _sheet2.dataProvider;

      var _stack$pop = this.stack.pop(),
          axis = _stack$pop.axis,
          index = _stack$pop.index,
          amount = _stack$pop.amount,
          changes = _stack$pop.changes;

      if (changes) {
        arrayEach(changes, function (change) {
          if (change[axis] > index + (amount - 1)) {
            change[axis] -= amount;
          }
          var row = change.row,
              column = change.column,
              value = change.value;

          var rawValue = dataProvider.getSourceDataAtCell(row, column);

          if (rawValue !== value) {
            dataProvider.updateSourceData(row, column, value);
            matrix.getCellAt(row, column).setState(CellValue.STATE_OUT_OFF_DATE);
          }
        });
      }
    }
Example #5
0
  /**
   * Create string body in desired format.
   *
   * @return {String}
  */
  export() {
    const options = this.options;
    const data = this.dataProvider.getData();
    let columnHeaders = this.dataProvider.getColumnHeaders();
    const hasColumnHeaders = columnHeaders.length > 0;
    let rowHeaders = this.dataProvider.getRowHeaders();
    const hasRowHeaders = rowHeaders.length > 0;

    // Starts with utf-8 BOM
    let result = '\ufeff';

    if (hasColumnHeaders) {
      columnHeaders = arrayMap(columnHeaders, (value) => this._escapeCell(value, true));

      if (hasRowHeaders) {
        result += options.columnDelimiter;
      }
      result += columnHeaders.join(options.columnDelimiter);
      result += options.rowDelimiter;
    }

    arrayEach(data, (value, index) => {
      if (index > 0) {
        result += options.rowDelimiter;
      }
      if (hasRowHeaders) {
        result += this._escapeCell(rowHeaders[index]) + options.columnDelimiter;
      }
      result += value.map((value) => this._escapeCell(value)).join(options.columnDelimiter);
    });

    return result;
  }
Example #6
0
  /**
   * On modify copyable range listener.
   *
   * @private
   * @param {Array} ranges Array of selected copyable text.
   * @returns {Array} Returns modyfied range.
   */
  onModifyCopyableRange(ranges) {
    let newRanges = [];

    let pushRange = (startRow, endRow, startCol, endCol) => {
      newRanges.push({startRow, endRow, startCol, endCol});
    };

    arrayEach(ranges, (range) => {
      let isHidden = true;
      let rangeStart = 0;

      rangeEach(range.startRow, range.endRow, (row) => {
        if (this.isHidden(row)) {
          if (!isHidden) {
            pushRange(rangeStart, row - 1, range.startCol, range.endCol);
          }
          isHidden = true;
        } else {
          if (isHidden) {
            rangeStart = row;
          }
          if (row === range.endRow) {
            pushRange(rangeStart, row, range.startCol, range.endCol);
          }
          isHidden = false;
        }
      });
    });

    return newRanges;
  }
Example #7
0
 /**
  * Reset all rendered cells meta.
  *
  * @private
  */
 resetCellsMeta() {
   arrayEach(this.hot.getCellsMeta(), (meta) => {
     if (meta) {
       meta.skipRowOnPaste = false;
     }
   });
 }
Example #8
0
    rangeEach(from, to, (column) => {
      for (let level = this.columnHeaderLevelCount - 1; level > -1; level--) {
        let visibleColumnIndex = this.getNestedParent(level, column);
        let topTH = wtOverlays.topOverlay ? wtOverlays.topOverlay.clone.wtTable.getColumnHeader(visibleColumnIndex, level) : void 0;
        let topLeftTH = wtOverlays.topLeftCornerOverlay ? wtOverlays.topLeftCornerOverlay.clone.wtTable.getColumnHeader(visibleColumnIndex, level) : void 0;
        let listTH = [topTH, topLeftTH];
        let colspanLen = this.getColspan(level - this.columnHeaderLevelCount, visibleColumnIndex);
        let isInSelection = visibleColumnIndex >= from && (visibleColumnIndex + colspanLen - 1) <= to;

        arrayEach(listTH, (TH, index, array) => {
          if (TH === void 0) {
            return false;
          }

          if ((!selectionByHeader && level < levelLimit) || (selectionByHeader && !isInSelection)) {
            if (hasClass(TH, classHighlight)) {
              removeClass(TH, classHighlight);
            }

          } else if (!hasClass(TH, classHighlight)) {
            addClass(TH, classHighlight);
          }
        });
      }
    });
Example #9
0
      renderer: (hot, wrapper, row, col, prop, value) => {
        addClass(wrapper.parentNode, 'htFiltersMenuActionBar');

        arrayEach(this.elements, (ui) => wrapper.appendChild(ui.element));

        return wrapper;
      }
Example #10
0
  /**
   * Add formula to the collection.
   *
   * @param {Number} column Column index.
   * @param {Object} formulaDefinition Object with keys:
   *  * `command` Object, Command object with formula name as `key` property.
   *  * `args` Array, Formula arguments.
   * @fires FormulaCollection#beforeAdd
   * @fires FormulaCollection#afterAdd
   */
  addFormula(column, formulaDefinition) {
    let args = arrayMap(formulaDefinition.args, (v) => typeof v === 'string' ? v.toLowerCase() : v);
    let name = formulaDefinition.name || formulaDefinition.command.key;

    this.runLocalHooks('beforeAdd', column);

    if (this.orderStack.indexOf(column) === -1) {
      this.orderStack.push(column);
    }
    if (this.hasFormulas(column, name)) {
      // Update formula
      arrayEach(this.getFormulas(column), (formula) => {
        if (formula.name === name) {
          formula.func = getFormula(formula.name, args);
          formula.args = args;

          return false;
        }
      });
    } else {
      // Add formula
      this.getFormulas(column).push({
        name,
        args,
        func: getFormula(name, args)
      });
    }
    this.runLocalHooks('afterAdd', column);
  }
Example #11
0
    value: function checkForOverlappingHeaders() {
      var _this5 = this;

      arrayEach(this.colspanArray, function (level, i) {
        arrayEach(_this5.colspanArray[i], function (header, j) {
          if (header.colspan > 1) {
            var row = _this5.levelToRowCoords(i);
            var childHeaders = _this5.getChildHeaders(row, j);

            if (childHeaders.length > 0) {
              var childColspanSum = 0;

              arrayEach(childHeaders, function (col, i) {
                childColspanSum += _this5.getColspan(row + 1, col);
              });

              if (childColspanSum > header.colspan) {
                console.warn('Your Nested Headers plugin setup contains overlapping headers. This kind of configuration is ' + 'currently not supported and might result in glitches.');
              }

              return false;
            }
          }
        });
      });
    }
Example #12
0
 /**
  * Calculate and refresh all defined endpoints.
  *
  * @param {Boolean} init `true` if it's the initial call.
  */
 refreshAllEndpoints(init) {
   arrayEach(this.endpoints, (value) => {
     this.currentEndpoint = value;
     this.calculate(value);
     this.setEndpointValue(value, 'init');
   });
   this.currentEndpoint = null;
 }
Example #13
0
  /**
   * Resets (removes) the endpoints from the table.
   *
   * @param {Array} endpoints Array containing the endpoints.
   */
  resetAllEndpoints(endpoints) {
    if (!endpoints) {
      endpoints = this.endpoints;
    }

    arrayEach(endpoints, (value) => {
      this.resetEndpointValue(value);
    });
  }
Example #14
0
  /**
   * Hide the rows provided in the array.
   *
   * @param {Array} rows Array of row index.
   */
  hideRows(rows) {
    arrayEach(rows, (row) => {
      row = parseInt(row, 10);

      if (!this.isHidden(row)) {
        this.hiddenRows.push(row);
      }
    });
  }
Example #15
0
  /**
   * Show the rows provided in the array.
   *
   * @param {Array} rows Array of row index.
   */
  showRows(rows) {
    arrayEach(rows, (row) => {
      row = parseInt(row, 10);

      if (this.isHidden(row)) {
        this.hiddenRows.splice(this.hiddenRows.indexOf(row), 1);
      }
    });
  }
Example #16
0
  /**
   * Import formulas to the collection.
   */
  importAllFormulas(formulas) {
    this.clean();

    arrayEach(formulas, (stack) => {
      this.orderStack.push(stack.column);

      arrayEach(stack.formulas, (formula) => this.addFormula(stack.column, formula));
    });
  }
Example #17
0
export function prepare() {
  const {matrix, dataProvider} = this;

  visualRows = new WeakMap();

  arrayEach(matrix.data, (cell) => {
    visualRows.set(cell, dataProvider.t.toVisualRow(cell.row));
  });
}
Example #18
0
  /**
   * Check if the nested headers overlap the fixed columns overlay, if so - display a warning.
   */
  checkForFixedColumnsCollision() {
    let fixedColumnsLeft = this.hot.getSettings().fixedColumnsLeft;

    arrayEach(this.colspanArray, (value, i) => {
      if (this.getNestedParent(i, fixedColumnsLeft) !== fixedColumnsLeft) {
        console.warn('You have declared a Nested Header overlapping the Fixed Columns section - it may lead to visual glitches. ' +
          'To prevent that kind of problems, split the nested headers between the fixed and non-fixed columns.');
      }
    });
  }
Example #19
0
  /**
   * Calculate and refresh endpoints only in the changed columns.
   *
   * @param {Array} changes Array of changes from the `afterChange` hook.
   */
  refreshChangedEndpoints(changes) {
    let needToRefresh = [];

    arrayEach(changes, (value, key, changes) => {
      // if nothing changed, dont update anything
      if ((value[2] || '') + '' === value[3] + '') {
        return;
      }

      arrayEach(this.endpoints, (value, j) => {
        if (this.hot.propToCol(changes[key][1]) === value.sourceColumn && needToRefresh.indexOf(j) === -1) {
          needToRefresh.push(j);
        }
      });
    });

    arrayEach(needToRefresh, (value) => {
      this.refreshEndpoint(this.endpoints[value]);
    });
  }
Example #20
0
function itemsToValue(availableItems) {
  let items = [];

  arrayEach(availableItems, (item) => {
    if (item.checked) {
      items.push(item.value);
    }
  });

  return items;
}
Example #21
0
  /**
   * Filter data based on specified column index.
   *
   * @param {Number} column Column index.
   * @param {Array} [dataSource] Data source as array of objects with `value` and `meta` keys (e.g. `{value: 'foo', meta: {}}`).
   * @returns {Array} Returns filtered data.
   */
  filterByColumn(column, dataSource = []) {
    let filteredData = [];

    arrayEach(dataSource, (dataRow) => {
      if (dataRow !== void 0 && this.formulaCollection.isMatch(dataRow, column)) {
        filteredData.push(dataRow);
      }
    });

    return filteredData;
  }
Example #22
0
export function operate(start, amount) {
  var modifyFormula = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  var matrix = this.matrix,
      dataProvider = this.dataProvider;

  var translate = [0, amount];

  arrayEach(matrix.cellReferences, function (cell) {
    if (cell.column >= start) {
      cell.translateTo.apply(cell, translate);
    }
  });

  arrayEach(matrix.data, function (cell) {
    var origRow = cell.row,
        origColumn = cell.column;


    if (cell.column >= start) {
      cell.translateTo.apply(cell, translate);
      cell.setState(CellValue.STATE_OUT_OFF_DATE);
    }

    if (modifyFormula) {
      var row = cell.row,
          column = cell.column;

      var value = dataProvider.getSourceDataAtCell(row, column);

      if (isFormulaExpression(value)) {
        var startCoord = cellCoordFactory('column', start);
        var expModifier = new ExpressionModifier(value);

        expModifier.useCustomModifier(customTranslateModifier);
        expModifier.translate({ column: amount }, startCoord({ row: origRow, column: origColumn }));

        dataProvider.updateSourceData(row, column, expModifier.toString());
      }
    }
  });
}
Example #23
0
  /**
   * Check if the value is matches the formulas.
   *
   * @param {Array} formulas List of formulas.
   * @param {Object} value Object with `value` and `meta` keys.
   * @returns {Boolean}
   */
  isMatchInFormulas(formulas, value) {
    let result = false;

    if (formulas.length) {
      arrayEach(formulas, (formula) => result = formula.func(value));

    } else {
      result = true;
    }

    return result;
  }
Example #24
0
  /**
   * Intersect data.
   *
   * @private
   * @param {Array} data
   * @param {Array} needles
   * @returns {Array}
   */
  _getIntersectData(data, needles) {
    let result = [];

    arrayEach(needles, (needleRow) => {
      let row = needleRow.meta.visualRow;

      if (data[row] !== void 0) {
        result[row] = data[row];
      }
    });

    return result;
  }
Example #25
0
  /**
   * Get handsontable source data with cell meta based on current selection.
   *
   * @param {Number} [column] Column index. By default column index accept the value of the selected column.
   * @returns {Array} Returns array of objects where keys as row index.
   */
  getDataMapAtColumn(column) {
    let data = [];

    arrayEach(this.hot.getSourceDataAtCol(column), (value, rowIndex) => {
      let {row, col, visualCol, visualRow, type, instance, dateFormat} = this.hot.getCellMeta(rowIndex, column);

      data.push({
        meta: {row, col, visualCol, visualRow, type, instance, dateFormat},
        value,
      });
    });

    return data;
  }
Example #26
0
    value: function untrimRows(rows) {
      var _this4 = this;

      arrayEach(rows, function (row) {
        row = parseInt(row, 10);

        if (_this4.isTrimmed(row)) {
          _this4.trimmedRows.splice(_this4.trimmedRows.indexOf(row), 1);
        }
      });

      this.hot.runHooks('skipLengthCache', 100);
      this.rowsMapper.createMap(this.hot.countSourceRows());
      this.hot.runHooks('afterUntrimRow', rows);
    }
Example #27
0
    value: function trimRows(rows) {
      var _this3 = this;

      arrayEach(rows, function (row) {
        row = parseInt(row, 10);

        if (!_this3.isTrimmed(row)) {
          _this3.trimmedRows.push(row);
        }
      });

      this.hot.runHooks('skipLengthCache', 100);
      this.rowsMapper.createMap(this.hot.countSourceRows());
      this.hot.runHooks('afterTrimRow', rows);
    }
Example #28
0
        arrayEach(nestedHeadersColspanArray, function (headerLevel, i) {
          arrayEach(headerLevel, function (header, j) {
            if (header.colspan > 1) {
              i = parseInt(i, 10);
              j = parseInt(j, 10);

              var row = _this4.nestedHeadersPlugin.levelToRowCoords(i);
              var col = j;

              _this4.markSectionAs(action === 'collapse' ? 'collapsed' : 'expanded', row, col, true);
              _this4.toggleCollapsibleSection({
                row: row,
                col: col
              }, action);
            }
          });
        });
Example #29
0
  /**
   * Filter data based on the formulas collection.
   *
   * @returns {Array}
   */
  filter() {
    let filteredData = [];

    if (!this.formulaCollection.isEmpty()) {
      arrayEach(this.formulaCollection.orderStack, (column, index) => {
        let columnData = this.columnDataFactory(column);

        if (index) {
          columnData = this._getIntersectData(columnData, filteredData);
        }

        filteredData = this.filterByColumn(column, columnData);
      });
    }

    return filteredData;
  }
Example #30
0
  /**
   * Export all previously added formulas.
   *
   * @returns {Array}
   */
  exportAllFormulas() {
    let result = [];

    arrayEach(this.orderStack, (column) => {
      const formulas = arrayMap(this.getFormulas(column), ({name, args} = formula) => {
        return {
          name, args
        };
      });

      result.push({
        column,
        formulas
      });
    });

    return result;
  }