2.5. Form items

VoiceXML defines a "form item" as an element that is a child of form and is of one of the following element types:

  • field,

  • block,

  • initial,

  • subdialog,

  • object,

  • record,

  • transfer.

Up until now, we've only discussed the first of these - the field element type. We have also seen form-level filled elements, but these are not considered "form items." A form item has a very particular meaning with respect to the Form Interpretation Algorithm.

Every form item has the following:

result variable

This is an ECMAScript variable whose name is defined by the form item's name attribute, and whose scope is that of the containing dialog. When a form item has been successfully visited, its result variable will contain the result of that visitation. For example, a field's result variable will contain the answer collected from the caller.

guard condition

This is an ECMAScript expression specified by theform item's cond attribute, which must evaluate to true in order for this form item to be visited.

count variable

This is an internal variable that keeps track of how many times the VoiceXML interpreter has attempted to fill a form item in a given invocation of the dialog.

Form items can be further classified into field items - those that interact with the user to collect a value (object is an exception in that it interacts with a software system instead of the user), and control items - those that guide the collection process.

The field items, namely field, object, subdialog, transfer, and record, can contain elements of the following types:

prompt

Specifies how this field item should be described to the user.

grammar

Specifies how this field item's value should be collected from user.

filled

Contains elements to be executed once this field item's value has been collected.

catch, error, help,noinput, and nomatch

Provide a local method of handling exceptional behavior.

property

Specifies a system property local to this field item.

For the sake of this discussion, we can consider the term "form item" to mean an element that represents a piece of information to be retrieved as part of a form and whose value can be determined by the execution of that element. Furthermore, any form item can be accessed as a variable once its value is determined.

The sections that follow will describe in detail these form item elements excluding field, which was covered in 2.1.2, “The field element type,” on page 29 and 2.1.3, “A field's value as a variable,” on page 30, and initial, which is covered in 2.6, “Mixed initiative forms,” on page 76. Before this, though, let's briefly examine those elements that can be children of form but are not form items per se. These include:

  • filled which describes a behavior to be used when either the entire form is filled, or any of a specific set of field items have been filled,

  • elements that describe input grammars, such as grammar and dtmf (note that dtmf has been deprecated in VoiceXML 2.0),

  • elements that describe event handlers, such as link, catch, help,nomatch, noinput, and error,and

  • var and property elements that define form-level variables and properties.

2.5.1. The record element type

A record element records digitized audio from the caller. This could be used, for example, to collect a voice message in a voice-mail system. Example 2-28 shows how record might be used:

Example 2-28. Using record and submit to post data up to a server
<?xml version="1.0" encoding="iso-8859-1"?>
<vxml>
  <form id="collectMessage">
    <record name="voiceMessage" beep="true" finalsilence="3000">
      <prompt>Please state your name after the tone. </prompt>
    </record>

    <field name="phoneNumber" type="digits?length=10">
      <prompt>
        Please say a phone-number where you can be reached, 
        including the area-code.
      </prompt>
    </field>

    <filled mode="all">
      <submit next="AcceptMessage.jsp" method="post" 
                          namelist="phoneNumber voiceMessage"/> 
    </filled>
  </form>
</vxml>

Unlike a field element's result variable that stores a string value, the record element's result variable contains an actual audio recording. Therefore on most platforms you can neither evaluate nor manipulate a record result variable from ECMAScript. You can, however, pass this variable up to an HTTP server using submit, as shown in Example 2-28. The result can also be played back using the value element.

There are several ways in which the caller can indicate to the VoiceXML interpreter that he has finished recording his message. If the record element's dtmfterm attribute is set to true, the caller can press any DTMF key to terminate their recording. If the record's finalsilence attribute is set to some number of milliseconds, any silent period after the caller has recorded his or her message, of at least that number of milliseconds, will be interpreted to mean the caller has completed their message.

In the latest version of the VoiceXML 2.0 Specification, the record element may contain grammar elements that represent grammars to remain active during the recording process. If the caller triggers one of these grammars during the recording process, this too would terminate the recording.

The record element's type attribute determines the format of the audio file submitted. The type must be an audio format supported by the VoiceXML platform. One can assume that 8 bit 8 kHz PCM type format (e.g. WAV file format) is supported. Different implementations might support other formats as well.

2.5.2. The transfer element type

A transfer element allows the voice application author to transfer the caller to another line. The form in Example 2-29 demonstrates the use of a transfer element.

