When working with voice input, it’s often critical to play back to the user what was understood by the server, especially in the world of crackly cell phone reception. Now that you understand how the form-processing algorithm works, we can expand our login form to include confirmation checks into the conversation and repeat back to the user what the voice recognition software heard.
To do this we’ll add two new fields to our form: confirm_id and confirm_pin. In these field items, we’ll ask the user to confirm the value the voice server has for the login-id and pin. To validate a prior field entry, our new confirm fields will need to access variables captured in another field. To access the value of any field variable, VoiceXML provides the value element, where field_id maps to the id of a field or block in our form:
Thus, our confirmation dialog will say something like the following:
I heard you say <value expr="userid"/>. Is that correct?
The problem here is that if the user enters the phone number 212 876 2110, the voice synthesizer will say the following:
"I heard you say 2 billion 128 million, 762 thousand, one hundred ten"
Ouch! Not very useful. But there’s a fix. To prevent the server from reading our phone number as a giant integer, we add a <say-as> element with an interpret-as attribute that forces the server to speak the value as a phone number, as in the following:
<say-as interpret-as="telephone"><value expr="userid"/></say-as>
Listing 2 shows our revised from that includes two new fields, confirmid and confirmpin.
Note that the data types of the two confirmation fields are the built-in boolean type. Acceptable spoken input for boolean fields are "yes", "ok", "no", "nope"; or the dtml keypress of 1 for yes, or 2 for no. When the user enters a response, we then need to take action based on whether we have an acceptable value. To take action immediately after a grammatically acceptable entry has been received, we add a <filled> element to our field. The optional <filled> element will be executed when the data item has been filled in.
In Listing 2, we check the value of our field variable and if false (the user said no or some equivalent) we clear the internal variables associated with both the pin and the confirm_pin fields. Keeping in mind the form algorithm, by clearing the variables associated with fields, we’re setting things up for the server algorithm to revisit both the pin and confirm pin fields. And since the pin field occurs higher up in the sequence, that’s where we go. Thus, by using the clear element, we can programmatically affect the sequence of blocks and forms presented to the user.
Listing 2 A VoiceXML with validation fields
<vxml version="2.0" xmlns=’http://www.w3.org/2001/vxml’ xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’ xsi:schemaLocation=’http://www.w3.org/2001/vxml http://www.w3.org/TR/voicexml20/vxml.xsd’> <form id="login"> <block> Welcome to the Baseball facts hotline. </block> <field name="userid" type="phone"> <prompt>Please say or key in your phone number</prompt> <noinput count="1">Sorry I did not hear any input for you phone number,</noinput> <noinput count="2">Hey are you asleep, or what</noinput> <nomatch count="1">Sorry, but that’s not a valid phone number</nomatch> <nomatch count="2">Phone number please.</nomatch> </field> <field name="confirmid" type="boolean"> <prompt> I heard your phone number as, <say-as interpret-as="telephone"><value expr="userid"/></say-as>, is this correct? </prompt> <filled> <if cond="confirmid==false"> <clear namelist="confirmid userid"/> </if> </filled> </field> <field name="pin" type="digits?maxlength=4"> <prompt>Please say or key in your PIN code</prompt> <noinput>Sorry I did not hear any input</noinput> <nomatch>Sorry, but that’s not a valid pin number. Please enter not more than 4 digits.</nomatch> </field> <field name="confirmpin" type="boolean"> <prompt> I heard and your pin as <say-as interpret-as="number"><value expr="pin"/></say-as>, did i get that pin correct? </prompt> <filled> <if cond="confirmpin==false"> <clear namelist="confirmpin pin"/> </if> </filled> </field> <block> Ok. thanks, submitting to our server. <submit next="http://www.example.com/servlet/login" namelist="phone_number pin_code"/> </block> </form> </vxml>