<!--
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Apache Thrift JavaScript Browser Client Demo</title>
    <script src="thrift.js" type="text/javascript"></script>
    <script src="gen-js/HelloSvc.js" type="text/javascript"></script>
    <script src="gen-js/TimesTwo.js" type="text/javascript"></script>
</head>
<body>
    <h1>Apache Thrift JavaScript Browser Client Demo</h1>
    <p>This html file demonstrates Apache Thrift JavaScrpt RPC between a browser client to a node.js server. Clicking the buttons below will call the RPC functions hosted by the Apache Thrift server at localhost:8585. The file hello.js contains the JavaScript node.js server required. Here are the steps to get the example running:</p>
    <ol>
        <li>Install Node.js <pre><a href="http://nodejs.org">nodejs.org</a></pre></li>
        <li>Install Apache Thrift for node (note that the node package manager will create the node_modules folder in the current directory so make sure to run npm from the same directory as hello.js so that the server can find the Thrift libraries. This example requires Apache Thrift 0.9.2+) <pre>$ npm install thrift</pre></li>
        <li>Compile the hello.idl for JavaScript and Node.js (you'll need to have the Apache Thrift compiler installed for this step. This also needs to be executed in the same directory as hello.js because hello.js and hello.html look for the gen-nodejs and gen-js directories here.)<pre>$ thrift -gen js -gen js:node hello.thrift</pre></li>
        <li>Run the node server in the directory with the hello.html file<pre>$ node hello.js</pre></li>
        <li>Copy the Apache Thrift JavaScript library, thrift.js, into the directory with this html file.<pre>$ cp ...../thrift.js . (you should be able to use Bower to install the browser based Apache Thrift library in the near future.)</pre>
        <li>Reload this page in a browser through the node server using using the URL: <pre>http://localhost:8585/hello.html</pre>then click a button below to make an RPC call</li>
    </ol>
    <button id="btn">Get Message from Node Server</button>
    <button id="btnDbl">Double 25</button>
    <script type="text/javascript">
        document.getElementById("btn").addEventListener("click", getMessage, false);

        function getMessage() {
            var transport = new Thrift.TXHRTransport("http://localhost:8585/hello");
            var protocol  = new Thrift.TJSONProtocol(transport);
            var client = new HelloSvcClient(protocol);
            var msg = client.hello_func();
            document.getElementById("output").innerHTML = msg;
        }

        document.getElementById("btnDbl").addEventListener("click", dblMessage, false);

        function dblMessage() {
            var transport = new Thrift.TXHRTransport("http://localhost:8585/dbl");
            var protocol  = new Thrift.TJSONProtocol(transport);
            var client = new TimesTwoClient(protocol);
            var val = client.dbl(25);
            document.getElementById("output2").innerHTML = val;
        }
    </script>
    <h2>Server Response: <div id="output"></div></h2>
    <h2>Server Dbl: <div id="output2"></div></h2>
</body> 
</html>