Example 2-29. Blind transfer
<?xml version="1.0" encoding="iso-8859-1"?>
<vxml>
  <form id="custSvc">
    <field name="verify" type="boolean">
      <prompt>
        Would you like to speak with a customer service 
        representative?
      </prompt>
    </field>

    <transfer cond="verify=='true'" dest="tel:18005551212" 
                                               bridge="false"/>
  </form>
</vxml>

Here, transfer is only visited if the response to the verify field was affirmative, as specified in the transfer element's guard condition. The telephone number to be transferred to is specified using the dest attribute. The tel: convention is used here to express telephone numbers as URIs.

We also instruct the interpreter to make "blind" transfer by setting the bridge attribute to false. A blind transfer means the VoiceXML interpreter initiates the transfer of the caller to the destination and then disconnects itself from the call, regardless of whether the transfer was successful. Once the VoiceXML interpreter successfully disconnects itself, it will throw a telephone.disconnect.transfer event which usually results in the VoiceXML interpreter being reset to receive a new call.

A bridge transfer is the opposite of a blind transfer. A bridge transfer means the VoiceXML interpreter will remain connected to both the original caller and to the destination phone terminal. This is useful in that it allows grammars to remain active. An example of a bridge transfer is shown in Example 2-30.

Example 2-30. Bridge transfer
<transfer cond="verify=='true'" dest="tel:18005551212" 
                                                 bridge="true">
  <grammar>continue</grammar>
  <filled>
    Continuing.
    <goto next="#mainMenu"/>
  </filled>
</transfer>

Example 2-31 shows a possible dialog using a bridge transfer.

Example 2-31. A dialog demonstrating a bridge transfer
IVR     : I will connect you to the pre-recorded weather phone 
          service. At any time you may say "continue" to be 
          returned to this system.


VoiceXML interpreter dials the weather phone service. Progress tones audible.

Service : Welcome to the weather phone service. There are no travel 
          advisories in the Northern Colorado area. There is a snow 
          advisory in the Southern Colorado area until noon today. 
          There is --
Caller  : Continue.
IVR     : Continuing. Please select from the following options...

The VoiceXML interpreter used a bridge transfer with an active grammar to connect the caller to a third party, but is still listening in for the word "continue."

The ability to transfer calls depends on the integration between the IVR and switching hardware. These topics will be covered in greater detail in Chapter 5, “Voice services,” on page 362.

2.5.3. The subdialog element type

A subdialog element can be used to call another form as if it were a subroutine. The form that is being called as a subdialog must end with a return element. A subdialog form can also accept input parameters. These are passed using param elements embedded within the calling subdialog.

Let's consider a telephone pizza ordering service. Let's say we want to abstract out the collection of credit card information from filling in the pizza order. This way we can use the credit card collection subdialog in other applications. Example 2-32 is the VoiceXML form for ordering pizza. It calls a subdialog for handling the credit card information.

Example 2-32. Form for ordering pizzas
<form id="orderPizza">
  <var name="purchaseAmount"/>
  <field name="largePies" type="number">
    <prompt> How many large pies would you like to order? </prompt>
    <filled> Got it! </filled>
  </field>

  <field name="smallPies" type="number">
    <prompt> How many small pies would you like to order? </prompt>
    <filled> Got it! </filled>
  </field>

  <filled mode="any" namelist="largePies smallPies">
    <if cond="(largePies != null) && (smallPies != null)">
      <assign name="purchaseAmount" 
                          expr="largePies*8.95 + smallPies*5.95"/>
      <prompt>
        Your total comes to <value expr="purchaseAmount"/>.
      </prompt>
    </if>
  </filled>

  <subdialog name="cc_results" src="#validateCard">
    <param name="amount" expr="purchaseAmount"/>
    <filled>
      <prompt>done</prompt>
      <if cond="cc_results.status == 'invalid'">
         Sorry, your credit card information could not be
         obtained.
         <exit/>
        <else/>
         Your credit card information has been processed.
       </if>
    </filled>
  </subdialog>

  <filled mode="all">
    Your total, <value expr="purchaseAmount"/>, has been charged
    to your credit card.
    We are scheduling your order to be delivered to 
    <value expr="cc_results.address"/>
    Goodbye.
    <disconnect/>
  </filled>
</form>

This form collects the number of large pies and then the number of small pies that the caller would like to order. It uses a mode-any filled to compute purchaseAmount, the total price once both of those fields are complete.

