Using the power of binding to animate changes
In a recent post, I showed how the binding component can be instantiated independently of the {binding} markup extension. But there’s a whole lot more it can do.
For instance, it has two very interesting callback properties, convert and convertBack that get called any time the binding sees a change respectively on the source or on the target of the binding. The original purpose of those functions is to handle the back and forth conversion of data.
For example, if you’re binding an input tag’s value property to a column of type Date, you’ll want to set convert to a function that formats the date according to the current culture, and convertBack to a function that parses it back from string form to date form.
But this couple of functions can also be used as change event handlers of sorts and even if we have no conversion to do, we can still use them to trigger some side effects, such as an animation. The functions get the value to convert and the binding as the parameters, and return the converted value. Here is a function that triggers an animation on the target of the binding and then returns the unchanged value that got passed in:
function flashTarget(value, binding) { var target = binding.get_target(); if (target.nodeType == 3) { target = target.parentNode; } $(target) .jFade({ property: 'background', start: 'FFFF00', end: 'FFFFFF', steps: 25, duration: 30 }); return value; }
The function first gets the target element from the binding component. Then it looks at the type of the target element because in the case of a text node you really want to animate its parent, not the text node itself. Then, we’re using jQuery and the jFade plug-in to animate the element. And finally, of course, we return value unchanged.
Adding the binding animation is as simple as specifying a convert or convertBack function on each binding, for example:
<span>{binding answer, convert=flashTarget}</span>
Here’s the complete code for the sample page:
<%@ Page Language="C#" %> <!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 runat="server"> <title>Binding</title> <script type="text/javascript"> var data = {
question: "Life, the universe and everything",
answer: 42
}; function flashTarget(value, binding) { var target = binding.get_target(); if (target.nodeType == 3) { target = target.parentNode; } $(target) .jFade({ property: 'background', start: 'FFFF00', end: 'FFFFFF', steps: 25, duration: 30 }); return value; } </script> </head> <body xmlns:sys="javascript:Sys" xmlns:dataview="javascript:Sys.UI.DataView" sys:activate="*"> <form id="form1" runat="server"> <asp:ScriptManager runat="server" ID="SM1"> <Scripts> <asp:ScriptReference Path="~/Script/MicrosoftAjaxTemplates.js" /> <asp:ScriptReference Path="~/Script/jquery-1.2.6.js" /> <asp:ScriptReference Path="~/Script/jquery.jfade.1.0.js" /> </Scripts> </asp:ScriptManager> <div sys:attach="dataview" dataview:data="{{ data }}"> <span id="questionDisplay">{binding question,
convert=flashTarget}</span><br /> <input type="text" id="question" value="{binding question, convertBack=flashTarget}"/><br /> <span id="answerDisplay">{binding answer,
convert=flashTarget}</span><br /> <input type="text" id="answer" value="{binding answer, convertBack=flashTarget}"/> </div> </form> </body> </html>
The page contains two input boxes and two labels that reflect the same values that are in the input boxes. Any time the text in one of the boxes is changed, both the box and the label that’s bound to the same data will flash yellow then fade back into white:
Cool, uh?