关于YII生成表单

视图文件:

create.php:

<?php
/* @var $this TagController */
/* @var $model Tag */


$this->breadcrumbs=array(
'Tags'=>array('index'),
'Create',
);


$this->menu=array(
array('label'=>'List Tag', 'url'=>array('index')),
array('label'=>'Manage Tag', 'url'=>array('admin')),
);
?>


<h1>Create Tag</h1>


<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>


_form.php

<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'tag-form',
'enableAjaxValidation'=>false,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>

<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'name'); ?>
<?php echo $form->textField($model,'name',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,'name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->textField($model,'password',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,'password'); ?>
</div>

<div class="row">
<?php echo $form->labelEx($model,'frequency'); ?>
<?php echo $form->textField($model,'frequency',array('size'=>32,'maxlength'=>32)); ?>
<?php echo $form->error($model,'frequency'); ?>
</div>


<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>


<?php $this->endWidget(); ?>
</div>

控制器文件:

class TagController extends Controller
{

……

public function actionCreate()
{
$model=new Tag;


// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);


if(isset($_POST['Tag']))
{
$model->attributes=$_POST['Tag'];
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}


$this->render('create',array(
'model'=>$model,
));
}

……

模型文件:Tga.php

class Tag extends CActiveRecord

{

……

}

关于YII生成表单

Yii 中的表单生成,有几种方法,

一种是普通生成,用些辅助器(helper)类CHtml类,

<?php echo CHtml::textField(string $name, string $value='', array $htmlOptions=array ( ))?> 

这种方法是没有模型的,它的值是要自己判断有无,通过第二个参数$value来预定义,第三个参数是属性。详情看framework/web/helpers/CHtml.php

 另一种是生成更动态的表单方法,这个就需要有CModel 类型的$model

如:CHtml::activeLabel()

<?php echo CHtml::beginForm(); ?> 

<?php echo $form->errorSummary($model); ?> //这显示全部错误信息

<li>

<?php echo CHtml::activeLabel($model,'username'); ?> 

<?php echo CHtml::activeTextField($model,'username') ?> 

</li>

<li>

<?php echo CHtml::activeLabel($model,'password'); ?> 

<?php echo CHtml::activePasswordField($model,'password') ?> 

</li>

 <li>

<?php echo CHtml::submitButton('Login'); ?> 

</li>

<?php echo CHtml::endForm(); ?> 

 

还有一种YII提供的自版本  1.1.1 开始一个新的  widget 称为 CActiveForm 被提供用来简化表单创建  widget 能够无缝和坚固
(consistent)的支持客户端和服务器端的验证.如可以用ajax异步验证。

<?php $form=$this->beginWidget('CActiveForm', array(
      'id'=>'theForm',
      'action'=>$this->createUrl("profile/index"),
      'enableAjaxValidation'=>true,//开启异步验证
      'clientOptions'=>array(
       'validateOnSubmit'=>true,
      ),
     ));?>

<div>

        <?php echo $form->label($model,'username'); ?> 
        <?php echo $form->textField($model,'username') ?> 
<?php echo $form->error($model, "realname"); ?>    </div> //显示单个错误信息
    <div class="row"> 
        <?php echo $form->label($model,'password'); ?> 
        <?php echo $form->passwordField($model,'password') ?> 
    </div> 
    <div class="row rememberMe"> 
        <?php echo $form->checkBox($model,'rememberMe'); ?> 
        <?php echo $form->label($model,'rememberMe'); ?> 
    </div> 
    <div class="row submit"> 
        <?php echo CHtml::submitButton('Login'); ?> 
    </div>

<?php $this->endWidget(); ?> 

 

关于$model

$model 必须是继承自CActiveRecord或是CFormModel的,它们都是继承自 CModel » CComponent

其中前都扩展的多,后都几乎没什么扩展。

所以,在一个只有一种表单的模型中,就直接在model中设定验证规则,在此类中,不用设定每种字段属性,CActiveRecord自动从数据表中获取了。

一个数据表有多个表单,可以用CFormModel来设定不同表单有验证规则roule(),在此类中,要自己设定表单属性。

1.myController是自己定义的一个控制器,login.php是在myController中login这个action指向执行的view.

2. 虚线表示一个是另一个类的子类.所以myController含有BaseController的那几个方法。所以在login.php中可以使用baseController中的方法。

3. baseController中beginWidget和widget方法都会调用createWidget(),并且在createWidget中使用init方法得到预处理的widget,而后widget和endWidget执行widget对象的run()。

 

复制代码
<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'login-form',
    'enableClientValidation'=>true,
    'clientOptions'=>array(
        'validateOnSubmit'=>true,
    ),
)); ?>

        <?php echo $form->textField($model,'username'); ?>

        <?php echo $form->passwordField($model,'password'); ?>

    <div class="row buttons">
        <?php echo CHtml::submitButton('Login'); ?>
    </div>

