<!DOCTYPE html>
<html lang="en">
<head>
    <script>var __basePath = '/';</script>
    <style media="only screen">
        html, body {
            height: 100%;
            width: 100%;
            margin: 0;
            box-sizing: border-box;
            -webkit-overflow-scrolling: touch;
        }

        html {
            position: absolute;
            top: 0;
            left: 0;
            padding: 0;
            overflow: auto;
        }

        body {
            padding: 1rem;
            overflow: auto;
        }
    </style>
    	<script src="https://cdnjs.cloudflare.com/ajax/libs/alasql/0.5.5/alasql.min.js"></script>
        <script src="https://unpkg.com/@ag-grid-enterprise/all-modules@23.2.0/dist/ag-grid-enterprise.min.js"></script>
    </head>

<body>
    <div id="myGrid" style="height: 100%;" class="ag-theme-alpine-dark"></div>

    <script src="fakeServer.js"></script>
    <script src="main.js"></script>
</body>
</html>
// This fake server uses http://alasql.org/ to mimic how a real server
// might generate sql queries from the Server-Side Row Model request.
// To keep things simple it does the bare minimum to support the example.
function FakeServer(allData) {
  alasql.options.cache = false;

  return {
    getData: function(request) {
      var results = executeQuery(request);

      return {
        success: true,
        rows: results,
        lastRow: getLastRowIndex(request, results),
      };
    },
  };

  function executeQuery(request) {
    var sql = buildSql(request);

    console.log('[FakeServer] - about to execute query:', sql);

    return alasql(sql, [allData]);
  }

  function buildSql(request) {
    return (
      selectSql(request) +
      ' FROM ?' +
      whereSql(request) +
      groupBySql(request) +
      orderBySql(request) +
      limitSql(request)
    );
  }

  function selectSql(request) {
    var rowGroupCols = request.rowGroupCols;
    var valueCols = request.valueCols;
    var groupKeys = request.groupKeys;

    if (isDoingGrouping(rowGroupCols, groupKeys)) {
      var rowGroupCol = rowGroupCols[groupKeys.length];
      var colsToSelect = [rowGroupCol.id];

      valueCols.forEach(function(valueCol) {
        colsToSelect.push(
          valueCol.aggFunc + '(' + valueCol.id + ') AS ' + valueCol.id
        );
      });

      return 'SELECT ' + colsToSelect.join(', ');
    }

    return 'SELECT *';
  }

  function whereSql(request) {
    var rowGroups = request.rowGroupCols;
    var groupKeys = request.groupKeys;
    var whereParts = [];

    if (groupKeys) {
      groupKeys.forEach(function(key, i) {
        var value = typeof key === 'string' ? "'" + key + "'" : key;

        whereParts.push(rowGroups[i].id + ' = ' + value);
      });
    }

    if (whereParts.length > 0) {
      return ' WHERE ' + whereParts.join(' AND ');
    }

    return '';
  }

  function groupBySql(request) {
    var rowGroupCols = request.rowGroupCols;
    var groupKeys = request.groupKeys;

    if (isDoingGrouping(rowGroupCols, groupKeys)) {
      var rowGroupCol = rowGroupCols[groupKeys.length];

      return ' GROUP BY ' + rowGroupCol.id;
    }

    return '';
  }

  function orderBySql(request) {
    var sortModel = request.sortModel;

    if (sortModel.length === 0) return '';

    var sorts = sortModel.map(function(s) {
      return s.colId + ' ' + s.sort.toUpperCase();
    });

    return ' ORDER BY ' + sorts.join(', ');
  }

  function limitSql(request) {
    var blockSize = request.endRow - request.startRow;

    return ' LIMIT ' + (blockSize + 1) + ' OFFSET ' + request.startRow;
  }

  function isDoingGrouping(rowGroupCols, groupKeys) {
    // we are not doing grouping if at the lowest level
    return rowGroupCols.length > groupKeys.length;
  }

  function getLastRowIndex(request, results) {
    if (!results || results.length === 0) {
      return null;
    }

    var currentLastRow = request.startRow + results.length;

    return currentLastRow <= request.endRow ? currentLastRow : -1;
  }
}
var gridOptions = {
  columnDefs: [
    { field: 'year', rowGroup: true, hide: true },
    { field: 'athlete', hide: true },
    { field: 'sport' },
    { field: 'gold', aggFunc: 'sum' },
  ],
  autoGroupColumnDef: {
    field: 'athlete',
    flex: 1,
    minWidth: 240,
    checkboxSelection: true
  },

  rowModelType: 'serverSide',
  rowSelection: 'multiple',
  // restrict selections to leaf rows
  isRowSelectable: function(rowNode) {
    return rowNode.group;
  },
  suppressRowClickSelection: true,
  animateRows: true,
  suppressAggFuncInHeader: true,
  onRowSelected: function(event) {
    //handle row selected logic, need to show popover either here
    console.log(event);
  },
  onRowClicked: function(event) {
    //rowClickedEvent does have MouseEvent property but this doesn't get fired.
    console.log(event);
  },
  onCellClicked: function(event) {
    //cellClickedEvent does have MouseEvent property but this doesn't get fired.
    console.log(event);
  }
};

function ServerSideDatasource(server) {
  return {
    getRows: function(params) {
      console.log('[Datasource] - rows requested by grid: ', params.request);

      var response = server.getData(params.request);

      // adding delay to simulate real server call
      setTimeout(function() {
        if (response.success) {
          // call the success callback
          params.successCallback(response.rows, response.lastRow);
        } else {
          // inform the grid request failed
          params.failCallback();
        }
      }, 200);
    },
  };
}

// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function() {
  var gridDiv = document.querySelector('#myGrid');
  new agGrid.Grid(gridDiv, gridOptions);

  agGrid
    .simpleHttpRequest({
      url:
        'https://raw.githubusercontent.com/ag-grid/ag-grid/master/grid-packages/ag-grid-docs/src/olympicWinners.json',
    })
    .then(function(data) {
      // setup the fake server with entire dataset
      var fakeServer = new FakeServer(data);

      // create datasource with a reference to the fake server
      var datasource = new ServerSideDatasource(fakeServer);

      // register the datasource with the grid
      gridOptions.api.setServerSideDatasource(datasource);
    });
});