문제

I need to add a jquery ui slider to each cell of slickgrid. Number of records is over 10,000 with over 150 columns. The problem is that the initial set of sliders are rendered fine but as I scroll (left or right), they disappear. Somehow, the grid is not getting invalidated for those cells. I am using the following formatter on the column:

SliderFormatter = function (row, cell, value, colDef, dataContext) {
     var html = "<div class='mySlider' id='slider_" + dataContext['id'] + "'></div>" + value;
     return html;
 }

and invoking the slider from my document.ready callback.

Any help will be appreciated. Thanks in advance !

도움이 되었습니까?

해결책

SlickGrid renders only what's visible in the viewport, plus a small buffer. As you scroll, rows/cells are dynamically added and removed.

What this means for your case, is that when you initialize the slider widget in your document.ready callback, you're only initializing a tiny portion of them, and the ones that did get initialized, don't get re-initialized when the cells they are in are removed and recreated by SlickGrid.

SlickGrid doesn't allow you to use jQuery widgets like the slider in cells and requires that formatters output pure HTML in order to make it hard to implement the grid in a way that will slow it down. (I won't get into my reasoning behind that admittedly controversial decision.)

My advice here is to avoid using the jQuery UI slider here. It is simply not scalable or performant enough. Without virtualization, what you're trying to do is impossible - initializing 100 sliders is going to be really slow; initializing 10'000 x 150 of them is out of the question. With virtualization, you'll need to initialize and destroy them on the fly as you're scrolling around, and that's just too slow to scroll smoothly.

Consider using an HTML5 range input - <INPUT type="range">. It's supported by all major browsers with the exception of IE <10. See http://caniuse.com/#feat=input-range.

다른 팁

I've created an example using SlickGrid's async post-render option. @Tin is probably right that it would be better to use the native <input type="range"> but just in case you need to support older browsers here's how you can do it.

function waitingFormatter(value) {
  return '<div class="slider"></div>';
}

function renderSlider(cellNode, row, dataContext, colDef) {
  var cell = $(cellNode);
  cell.find('.slider').slider({
    value: dataContext.value,
    slide: function(e, ui) {
      data[row].value = ui.value;
      cell.prev().html(ui.value);
    }
  });
}

var grid;
var data = [];
var columns = [
  { id: "title", name: "Title", field: "title", sortable: false, width: 120, cssClass: "cell-title" },
  { id: "value", name: "Value", field: "value", sortable: false, editor: Slick.Editors.Integer, width: 40, validator: requiredFieldValidator },
  { id: "chart", name: "Slider", sortable: false, width: 425, formatter: waitingFormatter, rerenderOnResize: true, asyncPostRender: renderSlider }
];

var options = {
  editable: true,
  enableAddRow: false,
  enableCellNavigation: true,
  asyncEditorLoading: false,
  enableAsyncPostRender: true
};


$(function () {
  for (var i = 0; i < 500; i++) {
    var d = (data[i] = {});
    d["title"] = "Record " + i;
    d["value"] = Math.round(Math.random() * 100);
  }
  grid = new Slick.Grid("#myGrid", data, columns, options);
})
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top