3
votes

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?

1
You can call any model inside view using this $model = JModel::getInstance('MODEL_NAME', 'COMPONENT_NAME'); $items= $model->getItems(); Using the ->get('items') syntax is only valid in a view (because get() is a method of the view class)Amit Ray
@Amit Ray JModel doesnt work, but JModelLegacy does with Joomla 3.5.1. When I use JModel, I get the following error in my server logs: PHP Fatal error: Call to undefined method JModel::getInstance() in /var/www/html/components/com_componentname/views/multiviewname/view.html.php. JModelLegacy does not throw the error, and the page loads fine.John W. Benac
Sorry my mistake, I forgot the legacy part. But did that solve the issue?Amit Ray
@Amit Ray, JModelLegacy was the correct function to use, rather than your suggested JModel. Also, rather than your suggested $items= $model->getItems(), I used $this->ItemsOtherModel = $this->get('Items','model-b');. You suggestion would not have worked because it did not specify the actual model to be used, which is a necessary step when using models beyond the default. On both counts, your suggestion did not solve the issue.John W. Benac
My job was to show you the direction. What I remembered vaguely I suggested. And google is there to handle the rest.Amit Ray

1 Answers

3
votes

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.