Search code examples
phpmodel-view-controllerjoomlacomponentsdashboard

How can I include multiple models in one view for in a Joomla 3.x component built with Component Creator


Joomla components use the MVC model. Component Creator is a widely used tool whose paid level supports creation of multi tabled views with SQL import. Also, developers build components from scratch according to Joomla documentation.

I want to build an advanced component that functions as a "dashboard" displaying data from multiple database tables with all the administrator back-end and visitor front-end CRUD (CREATE, READ, UPDATE, DELETE) capabilities of Joomla. This means that I need multiple models (from the MVC philosophy) drawing from multiple database tables shown on the screen simultaneously.

Joomla Documentation suggests the following code be inserted into the "controller task-method" to make the information available:

$view = $this->getView( 'model-a', 'html' );
$view->setModel( $this->getModel( 'model-a' ), true );
$view->setModel( $this->getModel( 'model-b' ) );
$view->display();

and then later call upon those models with the in the views display method:

$item1 = $this->get( 'data1' );
$item2 = $this->get( 'data2', 'model-b' );

However, these instructions provided in Joomla documentation are insufficient or incompatible with the component built when following the provided Joomla Hello World Tutorial tutorial or components built from the widely used and popular Component Creator tool. Either the component will fail to load the page when called upon or will not pass the data to the view with a simple copy and paste into any one of the multiple controller created by component creator or Joomla hello world tutorial.

How can I call upon multiple models in the same view for a Joomla 3.X component?


Solution

  • I was able to successfully use multiple models from the same view by making calls directly in the two view files to properly formed models. I did not follow Joomla documentation because I didn't modify either possible controller (one being the controller for the entire component and the other controller being view-specific). I also did not use the functions provided in Joomla documentation, as those produced errors.

    According to proper Joomla MVC convention, a view is created by two files in the relevant view directory and subfolder:

    • /site/views/multiviewname/view.html.php (which passes the model to the view)
    • /site/views/multiviewname/tmpl/default.php (which has the HTML template)

    Both these need to be changed to view data from more than one model at the same time. This works assuming that all of your other views, controllers, and models are built properly, as is done automatically when using the 'Component Creator' tool. My component had hundreds of files, including css, backend administration, installation, language, etc. All of these were build in moments with the component creator tool.

    The abridged but still completely functional code is as follows:

    /site/views/multiviewname/view.html.php

    <?php
    
    jimport('joomla.application.component.view');
    
    class ComponentnameViewMultiviewname extends JViewLegacy
    {
    //  $items is for the default model
        protected $items;
    //  $ItemsOtherModel is for second model. Notice the '$' used here but not elsewhere   
        protected $ItemsOtherModel;
    
        public function display($tpl = null)
        {
            $app = JFactory::getApplication();
            $this->state = $this->get('State');
            $this->items = $this->get('Items');
            $this->pagination = $this->get('Pagination');
            $this->params     = $app->getParams('com_componentname');
    
    //  sets default model
            $this->setModel( $this->getModel( 'model-a' ), true );
    //  sets second model & uses 'JModelLegacy,' contrary to documentation
            $this->setModel(JModelLegacy::getInstance('model-b', 'componentnameModel'));
    //  assigns array from the second model to 'ItemsOtherModel.' there is no '$' sign used.
            $this->ItemsOtherModel = $this->get('Items','model-b');
    
            parent::display($tpl);
        }
    
    }
    

    /site/views/multiviewname/tmpl/default.php

    <?php
    
    echo "<h3>Items from default model</h3> ";
    echo var_dump($this->items);
    
    echo "<h3>items from secondary model</h3> ";
    //  notice that the '$' is absent from 'ItemsOtherModel'
    echo var_dump($this->ItemsOtherModel);
    

    This breakthrough was only possible after days of research. The paid Component Creator tool was invaluable to start me off with well formed code that adheres to Joomla MVC component standards. After working with and examining all the files for days, the I found the prompt I needed in this google groups thread, calling my attention to the JModelLegacy class, found when searching google for terms from the PHP error message PHP Notice: Undefined index: left on my server when attempting to use the officially documented methods.

    This page rendered in the browser simply dumps out all information from the database table to the page, but further development can create the formatted and functional dashboard that I will ultimately need.

    This code is for displaying lists of information, as opposed to multiple single items. The Joomla documentation for adding multiple models to one view is set up for multiple single items, rather than arrays of items shown here.