1、TbActiveForm.php文件
分析:TbActiveForm的type属性的不同,通过getInputClassName()会引用不同的文件
Yii
:
:import(
'bootstrap.widgets.input.TbInput');
/**
* Bootstrap active form widget.
*/
class TbActiveForm extends CActiveForm
{
// Form types.
const TYPE_VERTICAL = 'vertical';
const TYPE_INLINE = 'inline';
const TYPE_HORIZONTAL = 'horizontal';
const TYPE_SEARCH = 'search';
// Input classes.
const INPUT_HORIZONTAL = 'bootstrap.widgets.input.TbInputHorizontal';
const INPUT_INLINE = 'bootstrap.widgets.input.TbInputInline';
const INPUT_SEARCH = 'bootstrap.widgets.input.TbInputSearch';
const INPUT_VERTICAL = 'bootstrap.widgets.input.TbInputVertical';
/**
* Bootstrap active form widget.
*/
class TbActiveForm extends CActiveForm
{
// Form types.
const TYPE_VERTICAL = 'vertical';
const TYPE_INLINE = 'inline';
const TYPE_HORIZONTAL = 'horizontal';
const TYPE_SEARCH = 'search';
// Input classes.
const INPUT_HORIZONTAL = 'bootstrap.widgets.input.TbInputHorizontal';
const INPUT_INLINE = 'bootstrap.widgets.input.TbInputInline';
const INPUT_SEARCH = 'bootstrap.widgets.input.TbInputSearch';
const INPUT_VERTICAL = 'bootstrap.widgets.input.TbInputVertical';
由以上代码可知,需要更改的文件有
TbInput TbInputHorizontal TbInputInline TbInputSearch TbInputVertical,对应于以下文件
2、
TbInput 文件添加以下代码
分析:此类为抽象类,所以不能被实例化。调用抽象类必定是写子类实例出对象。在第三段代码中调用此抽象方法有很高的重用性,不用管
Vertical、Horizontal这些参数设置。由于为
抽象方法(效果如同接口interface),子类
TbInputVertical TbInputHorizontal TbInputInline TbInputSearch
中则必须重写datetimepickerField()的具体方法。
TbInput 继承于 CInputWidget 继承于 Widget 含有getController()方法 继承于 CBaseController 继承于 CComponent
base
文件夹中
//新添加datetimepicker
const TYPE_DATETIMEPICKER = 'datetimepicker';
const TYPE_DATETIMEPICKER = 'datetimepicker';
abstract
protected
function datetimepickerField();
case self
:
:TYPE_DATETIMEPICKER
:
$this - >datetimepickerField();
break;
$this - >datetimepickerField();
break;
3、
TbInputHorizontal TbInputVertical文件添加以下代码
分析:
TbInputHorizontal TbInputVertical 继续于TbInput,datetimepickerField()重写抽象父类中的此抽象方法
TbInputInline继承于TbInputVertical TbInputSearch继承于TbInputInline
因此都不需要添加
protected
function datetimepickerField()
{
if ( isset($this - >htmlOptions[ 'options']))
{
$options = $this - >htmlOptions[ 'options'];
unset($this - >htmlOptions[ 'options']);
}
echo $this - >getLabel();
echo '<div class="controls">';
echo $this - >getPrepend();
$this - >widget( 'bootstrap.widgets.TbDateTimePicker', array(
'model' = > $this - >model,
'attribute' = > $this - >attribute,
'options' = > isset($options) ? $options : array(),
'htmlOptions' = > $this - >htmlOptions,
));
echo $this - >getAppend();
echo $this - >getError() . $this - >getHint();
echo '</div>';
}
{
if ( isset($this - >htmlOptions[ 'options']))
{
$options = $this - >htmlOptions[ 'options'];
unset($this - >htmlOptions[ 'options']);
}
echo $this - >getLabel();
echo '<div class="controls">';
echo $this - >getPrepend();
$this - >widget( 'bootstrap.widgets.TbDateTimePicker', array(
'model' = > $this - >model,
'attribute' = > $this - >attribute,
'options' = > isset($options) ? $options : array(),
'htmlOptions' = > $this - >htmlOptions,
));
echo $this - >getAppend();
echo $this - >getError() . $this - >getHint();
echo '</div>';
}
4、TbActiveForm.php文件添加以下代码
分析:当调用$form->datetimepickerRow($model, $attribute, $htmlOptions = array())时,会调用方法inputRow()和其参数TbInput::TYPE_DATETIMEPICKER,按理说TbInput是个抽象类,没法直接实例出对象。而在此处直接调用其静态常量,应该是在抽象类中的静态常量和方法,都能直接调用吧。(未实验)
public
function datetimepickerRow($model, $attribute, $htmlOptions
=
array())
{
return $this - >inputRow(TbInput : :TYPE_DATETIMEPICKER, $model, $attribute, null, $htmlOptions);
}
{
return $this - >inputRow(TbInput : :TYPE_DATETIMEPICKER, $model, $attribute, null, $htmlOptions);
}
注:此后是分析过程,不是需要添加的代码。
分析:
inputRow()
方法源代码
public
function inputRow($type, $model, $attribute, $data
= null, $htmlOptions
=
array())
{
ob_start();
Yii : :app() - >controller - >widget($this - >getInputClassName(), array(
'type' = > $type,
'form' = > $this,
'model' = > $model,
'attribute' = > $attribute,
'data' = > $data,
'htmlOptions' = > $htmlOptions,
));
return ob_get_clean();
}
{
ob_start();
Yii : :app() - >controller - >widget($this - >getInputClassName(), array(
'type' = > $type,
'form' = > $this,
'model' = > $model,
'attribute' = > $attribute,
'data' = > $data,
'htmlOptions' = > $htmlOptions,
));
return ob_get_clean();
}
注:
Yii::app()->controller的调用机制???
const INPUT_HORIZONTAL
=
'bootstrap.widgets.input.TbInputHorizontal';
const INPUT_INLINE = 'bootstrap.widgets.input.TbInputInline';
const INPUT_SEARCH = 'bootstrap.widgets.input.TbInputSearch';
const INPUT_VERTICAL = 'bootstrap.widgets.input.TbInputVertical';
protected function getInputClassName()
{
if ( isset($this - >input))
return $this - >input;
else
{
switch ($this - >type)
{
case self : :TYPE_HORIZONTAL :
return self : :INPUT_HORIZONTAL;
break;
case self : :TYPE_INLINE :
return self : :INPUT_INLINE;
break;
case self : :TYPE_SEARCH :
return self : :INPUT_SEARCH;
break;
case self : :TYPE_VERTICAL :
default :
return self : :INPUT_VERTICAL;
break;
}
}
}
const INPUT_INLINE = 'bootstrap.widgets.input.TbInputInline';
const INPUT_SEARCH = 'bootstrap.widgets.input.TbInputSearch';
const INPUT_VERTICAL = 'bootstrap.widgets.input.TbInputVertical';
protected function getInputClassName()
{
if ( isset($this - >input))
return $this - >input;
else
{
switch ($this - >type)
{
case self : :TYPE_HORIZONTAL :
return self : :INPUT_HORIZONTAL;
break;
case self : :TYPE_INLINE :
return self : :INPUT_INLINE;
break;
case self : :TYPE_SEARCH :
return self : :INPUT_SEARCH;
break;
case self : :TYPE_VERTICAL :
default :
return self : :INPUT_VERTICAL;
break;
}
}
}
分析:调用了
widget()方法,应该是抽象类CBaseController的
widget()方法。
$this
-
>getInputClassName()是根据type类型返回的相应的路径名并传入$className。
public
function widget($className,$properties
=
array(),$captureOutput
=false)
{
if($captureOutput)
{
ob_start();
ob_implicit_flush(false);
$widget =$this - >createWidget($className,$properties);
$widget - >run();
return ob_get_clean();
}
else
{
$widget =$this - >createWidget($className,$properties);
$widget - >run();
return $widget;
}
}
{
if($captureOutput)
{
ob_start();
ob_implicit_flush(false);
$widget =$this - >createWidget($className,$properties);
$widget - >run();
return ob_get_clean();
}
else
{
$widget =$this - >createWidget($className,$properties);
$widget - >run();
return $widget;
}
}
分析:调用此类方法createWidget()。
注:$captureOutput为true即返回html字符串,可以多次输出。
public
function createWidget($className,$properties
=
array())
{
$widget =Yii : :app() - >getWidgetFactory() - >createWidget($this,$className,$properties);
//exit(var_dump($widget));
$widget - >init();
//exit(var_dump($widget));
return $widget;
}
{
$widget =Yii : :app() - >getWidgetFactory() - >createWidget($this,$className,$properties);
//exit(var_dump($widget));
$widget - >init();
//exit(var_dump($widget));
return $widget;
}
分析:Yii
:
:app()
-
>getWidgetFactory()引用CWidgetFactory类
public
function createWidget($owner,$className,$properties
=
array())
{
//exit(var_dump($properties));
$className =Yii : :import($className,true);
$widget = new $className($owner);
//exit(var_dump(isset($this->widgets[$className])));
if( isset($this - >widgets[$className]))
$properties =$properties == = array() ? $this - >widgets[$className] : CMap : :mergeArray($this - >widgets[$className],$properties);
if($this - >enableSkin)
{
if($this - >skinnableWidgets == =null || in_array($className,$this - >skinnableWidgets))
{
$skinName = isset($properties[ 'skin']) ? $properties[ 'skin'] : 'default';
if($skinName != =false && ($skin =$this - >getSkin($className,$skinName)) != = array())
$properties =$properties == = array() ? $skin : CMap : :mergeArray($skin,$properties);
}
}
foreach($properties as $name = >$value)
$widget - >$name =$value;
//exit(var_dump($widget->title));
return $widget;
}
{
//exit(var_dump($properties));
$className =Yii : :import($className,true);
$widget = new $className($owner);
//exit(var_dump(isset($this->widgets[$className])));
if( isset($this - >widgets[$className]))
$properties =$properties == = array() ? $this - >widgets[$className] : CMap : :mergeArray($this - >widgets[$className],$properties);
if($this - >enableSkin)
{
if($this - >skinnableWidgets == =null || in_array($className,$this - >skinnableWidgets))
{
$skinName = isset($properties[ 'skin']) ? $properties[ 'skin'] : 'default';
if($skinName != =false && ($skin =$this - >getSkin($className,$skinName)) != = array())
$properties =$properties == = array() ? $skin : CMap : :mergeArray($skin,$properties);
}
}
foreach($properties as $name = >$value)
$widget - >$name =$value;
//exit(var_dump($widget->title));
return $widget;
}
分析:$className
=Yii
:
:import($className,true);通过import引入
TbInputHorizontal TbInputInline TbInputSearch TbInputVertical
中的任何一个子类。