0

I'm testing ATK4 for some scenarios to decide, if I can go with it. One of these Scenarios is a status page for groups and members, which should reload automatically the grids, which contains dynamic group and member informations.

The grid reload I've implemented like described in this Thread Agile toolkit : how to automatically reload grid

Here's the code for the members page:

<?php 
class page_members extends Page { 
    function init(){ 
        parent::init(); 
        $page = $this; 

        $page->api->stickyGET('group_id'); 
        $grid = $page->add('Grid'); 
        $model = $grid->setModel('Member'); 
        if ($_GET['group_id']) 
            $model->addCondition('group_id', $_GET['group_id']); 
        $page->js(true)->univ()->setInterval( 
                $grid->js()->reload()->_enclose() 
                ,10000); 
    } 
} 

If I call it from the Browser with the group_id parameter, it works like expected. But this page will called from a group page into a frameURL with the following code:

<?php 
class page_groups extends Page { 
    function init(){ 
        parent::init(); 
        $page = $this; 

        $grid = $page->add('Grid'); 
        $model = $grid->setModel('Group'); 
        $grid->addColumn('button','members'); 

        if($_GET['members']){ 
            $grid->js()->univ() 
                ->frameURL('Members' ,$page->api->url('../members',array('group_id'=>$_GET['members']))) 
                ->execute(); 
        } 

        $page->js(true)->univ()->setInterval( 
            $grid->js()->reload()->_enclose() 
            ,10000); 

    } 
} 

If I click on button 'members' from group 1, the members page for group 1 open in a frame and refreshes every 10 seconds. That's okay. But if I close the frame and open a new frame by clicking on 'members' button from group 2, the grid cycling through group 1 and 2 while refreshing the grid.

I think, the problem is the timer, created by the setInterval() function, which has to be cleared by clearInterval(id) before the frame is closed. The setInterval() function has a return value, but I don't know, how I can handle it over to the clearInterval(id) function in the ATK4 Framework?

Community
  • 1
  • 1
ATL
  • 25
  • 5
  • Where did you define that $details_grid variable in page_groups class? – DarkSide Apr 08 '14 at 22:22
  • yeah in this case you should somehow get that return value from setInterval and pass it to clearInterval. Or you can try to use setTimeout instead of setInterval, BUT setTimeout should be added to grid not page! That way setTimeout JS will reload and reload and reload together with grid on every grid refresh. – DarkSide Apr 08 '14 at 22:26
  • Ooohps... `$details_grid->grid` had to be changed in `$grid`. I 've changed the code above. Thanks. The problem of the return value of `setInterval()` is, that I get not an Id but a peace of jQuery code back. :-( But I will try to test this with `setTimeout`. Thanks for the hint. – ATL Apr 09 '14 at 10:19
  • Okay, I've tried replacing the `setInterval()` part with: `$grid->js(true)->univ()->setTimeout($grid->js()->reload()->_enclose(), 10000);` But the result is the same. Maybe, that the _frameURL_ will not really closed / destroyed after clicking the 'X' but only hidden!? – ATL Apr 09 '14 at 12:17
  • OK, I created testcase and you're right. Problem is that setInterval is registered in HTML page "events" and continue to reload all previously opened popups. I'll try to find solution and post it here. – DarkSide Apr 09 '14 at 14:34

1 Answers1

0

Description:

Problem exists because setInterval is added to global window object and because window object itself is not reloaded (using AJAX we only reload parts of DOM tree) setInterval method continues to be called even when you close modal dialog or reload "page" container.

In short it is written here: http://www.w3schools.com/jsref/met_win_setinterval.asp

The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.

So, possible workarounds in this case will be one of these:

  • use setTimeout instead of setInterval and reload widget with new setTimeout call every time
  • use clearInterval when you close modal dialog window to get rid of old globally registered intervals

A lot of useful information about setInterval can be found here: https://developer.mozilla.org/en/docs/Web/API/window.setInterval


Testcase:

