Source for file BootstrapFormBuilder.php
Documentation is available at BootstrapFormBuilder.php
namespace
Adianti \
Wrapper ;
use
Adianti \
Widget \
Form \
TField ;
use
Adianti \
Widget \
Form \
TForm ;
use
Adianti \
Widget \
Form \
TLabel ;
* Bootstrap form builder for Adianti Framework
* @author Pablo Dall'Oglio
* @copyright Copyright (c) 2006 Adianti Solutions Ltd. (http://www.adianti.com.br)
* @license http://www.adianti.com.br/framework-license
private $header_properties ;
private $client_validation ;
private $csrf_validation ;
$this -> decorated =
new TForm ( $name ) ;
$this -> tabcurrent =
NULL ;
$this -> header_actions =
array ( ) ;
$this -> actions =
array ( ) ;
$this -> id =
'bform_' .
mt_rand ( 1000000000 , 1999999999 ) ;
$this -> field_sizes =
null ;
$this -> automatic_aria =
false ;
$this -> client_validation =
false ;
$this -> csrf_validation =
false ;
$this -> column_classes =
array ( ) ;
$this -> column_classes [ 1 ] =
[ 'col-sm-12' ] ;
$this -> column_classes [ 2 ] =
[ 'col-sm-4 col-lg-2' , 'col-sm-8 col-lg-10' ] ;
$this -> column_classes [ 3 ] =
[ 'col-sm-4 col-lg-2' , 'col-sm-4' , 'col-sm-2' ] ;
$this -> column_classes [ 4 ] =
[ 'col-sm-4 col-lg-2' , 'col-sm-8 col-lg-4' , 'col-sm-4 col-lg-2' , 'col-sm-8 col-lg-4' ] ;
$this -> column_classes [ 5 ] =
[ 'col-sm-2' , 'col-sm-2' , 'col-sm-2' , 'col-sm-2' , 'col-sm-2' ] ;
$this -> column_classes [ 6 ] =
[ 'col-sm-2' , 'col-sm-2' , 'col-sm-2' , 'col-sm-2' , 'col-sm-2' , 'col-sm-2' ] ;
$this -> column_classes [ 7 ] =
[ 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' ] ;
$this -> column_classes [ 8 ] =
[ 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' ] ;
$this -> column_classes [ 9 ] =
[ 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' ] ;
$this -> column_classes [ 10 ] =
[ 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' ] ;
$this -> column_classes [ 11 ] =
[ 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' ] ;
$this -> column_classes [ 12 ] =
[ 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' , 'col-sm-1' ] ;
* Turn on/off client validation
$this -> client_validation =
$bool ;
$this -> csrf_validation =
true ;
public function addExpandButton ( $label =
null , $icon =
null , $start_hidden =
true )
$button =
new TButton ( $form_name .
'_show_hide' ) ;
$button -> { 'class' } =
'btn btn-info btn-sm active' ;
$button -> setLabel ( $label ??
AdiantiCoreTranslator :: translate ( 'Expand' )) ;
$button -> setImage ( $icon ??
'fa:search' ) ;
$button -> addFunction ( " \$('[name={
$form_name } ]').slideToggle('fast'); $(this).toggleClass( 'active' )
" ) ;
$this -> addHeaderWidget ( $button ) ;
$this -> decorated -> setProperty ( 'style' , 'display:none' ) ;
* Generate automatic aria-labels
$this -> automatic_aria = true ;
$this -> field_sizes = $size ;
* @param $title Form title
$this -> padding = $padding ;
* Define the current page to be shown
* @param $i An integer representing the page number (start at 0)
$this -> current_page = $i ;
* Redirect calls to decorated object
public function __call ( $method , $parameters )
* Redirect assigns to decorated object
public function __set ( $property , $value )
return $this -> decorated -> $property = $value ;
* Define a style property
* @param $name Property Name
* @param $value Property Value
$this -> properties [ $name ] = $value ;
* Define a header style property
* @param $name Property Name
* @param $value Property Value
$this -> header_properties [ $name ] = $value ;
return $this -> decorated -> setName ( $name ) ;
return $this -> decorated -> getName ( ) ;
* @param $field Form field
public function addField ( AdiantiWidgetInterface $field )
return $this -> decorated -> addField ( $field ) ;
* @param $field Form field
public function delField ( AdiantiWidgetInterface $field )
return $this -> decorated -> delField ( $field ) ;
* @param $fields Array of Form fields
* @param $name Field name
return $this -> decorated -> getField ( $name ) ;
public function clear ( $keepDefaults = FALSE )
return $this -> decorated -> clear ( $keepDefaults ) ;
* @param $object Data object
return $this -> decorated -> setData ( $object ) ;
* @param $class Object type of return data
public function getData ( $class = 'StdClass' )
return $this -> decorated -> getData ( $class ) ;
if ( $this -> csrf_validation )
if ( ! hash_equals ( $_POST [ 'csrf_token' ] , <a href="registry/TSession.html">TSession</a> :: getValue ( 'csrf_token_' .$this -> name .'_before' )))
throw new Exception ( <a href="core/AdiantiCoreTranslator.html">AdiantiCoreTranslator</a> :: translate ( 'CSRF Error' )) ;
* @param $title Tab title
$this -> tabcurrent = $title ;
$this -> tabcontent [ $title ] = array ( ) ;
$this -> tabFunction = $function ;
* Define the action for the Notebook tab
* @param $action Action taken when the user
* clicks over Notebook tab (A TAction object)
$this -> tabAction = $action ;
* @param mixed $fields,... Form fields
// object that represents a row
$row -> { 'content' } = $args ;
$row -> { 'type' } = 'fields' ;
$this -> tabcontent [ $this -> tabcurrent ] [ ] = $row ;
foreach ( $slot as $content )
if ( $content instanceof <a href="widget/form/AdiantiWidgetInterface.html">AdiantiWidgetInterface</a> )
if ( $content instanceof <a href="wrapper/BootstrapFormBuilder.html">BootstrapFormBuilder</a> )
$content -> setTagName ( 'div' ) ;
// return, because the user may fill aditional attributes
* @param mixed $content,... Form content
// object that represents a row
$row -> { 'content' } = $args ;
$row -> { 'type' } = 'content' ;
$this -> tabcontent [ $this -> tabcurrent ] [ ] = $row ;
if ( ! empty ( $slot ) && $slot instanceof <a href="wrapper/BootstrapFormBuilder.html">BootstrapFormBuilder</a> )
$slot -> setTagName ( 'div' ) ;
// return, because the user may fill aditional attributes
* @param $args Array of arguments
* @param $method Generator method
throw new Exception ( <a href="core/AdiantiCoreTranslator.html">AdiantiCoreTranslator</a> :: translate ( 'Method ^1 must receive a parameter of type ^2' , $method , 'Array' )) ;
* @param $label Button label
* @param $action Button action
* @param $icon Button icon
public function addAction ( $label , TAction $action , $icon = 'fa:save' )
$label_info = ( $label instanceof <a href="widget/form/TLabel.html">TLabel</a> ) ? $label -> getValue ( ) : $label ;
$button = new <a href="widget/form/TButton.html">TButton</a> ( $name ) ;
// define the button action
$button -> setAction ( $action , $label ) ;
$button -> setImage ( $icon ) ;
$this -> actions [ ] = $button ;
* @param $label Button label
* @param $action Button action
* @param $icon Button icon
public function addActionLink ( $label , TAction $action , $icon = 'fa:save' )
$label_info = ( $label instanceof <a href="widget/form/TLabel.html">TLabel</a> ) ? $label -> getValue ( ) : $label ;
$button = new <a href="widget/util/TActionLink.html">TActionLink</a> ( $label_info , $action , null , null , null , $icon ) ;
$button -> { 'class' } = 'btn btn-sm btn-default' ;
$this -> actions [ ] = $button ;
* Add a form header action
* @param $label Button label
* @param $action Button action
* @param $icon Button icon
public function addHeaderAction ( $label , TAction $action , $icon = 'fa:save' )
$label_info = ( $label instanceof <a href="widget/form/TLabel.html">TLabel</a> ) ? $label -> getValue ( ) : $label ;
$button = new <a href="widget/form/TButton.html">TButton</a> ( $name ) ;
// define the button action
$button -> setAction ( $action , $label ) ;
$button -> setImage ( $icon ) ;
$this -> header_actions [ ] = $button ;
* Add a form header widget
$this -> header_actions [ ] = $widget ;
* Add a form footer widget
$this -> actions [ ] = $widget ;
* Add a form header action
* @param $label Button label
* @param $action Button action
* @param $icon Button icon
$label_info = ( $label instanceof <a href="widget/form/TLabel.html">TLabel</a> ) ? $label -> getValue ( ) : $label ;
$button = new <a href="widget/util/TActionLink.html">TActionLink</a> ( $label_info , $action , null , null , null , $icon ) ;
$button -> { 'class' } = 'btn btn-sm btn-default' ;
$this -> header_actions [ ] = $button ;
* @param $label Button label
* @param $action JS Button action
* @param $icon Button icon
public function addButton ( $label , $action , $icon = 'fa:save' )
$label_info = ( $label instanceof <a href="widget/form/TLabel.html">TLabel</a> ) ? $label -> getValue ( ) : $label ;
$button = new <a href="widget/form/TButton.html">TButton</a> ( $name ) ;
if ( strstr ( $icon , '#' ) !== FALSE )
$button -> { 'style' } = " color: #{
$color } " ;
// define the button action
$button -> addFunction ( $action ) ;
$button -> setLabel ( $label ) ;
$button -> setImage ( $icon ) ;
$this -> actions [ ] = $button ;
public function delActions ( )
foreach ( $this -> actions as $key => $button )
unset( $this -> actions [ $key ] ) ;
* Return an array with action buttons
public function getActionButtons ( )
public function setColumnClasses ( $key , $classes )
$this -> column_classes [ $key ] = $classes ;
if ( $this -> csrf_validation )
$csrf_token = new THidden ( 'csrf_token' ) ;
$csrf_token -> setValue ( <a href="registry/TSession.html">TSession</a> :: getValue ( 'csrf_token_' .$this -> name )) ;
$this -> decorated -> silentField ( 'csrf_token' ) ;
$this -> decorated -> { 'class' } = 'form-horizontal' ;
$this -> decorated -> { 'type' } = 'bootstrap' ;
$panel = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$panel -> { 'class' } = 'card panel' ;
$panel -> { 'style' } = 'width: 100%' ;
$panel -> { 'widget' } = 'bootstrapformbuilder' ;
$panel -> { 'form' } = $this -> name ;
$panel -> { 'id' } = $this -> id ;
foreach ( $this -> properties as $property => $value )
$panel -> $property = $value ;
if ( ! empty ( $this -> title ) || count ( $this -> header_actions ) > 0 )
$heading = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$heading -> { 'class' } = 'card-header panel-heading' ;
$heading -> add ( <a href="widget/base/TElement.html">TElement</a> :: tag ( 'div' , $this -> title , [ 'class' =>'panel-title card-title' ] )) ;
if ( $this -> header_properties )
foreach ( $this -> header_properties as $property => $value )
if ( isset( $heading -> $property ))
$heading -> $property .= ' ' . $value ;
$heading -> $property = $value ;
if ( $this -> header_actions )
$title_actions = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$title_actions -> { 'class' } = 'header-actions' ;
$title_actions -> { 'style' } = 'float:right' ;
$heading -> add ( $title_actions ) ;
foreach ( $this -> header_actions as $action_button )
$title_actions -> add ( $action_button ) ;
$body = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$body -> { 'class' } = 'card-body panel-body' ;
$body -> { 'style' } = 'width: 100%' ;
$panel -> add ( $this -> decorated ) ;
$this -> decorated -> add ( $body ) ;
if ( $this -> tabcurrent !== null )
$tabs = new <a href="widget/base/TElement.html">TElement</a> ( 'ul' ) ;
$tabs -> { 'class' } = 'nav nav-tabs' ;
$tabs -> { 'role' } = 'tablist' ;
foreach ( $this -> tabcontent as $tab => $rows )
$class = ( $tab_counter == $this -> current_page ) ? 'active' : '' ;
$tab_li = new <a href="widget/base/TElement.html">TElement</a> ( 'li' ) ;
$tab_li -> { 'role' } = 'presentation' ;
$tab_li -> { 'class' } = $class . " nav-item" ;
$tab_link = new <a href="widget/base/TElement.html">TElement</a> ( 'a' ) ;
$tab_link -> { 'href' } = " #tab_{
$this -> id } _{
$tab_counter } " ;
$tab_link -> { 'role' } = 'tab' ;
$tab_link -> { 'data-toggle' } = 'tab' ;
$tab_link -> { 'aria-expanded' } = 'true' ;
$tab_link -> { 'class' } = "nav-link " . $class ;
$tab_link -> { 'onclick' } = $this -> tabFunction ;
$tab_link -> { 'data-current_page' } = $tab_counter ;
$this -> tabAction -> setParameter ( 'current_page' , $tab_counter ) ;
$string_action = $this -> tabAction -> serialize ( FALSE ) ;
$tab_link -> { 'onclick' } = " __adianti_ajax_exec('
$string_action ')
" ;
$tab_link -> add ( TElement :: tag ( 'span' , $tab , [ 'class' =>'tab-name' ] )) ;
$content = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$content -> { 'class' } = 'tab-content' ;
foreach ( $this -> tabcontent as $tab => $rows )
$tabpanel = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$tabpanel -> { 'role' } = 'tabpanel' ;
$tabpanel -> { 'class' } = 'tab-pane ' . ( ( $tab_counter == $this -> current_page ) ? 'active' : '' ) ;
$tabpanel -> { 'style' } = 'padding:10px; margin-top: -1px;' ;
$tabpanel -> { 'style' } .= 'border: 1px solid #DDDDDD' ;
$tabpanel -> { 'id' } = " tab_{
$this -> id } _{
$tab_counter } " ;
$content -> add ( $tabpanel ) ;
$slots = $row -> { 'content' } ;
$form_group = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$form_group -> { 'class' } = 'form-group tformrow row' . ' ' . ( isset( $row -> { 'class' } ) ? $row -> { 'class' } : '' ) ;
$tabpanel -> add ( $form_group ) ;
if ( isset( $row -> { 'style' } ))
$form_group -> { 'style' } = $row -> { 'style' } ;
$slot_counter = count ( $slots ) ;
foreach ( $slots as $slot )
$label_css = (( count ( $slots ) >1 ) AND ( count ( $slot ) ==1 ) AND $slot [ 0 ] instanceof <a href="widget/form/TLabel.html">TLabel</a> AND empty ( $row -> layout )) ? ' col-form-label control-label' : '' ;
$column_class = ( ! empty ( $row -> layout ) ? $row -> layout [ $row_counter ] : $this -> column_classes [ $slot_counter ] [ $row_counter ] ) ;
$slot_wrapper = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$slot_wrapper -> { 'class' } = $column_class . ' fb-field-container ' .$label_css ;
$slot_wrapper -> { 'style' } = 'min-height:26px' ;
$form_group -> add ( $slot_wrapper ) ;
// one field per slot do not need to be wrapped
foreach ( $slot as $field )
$field_wrapper = self :: wrapField ( $field , 'inherit' , $this -> field_sizes ) ;
$slot_wrapper -> add ( $field_wrapper ) ;
if ( ! $field instanceof <a href="widget/form/THidden.html">THidden</a> )
if ( $field instanceof <a href="widget/form/TLabel.html">TLabel</a> )
$aria_label = $field -> getValue ( ) ;
$aria_id = $field -> getId ( ) ;
if ( $this -> automatic_aria && ! empty ( $aria_label ) && ! $field instanceof <a href="widget/form/TLabel.html">TLabel</a> && $field instanceof <a href="widget/form/TField.html">TField</a> )
$field -> { 'aria-label' } = $aria_label ;
$field -> { 'aria-labelledby' } = $aria_id ;
if ( $field instanceof <a href="widget/form/TField.html">TField</a> && $field -> isRequired ( ))
$field -> { 'aria-required' } = 'true' ;
else // more fields must be wrapped
foreach ( $slot as $field )
$field_wrapper = self :: wrapField ( $field , 'inline-block' , $this -> field_sizes ) ;
if ( ( $field_counter +1 < count ( $slot )) and ( ! $field instanceof <a href="widget/wrapper/TDBSeekButton.html">TDBSeekButton</a> ) ) // padding less last element
$field_wrapper -> { 'style' } .= ';padding-right: ' .$this -> padding .'px;' ;
$slot_wrapper -> add ( $field_wrapper ) ;
if ( ! $field instanceof <a href="widget/form/THidden.html">THidden</a> )
if ( $field instanceof <a href="widget/form/TLabel.html">TLabel</a> )
$aria_label = $field -> getValue ( ) ;
$aria_id = $field -> getId ( ) ;
if ( $this -> automatic_aria && ! empty ( $aria_label ) && ! $field instanceof <a href="widget/form/TLabel.html">TLabel</a> && $field instanceof <a href="widget/form/TField.html">TField</a> )
$field -> { 'aria-label' } = $aria_label ;
$field -> { 'aria-labelledby' } = $aria_id ;
if ( $field instanceof <a href="widget/form/TField.html">TField</a> && $field -> isRequired ( ))
$field -> { 'aria-required' } = 'true' ;
if ( $row_visual_widgets == 0 )
$form_group -> { 'style' } = 'display:none' ;
$footer = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$footer -> { 'class' } = 'panel-footer card-footer' ;
$footer -> { 'style' } = 'width: 100%' ;
$this -> decorated -> add ( $footer ) ;
foreach ( $this -> actions as $action_button )
$footer -> add ( $action_button ) ;
if ( ! $this -> client_validation )
public static function wrapField ( $field , $display , $default_field_size = null )
$object = $field ; // BC Compability
$has_underline = ( ! $field instanceof <a href="widget/form/TLabel.html">TLabel</a> && ! $field instanceof <a href="widget/form/TRadioGroup.html">TRadioGroup</a> && ! $field instanceof <a href="widget/form/TCheckGroup.html">TCheckGroup</a> && ! $field instanceof <a href="widget/form/TButton.html">TButton</a> && ! $field instanceof <a href="widget/form/THidden.html">THidden</a> && ! $field instanceof <a href="widget/form/TSlider.html">TSlider</a> && ! $field instanceof <a href="widget/form/TCheckButton.html">TCheckButton</a> ) ;
$field_wrapper = new <a href="widget/base/TElement.html">TElement</a> ( 'div' ) ;
$field_wrapper -> { 'class' } = 'fb-inline-field-container ' . ((( $field instanceof <a href="widget/form/TField.html">TField</a> ) and ( $has_underline )) ? 'form-line' : '' ) ;
$field_wrapper -> { 'style' } = " display: {
$display } ;vertical-align:top;
" . ( $display =='inline-block' ?'float:left' :'' ) ;
if ( ! empty ( $default_field_size ))
$field_size [ 0 ] = $default_field_size ;
$field_size = $default_field_size ;
if ( $field instanceof <a href="widget/form/TField.html">TField</a> || $field instanceof <a href="widget/form/TCheckList.html">TCheckList</a> )
$height = $field_size [ 1 ] ;
$field_wrapper -> { 'style' } .= ( ( strpos ( $width , '%' ) !== FALSE ) ? ';width: ' . $width : ';width: ' . $width .'px' ) ;
if ( ! $object instanceof <a href="widget/form/THtmlEditor.html">THtmlEditor</a> )
$field_wrapper -> { 'style' } .= ( ( strpos ( $height , '%' ) !== FALSE ) ? ';height: ' . $height : ';height: ' . $height .'px' ) ;
else if ( $field_size && ! $object instanceof <a href="widget/form/TRadioGroup.html">TRadioGroup</a> AND ! $object instanceof <a href="widget/form/TCheckGroup.html">TCheckGroup</a> )
$field_wrapper -> { 'style' } .= ( ( strpos ( $field_size , '%' ) !== FALSE ) ? ';width: ' .$field_size : ';width: ' .$field_size .'px' ) ;
if ( is_callable ( [ $object , 'getAfterElement' ] ) && $object -> getAfterElement ( ))
$field_wrapper -> { 'style' } .= ';display:inline-table' ;
$field_wrapper -> add ( $field ) ;
if ( $field instanceof <a href="widget/form/AdiantiWidgetInterface.html">AdiantiWidgetInterface</a> )
$input_class = 'form-control' ;
if ( $field instanceof <a href="widget/form/TLabel.html">TLabel</a> || $field instanceof <a href="widget/form/TCheckButton.html">TCheckButton</a> )
else if ( $field instanceof <a href="widget/form/TButton.html">TButton</a> )
$input_class = empty ( $field -> { 'class' } ) ? 'btn btn-default btn-sm' : '' ;
$field_class = $input_class . ' ' . ( isset( $field -> { 'class' } ) ? $field -> { 'class' } : '' ) ;
$field -> { 'class' } = $field_class ;
if ( in_array ( $object -> getProperty ( 'widget' ) , [ 'tmultisearch' , 'tdbmultisearch' , 'thtmleditor' , 'tmultientry' ] ))
$object -> setSize ( '100%' , $field_size [ 1 ] - 3 ) ;
else if ( ( $field_size ) AND ! ( $object instanceof <a href="widget/form/TRadioGroup.html">TRadioGroup</a> || $object instanceof <a href="widget/form/TCheckGroup.html">TCheckGroup</a> ))
$object -> setSize ( '100%' , '100%' ) ;
public static function showField ( $form , $field , $speed = 0 )
<a href="widget/base/TScript.html">TScript</a> :: create ( " tform_show_field('{
$form } ', '{
$field } ', {
$speed } )
" ) ;
public static function hideField ( $form , $field , $speed = 0 )
TScript :: create ( " tform_hide_field('{
$form } ', '{
$field } ', {
$speed } )
" ) ;
* Converts the object into a string
public function __toString ( )
return $this -> getContents ( ) ;
* Returns the element content as a string
public function getContents ( )
$content = ob_get_contents ( ) ;