Selecting Categories and Products
Now that we've loaded the CategoryNav selectable navigator with categories, we prompt the user to select a category from the list. The CategoryNav control allows for an initial prompt to be read to the user and then proceeds to read each category in the list. The CategoryNav_prompt
function is indicative of SelectableNavigator
prompt functions used throughout the CommerceVoice application.
text = "";
lastCommandOrException = "NoReco";
lastCommandOrException = "";
// Fall through.
text = categoryName;
". <withtag tag='CategoryCount'>" +
+ "</withtag> " + description + " ");
The prompt function determines what to read back to the user based on the lastCommandOrException
parameter. In this function, when they request the contents of the category (i.e. by saying "Read"), we treat the user's response as a no recognition condition. Also, because navigator application controls have their own unique error handling which does not apply to normal QA controls, the PromptGenerator.GenerateNavigator
function is called instead of PromptGenerator.Generate
Parameters are used to retrieve the category name used to read the categories to the user and for more detailed information when the user asks for help (see Figure 10
|Figure 10: Setting the parameters used to retrieve category names and detailed help information.|
The SelectableNavigator control allows us to store multiple columns of information for each category, such as the number of products in a category and the category description.
The SelectableNavigator treats silence as the "Next" command when reading categories to the user. If the user is silent, the next category is read. This is the default behavior of the navigator application control encapsulated by the SelectableNavigator control.
When the user selects a category from the list, the SelectCategory
client-side handler function is called.
We use the attribute collection associated with the semantic item to store related information. In this case, the category ID is stored along with the category name in the semantic item. The true
parameter in the SetText
function call changes the state of the semantic item to Confirmed
Retrieving the List of Products
property for the siCategory
semantic item is set to true
. This means when the state changes to NeedsConfirmation
, the page is automatically posted back to the server. In the Page_Load event, we check the state of siCategory
to determine if we can load the products for the selected category into the ProductNav user control. The selected category is passed back to the database to retrieve the list of products for that category.
Adding Items to the Cart
if (siCategory.State != SemanticState.Empty)
The AddToCartQA is used to read the selected product and price to the user and to determine if the user wants to add the product to their shopping cart. First, we assign the BaseQAStyle to the QA defined in GlobalSpeechElements1. As described earlier, this provides us with common threshold settings and adds support to handle the three mumbles or silences in-a-row case.
is a Client Activation function for this QA. RunSpeech calls this function to determine if the QA is available for activation. Returning true
allows RunSpeech to activate the control. We only want this QA to be active if the user has selected a product.
function IsProductSelected (id, lastCommandOrException,
The value of the siAddToCart
semantic item is only used to control program flow on the page. If the item is empty and the user has selected a product, RunSpeech will activate the AddToCartQA. Once the user tells the system they wish to add the product to their cart, the siAddToCart
semantic item is no longer empty and RunSpeech moves on to the next QA on the page.
There are two additional commands scoped only to the AddToCartQA: the Description
command and the First
command. The Description
command is used to play back a description of the product. Because the product descriptions are very long, prompts are constructed in a special way described in the Recording_Long_Prompts
section of this document.
The other command scoped to this QA is the First
command. When the user is in the SelectableNavigator control hearing a list of products, they can say "First" to navigate to the first item in the list. We wanted that same functionality for this QA. When the user says "First," the OnFirstCmd client handler function is called.
function OnFirstCmd (smlNode)
Notice that the category semantic item is not cleared and the CategoryNav SelectableNavigator is not activated since we want to use the same category. Also, since the CategoryNav and ProductNav controls are already loaded with category and product data, we do not need to post back to the server to retrieve this data from the database again.
Specifying the Number of Items
Now that the user wants to add the product to their shopping cart, we ask them how many items of the selected product they wish to add. We use the cardinal_999 rule from the Grammar Library (the cmnrules.cfg
file) that ships with the Speech SDK. Refer to the SDK documentation for more information on the Grammar Library. The siNumberOfItems
semantic item is filled with the number of items for this product the user wishes to add to their shopping cart.
At this point, we allow the user to say "Cancel" to return to the list of products. Instead of returning them to the first item in the product list, we return them to the item they previously selected. The Cancel command is scoped only to the NumberOfItemsQA. The ReturnToProductList
client handler function is called when the user says Cancel.
function ReturnToProductList (smlNode)
When the product is selected we save the index of the product in the list in the attributes collection of the siProduct
semantic item. ReturnToProductList
sets the index of the ProductNavigator to this saved value so that when RunSpeech activates the ProductNav control again, the previously selected product will be read back to the user. The siAddToCart
semantic item is also cleared so that when the user selects another product they are prompted to add the item to their cart.
Confirming the Number of Items
The NumberOfItemsConfirm QA confirms the siNumberOfItems
semantic item set in the previous QA. Note that in the Answers tab of the NumberOfItemsQA, the Confirm Threshold for the siNumberOfItems
semantic item is set to 1 (see Figure 11
|Figure 11: Setting the Confirm Threshold for the number of items.|
By setting the Confirm Threshold to 1, we require the semantic item to always be confirmed. Setting the Confirm Threshold to a lower value would require confirmation of the item based on the confidence level. For instance, setting the Confirm Threshold to .5 would only require a confidence level of .5 or greater to automatically confirm the item. In that case, the NumberOfItemsConfirm QA would be skipped by RunSpeech since the item was already confirmed. Setting the Confirm Threshold to 1 ensures that this QA will never be skipped by RunSpeech.
The grammar for the NumberOfItemsConfirm QA allows the user to say "Yes," "No," or "No, I said three" (or any valid cardinal number). You can see this by looking at the QuantityConfirm grammar diagram (see Figure 12
|Figure 12: Here's the grammar diagram for the QuantityConfirm interation.|
Saying "Yes" confirms the item. RunSpeech will automatically set the state of the siNumberOfItems
semantic item to Confirmed. Saying "No" will set the semantic item's state to Empty. In this case, since the semantic item's state is Empty, the previous QA (NumberOfItemsQA) would be activated again and the user would be prompted for the quantity.
Saying "No" and a different number will set the state of the semantic item to empty, but would also fill its value with the new quantity without activating the previous QA. This provides the user familiar with the CommerceVoice application with a way to correct the quantity value quickly. This is easy to set up using the property builder for the NumberOfItemsConfirm QA (see Figure 13
|Figure 13: Use the property builder for the NumberOfITemsConfirm QA to give the user a chance to correct a quantity value by saying "No."|
First, notice that the Confirms tab is used instead of the Answers tab. This tells RunSpeech to confirm the semantic items in the list. We use XPath to tell RunSpeech what to extract from the SML document that is returned from the grammar file. For a simple Yes/No confirm, all that is required is a grammar that returns yes or no. We also allow the user to also specify a new quantity by providing an XPath trigger for siNumberOfItems