Introduction

User controls can be usually includes files or represent complex objects.

User controls can not use the directives, and they can not have their own localization files.

User controls can contain any client-side and server-side code.

Each instance of an user control can have its own, unique, property values.

The properties of an user controls may refer to other classes and are easily described in the HTML.

User controls can be placed in templates and content pages, without any restrictions.

Contents

Registration and placement of controls

Before placing the controls on the page, they need to register. This is done with the help of the directive #Register.

Register should be only those controls that are required on a specific page.

The following example shows the registration Message control.

<?#Register Src="~/Controls/Message.php" TagPrefix="php" TagName="Message"?>

The Src parameter contains the path to the main file of the control. The TagPrefix and TagName contains name of the control.

The following example shows the placement on the page multiple instances of the Message control.

<php:Message>Hello world! This is message #1!</php:Message>
<php:Message>This is message #2!</php:Message>
<php:Message>Such messages can be any number!</php:Message>

As a rule, the TagPrefix is set to php and TagName is the name of the control, but it is not a requirement.

The following example illustrates the use of non-standard values of the TagPrefix and TagName.

<?#Register Src="~/Controls/Message.php" TagPrefix="my" TagName="Information"?>

<my:Information>Hello world!</my:Information>
			     

On one page can place an unlimited number of user controls with different properties.

User controls as a replacement for include files

User controls can be included files.

The following example shows simple user control.

The simple user control.
<br /><br />
<?="You can use any tags and php code."?>

For controls have no class, used the Control class by default. This allows to use properties with a text values for each control instance.

The following example shows the source code of the Panel. The control consists of only server-side code and markup, and is not explicitly defined class. The Panel expects values for two anonymous property: Title and Content. The values for these properties can be passed when placing the control on the page.

<div class="panel panel-default">
  <?php if (isset($this->Title)) {?>
  <div class="panel-heading"><?=$this->Title?></div>
  <?php } ?>
  <div class="panel-body">
    <?=$this->Content?>
  </div>
</div>
<?#Register Src="~/Controls/Panel.php" TagPrefix="php" TagName="Panel"?>

<php:Panel Title="Title" Content="Hello world!" />
Title
Hello world!

Object model

As in the case of content pages, at the object model, the main control file must contain a class; marking is located in a .html.php file.

The following example shows the Message control, which is used at this site. Class of the control contained in the Message.php, the markup - Message.html.php.

<div class="<?=$this->GetCssClass()?>">
  <?=($this->ShowIcon ? $this->GetIcon() : '')?>
  <?=$this->Content?>
</div>
<?php
/**
 * Represents message control.
 */
class Message extends Nemiro\UI\Control
{

  /**
   * The message text.
   * 
   * @var string
   */
  public $Content = '';

  /**
   * Gets or sets the message type. Allowed: Danger (default), Warning, Info, Success.
   * @var mixed
   */
  public $Type = 'Danger';

  /**
   * 
   * @var bool
   */
  public $ShowIcon = true;

  /**
   * Returns css class for the message block.
   * 
   * @return string
   */
  function GetCssClass()
  {
    switch (strtolower($this->Type))
    {
      case 'warning':
        return 'alert alert-warning';

      case 'info':
      case 'question':
        return 'alert alert-info';
              
      case 'success':
        return 'alert alert-success';

      default:
        return 'alert alert-danger';
    }
  }

  /**
   * Returns icon for the message.
   * 
   * @return string
   */
  function GetIcon()
  {
    switch (strtolower($this->Type))
    {
      case 'warning':
        return '<span class="glyphicon glyphicon-warning-sign"></span> ';

      case 'info':
        return '<span class="glyphicon glyphicon-info-sign"></span> ';

      case 'question':
        return '<span class="glyphicon glyphicon-question-sign"></span> ';
      
      case 'success':
        return '<span class="glyphicon glyphicon-ok-sign"></span> ';

      default:
        return '<span class="glyphicon glyphicon-remove-sign"></span> ';
    }
  }
}
?>

Any public properties of the control can specify the value in the HTML, or programmatically in the Load event handler.

Programmatic access to specific controls carried out by the ID. By default, each control ID is assigned automatically. Control identifier you can manually specified to the ID property.

IDs are not checked for uniqueness!

The following example illustrates explicit definition identifiers for two instances of the Message.

<php:Message ID="MyMessage1">Message #1</php:Message>
<php:Message ID="AnyMessage">Other message</php:Message>

You can change message text for this controls in the Load event handler of the page.