class page_company extends Page
{
    function init()
    {
        parent::init();
        $page = $this;

        $grid = $page->add('Grid');
        $model = $grid->setModel('Company');
        $grid->addColumn('button','company');

        if ($_GET['company']) {
            $grid->js()->univ()
                ->frameURL('Employees', $page->api->url('../employee', array(
                    'company_id'=>$_GET['company'])))
                ->execute();
        }
    }
}

class page_employee extends Page
{
    function init()
    {
        parent::init();
        $page = $this;

        $page->api->stickyGET('company_id');
        $grid = $page->add('Grid');
        $model = $grid->setModel('Employee');
        if ($id = $_GET['company_id']) {
            $model->addCondition('company_id', $id);
        }

        // NOTE:Important is that you add setTimeout JS chain to grid not page!
        //      That's because you reload only grid and you need to receive
        //      this JS chain from server on each reload to keep it reloading.
        //      $page is not reloading, only $grid is!
        $grid->js(true)->univ()->setTimeout(
                $grid->js()->reload()->_enclose()
                ,5000);
    }
}

This way everything works fine except situation when you close one modal dialog and open new one in less that 5 seconds (setTimeout time). Problem is the same - setTimeout also is added to global window object and as result it still get executed after these 5 seconds even if you close your modal dialog in the mean time.


Last Edit

With newest ATK commit in Github you can now initialize periodic reloads of any View with just 1 simple chain.

So instead of something like this (which don't work):

$grid->js(true)->univ()->setTimeout(
            $grid->js()->reload()->_enclose()
            ,5000);

now you can simply call:

// reload grid every 5 seconds
$grid->js(true)->reload(null,null,null,5000);

NOTE: you should apply this to exactly that View object which you want to reload periodically.

DarkSide
  • 3,670
  • 1
  • 26
  • 34
  • Yepp, this would be wonderful. But at least there is method needed to get the timer Id from `setInterval()` for later usage. – ATL Apr 09 '14 at 18:00
  • In the mean time you can check out these resources related to this solution: http://stackoverflow.com/questions/13567634/agile-toolkit-how-to-automatically-reload-grid/13575212#13575212 and https://groups.google.com/forum/#!searchin/agile-toolkit-devel/setinterval/agile-toolkit-devel/jxVPF6ZAt-Y/Gkvo8yrS_NsJ – DarkSide Apr 09 '14 at 22:27
  • Thanks. I saw these discussions already, but maybe the point is, generating a own grid class and put it there. I will try it. – ATL Apr 10 '14 at 08:54
  • OK working solution is ready as patch for ATK. I hope Romans will accept it and push in ATK branch. – DarkSide Apr 10 '14 at 14:36
  • @ATL can you try your project with newest ATK4 commit from github: https://github.com/atk4/atk4/commit/2d6fd3f1bd53b1c133b94e144a4389ffe2dc7f85 and let us know did this work fine for you. – DarkSide Apr 10 '14 at 16:56
  • You should no more use any timeouts or anything, just call `$grid->js(true)->reload(null,null,null,5000);` or `$page->js(true)->reload(null,null,null,10000);` (can use on any other view too) and everything should work out of the box. If it'll work for you, then I'll change my answer above with correct solution / test case. – DarkSide Apr 10 '14 at 16:57
  • Yeah, it works. Except it seems to reload continuously the page/grid and not in interval of given (milli) seconds. – ATL Apr 11 '14 at 06:20
  • @ATL did you download latest atk 4.2.5 version from github? – DarkSide Apr 11 '14 at 08:42
  • github told me, that all is on current version, so I made all changes you've committed on my local copy. – ATL Apr 12 '14 at 07:53
  • Hi. So I've got the github problem handled and tested it again. And... YES it works like expected! Super job! Thanks! – ATL Apr 13 '14 at 07:43
  • @ATL there is some bugs in my github commit (with ->redirect method). I'll see how to fix them sometime soon. Maybe something with reload will change too. So, stay tuned and follow github and ATK community (Google groups, IRC channel). – DarkSide Apr 13 '14 at 12:14
  • All bugs fixed now. So, if you feel that I have answered (and maybe even more) your question, then please accept it :) – DarkSide Apr 15 '14 at 15:13