It then calls the form validateCard using subdialog. Let's assume that this document contains a form with id set to validateCard which implements a credit card validation dialog. The variable purchaseAmount is passed to this form as a parameter using the param element. The subdialog has a result variable within the orderPizza form named cc_results. When the VoiceXML interpreter calls the validateCard subdialog it will return its results into cc_results.

The remainder of this form looks at cc_results.status to ensure that the credit card was valid, and then looks at cc_results.address to get the billing address associated with this credit card.

We know that status and address are members of cc_result's response variable by looking at the validateCard form's return element, shown in Example 2-33. The return element specifies a namelist attribute that indicates the names of the variables that should be returned from the subdialog back to the calling dialog.

Example 2-33. The validateCard form
<form id="validateCard">
  <var name="amount"/>
  <var name="address"/>
  <var name="status"/>

  <field name="cardNumber" type="digits?length=16">
    <prompt>Please say your 16 digit credit card number.</prompt>
  </field>

  <field name="expirationDate" type="digits?length=4">
    <prompt>Please say the 4 digit expiration date.</prompt>
  </field>

  <subdialog name="validate" src="CreditCheck.jsp" 
                             namelist="cardNumber expirationDate">
    <param name="cardNumber" expr="cardNumber"/>
    <param name="expirationDate" expr="expirationDate"/>
    <filled>
      <assign name="address" expr="validate.address"/>
      <assign name="status" expr="validate.status"/>
    </filled>
  </subdialog>

  <filled mode="all">
    <return namelist="status address"/>
  </filled>
</form>

This form is specially designed to be called as a subdialog. We know this because:

  • it declares a variable for input parameter amount;

  • it declares variables for output parameters address and status;

  • it concludes with a return element, and that element's namelist attribute lists all of the output parameter variables.

This form collects from the caller his or her 16 digit credit card number and 4 digit expiration date and then calls yet another subdialog, CreditCheck.jsp, to check this credit information. It then copies the results of this credit check into its output parameter variables then returns them to the calling dialog - the orderPizza dialog.

The validateCard dialog is a static subdialog. Its contents are not generated dynamically. CreditCheck.jsp, on the other hand, is a dynamic subdialog as its contents are generated from a JSP page. Since it is a dynamic subdialog, we want to pass parameters to the HTTP server instead of the VoiceXML subdialog form. This is done using the subdialog's namelist attribute. Any variables listed in the namelist attribute will be passed up to the HTTP server using either get or post method as specified by the method attribute. The default is get. The JSP engine uses these parameters to look up the credit card information and produce a response dialog based on the lookup results. An example of a response dialog generated by CreditCheck.jsp might look like Example 2-34.

Example 2-34. A possible response from CreditCheck.jsp
<?xml version="1.0" encoding="iso-8859-1"?>
<vxml>
 <form id="retrieveCreditInfo">
    <!-- Input Parameters -->
    <var name="cardNumber"/>
    <var name="expirationDate"/>

    <!-- Return Parameters -->
    <var name="address" expr="'not available'"/>
    <var name="status" expr="'invalid'"/>

    <block>

      I was able to retrieve your credit card information.
      <assign name="address" expr="'Tenement. Lower East Side'"/>
      <assign name="status" expr="'valid'"/>

      <return namelist="address status"/>
    </block> 
  </form>
</vxml>

Once the JSP script generates this response dialog, it will be returned to the VoiceXML interpreter and called by the interpreter as a subdialog. Therefore, the response dialog must be specifically designed to be called as a subdialog.

This dialog takes two parameters and returns two parameters: address and status. Both of these parameters must have variables defined at the beginning of the dialog. In addition, this dialog must conclude by returning address and status with a return element.

The end result is a dialog like Example 2-35.

Example 2-35. A caller scenario
IVR     : How many large pies would you like to order?
Caller  : One.
IVR     : How many small pies would you like to order?
Caller  : Zero.
IVR     : Your total comes to eight dollars and ninety five cents.


Interpreter calls validateCard as a subdialog.

IVR     : Please say your 16 digit credit card number.
Caller  : 1111222233334444
IVR     : Please say your 4 digit expiration date.
Caller  : 0601

Interpreter passes this credit card number and expiration date in an HTTP request to CreditCheck.jsp. This JSP dynamically generates a VoiceXML document based on these values.

IVR     : I was able to retrieve your credit card information.

This dynamically generated page contains a return element passing the credit card owner's address and the retrieval status back to validateCard that in turn contains a return element returning these values back to the orderPizza dialog.

