Add and Edit actions both redirect to same form. Edit can come from either the Edit button or by clicking the title. If the id is 0, it indicates Add action. If the id is greater than 0, it indicates Edit action.

The tasks for these actions are:

  • helloworld.edit
  • helloworld.add

Joomla will look in the subcontroller file: admin/controllers/helloworld.php

Step 1: Subcontroller File

These functions, add() and edit(), are already defined in the class JControllerForm, so you are not required to define them again. Just extend the Controller class with JControllerForm. The add() function sets the redirect to the editing form layout with the id = 0. The edit() gets the id and then sets the redirect to the editing form layout.

class HelloWorldControllerHelloWorld extends JControllerForm
{

}

Step 2: View File

Now, Joomla will look into admin/views/helloworld/view.html.php. It will get the data (form and item) from the model, check for errors, set the toolbar and display the form using template layout file in tmpl/edit.php.

public function display($tpl = null)
{
// Get the Data
$this->form = $this->get('Form');
$this->item = $this->get('Item');

// Check for errors.
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));

return false;
}

// Set the toolbar
$this->addToolBar();

// Display the template
parent::display($tpl);
}

This file calls the functions getForm() and getItem() in the model file.

Step 3: Model File

The getItem() function gets the id of the record, then it gets the table and finally loads the record from the table. This function is already defined in the class JModelAdmin. So, you are not required to define it again. You need to extend the model class with JModelAdmin and write the function getTable().

The form is obtained in the model. You have to define the form in XML in the folder: admin/models/forms/helloworld.xml

Then, you have to write function getForm() in the Model class. This function will call another function loadForm(), that processes the XML to produce a JForm object. This method is defined in both the classes JModelAdmin and JModelForm.

public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_helloworld.helloworld', 'helloworld', array('control' => 'jform', 'load_data' => $loadData));

if (empty($form))
{
return false;
}
return $form;
}

Optionally, you can write loadFormData() to provide prefill data for the form.

protected function loadFormData()
{
// Check the session for previously entered form data.
$data = JFactory::getApplication()->getUserState('com_helloworld.edit.helloworld.data', array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}

Step 4: XML Form

The model inherits from the JModelAdmin class and uses its loadForm method. This method searches for forms in the forms folder

The file is at: admin/models/forms/helloworld.xml

<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
name="id"
type="hidden"
/>
<field
name="greeting"
type="text"
label="COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL"
description="COM_HELLOWORLD_HELLOWORLD_GREETING_DESC"
size="40"
class="inputbox"
default=""
/>
</fieldset>
</form>

Step 5: Layout File

The file is at: admin/views/helloworld/tmpl/edit.php

<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id=' . (int) $this->item->id); ?>"
method="post" name="adminForm" id="adminForm">
<div class="form-horizontal">
<fieldset class="adminform">
<legend><?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_DETAILS'); ?></legend>
<div class="row-fluid">
<div class="span6">
<?php foreach ($this->form->getFieldset() as $field): ?>
<div class="control-group">
<div class="control-label"><?php echo $field->label; ?></div>
<div class="controls"><?php echo $field->input; ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
</fieldset>
</div>
<input type="hidden" name="task" value="helloworld.edit" />
<?php echo JHtml::_('form.token'); ?>
</form>

The form is sending data through post request to the same url (action attribute of the form) it came from. This is the reason you need to get the item in the view.

Step 6: Save and Cancel Request

When the form is submitted, the tasks are: helloworld.save or helloworld.cancel.

Joomla will look for save() and cancel() functions in the helloworld subcontroller file. The save() gets the POST data, gets the model, calls the save() of the model for saving the data to the database, sets the message and finally sets the redirect to the list of items. The cancel() sets the redirect to the list of items.

In the model, the save() gets table and then saves the record in the database. These two functions are already defined in the class JControllerForm. So, you do not need to define them again.

However, if you want to perform certain operations on the submitted data before saving it to the database, you can overwrite in the model file and then call the parent save function.

public function save($data)
{
$input = JFactory::getApplication()->input;

// Automatic handling of alias for empty fields
if (in_array($input->get('task'), array('apply', 'save', 'save2new')))
{
if ($data['alias'] == null)
{
if (JFactory::getConfig()->get('unicodeslugs') == 1)
{
$data['alias'] = JFilterOutput::stringURLUnicodeSlug($data['title']);
}
else
{
$data['alias'] = JFilterOutput::stringURLSafe($data['title']);
}
}
}

// Automatic handling of dates for empty fields
if (in_array($input->get('task'), array('apply', 'save', 'save2new')))
{
if ($data['created'] == null)
{
$date = JFactory::getDate();
$data['created'] = $date->toSql();
}
}

return parent::save($data);
}