5 Replies Latest reply on May 29, 2010 8:53 AM by willise414

    Timer Question

    willise414

      I have an application which has a text input that places the input into a datagrid. I have created a timer that begins counting when the item is inserted into the datagrid. The counter is contained in a label.

       

      What I need to do is add multiple items to the datgrid, each with their own, individual timer. My button to submit the text input data to the datgrid has click="startTimer()", which works, however, I need to do this for every item I submit. I think the key may be removing the label that contains the timer.

       

      My initial thought is to bind the text input to the label, but that doesn't seem to work.

       

      Any ideas on how to accomplish this? I can post the code if anyone needs more clarification.

       

      Thanks!!

        • 1. Re: Timer Question
          jsd99 Level 3

          does every item in the datagrid have its own timer?  if so, then you just create an array of objects for the datagrid, and each object has a timer property.

           

          when someone clicks on the datagrid, use the itemClick handler, then access:  event.itemRenderer.data.timer.

           

          example:

           

          <?xml version="1.0" encoding="utf-8"?>

          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600" creationComplete="init()">

          <mx:Script>

          <![CDATA[

          import mx.events.*;

           

          private function init():void {

               var o:Object = new Object();

               o.label="hi mom";

               o.timer = new Timer(500, 1);

               trace("i stored " + o.timer);

           

               dg.dataProvider = new Array(o);

          }

           

          private function iclik(le:ListEvent):void {

               trace(le.itemRenderer.data.timer);

          }

          ]]>

          </mx:Script>

          <mx:DataGrid id="dg" itemClick="iclik(event)" />

          </mx:Application>

          run this with debug mode on and you'll see that the timer that goes in in init() comes out in iclik().

          1 person found this helpful
          • 2. Re: Timer Question
            willise414 Level 1

            I think I understand what you are saying. Here is my code:

             

            <?xml version="1.0" encoding="utf-8"?>
            <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                  xmlns:s="library://ns.adobe.com/flex/spark"
                  xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="init()">
            <fx:Declarations>
              <!-- Place non-visual elements (e.g., services, value objects) here -->
             
              <mx:DateFormatter id="df" formatString="JJ:NN:SS" />
             
            </fx:Declarations>

            <fx:Script>
              <![CDATA[
               import mx.collections.ArrayCollection;
               import flash.events.TimerEvent;
               import flash.utils.Timer;
               import mx.events.DragEvent;
              
               [Bindable]
              
               public var dgItems:ArrayCollection = new ArrayCollection();
              
               public function addItem():void
               {
                var temp:Object = new Object();
               
                temp = ({name:name_input.text,overtime:overtimeCheck.selected.valueOf()});
                dgItems.addItem(temp);
               
                name_input.text = "";
                onBreak_input.text = "";
                overtimeCheck.selected = "";
               }
              
               private const TIMER_INTERVAL:int = 0;
              
               private var baseTimer:int;
              
               private var t:Timer;
              
               private function init():void
               {
                t = new Timer(TIMER_INTERVAL);
                t.addEventListener(TimerEvent.TIMER, updateTimer);
               }
              
               private function updateTimer(evt:TimerEvent):void
               {
                var ms:Number=getTimer() - baseTimer;
                var d:Date = new Date(0,0,0,0,0,0,ms);               
                counter.text = df.format(d);
               }
              
               private function startTimer():void
               {
                baseTimer = getTimer();
                t.start();
               }
              
               private function stopTimer():void
               {
                t.stop();
               }
              
               private function dragCompleteHandler(event:DragEvent):void
               {
               
                baseTimer = getTimer();
                t.start();
               }
              
              ]]>
            </fx:Script>
              

            <mx:DataGrid x="51" y="32" dataProvider="{dgItems}"
                 dragEnabled="true" dropEnabled="true" dragMoveEnabled="true"
                 dragComplete="dragCompleteHandler(event)">
              <mx:columns>
               <mx:DataGridColumn headerText="Name" dataField="name" />
               <mx:DataGridColumn headerText="Break" dataField="onBreak"/>
               <mx:DataGridColumn headerText="Overtime" dataField="overtime" draggable="false" />
              </mx:columns>
            </mx:DataGrid>

            <s:TextInput x="518" y="64" id="name_input"/>

            <s:Button x="518" y="132" label="Button" id="button" click="addItem(), startTimer()" />

            <s:CheckBox x="518" y="104" label="Overtime" id="overtimeCheck" enabled="true" />
             
              <s:Label x="176" y="64" width="54" id="counter" height="22"/>




            </s:Application>

             

             

             

            As you can see, the startTimer will start my time counter in a label that has an id of "counter". I have placed this labe in the "Break" column of the datagrid. Obviously, I cannot duplicate this label, so I would like to bind the startTimer function to the value passed in the textInput box.

             

            Eventually, I want to e able to click and drag this value (the textInput and associated time counter) to other datagrids. That part I can do. Once the counter starts, I don't want it to reset until it is returned to the home datagrid.

             

            Does this make sense and will your code do this?

             

            Thank you so much for the quick reply! It is really appreciated!!

            • 3. Re: Timer Question
              jsd99 Level 3

              I'm not really sure what you're trying to do, to be honest.  The way that code is set up, there is only one timer, which is global to the class.  If you want many timers you need to make objects that encapsulate the data that is relevant to the timer, and the timer itself.  Then you pass an array of those objects to the datagrid.  You can find out which specific timer is being referenced by using the itemClick logic I showed before.

              • 4. Re: Timer Question
                Matt Le Fevre Level 4

                something like this?

                 

                <?xml version="1.0" encoding="utf-8"?>
                <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
                    
                    <mx:Script>
                        <![CDATA[
                        
                        public var itemCount:int = 2;
                        
                        private function addItemToGrid():void{
                            itemCount++;
                            var newItem:Object = new Object
                            newItem.name = "Item" + itemCount;
                            exampleAC.addItem(newItem);    
                        }
                            
                        ]]>
                    </mx:Script>
                    
                    <mx:DataGrid id="dg1" dataProvider="{exampleAC}" x="58" y="68" width="265" height="307">
                        <mx:columns>
                            <mx:DataGridColumn headerText="Items">
                                <mx:itemRenderer>
                                <mx:Component>
                                    <mx:Canvas width="100" height="30" creationComplete="doThis()">
                                        <mx:Script>
                                            <![CDATA[
                                                
                                                [Bindable]
                                                public var Counter:int = 0;
                                                
                                                private function doThis():void{
                                                    setTimeout(startCounting, 1000);
                                                }
                                                
                                                private function startCounting():void{
                                                    Counter++;
                                                    setTimeout(startCounting, 1000);
                                                }
                                                
                                            ]]>
                                        </mx:Script>            
                                        <mx:HBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">                
                                            <mx:Label text="{data.name}" fontWeight="bold"/>
                                            <mx:Spacer width="100%"/>
                                            <mx:Label text="Item was added {Counter} seconds ago"/>
                                        </mx:HBox>    
                                </mx:Canvas>
                                </mx:Component>
                            </mx:itemRenderer>
                            </mx:DataGridColumn>
                        </mx:columns>    
                    </mx:DataGrid>
                    
                    <mx:ArrayCollection id="exampleAC">
                         <mx:Object name="Item1"/>
                         <mx:Object name="Item2"/>
                    </mx:ArrayCollection>
                     
                    <mx:Button x="141" y="383" label="Add Item" click="addItemToGrid()"/>
                    
                </mx:Application>
                
                
                • 5. Re: Timer Question
                  willise414 Level 1

                  Thank to all for your help. I realized that there was an error in my thinking when it was pointed out I had a global timer, rather than individual ones. So I went back and did some redesigning. I created a VO (listed below)

                   

                  package VO

                  {

                  import flash.events.TimerEvent;

                  import flash.utils.Timer;

                   

                  import mx.formatters.DateFormatter;

                   

                   

                  public class UserVO

                  {

                  public var callsign:String;

                  public var timer:Timer;

                  public var overtime:String;

                  public var df:DateFormatter = new DateFormatter();

                   

                  public var hours:String;

                  public var minutes:String;

                  public var seconds:String;

                   

                  public var hrs:int = 0;

                  public var mins:int = 0;

                  public var secs:int = 0;

                   

                  [Bindable]

                  public var currentTime:String = "*****";

                   

                   

                  public function UserVO()

                  {

                  timer = new Timer(1000);

                  timer.addEventListener(TimerEvent.TIMER, timerTick);

                  timer.start();

                  }

                   

                   

                   

                  public function timerTick(event:TimerEvent):void

                  {

                  //currentTime = timer.currentCount.toString();

                   

                  secs += 1;

                   

                  if(secs == 60)

                  {

                  secs = 0;

                  mins += 1;

                  }

                  if(mins == 60)

                  {

                  mins = 0;

                  hrs +=1;

                  }

                   

                  // Build currentTime string

                   

                  if(secs <10)

                  {

                  seconds = "0" + secs.toString();

                  }

                  else

                  {

                  seconds = secs.toString();

                  }

                   

                  if(mins <10)

                  {

                  minutes = "0" + mins.toString();

                  }

                  else

                  {

                  minutes = mins.toString();

                  }

                   

                  if(hrs <10)

                  {

                  hours = "0" + hrs.toString();

                  }

                  else

                  {

                  hours = hrs.toString();

                  }

                   

                  currentTime = hours + ":" + minutes + ":" + seconds;

                   

                   

                  }

                  }

                  }

                   

                  This created the timer for each person and formatted it correctly. Now on to the main mxml file:

                   

                  <?xml version="1.0" encoding="utf-8"?>

                  <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

                     xmlns:s="library://ns.adobe.com/flex/spark"

                     xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" >

                   

                  <fx:Script>

                  <![CDATA[

                  import VO.UserVO;

                   

                  import mx.collections.ArrayCollection;

                  import mx.controls.Alert;

                  import mx.events.DragEvent;

                   

                   

                   

                  [Bindable]

                  public var userArray:ArrayCollection = new ArrayCollection();

                   

                  private function dragCompleteHandler(event:DragEvent):void

                  {

                   

                  }

                   

                  public function doSubmit():void

                  {

                  // Create the UserVO Value Object

                  var user:UserVO = new UserVO();

                  user.callsign = userInput.text;

                   

                  if(overtimeCB.selected)

                  {

                  user.overtime = "YES";

                  }

                  else

                  {

                  user.overtime = "NO";

                  }

                   

                  // Add the UserVO Value Object to the user array

                  userArray.addItem(user);

                  }

                   

                   

                   

                  ]]>

                  </fx:Script>

                  <fx:Declarations>

                  <!-- Place non-visual elements (e.g., services, value objects) here -->

                  </fx:Declarations>

                  <s:Button x="603" y="191" label="Submit" click="doSubmit()"/>

                  <s:TextInput x="545" y="161" id="userInput"/>

                  <mx:DataGrid x="10" y="41" dataProvider="{userArray}" dragEnabled="true" dropEnabled="true" dragMoveEnabled="true">

                  <mx:columns>

                  <mx:DataGridColumn headerText="CALLSIGN" dataField="callsign"/>

                  <mx:DataGridColumn headerText="TIMER" dataField="currentTime"/>

                  <mx:DataGridColumn headerText="OVERTIME" dataField="overtime"/>

                  </mx:columns>

                  </mx:DataGrid>

                  <s:CheckBox x="696" y="164" label="Overtime" id="overtimeCB"/>

                  <mx:DataGrid x="10" y="269" width="160" dragEnabled="true" dropEnabled="true" dragMoveEnabled="true"

                  dragComplete="dragCompleteHandler(event)">

                  <mx:columns>

                  <mx:DataGridColumn headerText="CallSign" dataField="callsign"/>

                  <mx:DataGridColumn headerText="Timer" dataField="currentTime"/>

                   

                  </mx:columns>

                  </mx:DataGrid>

                  </s:Application>

                  So when I input each callsign through the text input field, it will input the callsign and the timer into the datagrid for every entry. So far, so good.
                  Noe the final piece to my puzzle - the part I need help with. I want to drag the entry in the data grid to another datagrid and have the timer reset to zero and begin counting again. I I have already started to put in the dragCompleteHandler in the second datagrid, but how do I write the function to reset the timer and start it again on the drop complete?
                  THanks!