Introduction
In the first part of this tutorial on xml-script we introduced type descriptors and learned how to read them. In this second part we'll see how to declaratively handle events raised by client side controls.
Handling events
When talking about type descriptors in the first part of the tutorial, we stated that exposing a descriptor allows instantiating client side components using xml-script. Just by looking at the type descriptor of a class, we could get an idea of how the xml-script needed to create an instance, should look. For example, the Sys.Preview.UI.Button and the Sys.Preview.UI.Label classes contained in the PreviewScript.js file expose the following descriptors:
Sys.Preview.UI.Button.descriptor = {
properties: [ { name: 'command', type: String },
{ name: 'argument', type: String } ],
events: [ { name: 'click' } ]
}
Sys.Preview.UI.Label.descriptor = {
properties: [ { name: 'htmlEncode', type: Boolean },
{ name: 'text', type: String } ]
}
All the information we need to write the code in the following example is contained in the above descriptors. The code, based on the standard structure of an xml-script block of code, creates an instance of both the Button and the Label classes and wires the click event of the button with a JavaScript function that displays a message on the label.
<%@ Page %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Hello XML-script</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="TheScriptManager" runat="server">
<Scripts>
<asp:ScriptReference Assembly="Microsoft.Web.Preview"
Name="Microsoft.Web.Resources.ScriptLibrary.PreviewScript.js" />
</Scripts>
</asp:ScriptManager>
<div>
<input type="button" id="btnSay" value="Click Me" />
</div>
<div>
<h1><span id="lblHello"></span></h1>
</div>
<script type="text/xml-script">
<page xmlns="http://schemas.microsoft.com/xml-script/2005">
<components>
<label id="lblHello" />
<button id="btnSay" click="btnSay_click" />
</components>
</page>
</script>
<script type="text/javascript">
<!--
function btnSay_click(evt) {
$find('lblHello').set_text('Hello XML-script!');
}
//-->
</script>
</form>
</body>
</html>
After running the page, take a look at the xml-script code and specifically at the elements created under the components node. The first one is a label tag, that is mapped to the name of the client side type to instantiate: Sys.Preview.UI.Label. The id attribute is mapped to the id property of the Label instance. The second tag is button and, when parsed by the Microsoft Ajax runtime, it is used to create an instance of the Sys.Preview.UI.Button class with the id property set to btnSay.
The interesting part is the click attribute of the button element, whose value is the name of the global JavaScript function btnSay_click declared in the subsequent block of JavaScript code. An event exposed in the type descriptor is mapped to an xml attribute with the same name of the event. The value of the attribute is the name of the JavaScript function used to handle the event.
Let's examine a second way of handling an event raised by a client side control. Replace the line that contains the button tag with the following code:
<button id="btnSay">
<click>
<setPropertyAction target="lblHello" property="text"
value="Hello XML-script!" />
</click>
</button>
Now try running the page: nothing changes and everything works as before. What's going on?
Actions
An event exposed in a type descriptor can also be parsed also as an XML tag with the same name of the event. The contents of this element are one or more child elements that represent objects called actions.
An action is an object that encapsulates some built-in logic that is executed in response to an event. In the last example we are handling the click event of the button with an action called SetProperty, which allows setting a particular property exposed by a Microsoft Ajax component. This action is actually an instance of the Sys.Preview.SetPropertyAction class and, like many other classes, exposes its own type descriptor:
Sys.Preview.SetPropertyAction.descriptor = {
properties: [ {name: 'property', type: String},
{name: 'propertyKey' },
{name: 'value', type: String} ]
}
If you compare the descriptor of the SetPropertyAction class with the corresponding xml tag you'll notice that, as usual, the name of the class is mapped to the name of the corresponding xml element. The target property becomes a target attribute in the xml-script and its value is the id of the Label control that exposes the text property that is going to be modified. The value attribute contains the text that will be set in the label.
The SetPropertyAction's descriptor also exposes a property called propertyKey. Its purpose is to reach attributes that are children of other properties. Again, try to replace the line that contains the button tag with the following code:
<button id="btnSay">
<click>
<setPropertyAction target="lblHello"
property="text"
value="Hello XML-script!" />
<setPropertyAction target="lblHello"
property="element"
propertyKey="style.backgroundColor"
value="#FFFF00" />
</click>
</button>
In this case, we're declaring two actions; the first one sets the label's text, while the second one changes the background color of the label to yellow. The value of the property attribute is the name of the element property, which returns the DOM element associated to the Label control (the span element). While the value of the property attribute must be the name of a property whose name is prefaced by get_, the propertyKey attribute contains the path used to reach an expando attribute. In this case we are accessing the backgroundColor attribute of the style object; the following is the corresponding JavaScript statement:
$find('lblHello').get_element().style.backgroundColor = '#FFFF00';
Summary
Xml-script allows instantiating client side components that expose a type descriptor, using declarative code. It allows handling events raised by Microsoft Ajax components by calling a global JavaScript function or by executing one or multiple actions.
In the next part of this tutorial we'll continue the discussion about events and introduce other built-in actions available in the Microsoft Ajax Library.
References
Xml-script tutorial Part 1
Xml-script tutorial Part 2
Xml-script tutorial Part 3
Xml-script tutorial Part 4
About Alessandro Gallo
 |
Alessandro "Garbin" Gallo is a Microsoft MVP in the Visual ASP/ASP.NET category and a .NET developer/consultant. He is a contributor for the Ajax Control Toolkit project, owned by Microsoft. Alessandro won the Grand Prize at the "Mash-it-up with ASP.NET AJAX" contest held by Micr...
View complete profile
|
Please login to rate or to leave a comment.