Adding Back-end Actions: Save and Cancel

In the form View, you can add action buttons like Save and Cancel to submit the form or cancel the editing respectively. These buttons are added to the toolbar.

These buttons require compound tasks (controller and method). For example,

  • Save and Edit: planet.apply
  • Save and Close: planet.save
  • Cancel: planet.cancel

Step 1: View File

admin/src/View/Planet/HtmlView.php

In the view file, we create a new method to add a toolbar: addToolbar(). The toolbar hides the sidebar menu on forms, sets the title and adds action buttons.

use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;

protected function addToolbar()
{
   Factory::getApplication()->getInput()->set('hidemainmenu', true);
ToolbarHelper::title('Planet: Add');
     
  ToolbarHelper::apply('planet.apply');
  ToolbarHelper::save('planet.save');
  ToolbarHelper::cancel('planet.cancel', 'JTOOLBAR_CLOSE');
}

The display() calls this method to include the toolbar.

public function display($tpl = null) 
{
    $this->form = $this->get('Form');

    $this->addToolbar();

    parent::display($tpl);
}

Step 2: Controller File

admin/src/Controller/PlanetController.php

Now, when these action buttons are clicked, Joomla will look for apply(), save() or cancel() methods in the Planet controller. So, create a controller class that will extend FormController. These methods are already defined in the parent class.

use Joomla\CMS\MVC\Controller\FormController;

class PlanetController extends FormController
{
    
}

Step 3: Model File

admin/src/Model/PlanetModel.php

If you click on Save button, it will save the data and redirect to the editing screen. However, the data will not be present in the form. Though, we have set $loadData to true, we also need to create a method loadFormData() to get the data for the form.

protected function loadFormData()
{
    $app  = Factory::getApplication();
    $data = $app->getUserState('com_stars.edit.planet.data', []);

    if (empty($data)) 
    {
        $data = $this->getItem();
    }

    return $data;
}

First, this method tries to get the data from the session. If it fails to get data from the session, then, it gets from the database. The getItem() method is defined in the parent class.

Suppose the user has filled out the form to add a new item but has some invalid data in the form. In this case, the save will not be successful, so the data is not saved in the database. It would be very frustrating if the user had to reenter all the fields to fix a single error. To handle this scenario, you save the entered data in the user's session. Only after the save is successful, you clear this out of the session.

So, you either have data from the database, which you can get with getItem(), or you have data from the session, which you can get with getUserState().