Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
436734cd4c | |||
9db4ad808b | |||
df22394e33 | |||
2b5e287a78 | |||
7f79667409 | |||
a3787d1965 | |||
6928ff5a74 | |||
e30b2c6550 | |||
4786bf13d9 | |||
d9220cd888 | |||
70e987b338 | |||
47796a6ada | |||
f85556f466 | |||
5f1db1b0f5 | |||
eebafe0241 | |||
336eb346a7 | |||
f0b8e1ed02 |
@ -4,7 +4,7 @@ root = true
|
||||
[*]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
end_of_file = lf
|
||||
end_of_line = lf
|
||||
charset = UTF-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
243
README.md
243
README.md
@ -36,6 +36,17 @@ Add the following basic six files:
|
||||
|
||||
##### 1. DepotComponent.php
|
||||
This file contains class for the extension. The class extends MVCComponent.
|
||||
Compare this version with the original at [Tech Fry Tutorium](https://www.techfry.com/joomla/adding-basic-files-for-component).
|
||||
```php
|
||||
namespace KW4NZ\Component\Depot\Administrator\Extension;
|
||||
|
||||
use Joomla\CMS\Extension\MVCComponent;
|
||||
|
||||
class DepotComponent extends MVCComponent
|
||||
{
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
##### 2. provider.php
|
||||
This is a special file that tells Joomla how to initialize the component - which
|
||||
@ -283,3 +294,235 @@ Methods in the table objects are:
|
||||
1. **delete()** to delete the record from the database.
|
||||
|
||||
---
|
||||
|
||||
### Get a Form in Joomla component
|
||||
|
||||
The **Form** class of Joomla is used to create complex forms with flexible
|
||||
layouts and dynamic properties. First, the form fields are defined in the
|
||||
XML file. Then the view file gets the form from the model and layout file
|
||||
displays the form.
|
||||
|
||||
#### XML Form file
|
||||
**admin/forms/part.xml**
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<field
|
||||
name="title"
|
||||
type="text"
|
||||
label="JGLOBAL_TITLE"
|
||||
required="true"
|
||||
/>
|
||||
</form>
|
||||
```
|
||||
Similarly you can add other fields to the XML file.
|
||||
|
||||
#### View file
|
||||
**admin/src/View/Part/HtmlView.php**
|
||||
|
||||
This file is similar to the view file added earlier for the "Parts" view.
|
||||
The view file gets the form from the model in the display() method.
|
||||
```php
|
||||
<?php
|
||||
namespace KW4NZ\Component\Depot\Administrator\View\Part;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
|
||||
\defined('_JEDEC') or die;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
protected $form;
|
||||
protected $item;
|
||||
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->form = $this->get('Form');
|
||||
$this->item = $this->get('Item');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
```
|
||||
The code will look for the method **getForm()**
|
||||
and **getItem()** in the model file.
|
||||
We need to get the item to get the ID
|
||||
of the record in case of editing the existing record.
|
||||
|
||||
#### Model file
|
||||
**admin/src/Model/PartModel.php**
|
||||
|
||||
We need to extend the model class with the **AdminModel**.
|
||||
The AdminModel class extends FormModel class. The **getForm()**
|
||||
method gets the Form object for the edit form.
|
||||
|
||||
```php
|
||||
namespace KW4NZ\Component\Depot\Administrator\Model;
|
||||
use Joomla\CMS\MVC\Model\AdminModel;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
class PartModel extends AdminModel
|
||||
{
|
||||
public function getForm($data = array(), $loadData = true)
|
||||
{
|
||||
$form = $this->loadForm('com_depot.part',
|
||||
'part', array('control' => 'jform',
|
||||
'load_data' => $loadData));
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
```
|
||||
The **loadForm()** and **preprocessForm()** methods are defined in
|
||||
the FromModel class and the **bind()** method is defined in the
|
||||
Form class. The first argument (name) of loadForm() is set to
|
||||
"com_depot.part". The second argument (form xml source) is "part",
|
||||
and the third argument is the associative array for options.
|
||||
|
||||
The form is defined in the source file: **forms/part.xml**
|
||||
|
||||
After you have set the $form variable with the Form object,
|
||||
you check to see if you are loading data to the form.
|
||||
If you want to pre-load data for the form, you include an element
|
||||
called "load_data" that is set to a boolean true.
|
||||
Then, the method calls the loadFormData() method to get the data
|
||||
for the form. This method gets any previously loaded data from
|
||||
the session or database.
|
||||
|
||||
###### Modifying Form dynamically
|
||||
|
||||
Inside the getForm() method, before returning the $form, you can modify the form with many methods of the Form class. You can easily fine-tune your forms dynamically before they are rendered.
|
||||
|
||||
#### Layout file - rendering Form
|
||||
**tmpl/part/edit.php**
|
||||
|
||||
After you get the form in the view file ($this->form), the form
|
||||
is rendered in the layout file (edit.php).
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
|
||||
$wa->useScript('keepalive');
|
||||
$wa->useScript('form.validate');
|
||||
?>
|
||||
<form action="<?= Route::_('index.php?option=com_depot&layout=edit&id=' .
|
||||
(int) $this->item->id); ?>"
|
||||
method="post" name="adminForm" id="item-form" class="form-validate">
|
||||
|
||||
<?= $this->form->renderField('title'); ?>
|
||||
|
||||
<input type="hidden" name="task" value="part.edit" />
|
||||
<?= HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
```
|
||||
The form validate script is required to submit the for. The renderField() method
|
||||
of the Form class displays the field - both label and input.
|
||||
|
||||
We can access the form using following URL:
|
||||
```php
|
||||
administrator/index.php?option=com_depot&view=part&layout=edit
|
||||
```
|
||||
It displays edit.php layout file of the Part View. When the form is submitted, the
|
||||
data is sent to the controller depending upon the action buttons in the toolbar.
|
||||
|
||||
Please remember to add the additional folder `form` to the Manifest file "depot.xml", i.e.
|
||||
just a line before `<folder>services</folder>` :
|
||||
```xml
|
||||
<folder>form</folder>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Adding administrator's actions (Back-end) - 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: part.apply
|
||||
- Save and Close: part.save
|
||||
- Cancel: part.cancel
|
||||
|
||||
#### View file
|
||||
**admin/src/View/Part/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.
|
||||
```php
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
protected function addToolbar()
|
||||
{
|
||||
Factory::getApplication()->getInput()->set('hidemainmenu', true);
|
||||
ToolbarHelper::title('Part: Add');
|
||||
|
||||
ToolbarHelper::apply('part.apply');
|
||||
ToolbarHelper::save('part.save');
|
||||
ToolbarHelper::cancel('part.cancel', 'JTOOLBAR_CLOSE');
|
||||
}
|
||||
```
|
||||
The display() calls this method to include the toolbar.
|
||||
```php
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->form = $this->get('Form');
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
```
|
||||
#### Controller file
|
||||
**admin/src/Controller/PartController.php***
|
||||
Now, when these action buttons are clicked, Joomla will look for apply(), save() or cancel()
|
||||
methods in the Part controller. So, create a controller clss that will extend FormController.
|
||||
These methods are already defined in the parent class.
|
||||
```php
|
||||
use Joomla\CMS\MVC\Controller\FormController;
|
||||
|
||||
class PartController extends FormController
|
||||
{
|
||||
}
|
||||
```
|
||||
#### Model file
|
||||
|
||||
**admin/src/model/PartModel.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.
|
||||
|
||||
```php
|
||||
protected function loadFormData()
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
$data = $app->getUserState('com_depot.edit.part.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 data 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 hat 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 `getUserSate()`.
|
||||
|
||||
---
|
||||
|
18
admin/forms/part.xml
Normal file
18
admin/forms/part.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<field
|
||||
name="component_name"
|
||||
type="text"
|
||||
label="COM_DEPOT_FIELD_COMPONENT_NAME_LABEL"
|
||||
description="COM_DEPOT_FIELD_COMPONENT_NAME_DESC"
|
||||
required="true"
|
||||
/>
|
||||
<field
|
||||
name="id"
|
||||
type="text"
|
||||
label="JGLOBAL_FIELD_ID_LABEL"
|
||||
class="readonly"
|
||||
default="0"
|
||||
readonly="true"
|
||||
/>
|
||||
</form>
|
@ -5,4 +5,6 @@
|
||||
; @license GNU General Public License version 2 or later; see LICENSE.md
|
||||
; @since 0.0.1
|
||||
;
|
||||
COM_DEPOT_FIELD_COMPONENT_NAME_DESC="The name of the component is unique. Please do not enter special characters or umlauts."
|
||||
COM_DEPOT_FIELD_COMPONENT_NAME_LABEL="Component Name"
|
||||
COM_DEPOT_XML_DESCRIPTION="Depot, the component warehouse"
|
||||
|
@ -17,4 +17,4 @@ use Joomla\CMS\MVC\Controller\BaseController;
|
||||
class DisplayController extends BaseController
|
||||
{
|
||||
protected $default_view = 'parts';
|
||||
}
|
||||
}
|
19
admin/src/Controller/PartController.php
Normal file
19
admin/src/Controller/PartController.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Depot.Administrator
|
||||
* @subpackage com_depot
|
||||
* @author Thomas Kuschel <thomas@kuschel.at>
|
||||
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.md
|
||||
* @since 0.0.4
|
||||
*/
|
||||
|
||||
namespace KW4NZ\Component\Depot\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\FormController;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
class PartController extends FormController
|
||||
{
|
||||
}
|
@ -14,5 +14,4 @@ use Joomla\CMS\Extension\MVCComponent;
|
||||
|
||||
class DepotComponent extends MVCComponent
|
||||
{
|
||||
|
||||
}
|
||||
}
|
42
admin/src/Model/PartModel.php
Normal file
42
admin/src/Model/PartModel.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Depot.Administrator
|
||||
* @subpackage com_depot
|
||||
* @author Thomas Kuschel <thomas@kuschel.at>
|
||||
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.md
|
||||
* @since 0.0.3
|
||||
*/
|
||||
|
||||
namespace KW4NZ\Component\Depot\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Model\AdminModel;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
class PartModel extends AdminModel
|
||||
{
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
$form = $this->loadForm('com_depot.part', 'part', ['control' => 'jform', 'load_data' => $loadData]);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
protected function loadFormData()
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
$data = $app->getUserState('com_depot.edit.part.data', []);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->getItem();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -15,10 +15,10 @@ use Joomla\Database\DatabaseDriver;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
class DepotTable extends Table
|
||||
class PartTable extends Table
|
||||
{
|
||||
function __contruct(DatabaseDriver $db)
|
||||
function __construct(DatabaseDriver $db)
|
||||
{
|
||||
parent::__contruct('#__depot', 'id', $db);
|
||||
parent::__construct('#__depot', 'id', $db);
|
||||
}
|
||||
}
|
||||
}
|
75
admin/src/View/Part/HtmlView.php
Normal file
75
admin/src/View/Part/HtmlView.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Depot.Administrator
|
||||
* @subpackage com_depot
|
||||
* @author Thomas Kuschel <thomas@kuschel.at>
|
||||
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.md
|
||||
* @since 0.0.3
|
||||
*/
|
||||
|
||||
namespace KW4NZ\Component\Depot\Administrator\View\Part;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
// use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* View to edit an article.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The \JForm object
|
||||
*
|
||||
* @var \JForm
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The active item
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return mixed A string if successful, otherwise an Error object.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 1.6
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->form = $this->get('Form');
|
||||
$this->item = $this->get('Item');
|
||||
|
||||
// if (count($errors = $this->get('Errors'))) {
|
||||
// throw new GenericDataException(implode("\n", $errors), 500);
|
||||
// }
|
||||
$this->addToolbar();
|
||||
|
||||
return parent::display($tpl);
|
||||
}
|
||||
|
||||
protected function addToolbar()
|
||||
{
|
||||
Factory::getApplication()->getInput()->set('hidemainmenu', true);
|
||||
|
||||
ToolbarHelper::title('Part: Add');
|
||||
|
||||
ToolbarHelper::apply('part.apply');
|
||||
ToolbarHelper::save('part.save');
|
||||
ToolbarHelper::cancel('part.cancel', 'JTOOLBAR_CLOSE');
|
||||
}
|
||||
}
|
27
admin/tmpl/part/edit.php
Normal file
27
admin/tmpl/part/edit.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Depot.Administrator
|
||||
* @subpackage com_depot
|
||||
* @author Thomas Kuschel <thomas@kuschel.at>
|
||||
* @copyright (C) 2023 KW4NZ, <https://www.kuschel.at>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.md
|
||||
* @since 0.0.3
|
||||
*/
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('form.validate')
|
||||
->useScript('keepalive');
|
||||
|
||||
?>
|
||||
<form action="<?= Route::_('index.php?option=com_depot&view=part&layout=edit&id=' . (int) $this->item->id); ?>"
|
||||
method="post" name="adminForm" id="item-form" class="form-validate">
|
||||
|
||||
<?= $this->form->renderField('component_name'); ?>
|
||||
<?= $this->form->renderField('id'); ?>
|
||||
|
||||
<input type="hidden" name="task" value="part.edit" />
|
||||
<?= HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
@ -9,3 +9,5 @@
|
||||
*/
|
||||
?>
|
||||
<h2>Welcome to my Depot Component!</h2>
|
||||
|
||||
<p>Link: <a href="index.php?option=com_depot&view=part&layout=edit&id=1">Part</a></p>
|
@ -2,12 +2,12 @@
|
||||
<extension type="component" method="upgrade">
|
||||
<name>Depot</name>
|
||||
<author>KW4NZ</author>
|
||||
<creationDate>2023-10-04</creationDate>
|
||||
<creationDate>2023-10-06</creationDate>
|
||||
<copyright>(C) KW4NZ Thomas Kuschel</copyright>
|
||||
<license>GPL v2 +; see LICENSE.md</license>
|
||||
<authorEmail>thomas@kuschel.at</authorEmail>
|
||||
<authorUrl>https://kuschel.at</authorUrl>
|
||||
<version>0.0.2</version>
|
||||
<version>0.0.4</version>
|
||||
<description>COM_DEPOT_XML_DESCRIPTION</description>
|
||||
<namespace path="src/">KW4NZ\Component\Depot</namespace>
|
||||
<install> <!-- Runs on install -->
|
||||
@ -55,6 +55,7 @@
|
||||
</menu>
|
||||
</submenu>
|
||||
<files folder="admin">
|
||||
<folder>forms</folder>
|
||||
<folder>services</folder>
|
||||
<folder>sql</folder>
|
||||
<folder>src</folder>
|
||||
|
Reference in New Issue
Block a user