我也不知道标题该怎么写才能描述我要说明的问题,意思就是可以放 Yii 的表单生成器功能更加灵活。

默认的 Yii 的表单生成器只需要这样就可以了:

$form = new CForm('application.views.site.loginForm', $model);

这里的 application.views.site.loginForm 也可以是配置数组。但是如果$model 参数不传的话是会报错的:Fatal error: Call to a member function isAttributeSafe() 比如我要生成一个组表单,但是我不想依赖于 model,根据配置就可以生成一组表单该怎么办,google 一下,http://www.yiiframework.com/forum/index.php/topic/6839-cform-model/ 这个帖子受到启发!

默认生成的表单的 label 是根据$model->attributes 来显示的,所以我做了 2 件事:

  1. 继承 CFormInputElement 覆盖 renderLabel 方法,将 label 显示成自己配置的 element 的 label
  2. 继承 CForm 覆盖 renderElement 方法,$element instanceof UCFormInputElement,并覆盖 render 方法,将 Elements 和 getButtons 循环输出

直接上代码: app/protected/extensions/UCForm.php

<?php

/**
 * @author Ryan <yuansir@live.cn/yuanxuxu.com>
 */
class UCForm extends CForm
{

	public function render()
	{
		$output = $this->renderBegin();

		foreach ($this->getElements() as $element)
		{
			$output .= $element->render();
		}

		foreach ($this->getButtons() as $button)
		{
			$output .= $button->render();
		}

		$output .= $this->renderEnd();
		return $output;
	}

	public function renderElement($element)
	{
		if (is_string($element))
		{
			if (($e = $this[$element]) === null && ($e = $this->getButtons()->itemAt($element)) === null)
				return $element;
			else
				$element = $e;
		}
		if ($element->getVisible())
		{
			//UCFormInputElement 代替 CFormInputElement
			if ($element instanceof UCFormInputElement)
			{
				if ($element->type === 'hidden')
					return "<div style=\"visibility:hidden\">\n" . $element->render() . "</div>\n";
				else
					return "<div class=\"row field_{$element->name}\">\n" . $element->render() . "</div>\n";
			}
			else if ($element instanceof CFormButtonElement)
				return $element->render() . "\n";
			else
				return $element->render();
		}
		return '';
	}

}

app/protected/extensions/UCFormInputElement.php

<?php

/**
 * @author Ryan <yuansir@live.cn/yuanxuxu.com>
 */
class UCFormInpurtElement extends CFormInputElement
{

	public function renderLabel()
	{
		$options = array(
		    'label' => $this->getLabel(),
		    'required' => $this->getRequired()
		);

		//input 的label 用 $config[element][label]来代替
		if (!empty($this->attributes['label']))
		{
			$options['for'] = $this->attributes['label'];
		}

		return CHtml::activeLabel($this->getParent()->getModel(), $this->name, $options);
	}

}

再来个简单的调用示例:

<?php

/**
 * @author Ryan <yuansir@live.cn/yuanxuxu.com>
 */
class PlayerSearchController extends Controller
{

	public function actionIndex()
	{
		$config = array(
		    'class' => 'ddd',
		    'action'=>'',
		    'elements' => array(
			'<br><br>',
			'username' => array(
			    'label'=>'用户名啊',//注意这里的label
			    'type' => 'text',
			    'maxlength' => 32,
			    'value' => ''
			),
			'<br><br>',
			'password' => array(
			    'label'=>'昵称啊',//注意这里的label
			    'type' => 'password',
			    'maxlength' => 32,
			    'value' => ''
			),
		    ),
		    'buttons' => array(
			'login' => array(
			    'type' => 'submit',
			    'label' => 'Login',
			),
		    ),
		);

		$model = new CFormModel();
		$form = new UCForm($config, $model);
		$this->render('index', compact('form'));
	}

}

让Yii表单生成器不依赖Mode 注意这里的 input 的 label 的配置,是用来控制 label 的文本显示的。

转载请注明: 转载自Yuansir-web 菜鸟 | LAMP 学习笔记

如果觉得本篇文章对您十分有益,何不 打赏一下

谢谢打赏

本文链接地址: 让 Yii 表单生成器不依赖 Model

知识共享许可协议 本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可