How can I nicely to pre-load tab content before displaying tabs on the page? The tab content is another view with table and data loaded from DB using Zend controller. Basically, I want to avoid the first view, with showing some "loading ... " status, and showing the second view when it is ready.

I thought I can somehow do it from the module showing a message that data is loading, but I could not find a way to combine tabs and module.

Currently I have the following, and there is a significant delay between first and second page views:

**Tabs loaded, but tabs content is still loading **

enter image description here

Tabs loaded, and content loaded

enter image description here

The code is as the following:

View

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Index Tabs</title>
    <link rel="stylesheet" href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
</head>

<body>

<div id="tabs" style="width:100%">
    <ul>
        <li><a id="showform" href="<?php echo $this->url('OnlineFieldEvaluation',
                array('action' => 'listforms', 'controller' => 'OnlineFieldEvaluation')); ?>">Forms</a></li>
        <li><a id="showform" href="<?php echo $this->url('OnlineFieldEvaluation',
                array('action' => 'editidentityinformation', 'controller' => 'OnlineFieldEvaluation')); ?>">Student Information</a></li>
    </ul>
</div>

<script>
    $('#tabs').css('width','auto');
    $('#tabs').css('min-width','800px');
    $('#tabs').css('position','absolute');
    $("#tabs").tabs();
</script>

</body>
</html>

Controller:

   public function listformsAction()
    {
        if ($this->zfcUserAuthentication()->hasIdentity()) {

            $authorize = $this->getServiceLocator()->get('BjyAuthorize\Provider\Identity\ProviderInterface');
            $roles = $authorize->getIdentityRoles();

            $studentEvaluations = $this->getEntityManager()->getRepository('OnlineFieldEvaluation\Entity\StudentEvaluations')
                ->findBy(array('studEmail' => $this->zfcUserAuthentication()->getIdentity()->getEmail()));

            $view = new ViewModel(array(
                'evaluations' => $this->getEntityManager()->getRepository('OnlineFieldEvaluation\Entity\IdentityInformation')
                        ->findBy(array('stud_email' => $this->zfcUserAuthentication()->getIdentity()->getEmail())),
                'studentEvaluations' => $studentEvaluations,
                'roles' => $roles
            ));

            return $view;

        } else {
            return $this->redirect()->toRoute('zfcuser');

        }
    }
2

There are 2 best solutions below

0
On

I found a solution here:

Zend Framework 2 display a view within a view

As per this zf2 documentaion page

Write this in login Action:

public function loginAction()
{
    return new ViewModel();
}

And in indexAction :

$view = new ViewModel(
              array(
                //here any thig you want to assign to index view
              )
            );
$loginView = new ViewModel(
              array(
                    //here any thig you want to assign to login view
                )
            );


$loginView->setTemplate('moduleName/controllerName/login'); 

$view->addChild($loginView, 'login');
return $view

In index.phtml you can just echo login

<? echo $this->login ?> 

where ever you want to display loginView.

0
On

You can dispatch other controller actions using the Zend\Mvc\Controller\Plugin\Forward controller plugin. The result is an aggregated view model consisting of both view scripts.

The main benefit here is reusability; there is no need to recreate the logic to populate the second view model. Within the plugin, ZF2 will actually perform the controller dispatch loop (which means that you can attach to the application event's and they would be triggered just as if you had visited the second route in your browser).

public function FooController extends AbstractActionController
{
    public function tabOneAction()
    {
        $model = new ViewModel(array(
            'foo' => 'bar',
            'bar' => 'foo',
        ));

        $tab2 = $this->forward()->dispatch('MyModule\Controller\FooController', array(
            'action' => 'tab-two',
        ));
        if ($tab2 instanceof ViewModel) $model->addChild($tab2, 'tab2');

        $model->setTemplate('/path/to/tab1/view/script');

        return $model;
    }

    public function tabTwoAction()
    {
        // ....controller logic

        return new ViewModel(array('boo' => 'baz'));
    }
}

In the tab-one.phtml view script you will then be able to echo out the content of tab-two.phtml within the content of the second tab. Therefore, there would be no need to ajax the data and the users will have no delay in the second tab data being displayed.

echo $this->tab2; // The result of the tabTwoAction()