Yii框架表单生成器-有什么方法可以更改验证javascript中的inputID吗



在Yii中使用表单生成器时,是否有任何方法可以更改验证javascript中的inputID?

我的问题是,我在一个页面上有两个类似的表单(使用一个表单生成器代码)。这是登录表单,用了两次。第一,在模板中(显示在网站的每个页面上),第二,在/site/login页面中使用相同的形式(该页面用于在访问受限等情况下重定向用户)。

这两个表单运行良好,但是yii为两个表单的元素生成了具有相同inputID的验证javascript,我不知道如何更改它。看看:

<script type="text/javascript">
/*<![CDATA[*/
jQuery(function($) {
jQuery('a[rel="tooltip"]').tooltip();
jQuery('a[rel="popover"]').popover();
$('#loginForm').yiiactiveform({'attributes':[{'id':'LoginForm_email','inputID':'LoginForm_email','errorID':'LoginForm_email_em_','model':'LoginForm','name':'LoginForm[email]','enableAjaxValidation':true,'inputContainer':'div.control-group'},{'id':'LoginForm_password','inputID':'LoginForm_password','errorID':'LoginForm_password_em_','model':'LoginForm','name':'LoginForm[password]','enableAjaxValidation':true,'inputContainer':'div.control-group'},{'id':'LoginForm_rememberMe','inputID':'LoginForm_rememberMe','errorID':'LoginForm_rememberMe_em_','model':'LoginForm','name':'LoginForm[rememberMe]','enableAjaxValidation':true,'inputContainer':'div.control-group'}]});
$('#quickLoginForm').yiiactiveform({'attributes':[{'id':'LoginForm_email','inputID':'LoginForm_email','errorID':'LoginForm_email_em_','model':'LoginForm','name':'LoginForm[email]','enableAjaxValidation':true,'inputContainer':'div.control-group'},{'id':'LoginForm_password','inputID':'LoginForm_password','errorID':'LoginForm_password_em_','model':'LoginForm','name':'LoginForm[password]','enableAjaxValidation':true,'inputContainer':'div.control-group'},{'id':'LoginForm_rememberMe','inputID':'LoginForm_rememberMe','errorID':'LoginForm_rememberMe_em_','model':'LoginForm','name':'LoginForm[rememberMe]','enableAjaxValidation':true,'inputContainer':'div.control-group'}]});
jQuery('#collapse_0').collapse({'parent':false,'toggle':false});
});
/*]]>*/
</script>

这就是问题所在。我不明白,如何改变这一点:'id':'LoginForm_email','inputID':'LoginForm_email',收件人:'id':'quickLoginForm_email','inputID':'quickLoginForm_email',使两个表单的验证工作。我试图更改表单id、表单标题、元素id、元素名称(ofc),但没有结果。是否可以在不更改表单文件名等的情况下动态更改它?我试图阅读CActiveForm的来源,但没有找到它将inputID带到哪里。

Ofc可以不在/site/login页面上显示布局表单,但我认为这不是最好的方式。

因此,在阅读Yii来源3-4个小时后,让我发布我自己问题的答案。我们要在生成的javascript中更改的第一件事是error inputID。就像mashingan所写的,如果您不使用表单生成器,您可以设置$form->error。如果您使用的是表单生成器,您可以从CFormInputElement类的errorOptions属性访问错误选项:

'elements'=>array(
'email'=>array(
'id'=>$this->id.'_email',
'name'=>$this->id.'[email]',
'type'=>'text',
'maxlength'=>32,
'label'=>false,
'placeholder'=>'Your email address',            
'errorOptions'=>array('inputID'=>$this->id.'_email','id'=>$this->id.'_email'),
),

请注意,默认情况下,您不能从此数组访问表单id或其他内容。在构造表单对象时,必须发送$this->id(或者随意命名)。我创建了MyForm类,扩展了CForm,使用构造函数:

class MyForm extends CForm
{
public $id;
public function __construct($config, $model = null, $parent = null, $id = null) {
if($id != null) $this->id = $id;
parent::__construct($config, $model, $parent);
}

然后我在布局中创建我的表单:

$quickLoginForm = new MyForm('application.views.site.loginForm', $model, null, 'QuickLoginForm');

$loginForm = new MyForm('application.views.site.loginForm', $model, null, 'LoginForm');

上面的示例将允许您在Yii生成的验证javascript中动态更改inputID和errorID。

现在让我们看看yii:生成的JS

'id':'LoginForm_email','inputID':'QuickLoginForm_email','errorID':'QuickLoginForm_email'

我们已经更改了inputID和errorID,接下来我们必须更改的是"id",以便对两个相同的表单进行验证。

但是怎么做呢?文档中没有这方面的信息。让我们看看CActiveForm->error()来源:

...
$id=CHtml::activeId($model,$attribute);
...

好的,那么CHtml::activeId是做什么的呢?

public static function activeId($model,$attribute)
{
return self::getIdByName(self::activeName($model,$attribute));
}

public static function activeName($model,$attribute)
{
$a=$attribute; // because the attribute name may be changed by resolveName
return self::resolveName($model,$a);
} 

public static function resolveName($model,&$attribute)
{
...
return get_class($model).'['.$attribute.']';
}

真是天才!它们在生成的javascript中使用模型名称。不是表单id,也不是元素名称,它们使用的是模型类名!

我不知道,强雪抽了什么,但如果你想让验证javascript在一个页面上为两个相同的表单工作,你必须制作两个同样的模型。

因此,如果我们想更改javascript中的"id",我们必须这样做:

<?php
class QuickLoginForm extends LoginForm
{
}

(LoginForm是我们的模型)在生成第二个表单时使用。

$quickLoginModel=new QuickLoginForm;
$quickLoginForm = new MyForm('application.views.site.loginForm', $quickLoginModel, null, 'QuickLoginForm');

祝贺你!在进行了两次破解之后,我们的验证javascript可以用于两个相同的表单。如果你不能在一个页面上制作两个登录表单,而不像猴子一样在Yii javascript生成器的源代码周围跳跃,我不知道如何谈论代码重用或将Yii命名为"可扩展框架"。

我们也遇到了同样的问题,但经过广泛的研究,我们发现Yii已经支持更改InputID,以便您的验证工作。

然而,文件尚未完成。

要修复它,我们唯一需要做的就是在错误字段中设置InputID,使其与您在属性字段中设置的id相对应。像这样:

<?php echo $form->error($model,'attribute',array('inputID'=>'custom-id')); ?>

Yii 1.1.14发布后,此更改的文档将可用。在此期间,如果你做了我们做的事情,它应该会起作用。

希望这对任何有同样问题的人都有效。

参考文献:

1强雪描述了如何再现这个问题。https://github.com/yiisoft/yii/issues/158

2 mdomba文档提交到github存储库。这说明了如何修复代码:https://github.com/yiisoft/yii/commit/65b9bd06e885b96cc08922282b79a9c78484a9bd

这应该有效:

<?php echo $form->textField($model, 'attr', array('id' => 'someId')); ?>
<?php echo $form->error($model, 'attr', array('inputID' => 'someId')); ?>

不要忘记保持input.iderror.inputID不变。

最新更新