polymerpolymer-1.0ag-gridpaper-elementscellrenderer

How do I register the on-tap in a paper-icon-button in an ag-grid cell renderer?


I am working on adding ajax call to paper-icon-buttons that are rendered in an ag-grid cell renderer. Here is the script in my custom polymer component. The paper-icon-buttons do show up and clicking on them causes the ripple, but the functions in the on-tap are not being called.

Is there a better way to add the paper-icon-button entries to the cell? How can I add the registration of the on-tap properly?

Thank you!

<script>

  function sourceRenderer(params) {
    if (params.value)
      return '<span><a  href="/harvest/' + params.data.asource + '/' + params.value + '">' + params.value + '</a>'
    else 
      return null;
    }

  function innerCellRendererA(params) {
    var imageFullUrl = '/images/' + params.data.type + '.png';
    if (params.data.type == 'entity') {
      var entityUrl = '/analyze/' + params.data.asource + '/' + params.data.amodel + '/' + params.data.sourceName;
      return '<img src="'+imageFullUrl+'" style="padding-left: 4px;" />  <a href="'+entityUrl+'">' + params.data.name + ' (' + params.data.sourceName + ')</a>';
    }
    else if (params.data.type == 'model') {
      var entityUrl = '/harvest/' + params.data.asource + '/' + params.data.name;
      return '<a href="javascript:void(0);" title="Harvest Relational Data"><img src="'+imageFullUrl+'" style="padding-left: 4px;" /></a>  <a href="'+entityUrl+'">' + params.data.name + '</a>';
    }
    else
      return '<paper-icon-button  src="'+imageFullUrl+'" on-tap="testjdbc" data-args="'+params.data.classname+'~~'+params.data.url+'~~'+params.data.username+'~~'+params.data.password+'"></paper-icon-button> ' +
      '<paper-icon-button  src="/images/database_export.svg" on-tap="harvestmodel" data-args="'+params.data.classname+'~~'+params.data.url+'~~'+params.data.username+'~~'+params.data.password+'"></paper-icon-button> ' + params.data.name;
  }    

  Polymer({

    is: 'easymetahub-analyze',

    properties: {
      sourcelist: {
        type: Array,
        notify: true
      }
    },

    testjdbc: function(e){
      alert('Foo');
      var args = e.target.getAttribute('data-args').split('~~');
    },

    harvestmodel: function(e){
      alert('Bar');
      var args = e.target.getAttribute('data-args').split('~~');
    },

    handleData: function(e) {
      var resp = e.detail.response;
      this.sourcelist = resp;
    },

    ready: function() {
    },

    attached: function() {
      agGrid.initialiseAgGridWithWebComponents();

      var columnDefs = [
        {
          headerName: "Name", 
          'field': 'name', 
          width: 350, 
          cellRenderer: 'group', 
          sort: "asc",
          cellRendererParams: {
            innerRenderer: innerCellRendererA
          }
        },
        {headerName: "Database Type", field: "databasetype", width: 120 },
        {headerName: "URL", width: 250, field: "url" },
        {headerName: "User Name", field: "username", width: 120 }
      ];

      var gridOptions = {
        columnDefs: columnDefs,
        enableColResize: true,
        rowHeight: 36,
        enableSorting: true,
        getNodeChildDetails: function(file) {
          if (file.children) {
            return {
                group: true,
                children: file.children,
                expanded: file.open,
                field: 'name',
                key: file.name
            };
          } else {
            return null;
          }
        },
        onGridReady: function(params) {
          params.api.sizeColumnsToFit();
        }
      };

      this.$.myGrid.setGridOptions(gridOptions);
      var eInput = this.$.quickFilterInput;
      eInput.addEventListener("input", function () {
          var text = eInput.value;
          gridOptions.api.setQuickFilter(text);
      });

    },

    detached: function() {
      this.$.myGrid.api.destroy();
    }

  });

</script>

Solution

  • agGrid's grid options has a property for a callback -- onModelUpdated -- that is called when new rows are added to the grid.

    attached: function() {
        var self = this;
        var gridOptions = {
          ...
          onModelUpdated: function(e) {
            self._bindGridIconTap();
          }
        };
    }
    

    You could use this event to query the grid for its paper-icon-buttons and add their on-tap attributes as event handlers.

    _bindGridIconTap: function() {
      this._bindActionsOnGrid('paper-icon-button', 'tap');
    },
    
    _bindActionsOnGrid: function(selector, eventName) {
      var self = this;
      var buttons = this.$.myGrid.querySelectorAll(selector);
      buttons.forEach(function(b) {
        self._bindEvent(b, eventName);
      });
    },
    
    _bindEvent: function(el, eventName) {
      var self = this;
      var methodName = el.getAttribute('on-' + eventName);
      var method = self[methodName];
    
      if (method) {
        el.addEventListener(eventName, function(e) {
          method(e);
          e.stopPropagation();
          e.preventDefault();
          return false;
        });
      } else {
        console.warn(el.localName, 'listener method not found:', methodName);
      }
    }
    

    plunker

    Note you have a bug in:

    var args = e.target.getAttribute('data-args').split('~~');
    

    In a tap event for paper-icon-button, e.target is the icon image. You actually want e.currentTarget, which I've done for you in the Plunker.