Using JavaScript

JavaScript is a general-purpose, object-based programming language originally developed to allow Web developers to perform client-side form validation in HTML pages rendered in Web browsers such as Netscape Navigator and Microsoft Internet Explorer. Validating user input on the client allows network resources to be conserved since invalid data can be detected and corrected before that data is submitted back to the server.

Since its initial integration into Web browsers, JavaScript has been integrated into various platforms and applications.

Because of its enormous popularity and utility, JavaScript has also been integrated into VoiceXML. Using JavaScript in your voice applications will allow you to perform operations that are not otherwise supported in the VoiceXML language. In addition, JavaScript includes a number of objects that make programming tasks much easier.

Programmers can use JavaScript anywhere an expr attribute or cond attribute is allowed in VoiceXML. For example, both the var element and the assign element supports an expr attribute and expects a JavaScript expression. That's why, as you learned in the variables document, you must embed literal strings in quotes.

The following examples assume that the variables have been declared already. This example assigns a value to the variable "ui_path." The next assignment references ui_path and uses the JavaScript concatenation operator to append a literal string:

<assign name="ui_path" expr="'ui/'" />
<assign name="intro_path" expr="ui_path + 'welcome.wav'" />

The following example uses the intrinsic JavaScript Math object to generate a random prompt filename. The example assumes that the set of filenames "0.wav" through "9.wav" exist.

<assign name="class_prompt"
   expr="ui_path + Math.floor(Math.random()*10) + '.wav'" />
<audio expr="class_prompt" />

The following example uses a JavaScript expression in a condition to determine whether to play a recorded file representing "midnight," "noon," "am," or "pm."

<block>
   <var name="d" expr="new Date()" />
   <var name="iHour" expr="d.getHours()" />
   <var name="iMin" expr="d.getMinutes()" />

   <if cond="iHours == 0 &amp;&amp; iMin == 0">
      <audio src="ui/time/midnight.wav" />
   <elseif cond="iHours == 12 &amp;&amp; iMin == 0" />
      <audio src="ui/time/noon.wav" />
   <elseif cond="iHour &lt; 12" />
      <audio src="ui/time/am.wav" />
   <else />
      <audio src="ui/time/pm.wav" />
   </if>
</block>

As demonstrated in the previous example, because many JavaScript operators (<, >, &, &&) have special significance in XML, their equivalent entities must be used in expressions and conditions. The following lists shows such operators and their corresponding entities:

< &lt;
> &gt;
& &amp;

Oftentimes the JavaScript you write will involve more than a simple, single-line expression. Use the script element to define a block of JavaScript that performs more complex operations. Because several of the operators in JavaScript (<, >, &, &&) have special significance in XML, enclose your script in a CDATA section. In addition, you must set the type attribute to the name of the scripting language. Currently, the Tellme platform only supports JavaScript, so the type attribute must be set to the value "text/javascript".

On occasion, you will need to create variables in JavaScript that you will not have declared in VoiceXML. Before using a JavaScript variable, be sure to declare it. By explicitly declaring your JavaScript variables before using them, you will help the JavaScript interpreter keep the variable namespace clean and improve the performance of your application.

The following example uses the intrinsic JavaScript Date object to obtain the month, day, and year of the current date. The parts are assigned to variables that are accessible from both VoiceXML and JavaScript and could be used to build a concatenated prompt to be read back to the user.

<?xml version="1.0"?>
<vxml version="2.1"
 xmlns="http://www.w3.org/2001/vxml">

  <var name="utc_month" />
  <var name="utc_day" />
  <var name="utc_year" />

<script>
  <![CDATA[
    // explicitly declare d using var
     var d = new Date();
    // store the month
     utc_month = d.getUTCMonth();
    // store the day of the month
     utc_day = d.getUTCDate();
    // store the year including the century
     utc_year = d.getUTCFullYear();
  ]]> 
</script>
</vxml>

In addition to defining blocks of inline JavaScript, you can also define reusable script libraries by placing JavaScript in external files and by referencing them by URL using the src attribute of the script element. For example, the following example can be encapsulated in a file named dtlib.js in a scripts directory.