function Load()
{
  $this->Controls['MyMessage1']->Content = 'The text is set programmatically.';
  $this->Controls['AnyMessage']->Content = 'and here, too';
}

Properties controls may contain links to other members or to represent the collection. And all this can be described in the markup!

For example, this site uses TabControl control, which comprises: the markup file TabControl.html.php, the class files TabControl and TabItem. The TabItem represents the TabControl. In the TabControl class, the TabItem class is an array in the Items property.

<?php
require_once 'TabItem.php';

/**
 * Represents TabControl.
 */
class TabControl extends Nemiro\UI\Control
{

  /**
   * List of tabs.
   * 
   * @var TabItem[]
   */
  public $Items = array();

}
?>
<?php
class TabItem
{

  public $Key = '';

  public $Title = '';

  public $Content = '';

}
?>
<ul class="nav nav-tabs" role="tablist">
<?php
  $i = 0;
  foreach ($this->Items as $item)
  {
?>
  <li class="<?=($i == 0 ? 'active' : '')?>"><a href="#<?=sprintf('%s_%s', $this->ID, $item->Key)?>" aria-controls="<?=sprintf('%s_%s', $this->ID, $item->Key)?>" role="tab" data-toggle="tab"><?=$item->Title?></a></li>
<?php
    $i++;
  }
?>
</ul>

<div class="tab-content">
<?php
  $i = 0;
  foreach ($this->Items as $item)
  {
?>
  <div role="tabpanel" class="<?=($i == 0 ? 'tab-pane active' : 'tab-pane')?>" id="<?=sprintf('%s_%s', $this->ID, $item->Key)?>"><?=$item->Content?></div>
<?php
    $i++;
  }
?>
</div>

In HTML, the property Items must be presented in the same name tag with nested instances of the TabItem.

The following example shows a placement instance of the TabControl on the page.

<php:TabControl>
  <php:Items>
    <php:TabItem Key="Item1" Title="Tab #1">
      Tab content #1
    </php:TabItem>
    <php:TabItem Key="Item2" Title="Tab #2">
      Tab content #2
    </php:TabItem>
    <php:TabItem Key="Item3" Title="Tab #3">
      Tab content #3
    </php:TabItem>
  </php:Items>
</php:TabControl>

Class Control

The \Nemiro\UI\Control class (hereinafter Control) represents a user control.

From the Control дclass must inherit the classes of all of user controls.

If user control do not have a class, then uses a default instance of the Control.

The following code snippet shows an inheritance Menu class from the base class Control.

<?php
class Menu extends \Nemiro\UI\Control
{

}
?>

Properties

The Control class has the following public properties.

Property Value type Description
DefaultValues Collection (key=value) Read-only. The default values collection.
Used for technical purposes.
Source String Read-only. The path to the main file of the control.
TagPrefix String Read-only. The name prefix of the control.
TagName String Read-only. The control name.
Name String Read-only. The full name, with prefix. For example: php:Message.
Parent Object Read-only. Reference to parent.
Body String The content of the user control. It is used for output to the page.
Value of the property can be overridden in a handler of the LoadComplete event.

In addition, there is a virtual property Content, which can be defined in the descendant classes.

The Content property is used as the value of the content of the control when the markup contains a closing tag for this control.

The following example shows an explicit and implicit set a value for the Content property.

<php:Message>This text is implicitly passed to the Content property.</php:Message>
<php:Message Content="This text explicitly passed to the Content property." />

Events

User controls have two events: Load and LoadComplete.

Both events take place after the event Load and before the event LoadComplete of the page.

Load

The Load event occurs before building data to output.

In this event, in theory, you can change the Source, but it is better not to do so.

Load event handler can be useful to dynamically change the values of the custom properties of the control.

The following example shows the change in value of the Content property for the stripped-down version of the Message control.

<?php
class Message extends \Nemiro\UI\Control
{

  public $Content = '';

  function Load()
  {
    $this->Content = 'Text: '.$this->Content;
  }

}
?>

LoadComplete

The LoadComplete event occurs after build the data.

In this event handler, you can change the value of the Body, which contains data about the control, prepared for the output on the page.

The following example illustrates an override the value of the Body property for the stripped-down version of the Message control.

<?php
class Message extends \Nemiro\UI\Control
{

  public $Content = '';

  function LoadComplete()
  {
    $this->Body = 'Message: '.$this->Content;
  }

}
?>

Localization

User controls do not have their own localization files. They use global resources or resources of page on which are placed.

Read more.