<?php $this->endWidget(); ?>
复制代码

以上面代码为例子,beginWidget里的array("id"=>"login-form")等参数实际上是类CActiveForm的属性。查看生成的源码:

<form id="login-form" action="/site/login" method="post">

即当前指定了id,method,那么查看CActiveForm还有action属性,增加该属性如:

复制代码
<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'login-form',
    'action'=>"helloworld",
    'enableClientValidation'=>true,
    'clientOptions'=>array(
        'validateOnSubmit'=>true,
    ),
)); ?>
复制代码

查看源码:

<form id="login-form" action="helloworld" method="post">

以上测试证明了beginWidget就是这样实例化出这个form的widget,但是,如何已控制器进行交互了?

 

控制器处理:

复制代码
public function actionLogin()
    {
        $model=new LoginForm;


        // collect user input data
        if(isset($_POST['LoginForm']))
        {
            $model->attributes=$_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if($model->validate() && $model->login())
                $this->redirect(Yii::app()->user->returnUrl);
        }
        // display the login form
        $this->render('login',array('model'=>$model));
    }
复制代码

这段代码很让人迷惑,主要是$_POST['LoginForm']那里来的?一般PHP的post请求无外乎$_POST["username"], $_POST["password"],因为$_POST这个属性无外乎就是个array,所以,可以说在yii中,通过使用yii自己的form表单,会对一些name进行处理,然后对$_POST中的值进行修改!

验证一,原始html

<input name="LoginForm[username]" id="LoginForm_username" type="text" />

生成的表单中是这样的代码。当然主要是CHtml完成的。

?
public  static  function resolveNameID($model,&$attribute,&$htmlOptions)
     {
         if (!isset($htmlOptions[ 'name' ]))
             $htmlOptions[ 'name' ]=self::resolveName($model,$attribute);
         if (!isset($htmlOptions[ 'id' ]))
             $htmlOptions[ 'id' ]=self::getIdByName($htmlOptions[ 'name' ]);
         else  if ($htmlOptions[ 'id' ]=== false )
             unset($htmlOptions[ 'id' ]);
     }

我们的<?php echo $form->textField($model,'username'); ?>这行代码中的textField($model,$attribute,$htmlOptions=array())方法是可以指定$htmlOptions的,即可以指定name属性,但是这里没有指定,所以都各自调用了前面的2个方法

resolveName:

复制代码
public static function resolveName($model,&$attribute)
    {
        if(($pos=strpos($attribute,'['))!==false)
        {
            if($pos!==0)  // e.g. name[a][b]
                return get_class($model).'['.substr($attribute,0,$pos).']'.substr($attribute,$pos);
            if(($pos=strrpos($attribute,']'))!==false && $pos!==strlen($attribute)-1)  // e.g. [a][b]name
            {
                $sub=substr($attribute,0,$pos+1);
                $attribute=substr($attribute,$pos+1);
                return get_class($model).$sub.'['.$attribute.']';
            }
            if(preg_match('/\](\w+\[.*)$/',$attribute,$matches))
            {
                $name=get_class($model).'['.str_replace(']','][',trim(strtr($attribute,array(']['=>']','['=>']')),']')).']';
                $attribute=$matches[1];
                return $name;
            }
        }
        return get_class($model).'['.$attribute.']';
    }
复制代码

get_class这里是返回的对象的类名,是哪个类呢?

public function actionLogin()
    {
        $model=new LoginForm;

是最早我们实例化的这个类。

所以说,要使用yii的类最好得有一个自己的form类。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值