RE: XForms timer

Scott/Erik,

[Changed Erik's 'To' text, since it always says "W3C WG", which keeps
confusing me!]

I don't think this should be part of XForms. It's something that is needed
in lots of places, and has also been discussed at the DOM level in the Web
API group. However, whether you agree with that or not, it doesn't mean we
can't talk about the solution we would like, so the following is my
two-penneth worth.

We currently use something similar to a combination of both of your
proposals, like this:

  <t:setTimer
   id="clock"
   duration="1000" type="repeat"
   target="mdl-clock" event="tick"
  />

You need a name for the timer (@id) so that you can cancel it later, if need
be. You also need one-off or repeating times (setTimer() and setInterval()
in JavaScript), and of course you need the target and the name of the event
to dispatch when the time elapses. (I haven't looked at other timing modules
in other languages to see if there are other 'types', since we needed this
for something recently, but I'm sure there will be other things.)

To create a clock with this action handler, all you need do is:

  <xf:model id="mdl-clock">
    <xf:instance>
      <time xmlns="" />
    </xf:instance>

    <!--
      Set the clock to tick every second
    -->
    <xf:action ev:event="xforms-ready">
      <t:setTimer
       id="clock"
       duration="1000" type="repeat"
       target="mdl-clock" event="tick"
      />
    </xf:action>

    <xf:action ev:event="tick">
      <xf:setvalue ref="/time" value="now()" />
    </xf:action>
  </xf:model> 


At the moment we obtain t:setTimer functionality in a pre-processor module,
which expands pretty much to something like Allan's code. The only
difference is that we've set the functions up in such a way that we can call
them from XPath expressions, so that we can set the duration at run-time,
and so do things like let the user decide how often they want something to
happen. (For example, you might have a form that cycles through a list of
Flickr images and you want to allow the user to be able to slow down or
speed up the cycling, perhaps with a simple range control.) Also, we need to
name the timers because a couple of situations have come up where we need a
number of different timers going, at different rates, on the same form.

So, the 'expansion' of t:setTimer is basically as follows; first we have two
script functions, one to set up a named timer and one to dispatch the event
you want when the timer has elapsed (you only need these once per form):

  <script type="text/javascript">
    function timer_setTimer(sName, nSecs, sType, sTarget, sEvent)
    {
      if (sName[0])
        sName = sName[0].text;
      if (nSecs[0])
        nSecs = nSecs[0].text;
      if (sType[0])
        sType = sType[0].text;

      var sFn = "timer_Dispatch('" + sTarget + "', '" + sEvent + "')"; 

      switch (sType)
      {
        case "repeat":
          setInterval(sFn, nSecs);
          break;
    
        case "elapse":
        default:
          setTimeout(sFn, nSecs);
          break;
      }
      return true;
    }

    function timer_Dispatch(sTarget, sEvent)
    {
      var oEvt = document.createEvent("Event");
      var oTarget = document.getElementById(sTarget);

      oEvt.initEvent(sEvent, false, false);
      oTarget.dispatchEvent(oEvt);
      return;
    }
  </script>

Once you have these two functions in your form (either inline or in an
external JS file) you can just do this:

  <xf:setvalue ref="/SomeDummyValue"
    value="js:timer_setTimer('clock', 1000, 'repeat', 'mdl-clock', 'tick" />

At the moment this fully expanded version is what is delivered in our forms
to formsPlayer, and other than differences in the namespace expansion for
the prefix 'js', this code should work in most XForms processors. However,
it is pretty easy to set up a preprocessing step that generates the above
code from this:

  <t:setTimer
   id="clock"
   duration="1000" type="repeat"
   target="mdl-clock" event="tick"
  />

Regards,

Mark


Mark Birbeck
CEO
x-port.net Ltd.

e: Mark.Birbeck@x-port.net
t: +44 (0) 20 7689 9232
b: http://internet-apps.blogspot.com/
w: http://www.formsPlayer.com/

Download our XForms processor from
http://www.formsPlayer.com/


> -----Original Message-----
> From: www-forms-request@w3.org 
> [mailto:www-forms-request@w3.org] On Behalf Of Scott Shattuck
> Sent: 27 April 2006 19:22
> To: 'Xforms W3C WG'
> Subject: RE: XForms timer
> 
> 
> Why not simply extend dispatch as in:
> 
> <xforms:dispatch name="event-of-choice" repeat="1000" limit="5000" />
> 
> or, to allow dynamic computation and adjustment, the values 
> could be XPaths which allow both the repeat and limit values 
> to adjust based on current application state.
> 
> 
> 
> Scott Shattuck
> Architect, Team TIBET
> ss@technicalpursuit.com
> 720.220.0159
> 
> 
> -----Original Message-----
> From: www-forms-request@w3.org 
> [mailto:www-forms-request@w3.org] On Behalf Of Erik Bruchez
> Sent: Thursday, April 27, 2006 11:58 AM
> To: Xforms W3C WG
> Subject: Re: XForms timer
> 
> 
> What about:
> 
> <xforms:timer id="my-timer" timeout="1000" repeat="true"/>
> 
> The timer will just fire an event, for example 
> "xforms-timer", when necessary.
> 
> <xforms:timer id="my-timer" timeout="1000" repeat="true">
>    <xforms:send ev:event="xforms-timer" 
> submission="background-save"/> </xforms:timer>
> 
> You probably need actions and/or events to start and stop a 
> timer as well.
> 
> But it looks easier than the Javascript below, no? ;-)
> 
> -Erik
> 
> Allan Beaufour wrote:
> > On 4/26/06, Erik Bruchez <ebruchez@orbeon.com> wrote:
> >> If you can't do it directly with XForms, how do you do it, with
> Javascript?
> > 
> > <html xmlns="http://www.w3.org/1999/xhtml"
> >       xmlns:ev="http://www.w3.org/2001/xml-events"
> >       xmlns:xforms="http://www.w3.org/2002/xforms">
> >   <head>
> >     <title>Timer</title>
> >     <script type="text/javascript">
> >       function timer() {
> >         var ev = document.createEvent("Events");
> >         ev.initEvent("increment", true, true);
> > 	document.getElementById("setv").dispatchEvent(ev);
> > 	window.setTimeout(timer, 1000);
> >       }
> > 
> >       window.setTimeout(timer, 1000);
> >     </script>
> >     <xforms:model>
> >       <xforms:instance xmlns="">
> >         <data xmlns="">
> >           <counter>1</counter>
> >         </data>
> >       </xforms:instance>
> >       <xforms:setvalue id="setv" ref="counter" value=". + 1"
> > 		       ev:event="increment"/>
> >     </xforms:model>
> >   </head>
> >   <body>
> >     <xforms:output ref="counter">
> >       <xforms:label>Counter: </xforms:label>
> >     </xforms:output>
> >   </body>
> > </html>
> > 
> > --
> > ... Allan
> > 
> 
> --
> Orbeon - XForms Everywhere:
> http://www.orbeon.com/blog/
> 
> 
> 
> 
> 

Received on Thursday, 27 April 2006 21:37:32 UTC