IVR     : Your credit card information has been processed.
          Your total, eight dollars and ninety five cents, has been
          charged to your credit card. We are scheduling your
          order to be delivered to 'Tenement. Lower East Side.'
          Goodbye.

This example has demonstrated two main uses of subdialogs:

  • Reusing a frequently used VoiceXML form. In our case, the static subdialog validateCard collects credit card number and expiration date.

  • Interacting with dynamically generated VoiceXML document susing subdialog's namelist attribute. In our case, the dynamic CreditCheck.jsp dialog performs the credit database lookup and returns its results in the form of a VoiceXML document containing a subdialog form.

The topic of interaction between the VoiceXML interpreter and dynamic documents will be discussed in greater detail in Chapter 4, “Enterprise voice application architecture,” on page 308.

2.5.4. The object element type

An object element allows the voice application author to call vendor specific non-VoiceXML code resident in the VoiceXML interpreter. The object element type provides several attributes for indicating which method to call, the library, class, or package in which to find that method, and the parameters passed to that method. These attributes include:

classid

Specifies a URI to a class or method. Often the URI can been coded to contain both. For example,

method://BankAccount/makePayment

may refer to the makePayment() method in the BankAccount class.

data

Specifies the URI of the package or library. For Java, for example, this attribute could specify the location of a jar-file:

http://www.BankingCorp.com/banksystem.jar

In addition, param elements can be contained in an object to pass parameters to the method. Since object is a form item, it has a result variable specified by its name attribute. The value returned by the native method is an ECMAScript object that will be placed in the VoiceXML result variable.

Example 2-36 uses an object element to call a "native function" in the interpreter.

Example 2-36. A "native call" using an object element
<object name="debit"
  classid="method://BankAccount/makePayment"
  data="http://www.BankingCorp.com/banksystem.jar"/>
  <param name="amount" expr="document.amt"/>
  <param name="vendor" expr="vendor_num"/>
</object>

The name attribute of an object identifies the VoiceXML variable name used to reference the output of this native call. The classid and data attributes identify the native code to be called. The param elements occurring within the object element allow the voice application to specify the parameters passed into this native call. The name="amount" attribute instance in the first param indicates the parameter name of the function being called. The expr="document.amt" attribute instance indicates the value being passed in for this parameter.

Let's assume that the object element shown in Example 2-36 maps to a Java virtual machine call. Let us also assume that there is a class in the banksystem.jar file defined minimally as follows:

Public class BankAccount{
       static int makePayment(int amount, string vendor);
       ...
}

The object in Example 2-36 would then represent a call on this object equivalent to the following line of Java-code:

BankAccount.makePayment(the value of VoiceXML variable document.amt,
                               the value of VoiceXML variable vendor_num);

While this is one possible way of using object to call native code, the actual protocol specifying what goes in the classid and data attributes is platform specific. If a specific object is not supported on a platform, an error.unsupported.object event is thrown. In general, to avoid platform dependency issues, you should steer away from using object.

The object element was inspired by the object tag in HTML. As of the writing of this book however, the object element has only been implemented on a few VoiceXML platforms and in somewhat non-standard ways. As such the real usage for this sort of feature has yet to be figured out for VoiceXML.

2.5.5. The block element type

A block element can be used to perform an action in a form without interacting with the user. One use of block is to make a simple non-interactive form, such as an announcement form. This is demonstrated in Example 2-37.

Example 2-37. A simple announcement form using block
<?xml version="1.0" encoding="iso-8859-1"?>
<vxml>
  <form id="announce">
    <block name="msg">
      The following schools are closed due to bad weather: <break/>
      PS-101 <break/>
      PS-105 <break/>
      PS-36  <break/>
      PS-42  <break/>

      All other schools are operating on half-day schedules.
    </block>
  </form>
</vxml>

A block is a form item so it will be executed in accordance with the Form Interpretation Algorithm. Being a form item, it also has a result variable specified using the name attribute. The block result variable can therefore be used to affect the Form Interpretation Algorithm just like any other form item.

Consider the form shown in Example 2-38. The explicit clearing of member will force the block to be repeated indefinitely!

Example 2-38. Forcing a reenter on a block
<form id="welcome">
  <block name="member">
    <prompt>Welcome to member services</prompt>
    <clear namelist="member"/>
  </block>
</form>

While blocks are one of the simplest types of form items, they provide a handy way to embed procedural logic into VoiceXML forms.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.83.178