<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css" />
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-app="app" ng-controller="Main as ctrl" ng-cloak="">

<div class="container">

  <h1>Tableau 10.0 WDC 2.0 Sample</h1>

  <section class="container top-buffer">
    <p>Copy the following URL, please paste to the Tableau WDC.</p>
    <p><input type="text" ng-model="ctrl.siteUrl" disabled="disabled" /></p>
  </section>

  <section class="container top-buffer">
    <button class="btn btn-danger" ng-click="ctrl.buttonClickHandler()">AMZN &amp; GOOGL</button>
  </section>

</div>

<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="//connectors.tableau.com/libs/tableauwdc-2.0.0-beta.js"></script>
<script src="script.js"></script>

</body>
</html>
(function() {
  'use strict';
  angular.module('app', [], function(){})
  .config(function($httpProvider) {
    if (!$httpProvider.defaults.headers.get) {
      $httpProvider.defaults.headers.get = {};
    }
    $httpProvider.defaults.headers.get['If-Modified-Since'] = (new Date(0)).toUTCString();
    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
  })
  .controller('Main', function($scope) {

    var buildUri = function(tickerSymbol, startDate, endDate) {
      var startDateStr = getFormattedDate(startDate);
      var endDateStr   = getFormattedDate(endDate);
      var queryStatement = 'select * from yahoo.finance.historicaldata where symbol = "' +
              tickerSymbol +
              '" and startDate = "' + startDateStr +
              '" and endDate = "' + endDateStr + '"';
      return '//query.yahooapis.com/v1/public/yql?q=' +
              encodeURIComponent(queryStatement) +
              '&diagnostics=true&env=store://datatables.org/alltableswithkeys&format=json';
    };

    var makeTwoDigits = function(num) {
      return num < 9 ? '0' + num.toString() : num.toString();
    };

    var getFormattedDate = function getFormattedDate(date) {
      return date.getUTCFullYear()  +
          '-' +
          makeTwoDigits(date.getUTCMonth() + 1) +
          '-' +
          makeTwoDigits(date.getUTCDate());
    };

    var myWDC = tableau.makeConnector();

    myWDC.getSchema = function(schemaCallback) {

      var cols = [{
        'id'       : 'ticker',
        'alias'    : 'ticker',
        'dataType' : tableau.dataTypeEnum.string
      }, {
        'id'       : 'day',
        'alias'    : 'day',
        'dataType' : tableau.dataTypeEnum.date
      }, {
        'id'       : 'open',
        'alias'    : 'open',
        'dataType' : tableau.dataTypeEnum.float
      }, {
        'id'       : 'close',
        'alias'    : 'close',
        'dataType' : tableau.dataTypeEnum.float
      }, {
        'id'       : 'high',
        'alias'    : 'high',
        'dataType' : tableau.dataTypeEnum.float
      }, {
        'id'       : 'low',
        'alias'    : 'low',
        'dataType' : tableau.dataTypeEnum.float
      }];

      var tableInfoAmzn = {
        'id'      : 'amzn',
        'alias'   : 'AMZN Table',
        'columns' : angular.copy(cols)
      };

      var tableInfoGoogl = {
        'id'      : 'googl',
        'alias'   : 'GOOGL Table',
        'columns' : angular.copy(cols)
      };
      schemaCallback([tableInfoAmzn, tableInfoGoogl]);
    };

    myWDC.getData = function(table, doneCallback) {

      var tableData = [];
      var endDate = new Date();
      var startDate = new Date();
      startDate.setYear(endDate.getFullYear() - 1);

      var connectionUri = buildUri(table.tableInfo.id, startDate, endDate);

      $.ajax({
        'url' : connectionUri,
        'dataType' : 'json'
      })
      .done(function (result) {
        if (result.query.results) {
          var quotes = result.query.results.quote;
          angular.forEach(quotes, function(quote, key) {
            tableData.push({
              'ticker': quote.Symbol,
              'day'   : quote.Date,
              'open'  : quote.Open,
              'close' : quote.Close,
              'high'  : quote.High,
              'low'   : quote.Low
            });
          });
          table.appendRows(tableData);
          doneCallback();
        }
      })
      .fail(function (data, textStatus, jqXHR) {
        tableau.log('Connection error: ' + data.responseText + '\n' + jqXHR);
        tableau.abortWithError('Error while trying to connect to the Yahoo stock data source.');
      });
    };
    tableau.registerConnector(myWDC);

    var ctrl  = this;

    ctrl.siteUrl = window.location.href;

    ctrl.buttonClickHandler = function() {
      tableau.connectionName = 'Stock Data for AMZN & GOOGL';
      tableau.submit();
    };

  });
}());
button {
  margin-right : 10px;
  width : 200px;
}
input {
  width : 430px;
}