diff --git a/README.md b/README.md index 483ccb850b..6535f8cd25 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Agile UI is the quickest way for building back-end UI, admin interfaces, data ma [![GitHub release](https://img.shields.io/github/release/atk4/ui.svg)](CHANGELOG.md) [![Code Climate](https://codeclimate.com/github/atk4/ui/badges/gpa.svg)](https://codeclimate.com/github/atk4/ui) -Quick-Links: [Documentation](https://agile-ui.readthedocs.io). [Demo-site](https://ui.agiletoolkit.org). [ATK Data](https://github.com/atk4/data). [Forum](https://forum.agiletoolkit.org/). [Chat](https://gitter.im/atk4/atk4). [Commercial support](https://www.agiletoolkit.org/contact). +Quick-Links: [Documentation](https://atk4-ui.readthedocs.io/). [Demo-site](https://ui.atk4.org/). [ATK Data](https://github.com/atk4/data). [Forum](https://forum.agiletoolkit.org/). [Chat](https://gitter.im/atk4/atk4). [Commercial support](https://www.agiletoolkit.org/contact). ## How does Agile Toolkit work? @@ -41,7 +41,7 @@ Many companies use Agile Toolkit to implement admin interface and in some cases ### How does it work? -Download from www.agiletoolkit.org or Install ATK UI with `composer require atk4/ui` +Download from https://ui.atk4.org/ or install ATK UI with `composer require atk4/ui` Create "index.php" file with: @@ -78,7 +78,7 @@ ATK UI relies on https://fomantic-ui.com CSS framework to render the form beauti To get most of ATK UI, use [ATK Data](https://github.com/atk4/data) to describe your business models such as "User" or "Purchase". When you define models, you can start using some more advanced components: -[Crud](https://ui.agiletoolkit.org/demos/crud.php) is a fully-interactive component that supports pagination, reloading, conditions, data formatting, sorting, quick-search, ordering, custom actions and modals, but at the same time is very easy to use: +[Crud](https://ui.atk4.org/demos/crud.php) is a fully-interactive component that supports pagination, reloading, conditions, data formatting, sorting, quick-search, ordering, custom actions and modals, but at the same time is very easy to use: ```php $app = new \Atk4\Ui\App(['title' => 'hello world']); @@ -173,7 +173,7 @@ Another component implementation using a very friendly PHP syntax: ![wizard](docs/images/wizard.png) -You get most benefit when you use various ATK UI Components together. Try the following demo: https://ui.agiletoolkit.org/demos/interactive/wizard.php. The demo implements: +You get most benefit when you use various ATK UI Components together. Try the following demo: https://ui.atk4.org/demos/interactive/wizard.php. The demo implements: - Multi-step wizard with ability to navigate forward and backward - Form with validation @@ -220,7 +220,7 @@ The result is here: Agile UI comes with many built-in components: -_All components can be view using the [demos](https://ui.agiletoolkit.org/demos/) application._ +_All components can be view using the [demos](https://ui.atk4.org/demos/) application._ | Component | Description | Introduced | | --------- | ----------- | ---------- | @@ -272,9 +272,9 @@ External and 3rd party components may be subject to different licensing terms. ATK UI makes active use of ATK Core and ATK Data frameworks. -- [Agile UI Documentation](https://agile-ui.readthedocs.io) -- [Agile Data Documentation](https://agile-data.readthedocs.io) -- [Agile Core Documentation](https://agile-core.readthedocs.io) +- [Agile UI Documentation](https://atk4-ui.readthedocs.io/) +- [Agile Data Documentation](https://atk4-data.readthedocs.io/) +- [Agile Core Documentation](https://atk4-core.readthedocs.io/) ## ATK UI Schematic diff --git a/composer.json b/composer.json index 9c42ecee5e..cadabd39f3 100644 --- a/composer.json +++ b/composer.json @@ -20,12 +20,10 @@ "authors": [ { "name": "Romans Malinovskis", - "email": "romans@agiletoolkit.org", "homepage": "https://nearly.guru/" }, { - "name": "Alain Belair", - "homepage": "https://agiletoolkit.org/" + "name": "Alain Belair" }, { "name": "Imants Horsts", diff --git a/demos/form-control/input2.php b/demos/form-control/input2.php index a69ba7949c..fe4beb9c4e 100644 --- a/demos/form-control/input2.php +++ b/demos/form-control/input2.php @@ -123,7 +123,7 @@ $control = $form->addControl('surname', new Form\Control\Line([ 'hint' => [View::class, 'template' => new HtmlTemplate( - 'Click here' + 'Click here' )], ])); diff --git a/demos/others/sticky.php b/demos/others/sticky.php index a17d71d135..c8aed534e0 100644 --- a/demos/others/sticky.php +++ b/demos/others/sticky.php @@ -59,8 +59,8 @@ protected function renderView(): void Button::addTo($app, [$app->url('other.php')]); Button::addTo($app, [$app->url('other')]); Button::addTo($app, [$app->url(['other', 'b' => 2])]); -Button::addTo($app, [$app->url('http://yahoo.com/')]); -Button::addTo($app, [$app->url('http://yahoo.com/?q=abc')]); +Button::addTo($app, [$app->url('http://google.com/')]); +Button::addTo($app, [$app->url('http://google.com/?q=abc')]); // unset app/global sticky $app->stickyForget('xx'); diff --git a/docs/accordion.md b/docs/accordion.md index e4297a42a4..6409d5d7e6 100644 --- a/docs/accordion.md +++ b/docs/accordion.md @@ -1,13 +1,14 @@ -.. php:namespace:: Atk4\Ui +:::{php:namespace} Atk4\Ui +::: -.. php:class:: Accordion +:::{php:class} Accordion +::: # Accordion Accordion implement another way to organize your data. The implementation is based on: https://fomantic-ui.com/modules/accordion.html. - -Demo: https://ui.agiletoolkit.org/demos/accordion.php +Demo: https://ui.atk4.org/demos/accordion.php ## Basic Usage @@ -17,7 +18,6 @@ Once you create an Accordion container you can then mix and match static and dyn $acc = Accordion::addTo($app); ``` - Adding a static content section is pretty simple: ``` @@ -26,11 +26,12 @@ LoremIpsum::addTo($acc->addSection('Static Tab')); You can add multiple elements into a single accordion section, like any other view. -.. php:method:: addSection($name, $action = null, $icon = 'dropdown') +:::{php:method} addSection($name, $action = null, $icon = 'dropdown') +::: Use addSection() method to add more section in an Accordion view. First parameter is a title of the section. -Section can be static or dynamic. Dynamic sections use :php:class:`VirtualPage` implementation mentioned above. +Section can be static or dynamic. Dynamic sections use {php:class}`VirtualPage` implementation mentioned above. You should pass Closure action as a second parameter. Example: @@ -49,7 +50,7 @@ $t->addSection('Dynamically Loading', function (VirtualPage $vp) { ## Dynamic Accordion Section -Dynamic sections are based around implementation of :php:class:`VirtualPage` and allow you +Dynamic sections are based around implementation of {php:class}`VirtualPage` and allow you to pass a callback which will be triggered when user clicks on the section title.: ``` @@ -65,9 +66,14 @@ $acc->addSection('Dynamic Lorem Ipsum', function (VirtualPage $vp) { Accordion class has some wrapper method in order to control the accordion module behavior. -.. php:method:: jsOpen($section, $action = null) -.. php:method:: jsToggle($section, $action = null) -.. php:method:: jsClose($section, $action = null) +:::{php:method} jsOpen($section, $action = null) +::: + +:::{php:method} jsToggle($section, $action = null) +::: + +:::{php:method} jsClose($section, $action = null) +::: For example, you can set a button that, when clicked, will toggle an accordion section: diff --git a/docs/advanced.md b/docs/advanced.md index 3f371871c5..a733360260 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -1,4 +1,7 @@ -.. _advanced: +:::{php:namespace} Atk4\Ui +::: + +(advanced)= # Advanced Topics @@ -23,11 +26,11 @@ it appears as requirement. Most of the ORMs lack several important features that are necessary for UI framework design: - - ability to load/store data safely with conditions. - - built-in support for column meta-information - - field, type and table mapping - - "onlyFields" support for efficient querying - - domain-level model references. +- ability to load/store data safely with conditions. +- built-in support for column meta-information +- field, type and table mapping +- "onlyFields" support for efficient querying +- domain-level model references. Agile Data is distributed under same open-source license as Agile UI and the rest of this documentation will assume you are using Agile diff --git a/docs/app.md b/docs/app.md index f2e6f7dbf0..5e186f29ba 100644 --- a/docs/app.md +++ b/docs/app.md @@ -1,9 +1,12 @@ -.. _app: +:::{php:namespace} Atk4\Ui +::: -## Purpose of App class +(app)= -.. php:namespace:: Atk4\Ui -.. php:class:: App +# Purpose of App class + +:::{php:class} App +::: App is a mandatory object that's essential for Agile UI to operate. You should create instance of an App class yourself before other components: @@ -26,7 +29,7 @@ executing unit-tests, you may want to create new App instance. If your applicati exception, it will catch it and create a new App instance to display error message ensuring that the error is not repeated. -### Using App for Injecting Dependencies +## Using App for Injecting Dependencies Since App class becomes available for all objects and components of Agile Toolkit, you may add properties into the App class: @@ -39,24 +42,26 @@ $app->db = new \Atk4\Data\Persistence\Sql($dsn); $m = new MyModel($this->getApp()->db); ``` -.. IMPORTANT:: $app->db is NOT a standard property. If you use this property, that's your own convention. +:::{important} +$app->db is NOT a standard property. If you use this property, that's your own convention. +::: -### Using App for Injecting Behavior +## Using App for Injecting Behavior You may use App class hook to impact behavior of your application: - - using hooks to globally impact object initialization - - override methods to create different behavior, for example url() method may use advanced router logic - to create beautiful URLs. - - you may re-define set-up of :php:class:`Persistence\Ui` and affect how data is loaded from UI. - - load templates from different files - - use a different CDN settings for static files +- using hooks to globally impact object initialization +- override methods to create different behavior, for example url() method may use advanced router logic + to create beautiful URLs. +- you may re-define set-up of {php:class}`Persistence_i_Ui` and affect how data is loaded from UI. +- load templates from different files +- use a different CDN settings for static files -### Using App as Initializer Object +## Using App as Initializer Object App class may initialize some resources for you including user authentication and work with session. My next example defines property `$user` and `$system` for the app class to indicate a system which is currently -active. (See :ref:`system_pattern`): +active. (See {ref}`system_pattern`): ``` class Warehouse extends \Atk4\Ui\App @@ -72,7 +77,7 @@ class Warehouse extends \Atk4\Ui\App $this->db = new \Atk4\Data\Persistence\Sql($_CLEARDB_DATABASE_URL['DSN']); $this->db->setApp($this); -        // My App class provides access to a currently logged user and currently selected system. + // My App class provides access to a currently logged user and currently selected system. session_start(); // App class may be used for pages that do not require authentication @@ -88,7 +93,7 @@ class Warehouse extends \Atk4\Ui\App $this->user = $user->tryLoad($_SESSION['user_id']); } -       // Make sure user is valid + // Make sure user is valid if ($this->user === null) { $this->initLayout([\Atk4\Ui\Layout\Centered::class]); Message::addTo($this, ['Login Required', 'type' => 'error']); @@ -101,7 +106,7 @@ class Warehouse extends \Atk4\Ui\App $this->initLayout([\Atk4\Ui\Layout\Admin::class]); -       // Add more initialization here, such as a populating menu. + // Add more initialization here, such as a populating menu. } } ``` @@ -115,7 +120,7 @@ Crud::addTo($app) ->setModel($app->system->ref('Order')); ``` -### Quick Usage and Page pattern +## Quick Usage and Page pattern A lot of the documentation for Agile UI uses a principle of initializing App object first, then, manually add the UI elements using a procedural approach: @@ -128,15 +133,22 @@ There is another approach in which your application will determine which Page cl executing the request, subsequently creating setting it up and letting it populate UI (This behavior is similar to Agile Toolkit prior to 4.3). -In Agile UI this pattern is implemented through a 3rd party add-on for :ref:`page_manager` and routing. See also -:php:meth:`App::url()` +In Agile UI this pattern is implemented through a 3rd party add-on for {ref}`page_manager` and routing. See also +{php:meth}`App::url()` + +## Clean-up and simplification + +:::{php:method} run() +::: -### Clean-up and simplification +:::{php:attr} runCalled +::: -.. php:method:: run() -.. php:attr:: runCalled -.. php:attr:: isRendering -.. php:attr:: alwaysRun +:::{php:attr} isRendering +::: + +:::{php:attr} alwaysRun +::: App also does certain actions to simplify handling of the application. For instance, App class will render itself automatically at the end of the application, so you can safely add objects into the `App` @@ -150,12 +162,15 @@ $app->run(); ``` If you do not want the application to automatically execute `run()` you can either set `$alwaysRun` to false -or use :php:meth:`terminate()` to the app with desired output. +or use {php:meth}`terminate()` to the app with desired output. + +## Exception handling -### Exception handling +:::{php:method} caugthException +::: -.. php:method:: caugthException -.. php:attr:: catch_exception +:::{php:attr} catch_exception +::: By default, App will also catch unhandled exceptions and will present them nicely to the user. If you have a better plan for exception, place your code inside a try-catch block. @@ -163,13 +178,13 @@ better plan for exception, place your code inside a try-catch block. When Exception is caught, it's displayed using a Layout\Centered layout and execution of original application is terminated. -### Integration with other Frameworks +## Integration with other Frameworks If you use Agile UI in conjunction with another framework, then you may be using a framework-specific App class, that implements tighter integration with the host application or full-stack framework. - -.. php:method:: requireJs() +:::{php:method} requireJs() +::: Method to include additional JavaScript file in page: @@ -177,7 +192,8 @@ Method to include additional JavaScript file in page: $app->requireJs('https://example.com/file.min.js'); ``` -.. php:method:: requireCss($url) +:::{php:method} requireCss($url) +::: Method to include additional CSS style sheet in page: @@ -185,38 +201,47 @@ Method to include additional CSS style sheet in page: $app->requireCss('https://example.com/file.min.css'); ``` -.. php:method:: initIncludes() +:::{php:method} initIncludes() +::: Initializes all includes required by Agile UI. You may extend this class to add more includes. -.. php:method:: getRequestUrl() +:::{php:method} getRequestUrl() +::: Decodes current request without any arguments. If you are changing URL generation pattern, you -probably need to change this method to properly identify the current page. See :php:class:`App::url()` +probably need to change this method to properly identify the current page. See {php:class}`App::url()` -### Loading Templates for Views +## Loading Templates for Views -.. php:method:: loadTemplate($name) +:::{php:method} loadTemplate($name) +::: -Views use :php:attr:`View::$defaultTemplate` to specify which template they are using. By default +Views use {php:attr}`View::$defaultTemplate` to specify which template they are using. By default those are loaded from `vendor/atk4/ui/template` however by overriding this method, you can specify extended logic. You may override this method if you are using a different CSS framework. -## Utilities by App +# Utilities by App App provides various utilities that are used by other components. -.. php:method:: getTag() -.. php:method:: encodeHtml() +:::{php:method} getTag() +::: + +:::{php:method} encodeHtml() +::: Apart from basic utility, App class provides several mechanisms that are helpful for components. -### Sticky GET Arguments +## Sticky GET Arguments + +:::{php:method} stickyGet() +::: -.. php:method:: stickyGet() -.. php:method:: stickyForget() +:::{php:method} stickyForget() +::: Problem: sometimes certain PHP code will only be executed when GET arguments are passed. For example, you may have a file `detail.php` which expects `order_id` parameter and would contain a `Crud` component. @@ -232,18 +257,21 @@ $crud->setModel($order->load($orderId)->ref('Payment')); This make sure that pagination, editing, addition or any other operation that Crud implements will always address same model scope. -If you need to generate URL that respects stickyGet arguments, use :php:meth:`App::url()`. +If you need to generate URL that respects stickyGet arguments, use {php:meth}`App::url()`. -See also :php:meth:`View::stickyGet` +See also {php:meth}`View::stickyGet` -### Redirects +## Redirects -.. php:method:: redirect(page) -.. php:method:: jsRedirect(page) +:::{php:method} redirect(page) +::: + +:::{php:method} jsRedirect(page) +::: App implements two handy methods for handling redirects between pages. The main purpose for those is to provide a simple way to redirect for users who are not familiar with JavaScript and HTTP headers -so well. Example: +so well. Example: ``` if (!isset($_GET['age'])) { @@ -256,9 +284,10 @@ Button::addTo($app, ['Increase age']) No much magic in these methods. -### Database Connection +## Database Connection -.. php:property:: db +:::{php:property} db +::: If your `App` needs a DB connection, set this property to an instance of `Persistence`. @@ -268,24 +297,27 @@ Example: $app->db = \Atk4\Data\Persistence::connect('mysql://user:pass@localhost/atk'); ``` -See `Persistence::connect ` +See [Persistence::connect](https://atk4-data.readthedocs.io/en/develop/persistence.html?highlight=connect#associating-with-persistence) -### Execution Termination +## Execution Termination -.. php:method:: terminate(output) +:::{php:method} terminate(output) +::: Used when application flow needs to be terminated preemptively. For example when callback is triggered and need to respond with some JSON. -### Execution state +## Execution state -.. php:attr:: isRendering +:::{php:attr} isRendering +::: Will be true if the application is currently rendering recursively through the Render Tree. -### Links +## Links -.. php:method:: url(page) +:::{php:method} url(page) +::: Method to generate links between pages. Specified with associative array: @@ -301,40 +333,44 @@ contact.php?from=John+Smith If value with key 0 is specified ('contact') it will be used as the name of the page. By default url() will use page as "contact.php?.." however you can define different behavior -through :ref:`page_manager`. +through {ref}`page_manager`. The url() method will automatically append values of arguments mentioned to `stickyGet()`, but if you need URL to drop any sticky value, specify value explicitly as `false`. -.. php:method:: jsUrl(callback_page) +:::{php:method} jsUrl(callback_page) +::: Use jsUrl for creating callback, which return non-HTML output. This may be routed differently by a host framework (https://github.com/atk4/ui/issues/369). -### Includes +## Includes -.. php:method:: requireJs($url) +:::{php:method} requireJs($url) +::: -Includes header into the class that will load JavaScript file from a specified URL. +Includes header into the `` class that will load JavaScript file from a specified URL. This will be used by components that rely on external JavaScript libraries. -### Hooks +## Hooks -Application implements HookTrait (https://agile-core.readthedocs.io/en/develop/hook.html) +Application implements HookTrait (https://atk4-core.readthedocs.io/en/develop/hook.html) and the following hooks are available: - - beforeRender - - beforeOutput - - beforeExit +- beforeRender +- beforeOutput +- beforeExit Hook beforeExit is called just when application is about to be terminated. If you are -using :php:attr:`App::$alwaysRun` = true, then this hook is guaranteed to execute always +using {php:attr}`App::$alwaysRun` = true, then this hook is guaranteed to execute always after output was sent. ATK will avoid calling this hook multiple times. -.. note:: beforeOutput and beforeRender are not executed if $app->terminate() is called, even - if parameter is passed. +:::{note} +beforeOutput and beforeRender are not executed if $app->terminate() is called, even +if parameter is passed. +::: -## Application and Layout +# Application and Layout When writing an application that uses Agile UI you can either select to use individual components or make them part of a bigger layout. If you use the component individually, then it will @@ -353,9 +389,9 @@ echo $grid->render(); All of the objects created above - button, grid, toolbar and paginator will share the same value for the 'app' property. This value is carried into new objects through AppScopeTrait -(https://agile-core.readthedocs.io/en/develop/appscope.html). +(https://atk4-core.readthedocs.io/en/develop/appscope.html). -### Adding the App +## Adding the App You can create App object on your own then add elements into it: @@ -373,7 +409,7 @@ of GET/POST data and more. We are still not using the layout, however. -### Adding the Layout +## Adding the Layout Layout can be initialized through the app like this: @@ -396,15 +432,16 @@ not only change the overall page outline, but will also introduce some additiona Each layout, depending on it's content, may come with several views that you can populate. -### Admin Layout +## Admin Layout -.. php:namespace:: Atk4\Ui\Layout -.. php:class:: Admin +:::{php:class} Layout_i_Admin +::: Agile Toolkit comes with a ready to use admin layout for your application. The layout is built with top, left and right menu objects. -.. php:attr:: menuLeft +:::{php:attr} menuLeft +::: Populating the left menu object is simply a matter of adding the right menu items to the layout menu: @@ -420,7 +457,8 @@ $EditGroup = $layout->menuLeft->addGroup(['Edit', 'icon' => 'edit']); $EditGroup->addItem('Basics', ['edit/basic']); ``` -.. php:attr:: menu +:::{php:attr} menu +::: This is the top menu of the admin layout. You can add other item to the top menu using: @@ -430,15 +468,17 @@ Button::addTo($layout->menu->addItem(), ['View Source', 'class.teal' => true, 'i ->on('click', new \Atk4\Ui\Js\JsExpression('document.location = [];', [$url . $f])); ``` -.. php:attr:: menuRight +:::{php:attr} menuRight +::: The top right dropdown menu. -.. php:attr:: isMenuLeftVisible +:::{php:attr} isMenuLeftVisible +::: Whether or not the left menu is open on page load or not. Default is true. -### Integration with Legacy Apps +## Integration with Legacy Apps If you use Agile UI inside a legacy application, then you may already have layout and some patterns or limitations may be imposed on the app. Your first job would be to properly @@ -447,16 +487,15 @@ implement the "App" and either modification of your existing class or a new clas Having a healthy "App" class will ensure that all of Agile UI components will perform properly. -### 3rd party Layouts +## 3rd party Layouts You should be able to find 3rd party Layout implementations that may even be coming with some custom templates and views. The concept of a "Theme" in Agile UI consists of offering of the following 3 things: - - custom CSS build from Fomantic-UI - - custom Layout(s) along with documentation - - additional or tweaked Views +- custom CSS build from Fomantic-UI +- custom Layout(s) along with documentation +- additional or tweaked Views Unique layouts can be used to change the default look and as a stand-in replacement to some of standard layouts or as a new and entirely different layout. - diff --git a/docs/autocomplete.md b/docs/autocomplete.md index e78360330c..bf7fa3dc97 100644 --- a/docs/autocomplete.md +++ b/docs/autocomplete.md @@ -1,24 +1,27 @@ -.. _autocomplete: +:::{php:namespace} Atk4\Ui +::: + +(autocomplete)= # AutoComplete Form Control -.. php:namespace:: Atk4\Ui\Form\Control -.. php:class:: AutoComplete +:::{php:class} Form_i_Control_i_AutoComplete +::: -Agile UI uses "Form\\Control\\Dropdown" by default on the form, but there is also implementation +Agile UI uses "Form\Control\Dropdown" by default on the form, but there is also implementation for AutoComplete form control. Although they look similar, there are some differences: - - AutoComplete will perform callback to fetch values. - - AutoComplete can use callback to format options (both keys and values). - - AutoComplete can search in multiple fields. - - AutoComplete can use form current (dirty) values to apply dependency and limit options. - - AutoComplete can have multiple selection. - - AutoComplete has additional feature called "Plus" - - AutoComplete only works with models. Won't work for pre-defined value lists. +- AutoComplete will perform callback to fetch values. +- AutoComplete can use callback to format options (both keys and values). +- AutoComplete can search in multiple fields. +- AutoComplete can use form current (dirty) values to apply dependency and limit options. +- AutoComplete can have multiple selection. +- AutoComplete has additional feature called "Plus" +- AutoComplete only works with models. Won't work for pre-defined value lists. AutoComplete can be a drop-in replacement for Dropdown. -### Using Plus mode +## Using Plus mode In your application, it is handy if you can automatically add a missing "client" from the form where you add an invoice. AutoComplete implements "Plus" mode which will automatically open a modal @@ -32,7 +35,7 @@ $form->addControl('test', [\Atk4\Ui\Form\Control\AutoComplete::class, 'plus' => ->setModel(new Country($db)); ``` -### Specifying in Model +## Specifying in Model You can also specify that you prefer to use AutoComplete inside your model definition: @@ -40,7 +43,7 @@ You can also specify that you prefer to use AutoComplete inside your model defin $model->hasOne('country_id', ['model' => [Country::class], 'ui' => ['form' => [\Atk4\Ui\Form\Control\AutoComplete::class]]]); ``` -### Advanced Usage +## Advanced Usage You can do much more with AutoComplete form control by passing dropdown settings: diff --git a/docs/breadcrumb.md b/docs/breadcrumb.md index 36d0887f1a..10de6c13c7 100644 --- a/docs/breadcrumb.md +++ b/docs/breadcrumb.md @@ -1,16 +1,22 @@ -.. _breadcrumb: +:::{php:namespace} Atk4\Ui +::: + +(breadcrumb)= # Breadcrumb -.. php:namespace:: Atk4\Ui -.. php:class:: Breadcrumb +:::{php:class} Breadcrumb +::: Implement navigational Breadcrumb, by using https://fomantic-ui.com/collections/breadcrumb.html ## Basic Usage -.. php:method:: addCrumb() -.. php:method:: set() +:::{php:method} addCrumb() +::: + +:::{php:method} set() +::: Here is a simple usage: @@ -23,27 +29,31 @@ $crumb->set('Change Password'); Every time you call addCrumb a new one is added. With set() you can specify the name of the current page. addCrumb also requires a URL passed as second argument which can be either a string or array (which would then -be passed to url() (:php:meth:`View::url`). +be passed to url() ({php:meth}`View::url`). ## Changing Divider -.. php:attr:: dividerClass +:::{php:attr} dividerClass +::: By default value `right angle icon` is used, but you can change it to `right chevron icon` or simply set to empty string `""` to use slash. ## Working with Path -.. php:attr:: path -.. php:method: popTitle() +:::{php:attr} path +::: + +:::{php:method} popTitle() +::: Calling addCrumb adds more elements into the $path property. Each element there would contain 3 hash values: - - section - name that will appear to the user - - link - where to go if clicked - - divider - which divider to use after the crumb +- section - name that will appear to the user +- link - where to go if clicked +- divider - which divider to use after the crumb -By default `divider` is set to :php:attr:`Breadcrumb::dividerClass`. You may also manipulate $path array yourself. +By default `divider` is set to {php:attr}`Breadcrumb::dividerClass`. You may also manipulate $path array yourself. For example the next code will use some logic: ``` @@ -58,10 +68,8 @@ if ($id) { $model = $model->load($id); $crumb->addCrumb($model->get('name'), []); - // here we can check for additional criteria and display a deeper level on the crumb - Form::addTo($app)->setModel($model); } else { // display list of users @@ -72,5 +80,3 @@ if ($id) { $crumb->popTitle(); ``` - - diff --git a/docs/button.md b/docs/button.md index 7e19b87fdd..c36fab5373 100644 --- a/docs/button.md +++ b/docs/button.md @@ -1,10 +1,12 @@ -.. _button: +:::{php:namespace} Atk4\Ui +::: -# Button +(button)= -.. php:namespace:: Atk4\Ui +# Button -.. php:class:: Button +:::{php:class} Button +::: Implements a clickable button: @@ -12,7 +14,7 @@ Implements a clickable button: $button = Button::addTo($app, ['Click me']); ``` -The Button will typically inherit all same properties of a :php:class:`View`. The base class "View" +The Button will typically inherit all same properties of a {php:class}`View`. The base class "View" implements many useful methods already, such as: ``` @@ -28,14 +30,14 @@ $button->addClass('big red'); $app->add($button); ``` - You can refer to the Fomantic-UI documentation for Button to find out more about available classes: https://fomantic-ui.com/elements/button.html. -Demo: https://ui.agiletoolkit.org/demos/button.php +Demo: https://ui.atk4.org/demos/button.php -### Button Icon +## Button Icon -.. php:attr:: icon +:::{php:attr} icon +::: Property $icon will place icon on your button and can be specified in one of the following two ways: @@ -57,7 +59,8 @@ $button->icon = new Icon('thumbs u'); $app->add($button); ``` -.. php:attr:: iconRight +:::{php:attr} iconRight +::: Setting this will display icon on the right of the button: @@ -65,13 +68,13 @@ Setting this will display icon on the right of the button: $button = Button::addTo($app, ['Next', 'iconRight' => 'right arrow']); ``` -Apart from being on the right, the same rules apply as :php:attr:`Button::$icon`. Both +Apart from being on the right, the same rules apply as {php:attr}`Button::$icon`. Both icons cannot be specified simultaneously. -### Button Bar +## Button Bar -Buttons can be arranged into a bar. You would need to create a :php:class:`View` component -with property ``ui='buttons'`` and add your other buttons inside: +Buttons can be arranged into a bar. You would need to create a {php:class}`View` component +with property `ui='buttons'` and add your other buttons inside: ``` $bar = View::addTo($app, ['ui' => 'vertical buttons']); @@ -103,9 +106,10 @@ $bar->add($button); $app->add($bar); ``` -### Linking +## Linking -.. php:method:: link +:::{php:method} link +::: Will link button to a destination URL or page: @@ -115,15 +119,15 @@ $button->link('https://google.com/'); $button->link(['details', 'id' => 123]); ``` -If array is used, it's routed to :php:meth:`App::url` +If array is used, it's routed to {php:meth}`App::url` -For other JavaScript actions you can use :ref:`js`: +For other JavaScript actions you can use {ref}`js`: ``` $button->on('click', new JsExpression('document.location.reload()')); ``` -### Complex Buttons +## Complex Buttons Knowledge of the Fomantic-UI button (https://fomantic-ui.com/elements/button.html) can help you in creating more complex buttons: @@ -134,4 +138,3 @@ Icon::addTo(Button::addTo($forks, ['Forks', 'class.blue' => true]), ['fork']); Label::addTo($forks, ['1,048', 'class.basic blue left pointing' => true]); $app->add($forks); ``` - diff --git a/docs/callbacks.md b/docs/callbacks.md index ca383f21e4..16eb369131 100644 --- a/docs/callbacks.md +++ b/docs/callbacks.md @@ -1,13 +1,16 @@ -### Callback Introduction +:::{php:namespace} Atk4\Ui +::: + +# Callback Introduction Agile UI pursues a goal of creating a full-featured, interactive, user interface. Part of that relies on abstraction of Browser/Server communication. -Callback mechanism allow any :ref:`component` of Agile Toolkit to send HTTP requests back to itself +Callback mechanism allow any {ref}`component` of Agile Toolkit to send HTTP requests back to itself through a unique route and not worry about accidentally affecting or triggering action of any other component. -One example of this behavior is the format of :php:meth:`View::on` where you pass 2nd argument as a +One example of this behavior is the format of {php:meth}`View::on` where you pass 2nd argument as a PHP callback: ``` @@ -23,16 +26,17 @@ This creates callback route transparently which is triggered automatically durin To make this work seamlessly there are several classes at play. This documentation chapter will walk you through the callback mechanisms of Agile UI. -### The Callback class +# The Callback class -.. php:class:: Callback +:::{php:class} Callback +::: Callback is not a View. This class does not extend any other class but it does implement several important traits: - - `TrackableTrait `_ - - `AppScopeTrait `_ - - `DiContainerTrait `_ +- [TrackableTrait](https://atk4-core.readthedocs.io/en/develop/container.html?highlight=trackable#trackable-trait) +- [AppScopeTrait](https://atk4-core.readthedocs.io/en/develop/appscope.html) +- [DiContainerTrait](https://atk4-core.readthedocs.io/en/develop/di.html) To create a new callback, do this: @@ -41,12 +45,14 @@ $c = new \Atk4\Ui\Callback(); $app->add($c); ``` -Because 'Callback' is not a View, it won't be rendered. The reason we are adding into :ref:`render_tree` +Because 'Callback' is not a View, it won't be rendered. The reason we are adding into {ref}`render_tree` is for it to establish a unique name which will be used to generate callback URL: -.. php:method:: getUrl($val) +:::{php:method} getUrl($val) +::: -.. php:method:: set +:::{php:method} set +::: The following example code generates unique URL: @@ -59,7 +65,7 @@ $label->link($cb->getUrl()); I have assigned generated URL to the label, so that if you click it, your browser will visit callback URL triggering a special action. We haven't set that action yet, so I'll do it next with -:php:meth::`Callback::set()`: +{php:meth}`Callback::set()`: ``` $cb->set(function () use ($app) { @@ -67,28 +73,28 @@ $cb->set(function () use ($app) { }); ``` -### Callback Triggering +# Callback Triggering To illustrate how callbacks work, let's imagine the following workflow: - - your application with the above code resides in file 'test.php` - - when user opens 'test.php' in the browser, first 4 lines of code execute - but the set() will not execute "terminate". Execution will continue as normal. - - getUrl() will provide link e.g. `test.php?app_callback=callback` +- your application with the above code resides in file 'test.php` +- when user opens 'test.php' in the browser, first 4 lines of code execute + but the set() will not execute "terminate". Execution will continue as normal. +- getUrl() will provide link e.g. `test.php?app_callback=callback` When page renders, the user can click on a label. If they do, the browser will send another request to the server: - - this time same request is sent but with the `?app_callback=callback` parameter - - the :php:meth:`Callback::set()` will notice this argument and execute "terminate()" - - terminate() will exit app execution and output 'in callback' back to user. +- this time same request is sent but with the `?app_callback=callback` parameter +- the {php:meth}`Callback::set()` will notice this argument and execute "terminate()" +- terminate() will exit app execution and output 'in callback' back to user. -Calling :php:meth:`App::terminate()` will prevent the default behaviour (of rendering UI) and will +Calling {php:meth}`App::terminate()` will prevent the default behaviour (of rendering UI) and will output specified string instead, stopping further execution of your application. -### Return value of set() +# Return value of set() -The callback verifies trigger condition when you call :php:meth:`Callback::set()`. If your callback +The callback verifies trigger condition when you call {php:meth}`Callback::set()`. If your callback returns any value, the set() will return it too: ``` @@ -102,10 +108,11 @@ if ($cb->set(function () { return true; })) { } ``` -This example uses return of the :php:meth:`Callback::set()` to add class to a label, however a -much more preferred way is to use :php:attr:`$triggered`. +This example uses return of the {php:meth}`Callback::set()` to add class to a label, however a +much more preferred way is to use {php:attr}`$triggered`. -.. php:attr:: triggered +:::{php:attr} triggered +::: You use property `triggered` to detect if callback was executed or not, without short-circuting the execution with set() and terminate(). This can be helpful sometimes when you need to affect the @@ -127,7 +134,8 @@ if ($cb->triggered) { } ``` -.. php:attr:: postTrigger +:::{php:attr} postTrigger +::: A Callback class can also use a POST variable for triggering. For this case the $callback->name should be set through the POST data. @@ -135,14 +143,16 @@ through the POST data. Even though the functionality of Callback is very basic, it gives a very solid foundation for number of derived classes. -.. php:attr:: urlTrigger +:::{php:attr} urlTrigger +::: Specifies which GET parameter to use for triggering. Normally it's same as `$callback->name`, but you can set it to anything you want. As long as you keep it unique on a current page, you should be OK. -### CallbackLater +# CallbackLater -.. php:class:: CallbackLater +:::{php:class} CallbackLater +::: This class is very similar to Callback, but it will not execute immediately. Instead it will be executed either at the end at beforeRender or beforeOutput hook from inside App, whichever comes first. @@ -166,11 +176,11 @@ CallbackLater is used by several actions in Agile UI, such as JsReload(), and en you are reloading are fully rendered by the time callback is executed. Given our knowledge of Callbacks, lets take a closer look at how JsReload actually works. So what do we -know about :php:class:`JsReload` already? +know about {php:class}`Js_i_JsReload` already? - - JsReload is class implementing JsExpressionable - - you must specify a view to JsReload - - when triggered, the view will refresh itself on the screen. +- JsReload is class implementing JsExpressionable +- you must specify a view to JsReload +- when triggered, the view will refresh itself on the screen. Here is example of JsReload: @@ -183,7 +193,6 @@ $button->on('click', new \Atk4\Ui\Js\JsReload($view)); \Atk4\Ui\LoremIpsum::addTo($view); ``` - NOTE: that we can't perform JsReload on LoremIpsum directly, because it's a text, it needs to be inside a container. When JsReload is created, it transparently creates a 'CallbackLater' object inside `$view`. On the JavaScript side, it will execute this new route which will respond with a NEW content @@ -193,14 +202,15 @@ Should JsReload use regular 'Callback', then it wouldn't know that $view must co JsReload existence is only possible thanks to CallbackLater implementation. -### JsCallback +# JsCallback -.. php:class:: JsCallback +:::{php:class} JsCallback +::: So far, the return value of callback handler was pretty much insignificant. But wouldn't it be great if this value was meaningful in some way? -JsCallback implements exactly that. When you specify a handler for JsCallback, it can return one or multiple :ref:`js_action` +JsCallback implements exactly that. When you specify a handler for JsCallback, it can return one or multiple {ref}`js_action` which will be rendered into JavaScript in response to triggering callback's URL. Let's bring up our older example, but will use JsCallback class now: @@ -223,10 +233,10 @@ When you trigger callback, you'll see the output: ``` This is how JsCallback renders actions and sends them back to the browser. In order to retrieve and execute actions, -you'll need a JavaScript routine. Luckily JsCallback can be passed to :php:meth:`View::on()` as a JS action. +you'll need a JavaScript routine. Luckily JsCallback can be passed to {php:meth}`View::on()` as a JS action. -Let me try this again. JsCallback is an :ref:`js_action` which will execute request towards a callback-URL that will -execute PHP method returning one or more :ref:`js_action` which will be received and executed by the original action. +Let me try this again. JsCallback is an {ref}`js_action` which will execute request towards a callback-URL that will +execute PHP method returning one or more {ref}`js_action` which will be received and executed by the original action. To fully use jsAction above, here is a modified code: @@ -252,13 +262,13 @@ $label->on('click', function () { }); ``` -User Confirmation -^^^^^^^^^^^^^^^^^ +## User Confirmation The implementation perfectly hides existence of callback route, javascript action and JsCallback. The JsCallback -is based on 'Callback' therefore code after :php:meth:`View::on()` will not be executed during triggering. +is based on 'Callback' therefore code after {php:meth}`View::on()` will not be executed during triggering. -.. php:attr:: confirm +:::{php:attr} confirm +::: If you set `confirm` property action will ask for user's confirmation before sending a callback: @@ -276,7 +286,7 @@ $label->detail = $cb->getUrl(); $label->on('click', $cb); ``` -This is used with delete operations. When using :php:meth:`View::on()` you can pass extra argument to set the 'confirm' +This is used with delete operations. When using {php:meth}`View::on()` you can pass extra argument to set the 'confirm' property: ``` @@ -287,10 +297,10 @@ $label->on('click', function () { }, ['confirm' => 'sure?']); ``` -JavaScript arguments -^^^^^^^^^^^^^^^^^^^^ +## JavaScript arguments -.. php:method:: set($callback, $arguments = []) +:::{php:method} set($callback, $arguments = []) +::: It is possible to modify expression of JsCallback to pass additional arguments to it's callback. The next example will send browser screen width back to the callback: @@ -308,7 +318,7 @@ $label->on('click', $cb); ``` In here you see that I'm using a 2nd argument to $cb->set() to specify arguments, which, I'd like to fetch from the -browser. Those arguments are passed to the callback and eventually arrive as $arg1 inside my callback. The :php:meth:`View::on()` +browser. Those arguments are passed to the callback and eventually arrive as $arg1 inside my callback. The {php:meth}`View::on()` also supports argument passing: ``` @@ -329,9 +339,7 @@ $label->on('click', function (Jquery $j, $arg1) { }, [new \Atk4\Ui\Js\JsExpression('$(window).width()')]); ``` - -Referring to event origin -^^^^^^^^^^^^^^^^^^^^^^^^^ +## Referring to event origin You might have noticed that JsCallback now passes first argument ($j) which so far, we have ignored. This argument is a jQuery chain for the element which received the event. We can change the response to do something with this element. @@ -343,6 +351,4 @@ $j->text('width is ' . $arg1); Now instead of showing an alert box, label content will be changed to display window width. -There are many other applications for JsCallback, for example, it's used in :php:meth:`Form::onSubmit()`. - - +There are many other applications for JsCallback, for example, it's used in {php:meth}`Form::onSubmit()`. diff --git a/docs/components.md b/docs/components.md index 5a7763b3ff..aacee71cee 100644 --- a/docs/components.md +++ b/docs/components.md @@ -1,99 +1,107 @@ +:::{php:namespace} Atk4\Ui +::: + # Components -Classes that extend from :php:class:`View` are called `Components` and inherit abilities to render themselves (see :ref:`render`) +Classes that extend from {php:class}`View` are called `Components` and inherit abilities to render themselves (see {ref}`render`) ## Core Components Some components serve as a foundation of entire set of other components. A lot of qualities implemented by a core component is inherited by its descendants. -.. toctree:: - :maxdepth: 1 +:::{toctree} +:maxdepth: 1 - view - lister - table - field - fileupload - tablecolumn +view +lister +table +field +fileupload +tablecolumn +::: ## Simple components -.. figure:: images/simple.png - :scale: 30% - :align: right +:::{figure} images/simple.png +:align: right +:scale: 30% +::: Simple components exist for the purpose of abstraction and creating a decent interface which you can rely on when programming your PHP application with Agile UI. In some cases it may make sense to rely on HTML templates for the simple elements such as Icons, but when you are working with dynamic and generic components quite often you need to abstract HTML yet let the user have decent control over even the small elements. -.. toctree:: - :maxdepth: 1 - - button - label - text - loremipsum - header - beadcrumb - icon - image - message - tabs - accordion - helloworld +:::{toctree} +:maxdepth: 1 + +button +label +text +loremipsum +header +beadcrumb +icon +image +message +tabs +accordion +helloworld +::: ## Interactive components -.. figure:: images/interactive.png - :scale: 30% - :align: right +:::{figure} images/interactive.png +:align: right +:scale: 30% +::: -Interactive components rely on :ref:`callback`, :ref:`virtualpage` or :ref:`sse` to communicate with themselves in the PHP realm. You add them +Interactive components rely on {ref}`callback`, {ref}`virtualpage` or {ref}`sse` to communicate with themselves in the PHP realm. You add them just as you would add any other component, yet they will send additional requests, like loading additional data or executing other code. Here is how interactive components will typically communicate: 1. request by browser is made. -2. :php:class:`App` asks :php:class:`Console` to render HTML + JavaScript. -3. JavaScript invokes AJAX request using a :php:class:`Callback` URL. -4. Callback invokes user-defined PHP code, which will generate some :php:meth:`Console::output()`. +2. {php:class}`App` asks {php:class}`Console` to render HTML + JavaScript. +3. JavaScript invokes AJAX request using a {php:class}`Callback` URL. +4. Callback invokes user-defined PHP code, which will generate some {php:meth}`Console::output()`. 5. Response is encoded and -6. sent back to the browser either as JSON or :ref:`sse`. - +6. sent back to the browser either as JSON or {ref}`sse`. -.. toctree:: - :maxdepth: 1 +:::{toctree} +:maxdepth: 1 - console - loader - progressbar - popup - wizard - rightpanel - dataexecutor +console +loader +progressbar +popup +wizard +rightpanel +dataexecutor +::: ## Composite components -.. figure:: images/composite.png - :scale: 30% - :align: right +:::{figure} images/composite.png +:align: right +:scale: 30% +::: Composite elements such as Grid are the bread-and-butter of Agile UI. They will pass on rendering and -intractivity to several sub-components. Illustration shows how :php:class:`Grid` relies on :php:class:`Table` for -rendering the data table, but Grid will also rely on :php:class:`Menu` and :php:class:`Paginator` when necessary. - -Any component automatically becomes composite if, you use :php:meth:`View::add()`. +intractivity to several sub-components. Illustration shows how {php:class}`Grid` relies on {php:class}`Table` for +rendering the data table, but Grid will also rely on {php:class}`Menu` and {php:class}`Paginator` when necessary. +Any component automatically becomes composite if, you use {php:meth}`View::add()`. -.. toctree:: - :maxdepth: 1 +:::{toctree} +:maxdepth: 1 - columns - crud - grid - form - paginator - dropdown +columns +crud +grid +form +paginator +dropdown - misc +misc +::: diff --git a/docs/conf.py b/docs/conf.py index f2c8f31feb..d5727c4985 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,8 +14,11 @@ 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinxcontrib.phpdomain', + 'myst_parser', ] +myst_enable_extensions = ['colon_fence', 'linkify'] + source_suffix = '.md' master_doc = 'index' diff --git a/docs/console.md b/docs/console.md index a20d4b522e..cc6dd8b0a9 100644 --- a/docs/console.md +++ b/docs/console.md @@ -1,25 +1,28 @@ -.. php:namespace:: Atk4\Ui +:::{php:namespace} Atk4\Ui +::: -.. php:class:: Console +:::{php:class} Console +::: # Console -.. figure:: images/console.png +:::{figure} images/console.png +::: With console you can output real-time information to the user directly from PHP. It can be used do direct output from slow method or even execute commands on the server (such as `ping`). - -Demo: https://ui.agiletoolkit.org/demos/console.php +Demo: https://ui.atk4.org/demos/console.php ## Basic Usage -.. php:method:: set($callback) - -.. php:method:: send($callback) +:::{php:method} set($callback) +::: +:::{php:method} send($callback) +::: -After adding a console to your :ref:`render_tree`, you just need to set a callback: +After adding a console to your {ref}`render_tree`, you just need to set a callback: ``` $console = Console::addTo($app); @@ -32,16 +35,17 @@ $console->set(function (Console $console) { }); ``` -Console uses :ref:`sse` which works pretty much out-of-the-box with the modern browsers and unlike websockets +Console uses {ref}`sse` which works pretty much out-of-the-box with the modern browsers and unlike websockets do not require you to set up additional ports on the server. JavaScript in a browser captures real-time events and displays it on a black background. -Console integrates nicely with DebugTrait (https://agile-core.readthedocs.io/en/develop/debug.html?highlight=debug), +Console integrates nicely with DebugTrait (https://atk4-core.readthedocs.io/en/develop/debug.html?highlight=debug), and also allows you to execute shell process on the server while redirecting output in real-time. ## Using With Object -.. php:method:: runMethod($callback); +:::{php:method} runMethod($callback) +::: We recommend that you pack up your busineess logic into your Model methods. When it's time to call your method, you could either do this: @@ -82,9 +86,11 @@ $console->runMethod('StaticLib', 'myStaticMethod'); ## Executing Commands -.. php:method:: exec($cmd, $args); +:::{php:method} exec($cmd, $args) +::: -.. php:argument:: lastExitCode +:::{php:argument} lastExitCode +::: To execute a command, use: @@ -116,7 +122,7 @@ Console::addTo($app)->set(function (Console $c) { ``` Method exec() will return `$this` if command was run inside callback and was successful. It will return `false` on error -and will return `null` if called outside of callback. You may also refer to ::php:attr:`Console::lastExitCode` which +and will return `null` if called outside of callback. You may also refer to {php:attr}`Console::lastExitCode` which contains exit code of the last command. Normally it's safe to chain `exec` which ensures that execution will stack. Should any command fail, the subsequent diff --git a/docs/core.md b/docs/core.md index e102b7ff27..cf7bb12f98 100644 --- a/docs/core.md +++ b/docs/core.md @@ -1,6 +1,7 @@ -# Core Concepts +:::{php:namespace} Atk4\Ui +::: -.. php:namespace:: Atk4\Ui +# Core Concepts Agile Toolkit and Agile UI are built upon specific core concepts. Understanding those concepts is very important especially if you plan to write and distribute your own @@ -18,10 +19,11 @@ $app->initLayout([\Atk4\Ui\Layout\Centered::class]); LoremIpsum::addTo($app); ``` -.. toctree:: - app +:::{toctree} +app +::: -.. _seed: +(seed)= ## Seed @@ -45,11 +47,13 @@ $button->icon = 'book'; We call this format 'Seed'. This section will explain how and where it is used. -.. toctree:: - seed +:::{toctree} +seed +::: -.. _render: -.. _render_tree: +(render)= + +(render_tree)= ## Render Tree @@ -67,8 +71,9 @@ $app->add($msg); To find out more about how components are linked up together and rendered, see: -.. toctree:: - render +:::{toctree} +render +::: ## Sticky GET @@ -84,8 +89,8 @@ Button::addTo($app, ['Trigger message'])->link(['message' => 'Hello World']); ``` The code is simple - if you click the button, page will appear with the message just above, however -there is a potential problem here. What if "Message" wanted to perform a :ref:`Callback`? What if -we use :php:class:`Console` instead, which must display an interactive data stream? +there is a potential problem here. What if "Message" wanted to perform a {ref}`Callback`? What if +we use {php:class}`Console` instead, which must display an interactive data stream? In Agile UI you can request that some $_GET arguments are preserved and included into callback urls: @@ -99,21 +104,22 @@ Button::addTo($app, ['Trigger message'])->link(['message' => 'Hello World']); There are two types of "sticky" parameters, application-wide and view-specific. -.. toctree:: - - sticky +:::{toctree} +sticky +::: ## Type Presentation -Several components are too complex to be implemented in a single class. :php:class:`Table`, for example, -has the ability to format columns by utilizing type-specific column classes. Another example is :php:class:`Form` +Several components are too complex to be implemented in a single class. {php:class}`Table`, for example, +has the ability to format columns by utilizing type-specific column classes. Another example is {php:class}`Form` which relies on Field-specific Form\Control component. Agile UI uses a specific pattern for those definitions, which makes the overall structure more extensible by having the ability to introduce new types with consistent support throughout the UI. -.. toctree:: - type-presentation +:::{toctree} +type-presentation +::: ## Templates @@ -123,8 +129,9 @@ and manipulated by a Template class. To learn more on how to create a custom template or how to change global template behavior see: -.. toctree:: - template +:::{toctree} +template +::: ## Agile Data @@ -145,19 +152,20 @@ $view->setModel($user); Next section will explain you how the Agile UI interacts with the data layer and how it outputs or inputs user data. -.. toctree:: - data +:::{toctree} +data +::: -.. _callback: +(callback)= ## Callbacks -By relying on the ability of generating :ref:`unique_name`, it's possible to create several classes +By relying on the ability of generating {ref}`unique_name`, it's possible to create several classes for implementing PHP callbacks. They follow the pattern: - - present something on the page (maybe) - - generate URL with unique parameter - - if unique parameter is passed back, behave differently +- present something on the page (maybe) +- generate URL with unique parameter +- if unique parameter is passed back, behave differently Once the concept is established, it can even be used on a higher level, for example: @@ -167,18 +175,18 @@ $button->on('click', function () { }); ``` -.. toctree:: - :maxdepth: 4 +:::{toctree} +:maxdepth: 4 - callbacks +callbacks +::: - -.. _virtualpage: +(virtualpage)= ## VirtualPage -Building on the foundation of :ref:`callback`, components :php:class:`VirtualPage` and :php:class:`Loader` -exist to enhance other Components with dynamically loadable content. Here is example for :php:class:`Tabs`: +Building on the foundation of {ref}`callback`, components {php:class}`VirtualPage` and {php:class}`Loader` +exist to enhance other Components with dynamically loadable content. Here is example for {php:class}`Tabs`: ``` $tabs = Tabs::addTo($app); @@ -189,22 +197,22 @@ $tabs->addTab('Second tab is dynamic', function (VirtualPage $vp) { }); ``` -As you switch between those two tabs, you'll notice that the :php:class:`Button` label on the "Second tab" -reloads every time. :php:class:`Tabs` implements this by using :php:class:`VirtualPage`, read further to +As you switch between those two tabs, you'll notice that the {php:class}`Button` label on the "Second tab" +reloads every time. {php:class}`Tabs` implements this by using {php:class}`VirtualPage`, read further to find out how: +:::{toctree} +:maxdepth: 4 -.. toctree:: - :maxdepth: 4 - - virtualpage +virtualpage +::: ## Documentation is coming soon. -.. toctree:: - :maxdepth: 4 - - init - callback - stickyget +:::{toctree} +:maxdepth: 4 +init +callback +stickyget +::: diff --git a/docs/crud.md b/docs/crud.md index 950e103fff..7c93106b82 100644 --- a/docs/crud.md +++ b/docs/crud.md @@ -1,20 +1,26 @@ -.. _crud: +:::{php:namespace} Atk4\Ui +::: + +(crud)= # Crud -.. php:namespace:: Atk4\Ui -.. php:class:: Crud +:::{php:class} Crud +::: -Crud class offers a very usable extension to :php:class:`Grid` class, which automatically adds actions for deleting, +Crud class offers a very usable extension to {php:class}`Grid` class, which automatically adds actions for deleting, updating and adding records as well as linking them with corresponding Model actions. -.. important:: If you only wish to display a non-interactive table use :php:class:`Table` class. If you need to - display Data Grid with some custom actions (not update/delete/add) or if you want to use your own editing - mechanism (such as edit data on separate page, not inside a modal), use :php:class:`Grid` - +:::{important} +If you only wish to display a non-interactive table use {php:class}`Table` class. If you need to +display Data Grid with some custom actions (not update/delete/add) or if you want to use your own editing +mechanism (such as edit data on separate page, not inside a modal), use {php:class}`Grid` +::: -.. important:: ATK Addon - MasterCrud implements a higher-level multi-model management solution, that takes - advantage of model relations and traversal to create multiple levels of Cruds: https://github.com/atk4/mastercrud +:::{important} +ATK Addon - MasterCrud implements a higher-level multi-model management solution, that takes +advantage of model relations and traversal to create multiple levels of Cruds: https://github.com/atk4/mastercrud +::: ## Using Crud @@ -59,16 +65,20 @@ Model action using system property set to true, will not be display in Crud. Not ## Specifying Fields (for different views) -.. php:attr:: displayFields +:::{php:attr} displayFields +::: Only fields name set in this property will be display in Grid. Leave empty for all fields. -.. php:attr:: editFields +:::{php:attr} editFields +::: If you'd like to have different fields in the grid of the CRUD, but you need more/different fields in the editing modal (which opens when clicking on an entry), you can choose here the fields that are available in the editing modal window. -.. important:: Both views (overview and editing view) refer to the same model, just the fields shown in either of them differ +:::{important} +Both views (overview and editing view) refer to the same model, just the fields shown in either of them differ +::: Example: @@ -79,7 +89,8 @@ $crud->displayFields(['field1, field2']); $crud->editFields(['field1, field2, field3, field4']); ``` -.. php:attr:: addFields +:::{php:attr} addFields +::: Through those properties you can specify which fields to use when form is display for add and edit action. Field name add here will have priorities over the action fields properties. When set to null, the action fields property @@ -87,7 +98,7 @@ will be used. ## Custom Form Behavior -:php:class:`Form` in Agile UI allows you to use many different things, such as custom layouts. With Crud you can +{php:class}`Form` in Agile UI allows you to use many different things, such as custom layouts. With Crud you can specify your own form behavior using a callback for action: ``` @@ -116,9 +127,11 @@ Callback function will receive the Form and ActionExecutor as arguments. ## Changing titles -.. important:: Changing the title of the CRUD's grid view must be done before setting the model. - Changing the title of the modal of a CRUD's modal window must be done after loading the model. - Otherwise the changes will have no effect. +:::{important} +Changing the title of the CRUD's grid view must be done before setting the model. +Changing the title of the modal of a CRUD's modal window must be done after loading the model. +Otherwise the changes will have no effect. +::: Here's an example: @@ -132,10 +145,17 @@ $model->getUserAction('add')->ui['executor']->title = 'New title for modal'; // ## Notification -.. php:attr:: notifyDefault -.. php:attr:: saveMsg -.. php:attr:: deleteMsg -.. php:attr:: defaultMsg +:::{php:attr} notifyDefault +::: + +:::{php:attr} saveMsg +::: + +:::{php:attr} deleteMsg +::: + +:::{php:attr} defaultMsg +::: When a model action execute in Crud, a notification to user is display. You can specify your notifier default seed using `$notifyDefault`. The notifier message may be set via `$saveMsg`, `$deleteMsg` or `$defaultMsg` property. diff --git a/docs/data.md b/docs/data.md index edf0e00b8d..ce57e1145b 100644 --- a/docs/data.md +++ b/docs/data.md @@ -1,6 +1,9 @@ -.. _data: +:::{php:namespace} Atk4\Ui +::: -### Integration +(data)= + +# Integration Agile UI relies on Agile Data library for flexible access to user defined data sources. The purpose of this integration is to relieve a developer from manually creating data fetching and storing code. @@ -12,11 +15,11 @@ bigger code footprint. There are no way to use Agile UI without Agile Data, however Agile Data is flexible enough to work with your own data sources. The rest of this chapter will explain how you can map various data structures. -### Static Data Arrays +# Static Data Arrays -Agile Data contains Persistence\Array_ (https://agile-data.readthedocs.io/en/develop/design.html?highlight=array#domain-model-actions) +Agile Data contains Persistence\Array_ (https://atk4-data.readthedocs.io/en/develop/design.html?highlight=array#domain-model-actions) implementation that load and store data in a regular PHP arrays. For the "quick and easy" solution Agile UI Views provide a -method :php:meth:`View::setSource` which will work-around complexities and give you a syntax: +method {php:meth}`View::setSource` which will work-around complexities and give you a syntax: ``` $grid->setSource([ @@ -25,13 +28,14 @@ $grid->setSource([ ]); ``` -.. note:: -   Dynamic views will not be able to identify that you are working with static data, and some features may not work properly. -   There are no plans in Agile UI to improve ways of using "setSource", instead, you should learn more how to use Agile Data - for expressing your native data source. Agile UI is not optimized for setSource so its performance will generally be - slower too. +:::{note} +Dynamic views will not be able to identify that you are working with static data, and some features may not work properly. +There are no plans in Agile UI to improve ways of using "setSource", instead, you should learn more how to use Agile Data +for expressing your native data source. Agile UI is not optimized for setSource so its performance will generally be +slower too. +::: -### Raw SQL Queries +# Raw SQL Queries Writing raw SQL queries is source of many errors, both with a business logic and security. Agile Data provides great ways for abstracting your SQL queries, but if you have to use a raw query: @@ -40,7 +44,7 @@ for abstracting your SQL queries, but if you have to use a raw query: // not sure how TODO - write this section. ``` -.. note:: - The above way to using raw queries has a performance implications, because Agile UI is optimised to work with Agile - Data. - +:::{note} +The above way to using raw queries has a performance implications, because Agile UI is optimised to work with Agile +Data. +::: diff --git a/docs/dataexecutor.md b/docs/dataexecutor.md index f696625855..1903f4e80c 100644 --- a/docs/dataexecutor.md +++ b/docs/dataexecutor.md @@ -1,55 +1,63 @@ -.. _dataexecutor: +:::{php:namespace} Atk4\Ui +::: + +(dataexecutor)= # Data Action Executor Data action executor in UI is parts of interactive components that can execute a Data model defined user action. -For more details on Data Model User Action please visit: https://agile-data.readthedocs.io/en/develop/model.html#actions +For more details on Data Model User Action please visit: https://atk4-data.readthedocs.io/en/develop/model.html#actions Atk UI offers many types of action executor. A model user action may contain many properties. Usually, you would choose the type of executor based on the action definition. For example, an action that would required arguments prior to be executed can be set using an ArgumentFormExecutor. Or actions that can run using a single button can use a JsCallbackExecutor. -Demo: https://ui.agiletoolkit.org/demos/data-action/actions.php +Demo: https://ui.atk4.org/demos/data-action/actions.php ## Executor Interface -.. php:namespace:: Atk4\Ui\UserAction - All executors must implement the ExecutorInterface or JsExecutorInterface interface. -.. php:interface:: ExecutorInterface -.. php:interface:: JsExecutorInterface +:::{php:interface} UserAction_i_ExecutorInterface +::: + +:::{php:interface} UserAction_i_JsExecutorInterface +::: ## Basic Executor -.. php:class:: BasicExecutor +:::{php:class} UserAction_i_BasicExecutor +::: This is the base view for most of the other action executors. This executor generally required that necessary arguments needed to run the action has been set. BasicExecutor will display: - - a button for executing the action; - - a header where action name and description are displayed; - - an error message if an action argument is missing; +- a button for executing the action; +- a header where action name and description are displayed; +- an error message if an action argument is missing; ## Preview Executor -.. php:class:: PreviewExecutor +:::{php:class} UserAction_i_PreviewExecutor +::: This executor is specifically set in order to display the $preview property of the current model UserAction. You can select to display the preview using regular console type container, regular text or using HTML content. ## Form Executor -.. php:class:: FormExecutor +:::{php:class} UserAction_i_FormExecutor +::: This executor will display a form where user is required to fill in either all model fields or certain model fields depending on the model UserAction $field property. Form control will depend on model field type. ## Argument Form Executor -.. php:class:: ArgumentFormExecutor +:::{php:class} UserAction_i_ArgumentFormExecutor +::: This executor will display a form but instead of filling form control with model field, it will use model UserAction $args property. This is used when you need to ask user about an argument value prior to execute the action. @@ -57,33 +65,36 @@ The type of form control type to be used in form will depend on how $args is set ## JS Callaback Executor -.. php:class:: JsCallbackExecutor +:::{php:class} UserAction_i_JsCallbackExecutor +::: This type of executor will output proper javascript that you can assign to a view event using View::on() method. It is also possible to pass the UserAction argument via $_POST argument. ## Modal Executor -.. php:class:: ModalExecutor +:::{php:class} UserAction_i_ModalExecutor +::: The ModalExecutor is base on Modal view. This is a one size fits all for model UserAction. When setting the UserAction via the ModelExecutor::setAction($action) method, it will automatically determine what step is require and will display each step base on the action definition within a modal view: - Step 1: Argument definition. If the action required arguments, then the modal will display a form and ask user - to fill argument values required by the model UserAction; +- Step 1: Argument definition. If the action required arguments, then the modal will display a form and ask user + to fill argument values required by the model UserAction; - Step 2: Field definition. If the action required fields, then the modal will display a form and ask user to fill - field values required by the model UserAction; +- Step 2: Field definition. If the action required fields, then the modal will display a form and ask user to fill + field values required by the model UserAction; - Step 3: Preview. If the action preview is set, then the modal will display it prior to execute the action. +- Step 3: Preview. If the action preview is set, then the modal will display it prior to execute the action. The modal title default is set from the UserAction::getDescription() method but can be override using the Modal::$title property. ## Confirmation Executor -.. php:class:: ConfirmationExecutor +:::{php:class} UserAction_i_ConfirmationExecutor +::: Like ModalExecutor, Confirmation executor is also based on a Modal view. It allow to display UserAction::confirmation property prior to execute the action. Since UserAction::confirmation property may be set with a Closure function, this give a chance to @@ -92,15 +103,15 @@ return specific record information to be displayed to user prior to execute the Here is an example of an user action returning specific record information in the confirmation message: ``` - $country->addUserAction('delete_country', [ - 'caption' => 'Delete', - 'description' => 'Delete Country', - 'ui' => ['executor' => [\Atk4\Ui\UserAction\ConfirmationExecutor::class]], - 'confirmation' => function (Model\UserAction $action) { - return 'Are you sure you want to delete this country: $action->getModel()->getTitle(); - }, - 'callback' => 'delete', - ]); +$country->addUserAction('delete_country', [ + 'caption' => 'Delete', + 'description' => 'Delete Country', + 'ui' => ['executor' => [\Atk4\Ui\UserAction\ConfirmationExecutor::class]], + 'confirmation' => function (Model\UserAction $action) { + return 'Are you sure you want to delete this country: $action->getModel()->getTitle(); + }, + 'callback' => 'delete', +]); ``` The modal title default is set from the UserAction::getDescription() method but can be override using the @@ -118,10 +129,11 @@ other hand, if MODIFIER_UPDATE is set, then Table needs to be reloaded. ## The Executor Factory -.. php:class:: ExecutorFactory - -.. php:attr:: executorSeed +:::{php:class} UserAction_i_ExecutorFactory +::: +:::{php:attr} executorSeed +::: Executor factory is responsible for creating proper executor type in regards to the model user action being used. @@ -280,6 +292,6 @@ $button->on('click', $myAction); ### Demo For more information on how Model UserAction are assign to button and interact with user according to their definition, -please visit: `Assign action to button event `_ +please visit: [Assign action to button event](https://ui.atk4.org/demos/data-action/jsactions2.php) -You will find the UserAction definition for the demo `here `_ +You will find the UserAction definition for the demo [here](https://github.com/atk4/ui/blob/develop/demos/_includes/DemoActionsUtil.php) diff --git a/docs/filestructure.md b/docs/filestructure.md index cbb8029ae8..bdf4849114 100644 --- a/docs/filestructure.md +++ b/docs/filestructure.md @@ -1,4 +1,7 @@ -.. _filestructure: +:::{php:namespace} Atk4\Ui +::: + +(filestructure)= # File structure example & first app @@ -11,57 +14,30 @@ and modified to your needs and shows just one concept of how to setup an atk4 pr This file structure is a recommendation and no must. It is a best practice example. Feel free to experiment with it and find the ideal file structure for your project. -* config - - * db.php - -* public_html - - * images - - * index.php - - * init.php - - * admin.php (if needed) - -* projectfolder (could be named "app" for example) - - * Forms - - * ExampleForm1.php - - * ExampleForm2.php - - * UserDetailForm.php - - * Models - - * ExampleClass1.php - - * ExampleClass2.php - - * LoadAllUsers.php - - * Views - - * View1.php - - * View2.php - - * GridUserList.php - -* vendor (contains all needed composer modules - don't touch them) - - * atk4 - - * ... - - * autoload.php - - * ... - -* composer.json +- config + - db.php +- public_html + - images + - index.php + - init.php + - admin.php (if needed) +- projectfolder (could be named "app" for example) + - Forms + - ExampleForm1.php + - ExampleForm2.php + - UserDetailForm.php + - Models + - ExampleClass1.php + - ExampleClass2.php + - LoadAllUsers.php + - Views + - View1.php + - View2.php + - GridUserList.php +- vendor (contains all needed composer modules - don't touch them) + - autoload.php + - ... +- composer.json ## Composer configuration @@ -106,15 +82,12 @@ But you can't call it directly through the domain (that means in our case "db.ph ## Create your application To initialize your application we need to do the following steps: - #) Create db.php for database - - #) Create init.php - - #) Load Composer autoload.php (which loads up atk4) in init.php - #) Initialize the app class in init.php - - #) Create index.php and admin.php +1. Create db.php for database +2. Create init.php +3. Load Composer autoload.php (which loads up atk4) in init.php +4. Initialize the app class in init.php +5. Create index.php and admin.php ### Create db.php for database @@ -141,16 +114,12 @@ require_once $rootdir . "../config/db.php"; // contains database configuration o ### Load Composer autoload.php (which loads up atk4) in init.php -: - ``` require_once $rootdir . "vendor/autoload.php"; // loads up atk4 and our project files from Composer ``` ### Initialize the app class in init.php -: - ``` $app = new \Atk4\Ui\App('Welcome to my first app'); // initialization of our app $app->db = $db; // defines our database for reuse in other classes @@ -207,13 +176,15 @@ class View1 extends \Atk4\Data\View } ``` -"namespace MyProject\\Views;" defines the namespace to use. It reflects the folder structure of the app. -The file located in "projectfolder/Views/View1.php" becomes "MyProject\\Views\\View1" in the namespace. +"namespace MyProject\Views;" defines the namespace to use. It reflects the folder structure of the app. +The file located in "projectfolder/Views/View1.php" becomes "MyProject\Views\View1" in the namespace. For each of your classes create a separate file. As long as you follow the name conventions all your class files will be autoloaded by Composer. -.. warning:: Keep in mind that as soon as you have created one or more new file(s) within the projectfolder you have to run "composer dump-autoload"!!! Otherwise the newly generated file(s) and classes will not be autoloaded and are therefore unavailable in your application. +:::{warning} +Keep in mind that as soon as you have created one or more new file(s) within the projectfolder you have to run "composer dump-autoload"!!! Otherwise the newly generated file(s) and classes will not be autoloaded and are therefore unavailable in your application. +::: ## Load your class in index.php @@ -225,10 +196,10 @@ Please add the following lines into your index.php: \MyProject\Views\View1::addTo($app); ``` -or if you have added at the beginning of your index.php "use MyProject\\Views\\View1;" you can write: +or if you have added at the beginning of your index.php "use MyProject\Views\View1;" you can write: ``` View1::addTo($app); ``` -See also :ref:`using-namespaces` on this topic... +See also {ref}`using-namespaces` on this topic... diff --git a/docs/fileupload.md b/docs/fileupload.md index 8c34064b7d..6d72a1ea75 100644 --- a/docs/fileupload.md +++ b/docs/fileupload.md @@ -1,39 +1,44 @@ +:::{php:namespace} Atk4\Ui +::: + # File Upload -.. figure:: images/fileupload.png +:::{figure} images/fileupload.png +::: Upload (and UploadImage) classes implement form controls that can be used to upload files or images. -Implementation of :php:class:`Form` in Agile UI submits data using JavaScript request and +Implementation of {php:class}`Form` in Agile UI submits data using JavaScript request and therefore files should be uploaded before form submission. Process used can be described in steps: - 1. User arrives at the page with a form - 2. User selects file. - 3. File begins uploading. - 4. PHP upload callback :php:meth:`Upload::onUpload` is called, returns "file_id" - 5. "file_id" is placed inside form. - 6. User submits the form - 7. :php:meth:`\Atk4\Ui\Form::onSubmit()` receives "file_id" +1. User arrives at the page with a form +2. User selects file. +3. File begins uploading. +4. PHP upload callback {php:meth}`Form_i_Control_i_Upload::onUpload` is called, returns "file_id" +5. "file_id" is placed inside form. +6. User submits the form +7. {php:meth}`Form::onSubmit()` receives "file_id" Currently only one file can be uploaded at a time. If file is uploaded incorrectly, it can be removed. Both Upload and UploadImage controls contain an upload button which would open a File Selection dialog. UploadImage also implements image preview icon. During upload, a progress bar will appear. -.. php:namespace:: Atk4\Ui\Form\Control - -.. php:class:: Upload +:::{php:class} Form_i_Control_i_Upload +::: ## Attributes Upload control has the following properties: -.. php:attr:: accept +:::{php:attr} accept +::: An array of string containing the file type accepted by the form control, default is empty. Example would be: `['application/pdf', 'images/*']`. -.. php:attr:: action +:::{php:attr} action +::: The button view to use for displaying the file open dialog. A default action button is used if omitted. @@ -129,18 +134,22 @@ $img->onDelete(function (string $fileId) use ($img) { Similar to Upload, this is a control implementation for uploading images. Here are additional properties: -.. php:class:: UploadImage +:::{php:class} Form_i_Control_i_UploadImage +::: UploadImage form control inherits all of the Upload properties plus these ones: -.. php:attr:: thumbnail +:::{php:attr} thumbnail +::: The thumbnail view associated with the form control. -.. php:attr:: thumbnailRegion +:::{php:attr} thumbnailRegion +::: The region in input template where to add the thumbnail view, default to AfterAfterInput region. -.. php:attr:: defaultSrc +:::{php:attr} defaultSrc +::: The default image source to display to user, prior to uploading the images. diff --git a/docs/form-control.md b/docs/form-control.md index aa07cc35f1..9baecaad26 100644 --- a/docs/form-control.md +++ b/docs/form-control.md @@ -1,24 +1,29 @@ -.. _form-control: +:::{php:namespace} Atk4\Ui +::: -# Form Controls +(form-control)= -.. php:namespace:: Atk4\Ui\Form +# Form Controls -.. php:class:: Control +:::{php:class} Form_i_Control +::: Agile UI dedicates a separate namespace for the Form Controls. Those are quite simple components that present themselves as input controls: line, select, checkbox. ## Relationship with Form -All Form Control Decorators can be integrated with :php:class:`Atk4\\Ui\\Form` which will +All Form Control Decorators can be integrated with {php:class}`Form` which will facilitate collection and processing of data in a form. Form Control decorators can also be used as stand-alone controls. ### Stand-alone use -.. php:method:: set() -.. php:method:: jsInput() +:::{php:method} set() +::: + +:::{php:method} jsInput() +::: Add any form control to your application like this: @@ -31,12 +36,10 @@ You can set default value and interact with a form control using JavaScript: ``` $control->set('hello world'); - $button = \Atk4\Ui\Button::addTo($app, ['check value']); $button->on('click', new \Atk4\Ui\Js\JsExpression('alert(\'control value is: \' + [])', [$control->jsInput()->val()])); ``` - When used stand-alone, Form\Controls will produce a basic HTML (I have omitted id=): ``` @@ -67,7 +70,7 @@ page and the following HTML is now produced: ``` The markup that surronds the button which includes Label and formatting is produced by -:php:class:`Atk4\\Ui\\Form\\Layout`, which does draw some of the information from the Form Control +{php:class}`Form_i_Layout`, which does draw some of the information from the Form Control itself. ### Using in Form Layouts @@ -91,17 +94,18 @@ $form->onSubmit(function (Form $form) { }); ``` -This is further explained in documentation for :php:class:`Atk4\\Ui\\Form\\Layout` class, +This is further explained in documentation for {php:class}`Form_i_Layout` class, however if you do plan on adding your own form control types, it's important that you extend it properly: - - Generic (abstract, extends View) - Use this if form control is NOT based on `` - - Input (abstract, extends Generic) - Easiest since it already implements `` and various - ways to attach button to the input with markup of Fomantic-UI form control. +- Generic (abstract, extends View) - Use this if form control is NOT based on `` +- Input (abstract, extends Generic) - Easiest since it already implements `` and various + ways to attach button to the input with markup of Fomantic-UI form control. ### Hints -.. php:attr:: hint +:::{php:attr} hint +::: When Form Control appears in a Form, then you can specify a Hint also. It appears below the form control and although it intends to be "extra info" or "extra help" due to current limitation of Fomantic-UI @@ -134,12 +138,14 @@ $form->addControl('name', ['hint' => ['template' => new \Atk4\Ui\Template( ### Read only and disabled form controls -.. php:attr:: readOnly +:::{php:attr} readOnly +::: Read only form controls can be seen in form, can be focused and will be submitted, but we don't allow to change their value. -.. php:attr:: disabled +:::{php:attr} disabled +::: Disabled form controls can be seen in form, cannot be focused and will not be submitted. And of course we don't allow to change their value. Disabled form controls are used for read only model fields for example. @@ -149,7 +155,7 @@ don't allow to change their value. Disabled form controls are used for read only In the examples above, we looked at how to create Form Control Decorator object explicitly. The most common use-case in large application is the use with Models. You would need a model, such as `Country` model as well as -`Persistence $db `_: +[Persistence $db](https://atk4-data.readthedocs.io/en/develop/persistence.html): ``` class Country extends \Atk4\Data\Model @@ -179,19 +185,19 @@ $form->setModel(new Country($db); ``` The above will populate fields from model into the form automatically. You can use second -argument to :php:meth:`\Atk4\Ui\Form::setModel()` to indicate which fields to display -or rely on :ref:`field_visibility`. +argument to {php:meth}`Form::setModel()` to indicate which fields to display +or rely on {ref}`field_visibility`. -When Form controls are populated, then :php:meth:`\Atk4\Ui\Form::controlFactory` is +When Form controls are populated, then {php:meth}`Form::controlFactory` is consulted to make a decision on how to translate -`Model Field `_ into +[Model Field](https://atk4-data.readthedocs.io/en/develop/fields.html) into Form Control Decorator. The rules are rather straightforward but may change in future versions of Agile UI: - - if `enum `_ is defined, use :php:class:`Dropdown` - - consult :php:attr:`\Atk4\Ui\Form::$typeToDecorator` property for type-to-seed association - - type=password will use :php:class:`Password` +- if [enum](https://atk4-data.readthedocs.io/en/develop/fields.html#Field::$enum) is defined, use {php:class}`Form_i_Control_i_Dropdown` +- consult {php:attr}`Form::$typeToDecorator` property for type-to-seed association +- type=password will use {php:class}`Form_i_Control_i_Password` You always have an option to explicitly specify which field you would like to use: @@ -206,34 +212,37 @@ by all components: $model->addField('long_text', ['type' => 'text']); ``` -.. note:: All forms will be associated with a model. If form is not explicitly linked with a model, it will create - a ProxyModel and all form controls will be created automatically in that model. As a result, all Form Control Decorators - will be linked with Model Fields. +:::{note} +All forms will be associated with a model. If form is not explicitly linked with a model, it will create +a ProxyModel and all form controls will be created automatically in that model. As a result, all Form Control Decorators +will be linked with Model Fields. +::: ### Link to Model Field -.. php:attr:: field +:::{php:attr} field +::: Form decorator defines $field property which will be pointing to a field object of a model, so technically the value of the field would be read from `$decorator->entityField->get()`. -.. php:namespace:: Atk4\Ui\Form\Control - ## Line Input Form control -.. php:class:: Input - - Implements View for presenting Input form controls. Based around https://fomantic-ui.com/elements/input.html. +:::{php:class} Form_i_Control_i_Input +Implements View for presenting Input form controls. Based around https://fomantic-ui.com/elements/input.html. +::: Similar to other views, Input has various properties that you can specify directly or inject through constructor. Those properties will affect the look of the input element. For example, `icon` property: -.. php:attr:: icon -.. php:attr:: iconLeft +:::{php:attr} icon +::: - Adds icon into the input form control. Default - `icon` will appear on the right, while `leftIcon` - will display icon on the left. +:::{php:attr} iconLeft +Adds icon into the input form control. Default - `icon` will appear on the right, while `leftIcon` +will display icon on the left. +::: Here are few ways to specify `icon` to an Input/Line: @@ -263,42 +272,47 @@ $line->icon = new Icon('search'); $line->icon->addClass('big'); ``` -To see how Icon interprets `new Icon(['search', 'class.big' => true])`, refer to :php:class:`Icon`. +To see how Icon interprets `new Icon(['search', 'class.big' => true])`, refer to {php:class}`Icon`. -.. note:: +:::{note} +View's constructor will map received arguments into object properties, if they are defined +or addClass() if not. See {php:meth}`View::setProperties`. +::: - View's constructor will map received arguments into object properties, if they are defined - or addClass() if not. See :php:meth:`View::setProperties`. +:::{php:attr} placeholder +Will set placeholder property. +::: -.. php:attr:: placeholder +:::{php:attr} loading +Set to "left" or "right" to display spinning loading indicator. +::: - Will set placeholder property. +:::{php:attr} label +::: -.. php:attr:: loading +:::{php:attr} labelRight +Convert text into {php:class}`Label` and insert it into the form control. +::: - Set to "left" or "right" to display spinning loading indicator. +:::{php:attr} action +::: -.. php:attr:: label -.. php:attr:: labelRight - - Convert text into :php:class:`Label` and insert it into the form control. - -.. php:attr:: action -.. php:attr:: actionLeft - - Convert text into :php:class:`Button` and insert it into the form control. +:::{php:attr} actionLeft +Convert text into {php:class}`Button` and insert it into the form control. +::: To see various examples of form controls and their attributes see `demos/form-control/`. ### Integration with Form -When you use :php:class:`form::addControl()` it will create 'Form Control Decorator' +When you use {php:class}`Form::addControl()` it will create 'Form Control Decorator' ### JavaScript on Input -.. php:method:: jsInput([$event, [$otherChain]]) +:::{php:method} jsInput([$event, [$otherChain]]) +::: -Input class implements method jsInput which is identical to :php:meth:`View::js`, except +Input class implements method jsInput which is identical to {php:meth}`View::js`, except that it would target the INPUT element rather then the whole form control: ``` @@ -307,7 +321,8 @@ $control->jsInput(true)->val(123); ### onChange event -.. php:method:: onChange($expression) +:::{php:method} onChange($expression) +::: It's preferable to use this short-hand version of on('change', 'input', $expression) method. $expression argument can be JS expression or PHP callback function. @@ -330,7 +345,8 @@ $c1->onChange(\Atk4\Ui\Js\JsExpression('console.log(\'c1 changed: \' + date + \' ## Dropdown -.. php:class:: Dropdown +:::{php:class} Form_i_Control_i_Dropdown +::: Dropdown uses Fomantic-UI Dropdown (https://fomantic-ui.com/modules/dropdown.html). A Dropdown can be used in two ways: 1) Set a Model to $model property. The Dropdown will render all records of the model that matches the model's conditions. @@ -338,10 +354,10 @@ Dropdown uses Fomantic-UI Dropdown (https://fomantic-ui.com/modules/dropdown.htm ### Usage with a Model -A Dropdown is not used as default Form Control decorator (`$model->hasOne()` uses :php:class:`Lookup`), but in your Model, you can define that +A Dropdown is not used as default Form Control decorator (`$model->hasOne()` uses {php:class}`Form_i_Control_i_Lookup`), but in your Model, you can define that UI should render a Field as Dropdown. For example, this makes sense when a `hasOne()` relationship only has a very limited amount (like 20) of records to display. Dropdown renders all records when the paged is rendered, while Lookup always sends an additional request to the server. -:php:class:`Lookup` on the other hand is the better choice if there is lots of records (like more than 50). +{php:class}`Form_i_Control_i_Lookup` on the other hand is the better choice if there is lots of records (like more than 50). To render a model field as Dropdown, use the ui property of the field: @@ -349,9 +365,10 @@ To render a model field as Dropdown, use the ui property of the field: $model->addField('someField', ['ui' => ['form' => [\Atk4\Ui\Form\Control\Dropdown::class]]]); ``` -.. Customizing how a Model's records are displayed in Dropdown +### Customizing how entities are displayed in Dropdown + As default, Dropdown will use the `$model->idField` as value, and `$model->titleField` as title for each menu item. -If you want to customize how a record is displayed and/or add an icon, Dropdown has the :php:meth:`Form::renderRowFunction()` to do this. +If you want to customize how a record is displayed and/or add an icon, Dropdown has the {php:meth}`Form::renderRowFunction()` to do this. This function is called with each model record and needs to return an array: ``` @@ -399,7 +416,6 @@ class MyDropdown extends \Atk4\Ui\Dropdown } ``` - With the according renderRowFunction: ``` @@ -439,7 +455,7 @@ $dropdown->values = [ ]; ``` -If using $values property, you can also use the :php:meth:`Form::renderRowFunction()`, though there usually is no need for it. +If using $values property, you can also use the {php:meth}`Form::renderRowFunction()`, though there usually is no need for it. If you use it, use the second parameter as well, its the array key: ``` @@ -455,13 +471,15 @@ function (string $value, $key) { There's a bunch of settings to influence Dropdown behaviour. -.. php:attr:: empty +:::{php:attr} empty +::: Define a string for the empty option (no selection). Standard is non-breaking space symbol. -.. php:attr:: dropdownOptions +:::{php:attr} dropdownOptions +::: -Here you can pass an array of Fomantic-UI dropdown options (https://fomantic-ui.com/modules/dropdown.html#/settings) e.g. : +Here you can pass an array of Fomantic-UI dropdown options (https://fomantic-ui.com/modules/dropdown.html#/settings) e.g.: ``` $dropdown = new Dropdown(['dropdownOptions' => [ @@ -469,7 +487,8 @@ $dropdown = new Dropdown(['dropdownOptions' => [ ]]); ``` -.. php:attr:: multiple +:::{php:attr} multiple +::: If set to true, multiple items can be selected in Dropdown. They will be sent comma separated (value1,value2,value3) on form submit. @@ -497,19 +516,22 @@ $this->addField('expressions', [ ## DropdownCascade -.. php:class:: DropdownCascade +:::{php:class} Form_i_Control_i_DropdownCascade +::: DropdownCascade input are extend from Dropdown input. They rely on `cascadeFrom` and `reference` property. For example, it could be useful when you need to narrow a product selection base on a category and a sub category. User will select a Category from a list, then sub category input will automatically load sub category values based on user category selection. Same with product list values based on sub category selection and etc. -.. php:attr:: cascadeFrom +:::{php:attr} cascadeFrom +::: This property represent an input form control, mostly another Dropdown or DropdownCascade form control. The list values of this form control will be build base off the selected value of cascadeFrom input. -.. php:attr:: reference +:::{php:attr} reference +::: This property represent a model hasMany reference and should be an hasMany reference of the cascadeFrom input model. In other word, the model that will generated list value for this dropdown input is an hasMany reference of the cascadeFrom @@ -526,11 +548,11 @@ $form->addControl('product_id', [DropdownCascade::class, 'cascadeFrom' => 'sub_c ## Lookup -.. php:class:: Lookup +:::{php:class} Form_i_Control_i_Lookup +::: Lookup input is also based on Fomantic-UI dropdown module but with ability to dynamically request server for data it's data value. When clicking on a Lookup form control, it will send a query to server and start building it's list value. Typing into the input form control will reload list value according to search criteria. - diff --git a/docs/form.md b/docs/form.md index 7932189258..56a549831a 100644 --- a/docs/form.md +++ b/docs/form.md @@ -1,26 +1,29 @@ -.. _form: +:::{php:namespace} Atk4\Ui +::: -# Forms +(form)= -.. php:namespace:: Atk4\Ui +# Forms -.. php:class:: Form +:::{php:class} Form +::: -One of the most important components of ATK UI is the "Form". Class :php:class:`Form` +One of the most important components of ATK UI is the "Form". Class {php:class}`Form` implements the following 4 major features: - Form Rendering using Fomantic-UI HTML/CSS (https://fomantic-ui.com/collections/form.html): - .. image:: images/form.png + :::{image} images/form.png + ::: - Form controls are automatically populated based on your existing data model with special treatment for date/time, auto-complete and even file upload. - Loading data from database and storing it back. Any persistence (SQL, NoSQL) supported by - ATK Data (https://agile-data.readthedocs.io/en/develop/persistence.html) can be used. + ATK Data (https://atk4-data.readthedocs.io/en/develop/persistence.html) can be used. -- Support for Events and Actions on form controls, buttons and form callback. (:ref:`js`) Automatic - execution of PHP-based Submit Handler passing all the collected data (:ref:`callback`) +- Support for Events and Actions on form controls, buttons and form callback. ({ref}`js`) Automatic + execution of PHP-based Submit Handler passing all the collected data ({ref}`callback`) So if looking for a PHP Form class, ATK Form has the most complete implementation which does not require to fall-back into HTML / JS, perform any data conversion, load / store data and @@ -47,7 +50,7 @@ $form->onSubmit(function (Form $form) { ``` Form is a composite component and it relies on other components to render parts -of it. Form uses :php:class:`Button` that you can tweak to your liking: +of it. Form uses {php:class}`Button` that you can tweak to your liking: ``` $form->buttonSave->set('Subscribe'); @@ -74,13 +77,14 @@ $form->model->set([ ]); ``` -Form also relies on a ``\Atk4\Ui\Form::Layout`` class and displays form controls through -decorators defined at ``\Atk4\Ui\Form::Control``. See dedicated documentation for: +Form also relies on a `\Atk4\Ui\Form::Layout` class and displays form controls through +decorators defined at `\Atk4\Ui\Form::Control`. See dedicated documentation for: - - :php:class:`Form::Layout` - - :php:class:`Form::Control` +- {php:class}`Form::Layout` +- {php:class}`Form::Control` -To tweak the UI properties of an form control input use ``setInputAttr()`` (and not the surrounding
as ``setAttr()`` would do). Here is how to set the HTML "maxlength" attribute on the generated input field: +To tweak the UI properties of an form control input use `setInputAttr()` (and not the surrounding `
` as `setAttr()` +would do). Here is how to set the HTML "maxlength" attribute on the generated input field: ``` $form = \Atk4\Ui\Form::addTo($this); @@ -93,7 +97,7 @@ integration with front-end, integration with Model, error handling etc. ### Usage with Model -A most common use of form is if you have a working Model (https://agile-data.readthedocs.io/en/develop/model.html): +A most common use of form is if you have a working Model (https://atk4-data.readthedocs.io/en/develop/model.html): ``` // Form will automatically add a new user and save into the database @@ -103,39 +107,39 @@ $form->setModel(new User($db)); The basic 2-line syntax will extract all the required logic from the Model including: - - Fields defined for this Model will be displayed - - Display of default values in the form - - Depending on the field type, a form control will be selected from Form\Control namespace - - Using :php:class:`Form\Layout\Columns` can make form more compact by splitting it into columns - - Form control captions, placeholders, hints and other elements defined in Field::ui are respected (https://agile-data.readthedocs.io/en/develop/fields.html#Field::$ui) - - Fields that are not editable by default will not appear on the form (https://agile-data.readthedocs.io/en/develop/fields.html#Field::isEditable) - - Field typecasting will be invoked such as for converting dates - - Reference fields (https://agile-data.readthedocs.io/en/develop/references.html?highlight=hasOne#hasone-reference) displayed as Dropdown - - Booleans are displayed as checkboxes but stored as defined by the model field - - Not-nullable and Required fields will have form controls visually highlighted (https://agile-data.readthedocs.io/en/develop/fields.html?highlight=required#Field::$nullable) - - Validation will be performed and errors will appear on the form (NEED LINK) - - Unless you specify a submission handler, form will save the model ``User`` into ``$db`` on successful submission. +- Fields defined for this Model will be displayed +- Display of default values in the form +- Depending on the field type, a form control will be selected from Form\Control namespace +- Using {php:class}`Form_i_Layout_i_Columns` can make form more compact by splitting it into columns +- Form control captions, placeholders, hints and other elements defined in Field::ui are respected (https://atk4-data.readthedocs.io/en/develop/fields.html#Field::$ui) +- Fields that are not editable by default will not appear on the form (https://atk4-data.readthedocs.io/en/develop/fields.html#Field::isEditable) +- Field typecasting will be invoked such as for converting dates +- Reference fields (https://atk4-data.readthedocs.io/en/develop/references.html?highlight=hasOne#hasone-reference) displayed as Dropdown +- Booleans are displayed as checkboxes but stored as defined by the model field +- Not-nullable and Required fields will have form controls visually highlighted (https://atk4-data.readthedocs.io/en/develop/fields.html?highlight=required#Field::$nullable) +- Validation will be performed and errors will appear on the form (NEED LINK) +- Unless you specify a submission handler, form will save the model `User` into `$db` on successful submission. All of the above works auto-magically, but you can tweak it even more: - - Provide custom submission handler - - Specify which form controls and in which order to display on the form - - Override labels, form control classes - - Group form controls or use custom layout template - - Mix standard model fields with your own - - Add JS Actions around fields - - Split up form into multiple tabs +- Provide custom submission handler +- Specify which form controls and in which order to display on the form +- Override labels, form control classes +- Group form controls or use custom layout template +- Mix standard model fields with your own +- Add JS Actions around fields +- Split up form into multiple tabs -If your form is NOT associated with a model, then Form will automatically create a :php:class:`ProxyModel` +If your form is NOT associated with a model, then Form will automatically create a {php:class}`ProxyModel` and associate it with your Form. As you add form controls respective fields will also be added into ProxyModel. ### Extensions Starting with Agile UI 1.3 Form has a stable API and we expect to introduce some extensions like: - - Captcha form control - - File Upload form control (see https://github.com/atk4/filestore) - - Multi-record form +- Captcha form control +- File Upload form control (see https://github.com/atk4/filestore) +- Multi-record form If you develop such a feature please let me know so that I can include it in the documentation and give you credit. @@ -147,7 +151,7 @@ a View layout for it in order to create their HTML element. In other words, layo is responsible of rendering HTML for fields. When Form is first initialized, it will provide and set a default Generic layout within the form. -Then using :php:meth:`Form::addControl()` will rely on that layout to add form control to it and render it properly. +Then using {php:meth}`Form::addControl()` will rely on that layout to add form control to it and render it properly. You may also supply your own layout when creating your form. Form layout may contain sub layouts. Each sub layout being just another layout view, it is possible @@ -160,7 +164,8 @@ More on Form layout and sub layout below. ## Adding Controls -.. php:method:: addControl($name, $decorator = [], $field = []) +:::{php:method} addControl($name, $decorator = [], $field = []) +::: Create a new control on a form: @@ -181,7 +186,7 @@ $form->setModel(new User($db), ['email', 'gender', 'terms']); ``` Form control does not have to be added directly into the form. You can use a separate -:php:class:`Form\\Layout` or even a regular view. Simply specify property :php:meth:`Form\\Control::$form`: +{php:class}`Form_i_Layout` or even a regular view. Simply specify property {php:meth}`Form_i_Control::$form`: ``` $myview = View::addTo($form, ['defaultTemplate' => './mytemplate.html']); @@ -197,19 +202,19 @@ If a field exists inside associated model, then model field definition will be u a base, otherwise you can specify field definition through 3rd argument. I explain that below in more detail. -You can specify first argument ``null`` in which case control will be added without +You can specify first argument `null` in which case control will be added without association with field. This will not work with regular fields, but you can add custom control such as CAPTCHA, which does not really need association with a field. ### Form Control -To avoid term miss-use, we use "Field" to refer to ``\Atk4\Data\Field``. This class -is documented here: https://agile-data.readthedocs.io/en/develop/fields.html +To avoid term miss-use, we use "Field" to refer to `\Atk4\Data\Field`. This class +is documented here: https://atk4-data.readthedocs.io/en/develop/fields.html Form uses a small UI component to visualize HTML input fields associated with the respective Model Field. We call this object "Form Control". All form -controls extend from class :php:class:`Form::Control`. +controls extend from class {php:class}`Form::Control`. Agile UI comes with at least the following form controls: @@ -221,9 +226,9 @@ Agile UI comes with at least the following form controls: - Radio - Money -For some examples see: https://ui.agiletoolkit.org/demos/form3.php +For some examples see: https://ui.atk4.org/demos/form3.php -Field Decorator can be passed to ``addControl`` using 'string', :php:ref:`seed` or 'object': +Field Decorator can be passed to `addControl` using 'string', {php:ref}`seed` or 'object': ``` $form->addControl('accept_terms', [\Atk4\Ui\Form\Control\Checkbox::class]); @@ -236,16 +241,17 @@ $form->addControl('time', $calendar); ``` For more information on default form controls as well as examples on how to create -your own see documentation on :php:class:`Form::Control`. +your own see documentation on {php:class}`Form::Control`. -.. php:method:: controlFactory(\\Atk4\\Data\\Field $field, $defaults = []) +:::{php:method} controlFactory(\Atk4\Data\Field $field, $defaults = []) +::: -If form control class is not specified (``null``) then it will be determined from -the type of the Data control with ``controlFactory`` method. +If form control class is not specified (`null`) then it will be determined from +the type of the Data control with `controlFactory` method. ### Data Field -Data field is the 3rd argument to ``Form::addControl()``. +Data field is the 3rd argument to `Form::addControl()`. There are 3 ways to define Data form control using 'string', 'json' or 'object': @@ -261,13 +267,13 @@ class MyBoolean extends \Atk4\Data\Field $form->addControl('test2', [], new MyBoolean()); ``` -String will be converted into ``['caption' => $string]`` a short way to give +String will be converted into `['caption' => $string]` a short way to give field a custom label. Without a custom label, Form will clean up the name (1st argument) by replacing '_' with spaces and uppercasing words (accept_terms becomes "Accept Terms") -Specifying array will use the same syntax as the 2nd argument for ``\Atk4\Data\Model::addField()``. -(https://agile-data.readthedocs.io/en/develop/model.html#Model::addField) +Specifying array will use the same syntax as the 2nd argument for `\Atk4\Data\Model::addField()`. +(https://atk4-data.readthedocs.io/en/develop/model.html#Model::addField) If field already exist inside model, then values of $field will be merged into existing field properties. This example make email field mandatory for the form: @@ -282,7 +288,7 @@ $form->addControl('email', [], ['required' => true]); ### addControl into Form with Existing Model If your form is using a model and you add an additional control, then the underlying model field will be created but it will -be set as "neverPersist" (https://agile-data.readthedocs.io/en/develop/fields.html#Field::$neverPersist). +be set as "neverPersist" (https://atk4-data.readthedocs.io/en/develop/fields.html#Field::$neverPersist). This is to make sure that data from custom form controls wouldn't go directly into the database. Next example displays a registration form for a User: @@ -342,10 +348,10 @@ $form->onSubmit(function (Form $form) { }); ``` -Field ``date1`` is defined inside a :php:class:`ProxyModel` as a date field and will +Field `date1` is defined inside a {php:class}`ProxyModel` as a date field and will be automatically converted into DateTime object by Persistence typecasting. -Field ``date2`` has no data type, do not confuse with ui type => date pass as second argument for Calendar field, +Field `date2` has no data type, do not confuse with ui type => date pass as second argument for Calendar field, and therefore Persistence typecasting will not modify it's value and it's stored inside model as a string. The above code result in the following output: @@ -357,13 +363,13 @@ date1 = DateTime Object ( [date] => 2017-09-03 00:00:00 .. ) and date2 = Septemb ### Seeding Form Control from Model In large projects you most likely won't be setting individual form controls for each Form. Instead -you can simply use ``setModel()`` to populate all form controls from fields defined inside a model. Form does +you can simply use `setModel()` to populate all form controls from fields defined inside a model. Form does have a pretty good guess about form control decorator based on the data field type, but what if you want to use a custom decorator? -This is where ``$field->ui`` comes in (https://agile-data.readthedocs.io/en/develop/fields.html#Field::$ui). +This is where `$field->ui` comes in (https://atk4-data.readthedocs.io/en/develop/fields.html#Field::$ui). -You can specify ``'ui' => ['form' => $decoratorSeed]`` when defining your model field inside your Model: +You can specify `'ui' => ['form' => $decoratorSeed]` when defining your model field inside your Model: ``` class User extends \Atk4\Data\Model @@ -382,7 +388,7 @@ class User extends \Atk4\Data\Model } ``` -The seed for the UI will be combined with the default overriding :php:attr:`Form\\Control\\Calendar::type` +The seed for the UI will be combined with the default overriding {php:attr}`Form_i_Control_i_Calendar::type` to allow month/year entry by the Calendar extension, which will then be saved and stored as a regular date. Obviously you can also specify decorator class: @@ -397,9 +403,11 @@ Without the data 'type' property, now the calendar selection will be stored as t Although there were many examples above for the use of setModel() this method needs a bit more info: -.. php:attr:: model +:::{php:attr} model +::: -.. php:method:: setModel($model, [$fields]) +:::{php:method} setModel($model, [$fields]) +::: Associate form controls with existing model object and import all editable fields in the order in which they were defined inside model's init() method. @@ -408,12 +416,12 @@ You can specify which form controls to import from model fields and their order field names in an array as a second argument. Specifying "false" or empty array as a second argument will import no model fields as form controls, -so you can then use :php:meth:`Form::addControl` to import form controls from model fields individually. +so you can then use {php:meth}`Form::addControl` to import form controls from model fields individually. -Note that :php:meth:`Form::setModel` also delegates adding form control to the form layout +Note that {php:meth}`Form::setModel` also delegates adding form control to the form layout by using `Form->layout->setModel()` internally. -See also: https://agile-data.readthedocs.io/en/develop/fields.html#Field::isEditable +See also: https://atk4-data.readthedocs.io/en/develop/fields.html#Field::isEditable ### Using setModel() on a sub layout @@ -427,7 +435,6 @@ $subLayout = $form->layout->addSubLayout(); $subLayout->setModel($model, ['first_name', 'last_name']); ``` - When using setModel() on a sub layout to add controls per sub layout instead of entire layout, make sure you pass false as second argument when setting the model on the Form itself, like above. Otherwise all model fields will be automatically added in Forms main layout and you will not be @@ -435,8 +442,8 @@ able to add them again in sub-layouts. ### Loading Values -Although you can set form control values individually using ``$form->model->set('field', $value)`` -it's always nicer to load values for the database. Given a ``User`` model this is how +Although you can set form control values individually using `$form->model->set('field', $value)` +it's always nicer to load values for the database. Given a `User` model this is how you can create a form to change profile of a currently logged user: ``` @@ -453,22 +460,22 @@ Submitting this form will automatically store values back to the database. Form POST data to submit itself and will re-use the query string, so you can also safely use any GET arguments for passing record $id. You may also perform model load after record association. This gives the benefit of not loading any other fields, unless -they're marked as System (https://agile-data.readthedocs.io/en/develop/fields.html#Field::$system), -see https://agile-data.readthedocs.io/en/develop/model.html?highlight=onlyfields#Model::setOnlyFields: +they're marked as System (https://atk4-data.readthedocs.io/en/develop/fields.html#Field::$system), +see https://atk4-data.readthedocs.io/en/develop/model.html?highlight=onlyfields#Model::setOnlyFields: ``` $form = Form::addTo($app); $form->setModel((new User($db))->load($currentUserId), ['email', 'name']); ``` -As before, field ``password`` will not be loaded from the database, but this time +As before, field `password` will not be loaded from the database, but this time using onlyFields restriction rather then `neverPersist`. ### Validating The topic of validation in web apps is quite extensive. You should start by reading what Agile Data has to say about validation: -https://agile-data.readthedocs.io/en/develop/persistence.html#validation +https://atk4-data.readthedocs.io/en/develop/persistence.html#validation Sometimes validation is needed when storing field value inside a model (e.g. setting boolean to "blah") and sometimes validation should be performed only when storing model data into @@ -488,13 +495,13 @@ As far as form is concerned: - Decorators must be able to parse entered values. For instance Dropdown will make sure that value entered is one of the available values (by key) -- Form will rely on Agile Data Typecasting (https://agile-data.readthedocs.io/en/develop/typecasting.html) +- Form will rely on Agile Data Typecasting (https://atk4-data.readthedocs.io/en/develop/typecasting.html) to load values from POST data and store them in model. -- Form submit handler will rely on ``Model::save()`` (https://agile-data.readthedocs.io/en/develop/persistence.html#Model::save) +- Form submit handler will rely on `Model::save()` (https://atk4-data.readthedocs.io/en/develop/persistence.html#Model::save) not to throw validation exception. -- Form submit handler will also interpret use of :php:meth:`Form::jsError` by displaying errors that +- Form submit handler will also interpret use of {php:meth}`Form::jsError` by displaying errors that do not originate inside Model save logic. Example use of Model's validate() method: @@ -526,7 +533,6 @@ class Person extends \Atk4\Data\Model } ``` - We can now populate form controls based around the data fields defined in the model: ``` @@ -542,21 +548,21 @@ $form->addControl('terms', ['type' => 'boolean', 'ui' => ['caption' => 'Accept T ### Form Submit Handling -.. php:method:: onSubmit($callback) - - Specify a PHP callback that will be executed on successful form submission. - -.. php:method:: jsError($field, $message) - - Create and return :php:class:`JsChain` action that will indicate error on a form control. - -.. php:method:: jsSuccess($title, [$subTitle]) +:::{php:method} onSubmit($callback) +Specify a PHP callback that will be executed on successful form submission. +::: - Create and return :php:class:`JsChain` action, that will replace form with a success message. +:::{php:method} jsError($field, $message) +Create and return {php:class}`Js_i_JsChain` action that will indicate error on a form control. +::: -.. php:method:: setApiConfig($config) +:::{php:method} jsSuccess($title, [$subTitle]) +Create and return {php:class}`Js_i_JsChain` action, that will replace form with a success message. +::: - Add additional parameters to Fomantic-UI .api function which does the AJAX submission of the form. +:::{php:method} setApiConfig($config) +Add additional parameters to Fomantic-UI .api function which does the AJAX submission of the form. +::: For example, if you want the loading overlay at a different HTML element, you can define it with: @@ -566,9 +572,9 @@ $form->setApiConfig(['stateContext' => 'my-JQuery-selector']); All available parameters can be found here: https://fomantic-ui.com/behaviors/api.html#/settings -.. php:attr:: successTemplate - - Name of the template which will be used to render success message. +:::{php:attr} successTemplate +Name of the template which will be used to render success message. +::: To continue with the example, a new Person record can be added into the database but only if they have also accepted terms and conditions. An onSubmit handler @@ -587,7 +593,7 @@ $form->onSubmit(function (Form $form) { ``` Callback function can return one or multiple JavaScript actions. Methods such as -:php:meth:`jsError()` or :php:meth:`jsSuccess()` will help initialize those actions for your form. +{php:meth}`jsError()` or {php:meth}`jsSuccess()` will help initialize those actions for your form. Here is a code that can be used to output multiple errors at once. Errors were intentionally not grouped with a message about failure to accept of terms and conditions: @@ -620,7 +626,7 @@ $form->onSubmit(function (Form $form) { So far Agile UI / Agile Data does not come with a validation library but it supports usage of 3rd party validation libraries. -Callback function may raise exception. If Exception is based on ``\Atk4\Core\Exception``, +Callback function may raise exception. If Exception is based on `\Atk4\Core\Exception`, then the parameter "field" can be used to associate error with specific field: ``` @@ -635,33 +641,33 @@ will not be included in response for security reasons. ### Form Layout and Sub-layout -As stated above, when a Form object is created and form controls are added through either :php:meth:`addControl()` -or :php:meth:`setModel()`, the form controls will appear one under each-other. This arrangement of form controls as +As stated above, when a Form object is created and form controls are added through either {php:meth}`addControl()` +or {php:meth}`setModel()`, the form controls will appear one under each-other. This arrangement of form controls as well as display of labels and structure around the form controls themselves is not done by a form, but another object - "Form Layout". This object is responsible for the form control flow, presence of labels etc. -.. php:method:: initLayout(Form\\Layout $layout) - - Sets a custom Form\Layout object for a form. If not specified then form will automatically - use Form\Layout class. - -.. php:attr:: layout - - Current form layout object. +:::{php:method} initLayout(Form\Layout $layout) +Sets a custom Form\Layout object for a form. If not specified then form will automatically +use Form\Layout class. +::: -.. php:method:: addHeader($header) +:::{php:attr} layout +Current form layout object. +::: - Adds a form header with a text label. Returns View. +:::{php:method} addHeader($header) +Adds a form header with a text label. Returns View. +::: -.. php:method:: addGroup($header) - - Creates a sub-layout, returning new instance of a :php:class:`Form\\Layout` object. You - can also specify a header. +:::{php:method} addGroup($header) +Creates a sub-layout, returning new instance of a {php:class}`Form_i_Layout` object. You +can also specify a header. +::: ### Form Control Group Layout and Sub-layout -Controls can be organized in groups, using method `Form::addGroup()` or as sub section using `Form\\Layout::addSubLayout()` method. +Controls can be organized in groups, using method `Form::addGroup()` or as sub section using `Form\Layout::addSubLayout()` method. ### Using Group @@ -715,7 +721,7 @@ $group->addControl('last_name', ['width' => 'five']); There are four specific sub layout views that you can add to your existing form layout: Generic, Accordion, Tabs and Columns. Generic sub layout is simply another layout view added to your existing form layout view. You add fields -the same way as you would do for :php:class:`Form\\Layout`. +the same way as you would do for {php:class}`Form_i_Layout`. Sub layout section like Accordion, Tabs or Columns will create layout specific section where you can organize fields in either accordion, tabs or columns. @@ -763,15 +769,15 @@ form inside a segment (outline) and will make form controls appear smaller: $form = new \Atk4\Ui\Form(['class.small segment' => true])); ``` -For further styling see documentation on :php:class:`View`. +For further styling see documentation on {php:class}`View`. ## Not-Nullable and Required Fields ATK Data has two field flags - "nullable" and "required". Because ATK Data works with PHP values, the values are defined like this: - - nullable = value of the field can be null. - - required = value of the field must not be empty/false/zero, null is empty too. +- nullable = value of the field can be null. +- required = value of the field must not be empty/false/zero, null is empty too. Form changes things slightly, because it does not allow user to enter NULL values. For example - string (or unspecified type) fields will contain empty string if are not @@ -785,7 +791,8 @@ numeric field, if zero must be a permitted entry, use "nullable=false" instead. ## Conditional Form -.. php:method:: setControlsDisplayRules() +:::{php:method} setControlsDisplayRules() +::: So far we had to present form with a set of form controls while initializing. Sometimes you would want to hide/display controls while user enters the data. @@ -884,17 +891,19 @@ $form->setGroupDisplayRules([ ]); ``` -.. todo:: MOVE THIS TO SEPARATE FILE - -.. php:class:: Form\\Layout - - Renders HTML outline encasing form controls. - -.. php:attr:: form +:::{todo} +MOVE THIS TO SEPARATE FILE +::: - Form layout objects are always associated with a Form object. +:::{php:class} Form_i_Layout +Renders HTML outline encasing form controls. +::: -.. php:method:: addControl() +:::{php:attr} form +Form layout objects are always associated with a Form object. +::: - Same as :php:class:`Form::addControl()` but will place a form control inside this specific layout - or sub-layout. +:::{php:method} addControl() +Same as {php:class}`Form::addControl()` but will place a form control inside this specific layout +or sub-layout. +::: diff --git a/docs/grid.md b/docs/grid.md index 0c8f8089a8..b1c1120415 100644 --- a/docs/grid.md +++ b/docs/grid.md @@ -1,11 +1,14 @@ -.. _grid: +:::{php:namespace} Atk4\Ui +::: + +(grid)= # Grid -.. php:namespace:: Atk4\Ui -.. php:class:: Grid +:::{php:class} Grid +::: -If you didn't read documentation on :ref:`table` you should start with that. While table implements the actual +If you didn't read documentation on {ref}`table` you should start with that. While table implements the actual data rendering, Grid component supplies various enhancements around it, such as paginator, quick-search, toolbar and others by relying on other components. @@ -29,12 +32,14 @@ $grid->menu->addItem('Reload Grid', new \Atk4\Ui\Js\JsReload($grid)); ## Adding Menu Items -.. php:attr:: menu +:::{php:attr} menu +::: -.. php:method: addButton($label) +:::{php:method} addButton($label) +::: Grid top-bar which contains QuickSearch is implemented using Fomantic-UI "ui menu". With that -you can add additional items and use all features of a regular :php:class:`Menu`: +you can add additional items and use all features of a regular {php:class}`Menu`: ``` $sub = $grid->menu->addMenu('Drop-down'); @@ -56,11 +61,13 @@ $grid = Grid::addTo($app, ['menu' => false]); ## Adding Quick Search -.. php:attr:: quickSearch +:::{php:attr} quickSearch +::: -.. php:method: addQuickSearch($fields = [], $hasAutoQuery = false) +:::{php:method} addQuickSearch($fields = [], $hasAutoQuery = false) +::: -After you have associated grid with a model using :php:class:`View::setModel()` you can +After you have associated grid with a model using {php:class}`View::setModel()` you can include quick-search component: ``` @@ -68,7 +75,7 @@ $grid->addQuickSearch(['name', 'surname']); ``` If you don't specify argument, then search will be done by a models title field. -(https://agile-data.readthedocs.io/en/develop/model.html#title-field) +(https://atk4-data.readthedocs.io/en/develop/model.html#title-field) By default, quick search input field will query server when user press the Enter key. However, it is possible to make it querying the server automatically, i.e. after the user has finished typing, by setting the auto query parameter: @@ -79,9 +86,11 @@ $grid->addQuickSearch(['name', 'surname'], true); ## Paginator -.. php:attr:: paginator +:::{php:attr} paginator +::: -.. php:attr:: ipp +:::{php:attr} ipp +::: Grid comes with a paginator already. You can disable it by setting $paginator property to false. Alternatively you can provide seed for the paginator or even entire object: @@ -98,7 +107,8 @@ $grid->ipp = 10; ### JsPaginator -.. php:method:: addJsPaginator($ipp, $options = [], $container = null, $scrollRegion = 'Body') +:::{php:method} addJsPaginator($ipp, $options = [], $container = null, $scrollRegion = 'Body') +::: JsPaginator will load table content dynamically when user scroll down the table window on screen. @@ -106,20 +116,23 @@ JsPaginator will load table content dynamically when user scroll down the table $table->addJsPaginator(30); ``` -See :php:meth:`Table::addJsPaginator` +See {php:meth}`Table::addJsPaginator` -.. php:method:: addJsPaginatorInContainer($ipp, $containerHeight, $options = [], $container = null, $scrollRegion = 'Body') +:::{php:method} addJsPaginatorInContainer($ipp, $containerHeight, $options = [], $container = null, $scrollRegion = 'Body') +::: Use this method if you want fixed table header when scrolling down table. In this case you have to set fixed height of your table container. ## Actions -.. php:attr:: actions +:::{php:attr} actions +::: -.. php:method:: addActionButton($button, $action, $confirm = false) +:::{php:method} addActionButton($button, $action, $confirm = false) +::: -:php:class:`Table` supports use of :php:class:`Table\\Column\\\Actions`, which allows to display button for each row. +{php:class}`Table` supports use of {php:class}`Table_i_Column_i_Actions`, which allows to display button for each row. Calling addActionButton() provides a useful short-cut for creating column-based actions. $button can be either a string (for a button label) or something like `['icon' => 'book']`. @@ -128,9 +141,10 @@ If $confirm is set to true, then user will see a confirmation when he clicks on Calling this method multiple times will add button into same action column. -See :php:meth:`Table\\Column\\\Actions::addAction` +See {php:meth}`Table_i_Column_i_Actions::addAction` -.. php:method:: addModalAction($button, $title, $callback) +:::{php:method} addModalAction($button, $title, $callback) +::: Similar to addAction, but when clicking a button, will open a modal dialog and execute $callback to populate a content: @@ -146,22 +160,24 @@ $grid->addModalAction('Details', 'Additional Details', function (View $p, $id) u Calling this method multiple times will add button into same action column. -See :php:meth:`Atk4\\Ui\\Table\\Column\\Actions::addModal` +See {php:meth}`Table_i_Column_i_Actions::addModal` ## Column Menus -.. php:method:: addDropdown($columnName, $items, $fx, $icon = 'caret square down', $menuId = null) +:::{php:method} addDropdown($columnName, $items, $fx, $icon = 'caret square down', $menuId = null) +::: -.. php:method:: addPopup($columnName, $popup = null, $icon = 'caret square down') +:::{php:method} addPopup($columnName, $popup = null, $icon = 'caret square down') +::: -Methods addDropdown and addPopup provide a wrapper for :php:meth:`Atk4\\Ui\\Table\\Column::addDropdown` and -:php:meth:`Atk4\\Ui\\\Table\\Column::addPopup` methods. +Methods addDropdown and addPopup provide a wrapper for {php:meth}`Table_i_Column::addDropdown` and +{php:meth}`Table_i_Column::addPopup` methods. ## Selection -Grid can have a checkbox column for you to select elements. It relies on :php:class:`Table\\Column\\Checkbox`, but will -additionally place this column before any other column inside a grid. You can use :php:meth:`Table\\Column\\Checkbox::jsChecked()` -method to reference value of selected checkboxes inside any :ref:`js_action`: +Grid can have a checkbox column for you to select elements. It relies on {php:class}`Table_i_Column_i_Checkbox`, but will +additionally place this column before any other column inside a grid. You can use {php:meth}`Table_i_Column_i_Checkbox::jsChecked()` +method to reference value of selected checkboxes inside any {ref}`js_action`: ``` $sel = $grid->addSelection(); @@ -173,7 +189,8 @@ $grid->menu->addItem('show selection') ## Sorting -.. php:attr:: sortable +:::{php:attr} sortable +::: When grid is associated with a model that supports order, it will automatically make itself sortable. You can override this behaviour by setting $sortable property to `true` or `false`. @@ -181,10 +198,11 @@ override this behaviour by setting $sortable property to `true` or `false`. You can also set $sortable property for each table column decorator. That way you can enable/disable sorting of particular columns. -See also :php:attr:`Table::$sortable`. +See also {php:attr}`Table::$sortable`. ## Advanced Usage -.. php:attr:: table +:::{php:attr} table +::: -You can use a different component instead of default :php:class:`Table` by injecting $table property. +You can use a different component instead of default {php:class}`Table` by injecting $table property. diff --git a/docs/header.md b/docs/header.md index 85287efe98..76fa1c972a 100644 --- a/docs/header.md +++ b/docs/header.md @@ -1,4 +1,5 @@ -.. php:namespace:: Atk4\Ui +:::{php:namespace} Atk4\Ui +::: # Header @@ -6,7 +7,7 @@ Can be used for page or section headers. Based around: https://fomantic-ui.com/elements/header.html. -Demo: https://ui.agiletoolkit.org/demos/header.php +Demo: https://ui.atk4.org/demos/header.php ## Basic Usage @@ -18,9 +19,11 @@ Header::addTo($this, ['Hello, Header']); ## Attributes -.. php:attr:: size +:::{php:attr} size +::: -.. php:attr:: subHeader +:::{php:attr} subHeader +::: Specify size and sub-header content: @@ -42,10 +45,11 @@ Header::addTo($seg, [ ## Icon and Image -.. php:attr:: icon - -.. php:attr:: image +:::{php:attr} icon +::: +:::{php:attr} image +::: Header may specify icon or image: @@ -68,4 +72,3 @@ Header::addTo($seg, [ 'subHeader' => 'header with image', ]); ``` - diff --git a/docs/helloworld.md b/docs/helloworld.md index 05fb60bcae..0576d21982 100644 --- a/docs/helloworld.md +++ b/docs/helloworld.md @@ -1,10 +1,12 @@ -.. _helloworld: +:::{php:namespace} Atk4\Ui +::: -# HelloWorld +(helloworld)= -.. php:namespace:: Atk4\Ui +# HelloWorld -.. php:class:: HelloWorld +:::{php:class} HelloWorld +::: Presence of the "Hello World" component in the standard distribution is just us saying "The best way to create a Hello World app is around a HelloWorld component". diff --git a/docs/icon.md b/docs/icon.md index 4780a7fbe9..12fd15d84f 100644 --- a/docs/icon.md +++ b/docs/icon.md @@ -1,10 +1,12 @@ -.. _icon: +:::{php:namespace} Atk4\Ui +::: -# Icon +(icon)= -.. php:namespace:: Atk4\Ui +# Icon -.. php:class:: Icon +:::{php:class} Icon +::: Implements basic icon: @@ -18,8 +20,8 @@ Alternatively: $icon = Icon::addTo($app, [], ['flag'])->addClass('outline'); ``` -Most commonly icon class is used for embedded icons on a :php:class:`Button` -or inside other components (see :ref:`icon_other_comp`): +Most commonly icon class is used for embedded icons on a {php:class}`Button` +or inside other components (see {ref}`icon_other_comp`): ``` $b1 = new \Atk4\Ui\Button(['Click Me', 'icon' => 'book']); @@ -45,12 +47,12 @@ Button::addTo($app, ['Click Me', 'class.red' => true, 'icon' => 'flipped big que Label::addTo($app, ['Battery Low', 'class.green' => true, 'icon' => 'battery low']); ``` -.. _icon_other_comp: +(icon_other_comp)= ## Using on other Components -You can use icon on the following components: :php:class:`Button`, :php:class:`Label`, :php:class:`Header` -:php:class:`Message`, :php:class:`Menu` and possibly some others. Here are some examples: +You can use icon on the following components: {php:class}`Button`, {php:class}`Label`, {php:class}`Header` +{php:class}`Message`, {php:class}`Menu` and possibly some others. Here are some examples: ``` Header::addTo($app, ['Header', 'class.red' => true, 'icon' => 'flipped question']); @@ -66,7 +68,7 @@ Label::addTo($app, ['Label', 'class.right ribbon red' => true, 'icon' => 'flippe ## Groups -Fomantic-UI support icon groups. The best way to implement is to supply :php:class:`Template` to an +Fomantic-UI support icon groups. The best way to implement is to supply {php:class}`Template` to an icon: ``` @@ -115,20 +117,18 @@ $app->add($noUsers); ## Icon in Your Component Sometimes you want to build a component that will contain user-defined icon. Here you can find -an implementation for ``SocialAdd`` component that implements a friendly social button with +an implementation for `SocialAdd` component that implements a friendly social button with the following features: - - has a very compact usage ``new SocialAdd('facebook')`` - - allow to customize icon by specifying it as string, object or injecting properties - - allow to customize label +- has a very compact usage `new SocialAdd('facebook')` +- allow to customize icon by specifying it as string, object or injecting properties +- allow to customize label Here is the code with comments: ``` /** -``` -     * Implements a social network add button. You can initialize the button by passing -``` + * Implements a social network add button. You can initialize the button by passing * social network as a parameter: new SocialAdd('facebook') * or alternatively you can specify $social, $icon and content individually: * new SocialAdd(['Follow on Facebook', 'social' => 'facebook', 'icon' => 'facebook f']); @@ -180,10 +180,8 @@ class SocialAdd extends \Atk4\Ui\View $this->add($this->icon, 'Icon'); } } -``` -   // Usage Examples. Start with the most basic usage -``` +// Usage Examples. Start with the most basic usage SocialAdd::addTo($app, ['instagram']); // Next specify label and separately name of social network diff --git a/docs/image.md b/docs/image.md index 17d573bb95..3b4035ec03 100644 --- a/docs/image.md +++ b/docs/image.md @@ -1,10 +1,12 @@ -.. _image: +:::{php:namespace} Atk4\Ui +::: -# Image +(image)= -.. php:namespace:: Atk4\Ui +# Image -.. php:class:: Image +:::{php:class} Image +::: Implements Image around https://fomantic-ui.com/elements/image.html. @@ -26,4 +28,3 @@ You can pass additional classes to an image: $img = $app->cdn['atk'] . '/logo.png'; $icon = Image::addTo($app, [$img, 'class.disabled' => true]); ``` - diff --git a/docs/index.md b/docs/index.md index 52a53b51e1..5a2708107d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,37 +1,23 @@ -## Agile UI Documentation +:::{php:namespace} Atk4\Ui +::: -Contents: - -.. toctree:: - :maxdepth: 4 - - overview - quickstart - core - filestructure - components - js - advanced +# Agile UI Documentation +Contents: -.. +:::{toctree} +:maxdepth: 4 - base-components - core - layouts - building-components - menu - lister - table - paginator - grid - form - crud - tree - virtual-page - console +overview +quickstart +core +filestructure +components +js +advanced +::: -## Indices and tables +# Indices and tables -* :ref:`genindex` -* :ref:`search` +- {ref}`genindex` +- {ref}`search` diff --git a/docs/js.md b/docs/js.md index 9ae560387a..47cdb51800 100644 --- a/docs/js.md +++ b/docs/js.md @@ -1,6 +1,7 @@ -.. php:namespace: Atk4\Ui +:::{php:namespace} Atk4\Ui +::: -.. _js: +(js)= # JavaScript Mapping @@ -21,16 +22,14 @@ as possible, then associate them with your UI through actions and events. A great example would be `jQuery` library. It is designed to be usable with any HTML mark-up and by specifying selector, you can perform certain actions: -.. code-block:: js - -``` +```js $('#my-long-id').hide(); ``` Agile UI provides a built-in integration for jQuery. To use jQuery and any other JavaScript library in Agile UI you need to understand how Actions and Events work. -.. _js_action: +(js_action)= ### Actions @@ -41,7 +40,7 @@ the code for hiding a view can be generated by calling: $action = $view->js()->hide(); ``` -There are other ways to generate an action, such as using :php:meth:`JsExpression`: +There are other ways to generate an action, such as using {php:class}`Js_i_JsExpression`: ``` $action = new JsExpression('alert([])', ['Hello world']); @@ -68,10 +67,10 @@ $action = $view->js()->text(new JsExpression('[] + []', [ All of the above examples will produce a valid "Action" object that can be used further. -.. important:: - - We never encourage writing JavaScript logic in PHP. The purpose of JS layer is for binding - events and actions with your generic JavaScript routines. +:::{important} +We never encourage writing JavaScript logic in PHP. The purpose of JS layer is for binding +events and actions with your generic JavaScript routines. +::: ### Events @@ -79,7 +78,7 @@ Agile UI also offers a great way to associate actions with certain client-side e events can be triggered by the user or by other JavaScript code. There are several ways to bind `$action`. -To execute actions instantly on page load, use `true` as first argument to :php:meth:`View::js()`: +To execute actions instantly on page load, use `true` as first argument to {php:meth}`View::js()`: ``` $view->js(true, new JsExpression('alert([])', ['Hello world'])); @@ -116,42 +115,42 @@ All the above examples will map themselves into a simple and readable JavaScript Agile UI builds upon the concepts of actions and events in the following ways: - - Action can be any arbitrary JavaScript with parameters: +- Action can be any arbitrary JavaScript with parameters: - - parameters are always encoded/escaped, - - action can contain nested actions, - - you can build your own integration patterns. + - parameters are always encoded/escaped, + - action can contain nested actions, + - you can build your own integration patterns. - - JsChain provides Action extension for JavaScript frameworks: +- JsChain provides Action extension for JavaScript frameworks: - - Jquery is implementation of jQuery binding through JsChain, - - various 3rd party extensions can integrate other frameworks, - - any jQuery plugin will work out-of-the-box. + - Jquery is implementation of jQuery binding through JsChain, + - various 3rd party extensions can integrate other frameworks, + - any jQuery plugin will work out-of-the-box. - - PHP closure can be used to wrap action-generation code: +- PHP closure can be used to wrap action-generation code: - - Agile UI event will map AJAX call to the event, - - closure can respond with additional actions, - - various UI elements (such as Form) extend this concept further. + - Agile UI event will map AJAX call to the event, + - closure can respond with additional actions, + - various UI elements (such as Form) extend this concept further. ### Including JS/CSS Sometimes you need to include an additional .js or .css file for your code -to work. See :php:meth:`App:requireJs()` and :php:meth:`App::requireCss()` +to work. See {php:meth}`App:requireJs()` and {php:meth}`App::requireCss()` for details. ## Building actions with JsExpressionable -.. php:interface:: JsExpressionable - - Allow objects of the class implementing this interface to participate in - building JavaScript expressions. +:::{php:interface} Js_i_JsExpressionable +Allow objects of the class implementing this interface to participate in +building JavaScript expressions. +::: -.. php:method:: jsRender +:::{php:method} jsRender +Express object as a string containing valid JavaScript statement or expression. +::: - Express object as a string containing valid JavaScript statement or expression. - -:php:class:`View` class is supported as JsExpression argument natively and will present +{php:class}`View` class is supported as JsExpression argument natively and will present itself as a valid selector. Example: ``` @@ -161,18 +160,16 @@ $button->js(true)->appendTo($frame); The resulting Javascript will be: -.. code-block:: js - -``` +```js $('#button-id').appendTo('#frame-id'); ``` ### JavaScript Chain Building -.. php:class:: JsChain - - Base class JsChain can be extended by other classes such as Jquery to provide transparent - mappers for any JavaScript framework. +:::{php:class} Js_i_JsChain +Base class JsChain can be extended by other classes such as Jquery to provide transparent +mappers for any JavaScript framework. +::: Chain is a PHP object that represents one or several actions that are to be executed on the client side. The JsChain objects themselves are generic, so in these examples we'll be using Jquery which @@ -184,11 +181,11 @@ $chain = new Jquery('#the-box-id'); $chain->dropdown(); ``` -The calls to the chain are stored in the object and can be converted into JavaScript by calling :php:meth:`JsChain::jsRender()` +The calls to the chain are stored in the object and can be converted into JavaScript by calling {php:meth}`Js_i_JsChain::jsRender()` -.. php:method:: jsRender() - - Converts actions recorded in JsChain into string of JavaScript code. +:::{php:method} jsRender() +Converts actions recorded in JsChain into string of JavaScript code. +::: Executing: @@ -198,24 +195,22 @@ echo $chain->jsRender(); will output: -.. code-block:: js - -``` +```js $('#the-box-id').dropdown(); ``` -.. important:: - - It's considered very bad practice to use jsRender to output JavaScript manually. Agile UI takes care of - JavaScript binding and also decides which actions should be available while creating actions for your chain. +:::{important} +It's considered very bad practice to use jsRender to output JavaScript manually. Agile UI takes care of +JavaScript binding and also decides which actions should be available while creating actions for your chain. +::: -.. php:method:: _jsEncode - - JsChain will map all the other methods into JS counterparts while encoding all the arguments using `_jsEncode()`. - Although similar to the standard JSON encode function, this method quotes strings using single quotes - and recognizes :php:interface:`JsExpressionable` objects and will substitute them with the result of - :php:meth:`JsExpressionable::jsRender`. The result will not be escaped and any object implementing - :php:interface:`JsExpressionable` interface is responsible for safe JavaScript generation. +:::{php:method} _jsEncode +JsChain will map all the other methods into JS counterparts while encoding all the arguments using `_jsEncode()`. +Although similar to the standard JSON encode function, this method quotes strings using single quotes +and recognizes {php:interface}`Js_i_JsExpressionable` objects and will substitute them with the result of +{php:meth}`Js_i_JsExpressionable::jsRender`. The result will not be escaped and any object implementing +{php:interface}`Js_i_JsExpressionable` interface is responsible for safe JavaScript generation. +::: The following code is safe: @@ -230,17 +225,19 @@ argument to `text()`. ### View to JS integration We are not building JavaScript code just for the exercise. Our whole point is ability to link that code -between actual views. All views support JavaScript binding through two methods: :php:meth:`View::js()` and :php:meth:`View::on()`. +between actual views. All views support JavaScript binding through two methods: {php:meth}`View::js()` and {php:meth}`View::on()`. -.. php:class:: View -.. php:method:: js([$event, [$otherChain]]) +:::{php:class} View +::: - Return action chain that targets this view. As event you can specify `true` which will make chain automatically execute - on document ready event. You can specify a specific JavaScript event such as `click` or `mousein`. You can also use your - custom event that you would trigger manually. If `$event` is false or null, no event binding will be performed. +:::{php:method} js([$event, [$otherChain]]) +Return action chain that targets this view. As event you can specify `true` which will make chain automatically execute +on document ready event. You can specify a specific JavaScript event such as `click` or `mousein`. You can also use your +custom event that you would trigger manually. If `$event` is false or null, no event binding will be performed. - If `$otherChain` is specified together with event, it will also be bound to said event. `$otherChain` can also be - a PHP closure. +If `$otherChain` is specified together with event, it will also be bound to said event. `$otherChain` can also be +a PHP closure. +::: Several usage cases for plain `js()` method. The most basic scenario is to perform action on the view when event happens: @@ -252,10 +249,10 @@ $b2 = new Button('Two'); $b2->js('click', $b1->js()->hide()); ``` -.. php:method:: on(String $event, [String selector], $callback = null) - - Returns chain that will be automatically executed if $event occurs. If $callback is specified, it - will also be executed on event. +:::{php:method} on(String $event, [String selector], $callback = null) +Returns chain that will be automatically executed if $event occurs. If $callback is specified, it +will also be executed on event. +::: The following code will show three buttons and clicking any one will hide it. Only a single action is created: @@ -270,14 +267,14 @@ $buttons->on('click', '.button')->hide(); // Generates: // $('#top-element-id').on('click', '.button', function (event) { -// event.preventDefault(); -// event.stopPropagation(); -// $(this).hide(); +// event.preventDefault(); +// event.stopPropagation(); +// $(this).hide(); // }); ``` -:php:meth:`View::on()` is handy when multiple elements exist inside a view which you want to trigger individually. -The best example would be a :php:class:`Lister` with interactive elements. +{php:meth}`View::on()` is handy when multiple elements exist inside a view which you want to trigger individually. +The best example would be a {php:class}`Lister` with interactive elements. You can use both actions together. The next example will allow only one button to be active: @@ -300,10 +297,12 @@ $buttons->on('click', '.button', $b3->js()->hide()); ## JsExpression -.. php:class:: JsExpression -.. php:method:: __construct(template, args) +:::{php:class} Js_i_JsExpression +::: - Returns object that renders into template by substituting args into it. +:::{php:method} __construct(template, args) +Returns object that renders into template by substituting args into it. +::: Sometimes you want to execute action by calling a global JavaScript method. For this and other cases you can use JsExpression: @@ -314,8 +313,8 @@ $action = new JsExpression('alert([])', [ ]); ``` -Because :php:class:`JsChain` will typically wrap all the arguments through -:php:meth:`JsChain::_jsonEncode()`, it prevents you from accidentally injecting JavaScript code: +Because {php:class}`Js_i_JsChain` will typically wrap all the arguments through +{php:meth}`Js_i_JsChain::_jsonEncode()`, it prevents you from accidentally injecting JavaScript code: ``` $b = new Button(); @@ -366,8 +365,8 @@ must operate with it in your browser by passing expressions into chain. The template language for JsExpression is super-simple: - - [] will be mapped to next argument in the argument array - - [foo] will be mapped to named argument in argument array +- `[]` will be mapped to next argument in the argument array +- `[foo]` will be mapped to named argument in argument array So the following lines are identical: @@ -377,10 +376,10 @@ $sum = new JsExpression('[0] + [1]', [$h1, $h2]); $sum = new JsExpression('[a] + [b]', ['a' => $h1, 'b' => $h2]); ``` -.. important:: - - We have specifically selected a very simple tag format as a reminder not to write - any code as part of JsExpression. You must not use JsExpression() for anything complex. +:::{important} +We have specifically selected a very simple tag format as a reminder not to write +any code as part of JsExpression. You must not use JsExpression() for anything complex. +::: ### Writing JavaScript code @@ -390,16 +389,16 @@ but you should follow a proper pattern. Create a file `test.js` containing: -.. code-block:: js - - function mySum(arr) { - return arr.reduce(function (a, b) { - return a + b; - }, 0); - } +```js +function mySum(arr) { + return arr.reduce(function (a, b) { + return a + b; + }, 0); +} +``` -Then load this JavaScript dependency on your page (see :php:meth:`App::includeJS()` and -:php:meth:`App::includeCSS()`). Finally use UI code as a "glue" between your routine +Then load this JavaScript dependency on your page (see {php:meth}`App::includeJS()` and +{php:meth}`App::includeCSS()`). Finally use UI code as a "glue" between your routine and the actual View objects. For example, to match the size of `$rightContainer` with the size of `$leftContainer`: @@ -414,11 +413,11 @@ $rightContainer->js(true)->height(new JsExpression('mySum([])', [$heights])); This will map into the following JavaScript code: -.. code-block:: js - - $('#right_container_id').height(mySum([ - $('#left_box1').height(), $('#left_box2').height(), $('#left_box3').height(), // etc - ])); +```js +$('#right_container_id').height(mySum([ + $('#left_box1').height(), $('#left_box2').height(), $('#left_box3').height(), // etc +])); +``` You can further simplify JavaScript code yourself, but keep the JavaScript logic inside the `.js` files and leave PHP only for binding. @@ -427,25 +426,37 @@ and leave PHP only for binding. There are two modal implementations in ATK: -* View - Modal: This works with a pre-existing Div, shows it and can be populated with contents; -* JsModal: This creates an entirely new modal Div and then populates it. +- View - Modal: This works with a pre-existing Div, shows it and can be populated with contents; +- JsModal: This creates an entirely new modal Div and then populates it. -In contrast to :php:class:`Modal`, the HTML `
` element generated by :php:class:`JsModal` +In contrast to {php:class}`Modal`, the HTML `
` element generated by {php:class}`Js_i_JsModal` is always destroyed when the modal is closed instead of only hiding it. ### Modal -.. php:class:: Modal +:::{php:class} Modal +::: + +:::{php:method} set(callback) +::: + +:::{php:method} jsShow() +::: + +:::{php:method} jsHide() +::: -.. php:method:: set(callback) -.. php:method:: jsShow() -.. php:method:: jsHide() -.. php:method:: addContentCss() -.. php:method:: addScrolling() -.. php:method:: setOption() +:::{php:method} addContentCss() +::: + +:::{php:method} addScrolling() +::: + +:::{php:method} setOption() +::: This class allows you to open modal dialogs and close them easily. It's based around Fomantic-UI -`.modal(), `_ but integrates PHP callback for dynamically +[.modal()](https://fomantic-ui.com/modules/modal.html), but integrates PHP callback for dynamically producing content of your dialog: ``` @@ -479,12 +490,13 @@ or `contentCss` or use the method `addContentCss()`. See the Fomantic-UI modal d ### JsModal -.. php:class:: JsModal +:::{php:class} Js_i_JsModal +::: -This alternative implementation to :php:class:`Modal` is convenient for situations +This alternative implementation to {php:class}`Modal` is convenient for situations when the need to open a dialog box is not known in advance. This class is not a component, but rather an Action so you **must not** add it to the Render Tree. -To accomplish that, use a :ref:`virtualpage`: +To accomplish that, use a {ref}`virtualpage`: ``` $vp = \Atk4\Ui\VirtualPage::addTo($app); @@ -494,16 +506,17 @@ $vp = \Atk4\Ui\VirtualPage::addTo($app); ->on('click', new \Atk4\Ui\Js\JsModal('My Popup Title', $vp->getUrl('cut'))); ``` -Note that this element is always destroyed as opposed to :php:class:`Modal`, +Note that this element is always destroyed as opposed to {php:class}`Modal`, where it is only hidden. -.. important:: - - See `Modals and reloading`_ concerning the intricacies between jsMmodals and callbacks. +:::{important} +See [Modals and reloading](#modals-and-reloading) concerning the intricacies between jsMmodals and callbacks. +::: ## Reloading -.. php:class:: JsReload +:::{php:class} Js_i_JsReload +::: JsReload is a JavaScript action that performs reload of a certain object: @@ -535,7 +548,7 @@ In this example, filling out and submitting the form will result in table conten ### Modals and reloading -Care needs to be taken when attempting to combine the above with a `JsModal`_ which requires a :ref:`virtualpage` to +Care needs to be taken when attempting to combine the above with a {php:class}`Js_i_JsModal` which requires a {ref}`virtualpage` to store its contents. In that case, the order in which declarations are made matters because of the way the Render Tree is processed. @@ -543,10 +556,10 @@ For example, in order to open a modal dialog containing a form and reload a tabl with the updated data on form submission (thus without having to reload the entire page), the following elements are needed: -* a virtual page containing a JsModal's contents (in this case a form), -* a table showing data on the main page, -* a button that opens the modal in order to add data, and -* the form's callback on submit. +- a virtual page containing a JsModal's contents (in this case a form), +- a table showing data on the main page, +- a button that opens the modal in order to add data, and +- the form's callback on submit. The following will **not** work: @@ -654,16 +667,18 @@ $button->on('click', function () use ($button, $image) { }); ``` -However, it would be nice if the user was aware of the progress of your process, which is when `Server Sent Event (JsSse)`_ +However, it would be nice if the user was aware of the progress of your process, which is when {ref}`sse` comes into play. -.. _sse: +(sse)= ### Server Sent Event (JsSse) -.. php:class:: JsSse +:::{php:class} JsSse +::: -.. php:method:: send(action) +:::{php:method} send(action) +::: This class implements ability for your PHP code to send messages to the browser during process execution: @@ -689,4 +704,4 @@ $button->on('click', $sse->set(function () use ($sse, $button, $image) { })); ``` -The JsSse component plays a crucial role in some high-level components such as :php:class:`Console` and :php:class:`ProgressBar`. +The JsSse component plays a crucial role in some high-level components such as {php:class}`Console` and {php:class}`ProgressBar`. diff --git a/docs/label.md b/docs/label.md index 9a6390ce57..8cc0ac67de 100644 --- a/docs/label.md +++ b/docs/label.md @@ -1,17 +1,19 @@ -.. _label: +:::{php:namespace} Atk4\Ui +::: -# Label +(label)= -.. php:namespace:: Atk4\Ui +# Label -.. php:class:: Label +:::{php:class} Label +::: Labels can be used in many different cases, either as a stand-alone objects, inside tables or inside other components. To see what possible classes you can use on the Label, see: https://fomantic-ui.com/elements/label.html. -Demo: https://ui.agiletoolkit.org/demos/label.php +Demo: https://ui.atk4.org/demos/label.php ## Basic Usage @@ -27,33 +29,41 @@ $label = new \Atk4\Ui\Label('hello world'); $app->add($label); ``` - Label has the following properties: -.. php:attr:: icon +:::{php:attr} icon +::: -.. php:attr:: iconRight +:::{php:attr} iconRight +::: -.. php:attr:: image +:::{php:attr} image +::: -.. php:attr:: imageRight +:::{php:attr} imageRight +::: -.. php:attr:: detail +:::{php:attr} detail +::: All the above can be string, array (passed to Icon, Image or View class) or an object. ## Icons -There are two properties (icon, iconRight) but you can set only one at a time:: +There are two properties (icon, iconRight) but you can set only one at a time: - Label::addTo($app, ['23', 'icon' => 'mail']); - Label::addTo($app, ['new', 'iconRight' => 'delete']); +``` +Label::addTo($app, ['23', 'icon' => 'mail']); +Label::addTo($app, ['new', 'iconRight' => 'delete']); +``` -You can also specify icon as an object:: +You can also specify icon as an object: - Label::addTo($app, ['new', 'iconRight' => new \Atk4\Ui\Icon('delete')]); +``` +Label::addTo($app, ['new', 'iconRight' => new \Atk4\Ui\Icon('delete')]); +``` -For more information, see: :php:class:`Icon` +For more information, see: {php:class}`Icon` ## Image @@ -133,4 +143,3 @@ $table->onHook(\Atk4\Ui\Table\Column::HOOK_GET_HTML_TAGS, function (Table $table Now while $table will be rendered, if it finds a record with id=1, it will replace $name value with a HTML tag. You need to make sure that 'name' column appears first on the left. - diff --git a/docs/lister.md b/docs/lister.md index 1d351bd861..4f9a48ed06 100644 --- a/docs/lister.md +++ b/docs/lister.md @@ -1,13 +1,15 @@ -.. _Lister: +:::{php:namespace} Atk4\Ui +::: -# Lister +(Lister)= -.. php:namespace:: Atk4\Ui +# Lister -.. php:class:: Lister +:::{php:class} Lister +::: Lister can be used to output unstructured data with your own HTML template. If you wish to output -data in a table, see :php:class:`Table`. Lister is also the fastest way to render large amount of +data in a table, see {php:class}`Table`. Lister is also the fastest way to render large amount of output and will probably give you most flexibility. ## Basic Usage @@ -61,10 +63,10 @@ Lister::addTo($view, [], ['Countries']) While most other objects in Agile UI come with their own templates, lister will prefer to use template inside your region. It will look for "row" and "rows" tag: - 1. Create clone of {row} tag - 2. Delete contents of {rows} tag - 3. For each model row, populate values into {row} - 4. Render {row} and append into {rows} +1. Create clone of {row} tag +2. Delete contents of {rows} tag +3. For each model row, populate values into {row} +4. Render {row} and append into {rows} If you refresh your page now, you should see "Andorra" duplicated 20 times. This is because the {row} did not contain any field tags. Lets set them up: @@ -102,7 +104,7 @@ Finally, Lister permits you not to use {rows} and {row} tags if entire region ca ## Tweaking the output -Output is formatted using the standard :ref:`uiPersistence` routine, but you can also fine-tune the content +Output is formatted using the standard {ref}`uiPersistence` routine, but you can also fine-tune the content of your tags like this: ``` @@ -126,9 +128,9 @@ $lister->setSource([ Your {row} template may contain few special tags: - - {$_id} - will be set to ID of the record (regardless of how your id_field is called) - - {$_title} - will be set to the title of your record (see $model->$titleField) - - {$_href} - will point to current page but with ?id=123 extra GET argument. +- {$_id} - will be set to ID of the record (regardless of how your id_field is called) +- {$_title} - will be set to the title of your record (see $model->$titleField) +- {$_href} - will point to current page but with ?id=123 extra GET argument. ## Load page content dynamically when scrolling @@ -153,4 +155,3 @@ Lister::addTo($app, ['defaultTemplate' => 'lister.html']); ``` This should display a list nicely formatted by Fomantic-UI, with header, links, icons and description area. - diff --git a/docs/loremipsum.md b/docs/loremipsum.md index 6df5330bef..4e37ee3f8d 100644 --- a/docs/loremipsum.md +++ b/docs/loremipsum.md @@ -1,13 +1,15 @@ -.. _text: +:::{php:namespace} Atk4\Ui +::: -# LoremIpsum +(text)= -.. php:namespace:: Atk4\Ui +# LoremIpsum -.. php:class:: LoremIpsum +:::{php:class} LoremIpsum +::: This class implements a standard filler-text which is so popular amongst web developers and designers. -LoremIpsum will generate a dynamic filler text which should help you test :ref:`reloading` or layouts. +LoremIpsum will generate a dynamic filler text which should help you test {ref}`reloading` or layouts. ## Basic Usage @@ -25,7 +27,6 @@ $text = Text::addTo($app) ->addParagraph('Second Paragraph'); ``` - You may specify amount of text to be generated with lorem: ``` @@ -35,5 +36,3 @@ LoremIpsum::addTo($app, [1]); // just add a little one LoremIpsum::addTo($app, [5]); // adds a lot of text ``` - - diff --git a/docs/menu.md b/docs/menu.md index 883fc6575c..991d876355 100644 --- a/docs/menu.md +++ b/docs/menu.md @@ -1,15 +1,19 @@ -.. _menu: +:::{php:namespace} Atk4\Ui +::: + +(menu)= # Menu -.. php:namespace:: Atk4\Ui -.. php:class:: Menu +:::{php:class} Menu +::: Menu implements horizontal or vertical multi-level menu by using Fomantic-UI 'menu'. ## Using Menu -.. php:method: addItem($label, $action) +:::{php:method} addItem($label, $action) +::: Here is a simple usage: @@ -27,7 +31,7 @@ $menu->addClass('vertical'); ## Decorating Menu Items -See :php:class:`MenuItem` for more options: +See {php:class}`MenuItem` for more options: ``` $menu->addItem(['foo', 'icon' => 'book']); @@ -44,15 +48,18 @@ $menu->addItem('bar', new JsModal('Test')); ## Creating sub-menus -.. php:method: addMenu($label) -.. php:method: addGroup($label) -.. php:method: addRightMenu($label) +:::{php:method} addMenu($label) +::: + +:::{php:method} addGroup($label) +::: + +:::{php:method} addRightMenu($label) +::: You can create sub-menu for either vertical or horizontal menu. For a vertical menu you can also use groups. For horizontal menu, you can use addRightMenu. -: - ``` $menu = Menu::addTo($app); $menu->addItem('foo'); @@ -63,7 +70,8 @@ $sub->addItem('bar 2'); ## Headers -.. php:method: addHeader($label) +:::{php:method} addHeader($label) +::: ## Advanced Use @@ -71,10 +79,13 @@ You can add other elements inside menu. Refer to demos/menu.php. ## MenuItem -.. php:class:: MenuItem +:::{php:class} MenuItem +::: -.. php:attr:: label +:::{php:attr} label +::: -.. php::attr:: $icon +:::{php:attr} icon +::: -Additionally you can use :php:meth:`View::addClass()` to disable or style your menu items. +Additionally you can use {php:meth}`View::addClass()` to disable or style your menu items. diff --git a/docs/message.md b/docs/message.md index ee4d2f370f..3288a4d9dd 100644 --- a/docs/message.md +++ b/docs/message.md @@ -1,14 +1,16 @@ -.. _message: +:::{php:namespace} Atk4\Ui +::: -# Message +(message)= -.. php:namespace:: Atk4\Ui +# Message -.. php:class:: Message +:::{php:class} Message +::: Outputs a rectangular segment with a distinctive color to convey message to the user, based around: https://fomantic-ui.com/collections/message.html -Demo: https://ui.agiletoolkit.org/demos/message.php +Demo: https://ui.atk4.org/demos/message.php ## Basic Usage @@ -34,9 +36,10 @@ $message = Message::addTo($app, ['Warning Message Title', 'type' => 'warning']); ## Adding message text -.. php:attr:: text +:::{php:attr} text +::: -Property $text is automatically initialized to :php:class:`Text` so you can call :php:meth:`Text::addParagraph` +Property $text is automatically initialized to {php:class}`Text` so you can call {php:meth}`Text::addParagraph` to add more text inside your message: ``` @@ -48,7 +51,8 @@ $message->text->addParagraph('Second para'); ## Message Icon -.. php:attr:: icon +:::{php:attr} icon +::: You can specify icon also: @@ -59,5 +63,3 @@ $message = Message::addTo($app, [ 'icon' => 'battery low', ])->text->addParagraph('Your battery is getting low. Re-charge your Web App'); ``` - - diff --git a/docs/misc.md b/docs/misc.md index bfe8ef7b54..03deebcacb 100644 --- a/docs/misc.md +++ b/docs/misc.md @@ -1,13 +1,15 @@ -.. php:namespace:: Atk4\Ui +:::{php:namespace} Atk4\Ui +::: -## Columns +# Columns This class implements CSS Grid or ability to divide your elements into columns. If you are an expert designer with knowledge of HTML/CSS we recommend you to create your own layouts and templates, but if you are not sure how to do that, then using "Columns" class might be a good alternative for some basic content arrangements. -.. php:method:: addColumn() +:::{php:method} addColumn() +::: When you add new component to the page it will typically consume 100% width of its container. Columns will break down width into chunks that can be used by other elements: @@ -35,7 +37,7 @@ Box::addTo($c->addColumn(), ['red']); Box::addTo($c->addColumn(['class.right floated' => true]), ['blue']); ``` -### Rows +## Rows When you add columns for a total width which is more than permitted, columns will stack below and form a second row. To improve and control the flow of rows better, you can specify addRow(): @@ -57,10 +59,10 @@ Icon::addTo($r->addColumn(2), ['huge trash']); This example also uses custom class for Columns ('internally celled') that adds dividers between columns and rows. For more information on available classes, see https://fomantic-ui.com/collections/grid.html. -### Responsiveness and Performance +## Responsiveness and Performance Although you can use responsiveness with the Column class to some degree, we recommend that you create your own component template where you can have greater control over all classes. -Similarly if you intend to output a lot of data, we recommend you to use :php:class:`Lister` instead with a custom +Similarly if you intend to output a lot of data, we recommend you to use {php:class}`Lister` instead with a custom template. diff --git a/docs/multiline.md b/docs/multiline.md index 579476e4a0..af7a9c4789 100644 --- a/docs/multiline.md +++ b/docs/multiline.md @@ -1,6 +1,8 @@ -.. php:namespace:: Atk4\Ui\Form\Control +:::{php:namespace} Atk4\Ui +::: -.. php:class:: Multiline +:::{php:class} Form_i_Control_i_Multiline +::: # Multiline Form Control @@ -23,7 +25,7 @@ class User extends \Atk4\Data\Model protected function init(): void { - parent:: init(); + parent::init(); $this->addField('firstname', ['type' => 'string']); $this->addField('lastname', ['type' => 'string']); @@ -53,7 +55,8 @@ class Address extends \Atk4\Data\Model This leads to a Multiline component automatically rendered for adding, editing and deleting Addresses of the current user record: -.. image:: images/multiline_user_addresses.png +:::{image} images/multiline_user_addresses.png +::: You can also check LINK_TO_DEMO/multiline.php for this example @@ -91,7 +94,7 @@ class User extends \Atk4\Data\Model protected function init(): void { - parent:: init(); + parent::init(); $this->addField('firstname', ['type' => 'string']); $this->addField('lastname', ['type' => 'string']); @@ -103,7 +106,8 @@ class User extends \Atk4\Data\Model Using a form with User model won't automatically add a Multiline to edit the related email addresses. -.. php:method:: setReferenceModel(string $refModelName, Model $entity = null, array $fieldNames = []): Model +:::{php:method} setReferenceModel(string $refModelName, Model $entity = null, array $fieldNames = []): Model +::: If you want to edit them along with the user, Multiline need to be set up accordingly using the setReferenceModel method: @@ -125,7 +129,6 @@ $userForm->onSubmit(function (Form $form) use ($ml) { }); ``` - Using the example above will create a form with control from the User model as well as a Multiline control for editing the Email model's field. @@ -140,9 +143,9 @@ normally call this method in your form onSubmit handler method. ## Multiline and Expressions If a Model contains Expressions, there resulting values will automatically get updated when one of the form control value is changed. -A loading icon on the ``+`` button will indicates that the expression values are being update. +A loading icon on the `+` button will indicates that the expression values are being update. -Lets use the example of demos/multiline.php: +Lets use the example of `demos/multiline.php`: ``` class InventoryItem extends \Atk4\Data\Model @@ -166,7 +169,7 @@ The 'total' expression will get updated on each field change automatically. ## OnLineChange Callback If you want to define a callback which gets executed when a field value in a Multiline row is changed, -you can do so using the ``onLineChange()`` method. +you can do so using the `onLineChange()` method. The first parameter is the callback function, the second one is an array containing field names that will trigger the callback when values are changed. You can return a single JsExpressionable or an array of JsExpressionables which then will be sent to the browser. @@ -194,7 +197,8 @@ field type associated with Multiline control. You will find a list of Vue component associated with each field type within the Multiline $fieldMapToComponent array. -.. php:attr:: fieldMapToComponent +:::{php:attr} fieldMapToComponent +::: Each control being a Vue component means that they accept 'Props' that may change their look or behaviour. Props on each component may be applied globally, i.e. to all control within Multiline that use that control, or @@ -204,7 +208,8 @@ per component. Use the $componentProps property of Multiline in order to apply 'Props' to component globally. -.. php:attr:: componentProps +:::{php:attr} componentProps +::: Example of changing all Dropdown(SuiDropdown) within Multiline: @@ -253,6 +258,5 @@ $ml = $form->addControl('ml', [Multiline::class, 'tableProps' => ['color' => 'bl ### Header - The header uses the field's caption by default. -- You can edit it by setting the ``$caption`` property. -- If you want to hide the header, set the ``$caption`` property to an empty string ``''``. - +- You can edit it by setting the `$caption` property. +- If you want to hide the header, set the `$caption` property to an empty string `''`. diff --git a/docs/overview.md b/docs/overview.md index 5d35590c0b..19df3251c1 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -1,4 +1,7 @@ -.. _overview: +:::{php:namespace} Atk4\Ui +::: + +(overview)= # Overview of Agile UI @@ -6,15 +9,16 @@ Agile UI is a PHP component framework for building User Interfaces entirely in P Although the components of Agile UI will typically use HTML, JavaScript, jQuery and CSS, the goal of Agile UI is to abstract them away behind easy-to-use component objects. -As a framework it's closely coupled with Agile Data (https://agile-data.readthedocs.io) +As a framework it's closely coupled with Agile Data (https://atk4-data.readthedocs.io/) which abstracts database interaction operations. The default UI template set uses Fomantic-UI (https://fomantic-ui.com) for presentation. At a glance, Agile UI consists of the following: -.. figure:: images/all-atk-classes.png +:::{figure} images/all-atk-classes.png +::: -Agile UI is designed and built for the Agile Toolkit (https://agiletoolkit.org/) platform, +Agile UI is designed and built for the Agile Toolkit (https://atk4.org/) platform, with the goal of providing a user-friendly experience when creating data-heavy API / UI backends. @@ -66,7 +70,7 @@ Agile UI is designed and optimized for quick deployment into modern serverless architecture providers such as: Heroku, Docker, or even AWS Lambdas. Agile UI / PHP application has a minimum "start-up" time, has the best CPU usage, -and gives you the highest efficiency and best scaling.   +and gives you the highest efficiency and best scaling. ### 5. High-level Solution @@ -77,10 +81,9 @@ Simple scenario:   digging through heaps of HTML, CSS, or JS frameworks and need a solution   which will be quick and just works. -.. _overview_example: +(overview_example)= -Overview Example -^^^^^^^^^^^^^^^^ +#### Overview Example Agile UI / Agile Data code for your app can fit into a single file. See below for clarifications: @@ -120,71 +123,66 @@ $db = new \Atk4\Data\Persistence\Sql($dsn); Through the course of this example, We are performing several core actions: - - `$app` is an object representing our Web Application and abstracting - all the input, output, error-handling, and other technical implementation - details of a standard web application. - - In most applications you would want to extend this class yourself. When - integrating Agile UI with MVC framework, you would be using a different - App class that properly integrates framework capabilities. - - For a :ref:`component` the App class provides level of abstraction and - utility. +- `$app` is an object representing our Web Application and abstracting + all the input, output, error-handling, and other technical implementation + details of a standard web application. - For full documentation see :ref:`app`. + In most applications you would want to extend this class yourself. When + integrating Agile UI with MVC framework, you would be using a different + App class that properly integrates framework capabilities. - - `$db` this is a database persistence object. It may be a Database which is - either SQL or NoSQL but can also be RestAPI, a cache, or a pseudo-persistence. + For a {ref}`component` the App class provides level of abstraction and + utility. - We used `Persistence\Sql` class, which takes advantage of a standard-compliant - database server to speed up aggregation, multi-table, and multi-record operations. + For full documentation see {ref}`app`. - For a :ref:`component` the Persistence class provides data storage abstraction - through the use of a Model class. +- `$db` this is a database persistence object. It may be a Database which is + either SQL or NoSQL but can also be RestAPI, a cache, or a pseudo-persistence. - Agile Data has full documentation at https://agile-data.readthedocs.io. + We used `Persistence\Sql` class, which takes advantage of a standard-compliant + database server to speed up aggregation, multi-table, and multi-record operations. - - `Offer` is a Model - a database-agnostic declaration of your business entity. - Model object represents a data-set for specific persistence and conditions. + For a {ref}`component` the Persistence class provides data storage abstraction + through the use of a Model class. -   In our example, the object is created representing all our offer records that is then - passed into the Crud :ref:`component`. + Agile Data has full documentation at https://atk4-data.readthedocs.io/. - For a :ref:`component`, the Model represents information about the structure - and offers a mechanism to retrieve, store, and delete date from `$db` persistence. +- `Offer` is a Model - a database-agnostic declaration of your business entity. + Model object represents a data-set for specific persistence and conditions. + In our example, the object is created representing all our offer records that is then + passed into the Crud {ref}`component`. - - `Crud` is a :ref:`component` class. Particularly Crud is bundled with Agile UI -   and implements out-of-the-box interface for displaying data in a table format -   with operations to add, delete, or edit the record. + For a {ref}`component`, the Model represents information about the structure + and offers a mechanism to retrieve, store, and delete date from `$db` persistence. - Although it's not obvious from the code, Crud relies on multiple other components - such as :php:class:`Grid`, :php:class:`Form`, :php:class:`Menu`, :php:class:`Paginator`, - and :php:class:`Button`. +- `Crud` is a {ref}`component` class. Particularly Crud is bundled with Agile UI + and implements out-of-the-box interface for displaying data in a table format + with operations to add, delete, or edit the record. + Although it's not obvious from the code, Crud relies on multiple other components + such as {php:class}`Grid`, {php:class}`Form`, {php:class}`Menu`, {php:class}`Paginator`, + and {php:class}`Button`. To sum up Agile UI in more technical terms: - - Fully utilizes abstraction of Web technologies through components. - - Contains concise syntax to define UI layouts in PHP. - - Has built-in security and safety. - - Decouples from data storage/retrieval mechanism. - - Designed to be integrated into full-stack frameworks. - - Abstains from duplicating field names, types, or validation logic outside of Model - class. +- Fully utilizes abstraction of Web technologies through components. +- Contains concise syntax to define UI layouts in PHP. +- Has built-in security and safety. +- Decouples from data storage/retrieval mechanism. +- Designed to be integrated into full-stack frameworks. +- Abstains from duplicating field names, types, or validation logic outside of Model + class. ### Best use of Agile UI - - Creating admin backend UI for data entry and dashboards in shortest time and with - minimum amount of code. - - - Building UI components which you are willing to use across multiple environments - (Laravel, WordPress, Drupal, etc) - - - Creating MVP prototype for Web Apps. +- Creating admin backend UI for data entry and dashboards in shortest time and with + minimum amount of code. +- Building UI components which you are willing to use across multiple environments + (Laravel, WordPress, Drupal, etc) +- Creating MVP prototype for Web Apps. - -.. _component: +(component)= ## Component @@ -202,21 +200,21 @@ $button = \Atk4\Ui\Button::addTo($form, [ ])->link('dashboard.php'); ``` -:php:class:`Button` and :php:class:`Icon` are some of the most basic components in +{php:class}`Button` and {php:class}`Icon` are some of the most basic components in Agile UI. You will find Crud / Form / Grid components much more useful: -.. figure:: images/all-atk-classes.png +:::{figure} images/all-atk-classes.png +::: ### Using Components -Look above at the :ref:`overview_example`, component `GRID` was made part +Look above at the {ref}`overview_example`, component `GRID` was made part of application layout with a line: ``` \Atk4\Ui\Crud::addTo($app); ``` - To render a component individually and get the HTML and JavaScript use this format: ``` @@ -228,7 +226,6 @@ $form->setModel(new User($db)); $html = $form->render(); ``` - This would render an individual component and will return HTML: ``` @@ -240,7 +237,7 @@ This would render an individual component and will return HTML:
``` -For other use-cases please look into :php:meth:`View::render()` +For other use-cases please look into {php:meth}`View::render()` ### Factory @@ -254,35 +251,37 @@ in PHP language allows us to use an alternative shorter syntax: ``` By default, class names specified as the first array elements passed to the add() method are -resolved to namespace `Atk4\\Ui`; however the application class can fine-tune the +resolved to namespace `Atk4\Ui`; however the application class can fine-tune the search. Using a factory is optional. For more information see: -https://agile-core.readthedocs.io/en/develop/factory.html +https://atk4-core.readthedocs.io/en/develop/factory.html ### Templates -Components rely on :php:class:`Template` class for parsing and rendering their +Components rely on {php:class}`Template` class for parsing and rendering their HTML. The default template is written for Fomantic-UI framework, which makes sure that elements will look good and be consistent. ### Layouts -.. image:: images/layout-hierarchy.png - :width: 40% - :align: right +:::{image} images/layout-hierarchy.png +:align: right +:width: 40% +::: Using App class will utilize a minimum of 2 templates: - - html.html - boilerplate HTML code (,