Извлечение скрытого заголовка внутри сортированного портативного экземпляра

При использовании Handsontable кажется трудно получить заголовок строки из контекстного меню.

Рассмотрим следующий источник данных:

var data = function () {
 return [["1212", "roman", "i", "ii", "iii"],
         ["3121", "numeric", 1, 2 ,3],
         ["4126", "alpha", 'a', 'b', 'c']];
};

Можно создать экземпляр Handsontable, который отображает все данные, но первые два "столбца", и имеет контекстное меню:

// Settings to display all columns but the first two
var dataCols = []
for(var i=2; i<data()[0].length; i++) {
  dataCols.push({ data: i })
}

// Instance creation
var hot = new Handsontable(container, {
  data: data(),
  height: 396,
  colHeaders: true,
  rowHeaders: false,
  columns: dataCols,
  stretchH: 'all',
  columnSorting: true,
  contextMenu: {
    callback: function(key, options) {
      switch(key) {
      case 'header_pls':
        // TODO retrieve the "hidden header" from here    
        break;
      }
    },
    items: {
      "header_pls": {
        name: "Header please?"
      }
    }
  },
});

Параметр options из обратного вызова контекстного меню состоит из двух объектов start и end, имеющих свойства row и col.

Пусть это будет просто и предположим, что всегда будет выбрана одна ячейка: start и end - это один и тот же объект.

Затем можно получить заголовок из источника данных (а не данные, привязанные к экземпляру), используя метод Handsontable getSourceDataAtRow.

Это может сделать трюк, но когда таблица была отсортирована, щелкнув заголовок столбца, номер строки из источника данных и данные, привязанные к экземпляру, уже не совпадают.

Вот пример, который показывает, в чем проблема.

Невозможно получить один из двух первых элементов строки после сортировки таблицы.

Пропустил ли я что-нибудь?

Ответ 1

Я думаю, что ваша проблема сводится к тому, как получить реальный (физический) индекс после сортировки. Пожалуйста, поправьте меня, если я ошибаюсь, потому что этот ответ вращается вокруг этого.

Здесь вам нужно знать: когда вы используете встроенный сортировщик, Handson фактически не сортирует ваш массив данных. Это поведение по умолчанию, которое может быть или не быть полезным для вас. Несмотря на это, с этого момента каждый внутренний метод использует то, что называется "логическим индексом", который является только новым отсортированным индексом. Затем внутренние методы используют преобразование из логического в физический индекс при попытке доступа к точке данных.

В вашем случае вы хотите получить свой физический индекс, указав свой логический индекс, чтобы вы могли правильно обращаться к данным. Это можно сделать с помощью простой функции:

physicalIndex = instance.sortIndex[logicalIndex][0];

Учитывая эту информацию, вы должны иметь возможность добавить некоторую логику, чтобы всякий раз, когда вы пытаетесь получить доступ к данным, просто убедитесь, что вы используете этот преобразованный физический индекс; в моем случае я просто проверяю, что instance.sortIndex не undefined (который, по моему мнению, имеет место перед сортировкой), и каждый раз просто назначайте этот индекс, так как даже без сортировки logicalIndex == physicalIndex.

Надеюсь, что это поможет!

Ответ 2

Я обнаружил, что вы можете использовать собственный рендерер для скрытия ячеек.

function customRenderer(instance, td, row, col) {
    Handsontable.renderers.TextRenderer.apply(this, arguments);
    if([0, 1].indexOf(col) > -1) {
      td.style.display =  "none";
    }
    return td;
}

С помощью этого вы можете получить данные скрытых столбцов с помощью getDataAtCell, потому что вы используете исходный источник данных в отображаемой таблице. Вот обновленная скрипка: https://jsfiddle.net/xartok/upc4mcd0/5/

Есть еще одна проблема, хотя с заголовками столбцов...