SlickGrid button click handler stops functioning on scroll event?

857 views Asked by At

In attempting to use SlickGrid in my page, I have noticed that a jQuery click handler I declare after the grid is rendered only works for approximately 2x the number of rows visible.

Moreover, when a button is clicked the value property is changed to provide visual confirmation to the user. However, upon scrolling too far down past one of the previously clicked buttons, scrolling back up appears to reset the value to the original/default value.

As far as I can tell, it looks like the grid is re-rendering at various intervals. If that suspicion is correct, how do I preserve the effect of the click handler and the values in those buttons already clicked?

It may be important to note that I am not using dataView.

<script type="text/javascript">
  var j$ = jQuery.noConflict();
  var grid,
      data = [],
      columns = [
          { id: "rownum", name: "Row #", field: "rownum", width: 50 },
          { id: "accname", name: "Account Name", field: "accname", width: 500 },
          { id: "accid", name: "Id", field: "accid", width: 150 },
          { id: "rectypeid", name: "Record Type ID", field: "rectypeid", width: 150 },
          { id: "itemurl", name: "Item URL Link", field: "itemurl", width: 300, formatter: function (r,c,v,def,datactx) { return "<a target='_blank' href='" + v + "'>" + v + "</a>" } },
          { id: "rfrbtn", name: "Notify Staff", field: "rfrbtn", width: 75, formatter: function (r,c,v,def,datactx) { return "<input class='rfrch' value='Yes' type='button' id='" + datactx.accid + "'/>" } }
      ],
      options = {
        enableCellNavigation: false,
        enableColumnReorder: true,
      };

  var acc = new SObjectModel.Acc();

  // Query Accounts
  var count = 1;
  acc.retrieve({ where: {Name: {like: '%Test Acct%'}, RecordTypeId: {eq: '01230000003MJmr'}}, limit: 100 }, function(err, records, event){
    if(err) {
      alert(err.message);
    }
    else {
      records.forEach(function(record) {
        data.push({
          rownum: count++,
          accname: record.get("Name"),
          accid: record.get("Id"),
          rectypeid: record.get("RecordTypeId"),
          itemurl: record.get("itemurl")
        });
      });
    }
    grid.invalidate();
    rfrClickHandler();
  });

  grid = new Slick.Grid("#container", data, columns, options);

  var rfrClickHandler = function() {
    j$(".rfrch").click(function() {
      var rfrbtnClicked = j$(this).prop('id');
      j$(this).prop('value','Cancel');
      console.log(rfrbtnClicked);
    });
  }

</script>
1

There are 1 answers

0
Ryan Neuffer On

Use .on() so that you do not have to re-bind the click handlers after the rows are re-rendered.

j$("#container").on('click', '.rfrch', function(){
    //... your handler code
}

In your formatter for the button you can add a property to dataContext for the current value state of the button and also a data property to hold the row index:

if(datactx.rfrchState === undefined){
    datactx.rfrchState = "Yes";
}
return "<input class='rfrch' value='"+datactx.rfrchState+"' data-row-index='"+r+"' type='button' id='" + datactx.accid + "'/>"

Then in your button handler add code to retrieve the data object and set rfrchState. That way when you scroll up and down and the rows are re-rendered the state will be preserved and set on the button via the formatter.

var rowIndex = j$(this).data('row-index');
var dataItem = grid.getDataItem(rowIndex);
dataItem.rfrchState = dataItem.rfrchState === 'Yes'?'No':'Yes';

Hope this helps.