Location: PHPKode > projects > tgsf > tgsf-0.9.2/tgsf_core/libraries/html/tgForm.php
<?php defined( 'BASEPATH' ) or die( 'Restricted' );
/*
This code is copyright 2009-2010 by TMLA INC.  ALL RIGHTS RESERVED.
Please view license.txt in /tgsf_core/legal/license.txt or
http://tgWebSolutions.com/opensource/tgsf/license.txt
for complete licensing information.
*/

//------------------------------------------------------------------------
// form enums

// form field type
enum( 'fft',
	array(
		'Hidden'	=> 'hidden',
		'Text'		=> 'text',
		'TextArea'	=> 'textarea',
		'File'		=> 'file',
		'DropDown'	=> 'dropdown',
		'List'		=> 'list',
		'Radio'		=> 'radio',
		'Check'		=> 'checkbox',
		'Image'		=> 'image',
		'Button'	=> 'button',
		'Submit'	=> 'submit',
		'Reset'		=> 'reset',
		'Password'	=> 'password',
		'OtherTag'	=> 'other',
		'Static'	=> 'statictext'
		)
	);
define( 'FORM_AUTOCOMPLETE_ON', true );
define( 'FORM_AUTOCOMPLETE_OFF', false );

load_library( 'html/tgsfHtmlTag', IS_CORE_LIB );
//------------------------------------------------------------------------
/**
* form class
*/
abstract class tgsfForm extends tgsfHtmlTag
{
	protected	$_fields		= array();
	protected	$_fieldsByName	= array();
	protected	$_template		= null;
	protected	$_validator		= null;
	protected	$_ro_ds			= null;
	protected	$_processor		= '';
	protected	$_ro_valid		= true;
	protected	$_groupName		= '_main';
	protected	$_ro_setup		= false;
	protected	$_ro_autocomplete	= false;
	//------------------------------------------------------------------------
	public		$errors			= array();
	/**
	* not used yet - why do we need to reuse a form object?
	*/
 	private function _reset()
	{
		throw new tgsfFormException( 'Form resetting not allowed.' );
		/*
		$this->_fields			= array();
		$this->_fieldsByName	= array()
		$this->_template		= null;
		$this->_validator		= null;
		$this->_errors			= array();
		$this->_ro_ds			= null;
		$this->_id				= '';
		$this->_processor		= '';
		$this->_ro_setup		= false;
		*/
	}
	//------------------------------------------------------------------------
	abstract protected function _setup();
	abstract protected function _setupValidate( &$v );
	/* abstract */ public function onLabel( &$label ){}
	/* abstract */ public function onField( &$field ){}
	/* abstract */ public function onSelectOption( &$field ){}
	/* abstract */ public function onGroupContainer( &$container, $groupName ){}

	//------------------------------------------------------------------------

