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

При использовании 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.

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

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

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

Я что-то пропустил?


person Thibault Martin    schedule 24.07.2015    source источник


Ответы (2)


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

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

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

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

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

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

person ZekeDroid    schedule 27.07.2015
comment
Полностью то, что мне было нужно, спасибо. Вот обновленный jsFiddle с решением для тех, кто заинтересован в том, чтобы решение работало. - person Thibault Martin; 28.07.2015

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

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/

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

person Xartok    schedule 25.07.2015
comment
Спасибо за помощь. Это помогло бы, если бы не проблема с заголовками. В моем реальном проекте каждый столбец имеет разную ширину (я использую пользовательские заголовки). Я почти уверен, что это испортит весь лист! - person Thibault Martin; 25.07.2015
comment
да, вы должны использовать логические индексы - person ZekeDroid; 27.07.2015