arse/includes/form/view.inc.php
Emmanuel BENOîT cdb2e952f5 Form fields clean-up
Added a FieldView interface which must be implemented by field
renderers. The form's main view will look for FieldView implementations
to determine how to render specific field types. The only exception are
hidden fields, which are handled separately.
2012-02-07 09:27:46 +01:00

135 lines
3.6 KiB
PHP

<?php
class View_Form
extends BaseURLAwareView
{
protected $form;
protected $fieldTypes;
public function __construct( Form $form )
{
$this->form = $form;
}
protected function renderHiddenFields( $prefix )
{
$result = array( );
foreach ( $this->form->fields( ) as $field ) {
if ( $field === null || $field->type( ) !== 'hidden' ) {
continue;
}
array_push( $result , HTML::make( 'input' )
->setAttribute( 'type' , 'hidden' )
->setAttribute( 'name' , $field->name( ) )
->setAttribute( 'value' , HTML::from( $field->value( ) ) )
->setAttribute( 'id' , $prefix . $field->name( ) ) );
}
return $result;
}
protected function renderField( $field , $prefix )
{
$type = $field->type( );
if ( array_key_exists( $type , $this->fieldTypes ) ) {
return $this->fieldTypes[ $type ]->render( $field , $prefix );
}
throw new Exception( "field " . $field->name() . " has unknown type " . $field->type() );
}
private function loadFieldTypes( )
{
$types = Loader::Find( 'FieldView' );
$loaded = array( );
foreach ( $types as $type ) {
$instance = Loader::Create( $type );
$loaded[ $instance->getFieldType( ) ] = $instance;
}
$this->fieldTypes = $loaded;
}
protected function renderVisibleFields( $target , $prefix )
{
$this->loadFieldTypes( );
foreach ( $this->form->fields( ) as $field ) {
if ( $field === null ) {
$target->appendElement( HTML::make( 'hr' ) );
continue;
}
if ( $field->type( ) === 'hidden' ) {
continue;
}
$fPrefix = $prefix . $field->name( ) . '-';
if ( $field->type( ) === 'html' ) {
$target->appendElement( HTML::make( 'dd' )
->setAttribute( 'id' , $fPrefix )
->setAttribute( 'class' , 'html-section' )
->append( $field->value( ) ) );
continue;
}
$fClass = 'field' . ( $field->mandatory( ) ? ' mandatory' : '' );
$target->appendElement( HTML::make( 'dt' )
->setAttribute( 'class' , $fClass )
->setAttribute( 'id' , $fPrefix . 'label' )
->appendElement( HTML::make( 'label' )
->setAttribute( 'for' , $fPrefix . 'field' )
->appendText( $field->description( ) ) ) );
$errors = $field->errors( );
if ( !empty( $errors ) ) {
foreach ( $errors as $error ) {
$target->appendElement( HTML::make( 'dd' )
->setAttribute( 'class' , 'form-error' )
->appendText( $error ) );
}
$fClass .= ' erroneous';
}
$target->appendElement( HTML::make( 'dd' )
->setAttribute( 'id' , $fPrefix . 'container' )
->setAttribute( 'class' , $fClass )
->append( $this->renderField( $field , $fPrefix ) ) );
}
}
public function render( )
{
$name = $this->form->name();
$prefix = $name . '-';
$action = $this->form->action( );
if ( $action{0} != '?' ) {
if ( $action{0} != '/' ) {
$action = "/$action";
}
$action = $this->base . $action;
}
$form = HTML::make( 'form' )
->setAttribute( 'name' , $name )
->setAttribute( 'id' , $prefix . 'form' )
->setAttribute( 'action' , $action )
->setAttribute( 'method' , $this->form->method( ) )
->append( $this->renderHiddenFields( $prefix ) )
->append( $visibleArea = HTML::make( 'dl' ) );
$this->renderVisibleFields( $visibleArea , $prefix );
$visibleArea->appendElement( HTML::make( 'dt' )
->setAttribute( 'class' , 'submit-button' )
->setAttribute( 'id' , $prefix . 'submit-container' )
->appendElement( HTML::make( 'input' )
->setAttribute( 'type' , 'submit' )
->setAttribute( 'name' , $prefix . 'submit' )
->setAttribute( 'id' , $prefix . 'submit' )
->setAttribute( 'value' , $this->form->buttonTitle( ) ) ) );
return $form;
}
}