	public function __construct()
	{
		parent::__construct( 'form' );
		$this->setAttribute( 'method', 'POST' );
	}
	//------------------------------------------------------------------------
	/**
	*
	*/
	public function autocomplete( $on = true )
	{
		$this->removeAttribute( 'autocomplete' );
		$this->_ro_autocomplete = $on;
		if ( $on === false )
		{
			$this->addAttribute( 'autocomplete', 'off' );
		}
	}
	//------------------------------------------------------------------------
	protected function useTemplate( $template, $core = true )
	{
		if ( is_object( $template ) && $template instanceof tgsfFormTemplate )
		{
			$this->_template = $template;
		}
		else
		{
			$this->_template = load_template_library( 'form/' . $template, $core );
		}
	}
	//------------------------------------------------------------------------
	protected function &_getValidator()
	{
		if ( $this->_validator === null )
		{
			load_library( 'validate/tgsfValidate',			IS_CORE_LIB );
			load_library( 'validate/tgsfValidateField',		IS_CORE_LIB );
			load_library( 'validate/tgsfValidateRule',		IS_CORE_LIB );
			$this->_validator = new tgsfValidate();
			$this->_validator->setForm( $this );
			$this->_setupValidate( $this->_validator );
		}

		return $this->_validator;
	}
	//------------------------------------------------------------------------
	public function &validator()
	{
		return $this->_getValidator();
	}
	//------------------------------------------------------------------------
	/**
	* Sets a datasource for this form.
	* @param a datasource object - either a db datasource or an http post datasource
	*/
	public function &ds( &$ds )
	{
		$this->_ro_ds =& $ds;
		return $this;
	}
	//------------------------------------------------------------------------
	public function &_( $type )
	{
		$field = new tgsfFormField( $type );
		$field->useTemplate( $this->_template );
		$field->useGroup( $this->_groupName );
		$field->form =& $this;
		$this->_fields[] =& $field;
		return $field;
	}
	//------------------------------------------------------------------------
	/**
	* Not a public API, only to be used by the field object to link itself back when its name has been set
	*/
	public function _addByName( &$field )
	{
		$this->_fieldsByName[$field->name] =& $field;
		return false; // trickery
	}
	//------------------------------------------------------------------------
	/**
	* Returns a field object for the given name
	* @param String The name of the field.  Using $this->_( fftText )->name( 'fieldName' ); is required.
	* in other words, you must name a field for it to be available to this function.
	* Using this allows you to output a form one field at a time.
	* Example: $form = load_form( 'example' );
	* echo $form->fieldByName( 'example_field' )->getLabelTag()->render();
	* echo $form->fieldByName( 'example_field' )->getFieldTag()->render();
	*/
	public function &fieldByName( $name )
	{
		if ( $this->_ro_setup === false )
		{
			$this->_setup();
			$this->_ro_setup = true;
		}

		return $this->_fieldsByName[$name];
	}
	//------------------------------------------------------------------------
	/**
	* Keeps track of the current group - template renderers can make choices based on groups
	* @param String The name of a group
	*/
	public function startGroup( $name )
	{
		$this->_groupName = $name;
	}
	//------------------------------------------------------------------------
	/**
	* Sets the processing URL
	* @param String The url of the form's processor
	*/
	public function processor( $url )
	{
		$this->setAttribute( 'action', $url );
	}
	//------------------------------------------------------------------------
	/**
	*
	*/
	public function renderTagOnly()
	{
		if ( $this->_ro_setup === false )
		{
			$this->_setup();
			$this->_ro_setup = true;
		}
		return parent::renderTagOnly();
	}
	//------------------------------------------------------------------------
	/**
	*
	*/
	public function __toString()
	{
		return $this->render();
	}
	//------------------------------------------------------------------------
	/*
	* Renders a form
	*@param Bool True = only return html
	*/
	public function render()
	{
		if ( $this->_ro_setup === false )
		{
			$this->_setup();
			$this->_ro_setup = true;
		}

		if ( empty($this->_fields) )
		{
			throw new tgsfFormException( 'The form has no fields.' );
		}

		$curGroup = $this->_fields[0]->group;
		$container = $this->_template->fieldContainer( $this, $curGroup );
		$this->onGroupContainer( $container, $curGroup );

		foreach ( $this->_fields as &$field )
		{
			if ( $field->group != $curGroup )
			{
				$container = $this->_template->fieldContainer( $this, $field->group );
				$this->onGroupContainer( $container, $field->group );
			}
			$curGroup = $field->group;

			$field->setError( $this->errors );
			$field->render( $container );
		}

	 	$html = parent::render();
		$this->_children = array();
		$this->_ro_content = '';
		//$html .= $this->renderJsValidation();
		return $html;
	}
	//------------------------------------------------------------------------
	/**
	*
	*/
	public function renderJsValidation()
	{
		$v = $this->_getValidator();

		$s = new tgsfHtmlTag( 'script' );
		$s->type = "text/javascript";
		$v->jsOutput( $s );
		return $s;
	}
	//------------------------------------------------------------------------
	/**
	* Forces a valid/invalid condition on the form.
	* @param Bool - Use defines from validate/tgsfValidate.php  FORCE_VALID, FORCE_INVALID
	*/
	protected function forceValid( $value )
	{
		$this->_ro_valid = $value;
		$this->errors = array();
	}
	//------------------------------------------------------------------------
	public function validate()
	{
		if ( $this->_ro_setup === false )
		{
			$this->_setup();
			$this->_ro_setup = true;
		}

		if ( $this->_ro_ds === null )
		{
			throw new tgsfFormException( 'The form has no datasource to validate with.' );
		}

		$v = $this->_getValidator();

		if ( $this->_validator->execute( $this->_ro_ds ) === false )
		{
			$this->errors = $this->_validator->errors;
			$this->_ro_valid = false;
		}

		$this->validateForm( $this->_ro_ds, $v );
		
		return $this->_ro_valid;
	}
	//------------------------------------------------------------------------
	/**
	* Overwrite this function in extending classes to do a form-level validation
	*/
	public function validateForm( &$ds, &$v )
	{
		// empty
	}
}
//------------------------------------------------------------------------
// Abstract form template class defines the methods a form template class must implement
//------------------------------------------------------------------------
abstract class tgsfFormTemplate extends tgsfBase
{
	protected $_field;
	//------------------------------------------------------------------------

	public function hidden( &$field, &$container )
	{
		$container->addTag( $field->tag );
	}

	abstract public function fieldContainer(  &$form, $group = '' );

	abstract public function dropdown(	&$field, &$container );
	abstract public function file(		&$field, &$container );
	abstract public function text(		&$field, &$container );
	abstract public function textArea(	&$field, &$container );
	abstract public function radio(		&$field, &$container );
	abstract public function checkbox(	&$field, &$container );
	abstract public function image(		&$field, &$container );
	abstract public function button(	&$field, &$container );
	abstract public function submit(	&$field, &$container );
	abstract public function reset(		&$field, &$container );
	abstract public function password(	&$field, &$container );
	abstract public function other(		&$field, &$container );
}
Return current item: tgsf