<!DOCTYPE html>
<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
<!-- vim: set ts=2: -->
<html ng-app="sjs">
<head>
  <title>SheetJS + KnockoutJS</title>
  <!-- KnockoutJS -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

  <!-- SheetJS js-xlsx library -->
  <script src="shim.js"></script>
  <script src="xlsx.full.min.js"></script>
</head>
<body>
<pre>
<b><a href="https://sheetjs.com">SheetJS + KnockoutJS demo</a></b>

The core library can be used as-is in KnockoutJS applications.
The <a href="https://github.com/sheetjs/js-xlsx">Community Edition README</a> details some common use cases.
We also have some <a href="http://sheetjs.com/demos/">more public demos</a>

This demo shows:
- view model backed by an array of arrays
- file import that refreshes the model
- table of editable `input` elements that are bound to the model
- file export based on the model

<a href="https://sheetjs.com/pres.xlsx">Sample Spreadsheet</a>
</pre>

<input name="xlfile" id="xlf"  class="left" style="width: 200px;" type="file">
<table data-bind="foreach: aoa">
    <tr data-bind="foreach: $data">
      <td><input data-bind="value: $parent[$index()]"/></td>
    </tr>
</table>
<script id='aoa' type="text/html"></script>
<button id="export">Export Sheet to XLSX</button>

</div>

<script>
/* knockout setup */
var ViewModel = function() {
  /* use an array of arrays */
  this.aoa = ko.observableArray([
    [1,2],
    [3,4]
  ]);
};

var model = new ViewModel();
ko.applyBindings(model);
/* do an update to confirm KO was loaded properly */
model.aoa([[1,2,3],[4,5,6]]);
model.aoa.push([7,8,9]);

/* set up file input handler */
(function() {
  var input_dom_element = document.getElementById('xlf');
  function handleFile(e) {
    var files = e.target.files, f = files[0];
    var reader = new FileReader();
    reader.onload = function(e) {
      var data = e.target.result;
      data = new Uint8Array(data);
      var workbook = XLSX.read(data, {type: 'array'});
      process_wb(workbook);
    };
    reader.readAsArrayBuffer(f);
  }
  input_dom_element.addEventListener('change', handleFile, false);
})();

/* update model */
function process_wb(wb) {
  /* pull first worksheet */
  var ws = wb.Sheets[wb.SheetNames[0]];
  /* convert to AOA */
  var aoa = XLSX.utils.sheet_to_json(ws, {header:1});
  /* update model */
  model.aoa(aoa);
}

document.getElementById("export").onclick = function() {
  /* get array of arrays */
  var data = model.aoa();
  /* convert to worksheet */
  var ws = XLSX.utils.aoa_to_sheet(data);
  /* build new workbook */
  var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
  /* write file */
  XLSX.writeFile(wb, "knockout.xlsx")
};
</script>
<script type="text/javascript">
/* eslint no-use-before-define:0 */
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-36810333-1']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
</script>
</body>
</html>