This is an old revision of the document!
Table of Contents
Component class
The component class is a base UI class providing a close binding between PHP and Javascript. The class is intended to be subclassed.
Simple component
In order to create a new, simple component just override the renderContent
-function, such as:
class helloWorld extends Component { public function renderContent() { echo 'Hello world'; } } $mycomponent = new helloWorld(); // Start page $mycomponent->render();
Component properties
In order for components to work correctly, all variables needed for configuring the component should be implemented as properties. This can be done with the addPropertyMap function, which expect an array of property keys and default values.
To extend the component from above to make the text and text color configurable, do this:
class textOutput extends Component { public function __construct() { $this->addPropertyMap(array( 'text' => 'Hello world', 'color' => 'black' ); parent::__construct(); ); public function renderContent() { echo '<span style="color:'.$this->color.';">'; echo $this->text; echo '</span>'; } } $mycomponent = new textOutput(); $mycomponent->text = 'Platform4PHP is cool'; $mycomponent->color = 'red'; $mycomponent->render();
Note how the configuration properties are easily set and read.
HTML output
The base component will render a div with the following properties:
- The id will match the id set by the
SetID()
function. If no ID is set, one will be auto-generated. - It will add a class platform_component
- It will add a class platform_component_CLASSNAME where CLASSNAME is the name of the class.
- It will add up to three data-elements: redraw_url, componentclass and componentproperties for internal handling.
Example
- output.html
<div class="platform_component platform_component_textoutput" id="example_output" data-componentproperties="..." data-redraw_url="..." data-componentclass="textOutput"> <span style="color:red;">Platform4PHP is cool</span> </div>
Javascript and CSS handling
A component will typically need its own css-files and javascript to function properly. These can just be included in the constructor using the general Page::JSFile()
and Page::CSSFile()
. Platform will ensure that each file is only included once.
class textOutput extends Component { public function __construct() { Page::JSFile('script.js'); Page::CSSFile('style.css'); parent::__construct(); ); }
In order for javascript to work, especially if the page is hyper-dynamic, it need to be wrapped in the following structure:
- textoutput.js
addPlatformComponentHandlerFunction('CLASS_IN_LOWERCASE', function(item) { // Do your stuff here! });
CLASS_IN_LOWERCASE should be exchanged with the class name of the PHP class in lowercase, so for the class textOutput, it should read like this:
- textoutput.js
addPlatformComponentHandlerFunction('textoutput', function(item) { // Do your stuff here! });
The item variable passed is a Jquery-selector pointing to the DOM node of the component. This will always point to a single node, so there is no need to iterate it. If several components of the same type exists, the function will be called multiple times.
Easy Javascript / PHP interaction
Components support easy interaction between Javascript and PHP. This interaction can both take place using forms and also directly from Javascript.
In javascript this interaction takes place through two JQuery plugins called componentIO
and componentIOForm
.
In PHP everything is handled by overriding the handleIO()
function in the Component.
Easy form interaction
If you have a form, you can get your component to handle it. In javascript do this:
- script.js
mycomponent.componentIOForm($('#myform'), function(data) { console.log('This is called on success.'); })
mycomponent is expected to be the jquery node for a valid component. myform is the HTML ID for a form. The anonymous function is called if the form is handled without errors.
When the form is submitted it will be intercepted by the component and the form output will end up in the handleIO()
PHP function:
- component.php
public function handleIO() : array { $form = new \Platform\Form(); // You need to get the appropriate form. if (! $form->validate) return ['status' => 0, 'form_errors' => $form->getAllErrors()]; return ['status' => 1, 'message' => 'This entire array is returned to javascript']; }
If you want the form to fail, you need to return an array with two keys. status which must be 0 or false, and form_errors which should contain the output from Form→getAllErrors()
. This will automatic cause the frontend to fail the form.
Otherwise the array returned from the function will be passed into the javascript anonymous function.
Without javascript
It is possible to attach a form entirely from PHP like this:
- component.php
class myComponent { ... $form = new \Platform\Form(); // You need to get the appropriate form. $this->attachIOForm($form); ... }
When this form is submitted it is processed by the component like above, but without the need to write javascript-code.
Easy general interaction
If you just want to pass some variables to the handleIO()
-function, you can also do that easily:
- script.js
mycomponent.componentIOForm({action: 'setvalue', value: 'myvalue'}, function(data) { console.log('This is called with the return values from the PHP function.');})
This will immediately pass the variables to the handleIO()
-function, where they can be handled.
- component.php
public function handleIO() : array { if ($_POST['action'] == 'setvalue' && $_POST['value'] == 'myvalue') return ['status' => true, 'text' => 'This was exactly as expected.']; else return ['status' => false, 'text' => 'I didn\'t expect that input!']; }
The return values will be passed back into the javascript anonymous functions.
Components in headless scripts
If you use components in headless scripts, which are scripts that doesn't contain a complete html page, but are instead meant to be loaded dynamically, be sure to call the Page::setPagestarted()
function before adding your components. Otherwise included javascript and css-files will not load correctly.
Component event model
Components are designed to work with the Javascript/Jquery event model, so communication is expected to take place by triggering events on the DOM node containing the component. There are some built-in events already available on all basic components:
event | Effect |
---|---|
redraw | Redraws the component by fetching its content from the server. See below. |
Automatic component redraw
It is possible for Platform-components to automatically redraw themselves if they are designed correctly. The condition for a component to be able to redraw itself, is that it must be able to do so based solely on the content of its properties. In other words, the component should be able to render by doing just the following:
$component = new textOutput(); $component->setPropertyMap(PROPERTIES NEEDED TO RENDER COMPONENT); $component->render();
In this case, you can force the component to redraw, by just triggering the Javascript redraw event on it.
Advanced redrawing
If you make a component which isn't able to redraw itself, then you should overwrite the static variable:
protected static $can_redraw = false;
If a component is to redraw itself, it needs to know if it should validate itself for security reasons. By default it will fail to redraw if it can't detect a valid session.
To skip this check, then overwrite the static variable:
protected static $is_secure = false;
In this case everyone can replay the Ajax redraw request and see the content of the component.