The JForm class of Joomla can also be used to create complex forms with flexible layouts and dynamic properties.

Step 1

In the view.html.php file, get the form for the model in the function display().

// Get data from the model
$this->form = $this->get('Form');

Above code will look for the function getForm() in the model file.

Step 2

You need to extend the model class with JModelAdmin (for back-end) or JModelForm (for front-end), JModelAdmin extends JModelForm. JModelForm extends JModel.

The getForm() method gets the JForm object for the edit form. 

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

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

return $form;
}

The loadForm() and preprocessForm() methods are in JModelForm and the bind() method is in JForm. The first argument of loadForm(), $name, is set to "com_content.article". The second argument, $source, is "article", and $options is the associative array.

The form is defined in the source file: models/forms/article.xml

After you have set the $form variable with the JForm object, you check to see if you are loading data to the form. the third argument is an associative array called $options. If you want to pre-load data for the form, you include an element called "load_data" that is set to a boolean true. The, you execute the loadFormData() method. This gets any previously loaded data from the session. Normally, this is empty.

If you are editing an item for the first time or creating a new item, you call $this- >getItem(), which creates a JObject with the fields for the form. If you have an existing item, you get the data for that item. For a new item, you get the default values or, if no default is specified in the field, you get an empty value.

protected function loadFormData()
{
// Check the session for previously entered form data.
$app = JFactory::getApplication();
$data = $app->getUserState('com_content.edit.article.data', array());

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

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().

Step 3: Modifying Forms Dynamically

Inside the getForm() method, before return $form, you can modify the form with many methods of JForm class. You can easily fine-tune your forms dynamically before they are rendered.

Step 4: Rendering the Form

The form is rendered in the layout file (edit.php or default.php).

<form action="<?php echo JRoute::_('index.php?option=com_<componentname>&layout=edit&id=' . (int) $this->item->id); ?>"
method="post" name="adminForm" id="adminForm" class="form-validate">
<div class="form-horizontal">
<fieldset class="adminform">
<div class="row-fluid">
<div class="span6">
foreach ($this->form->getFieldsets() as $fieldset)
{
$fields = $this->form->getFieldset($fieldset->name);
if (count($fields))
{
foreach ($fields as $field)
{
echo $field->renderField();
}
}
}
</div>
</div>
</fieldset>
</div>
<input type="hidden" name="task" value="contact.edit" />
<?php echo JHtml::_('form.token'); ?>
</form>

You can loop through the fields in the JForm object. There are two loops. The outer loop loops through each fieldset. The array of fieldsets is obtained using getFieldSets('params'). Then, in the inner loop, each field is rendered.