Emmanuel BENOîT
cdb2e952f5
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.
135 lines
3.6 KiB
PHP
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;
|
|
}
|
|
}
|