// Is the date/time after noon
function IsPM(d)
{
   return (d.getHours() > 12 ? true : false);
}
// Is the date/time noon?
function IsNoon(d)
{
   return (12 == d.getHours() && 0 == d.getMinutes()); 
}
// Is the date/time midnight?
function IsMidnight(d)
{
   return (0 == d.getHours() && 0 == d.getMinutes());
}
// Return the hour between 1 and 12
function GetNormalizedHour(d)
{
   var iHour = d.getHours();
   if (0 == iHour)
   {
      return 12;
   }
   else if (iHour > 12)
   {
      return iHour-12;
   }
   else
   {
      return iHour;
   }
}

If the script is contained in an external file, the code should not be enclosed in a CDATA section.

The following example demonstrates how to reference the script and to call the functions from a VoiceXML document. The result of the function calls are used to playback the appropriate audio files to the user.

<vxml version="2.1">
   <script src="scripts/dtlib.js"/>
   <form>
   <block>
      <audio src="ui/time_is.wav"/>
 
      <var name="dNow" expr="new Date()"/>
      <if cond="IsMidnight(dNow)">
         <audio src="ui/time/midnight.wav"/>
      <elseif cond="IsNoon(dNow)"/>
         <audio src="ui/time/noon.wav"/>
      <else/>
          <var name="iHour" 
             expr="GetNormalizedHour(dNow)"/>
          <var name="iMinutes" 
             expr="dNow.getMinutes()"/> 
          <audio expr="'ui/time/' + iHour"/>
          <if cond="iMinutes != 0">
   	         <audio expr="'ui/time/' + iMinutes"/>
          </if>
          <if cond="IsPM(dNow)">
             <audio src="ui/time/pm.wav"/>
          <else/>
             <audio src="ui/time/am.wav"/>
          </if>
      </if>
  </block>
 </form>
</vxml>

A variable declared in VoiceXML is accessible from JavaScript as a native JavaScript variable. The following example sets a VoiceXML variable to the numeric equivalent of the current month. The month is played back to the user by referencing an audio file. An application developer using this code would create audio files with names that correspond to the numbers returned by the getUTCMonth method of the Date object - zero through eleven.

<block>
   <var name="iCurrentMonth" />
   <script>
      var d = new Date();
      iCurrentMonth = d.getUTCMonth());
   </script>

   <!-- The current month is... -->
   <audio src="curmonth.wav"/>
   <audio expr="'ui/months/' + iCurrentMonth + '.wav'"/>
</block>

A script element can contain JavaScript functions and blocks of immediately executable script. When the VoiceXML interpreter encounters a script element, it passes the contents of the element to an instance of the JavaScript interpreter running in the scope of the element that contains the script element. A script element shares the scope of the element that contains it.

If the script element is a direct descendent of the vxml element, any JavaScript functions and variables defined within the element are accessible elsewhere in the document. If the document is the root application document, the JavaScript functions and variables are accessible throughout the application.

In the following example, app_root.vxml represents the root application document. app_doc1.vxml represents another document in the application. Here is a list of observations about the example code:

  • The variable g1, defined in app_root.vxml, can be referenced from any script element, expression, or condition in app_root.vxml and app_doc1.vxml. g1 is at application scope.
  • The JavaScript function GlobalFunc, defined in root.vxml, can be called from any script element, expression, or condition in app_root.vxml and app_doc1.vxml. GlobalFunc is defined at application scope.
  • The JavaScript function DocFunc, defined in app_doc1.vxml, can be called from any script block, expression, or condition in app_doc1.vxml. DocFunc is defined at document scope.
  • The JavaScript function LocalFunc, defined in dialog1 of app_doc1.vxml can be called from dialog1 only. LocalFunc is defined at dialog scope.
<!-- app_root.vxml -->
<vxml version="2.1">
   <var name="g1" expr="0"/>
   <script>
      function GlobalFunc() { return g1++; }
   </script>
</vxml>

<!-- app_doc1.vxml -->
<vxml version="2.1" application="root.vxml">
    <var name="d1"/>

    <script>
        function DocFunc() { return d1++; }
    </script>

    <form id="dialog1">
       <var name="l1"/>
       <var name="l2"/>

       <script>
          function LocalFunc() { return ++l1; }
      </script>

        <block>
          <script>
             l1 = GlobalFunc();
             l2 = LocalFunc();
          </script>
       </block>
    </form>
</vxml>

The following are useful resources for learning more about JavaScript:

[24]7 Inc.| Terms of Service| Privacy Policy| General Disclaimers