0

Yiiでフォームビルダーを使用しているときに検証javascriptでinputIDを変更する方法はありますか?

私の問題は、1 つのページに (1 つのフォーム ビルダー コードを使用して) 2 つの類似したフォームがあることです。これはログイン フォームで、2 回使用されます。1 つ目はテンプレート (Web サイトのすべてのページに表示) で、2 つ目は /site/login ページで使用される同じフォーム (このページは、アクセス制限などの場合にユーザーをリダイレクトするために使用されます)。

この 2 つのフォームは問題なく動作しますが、yii は 2 つのフォームの要素に対して同じ 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', to: 'id':'quickLoginForm_email','inputID':'quickLoginForm_email', 2 つのフォームに対して検証を機能させるには。フォーム ID、フォーム タイトル、要素 ID、要素名 (ofc) を変更しようとしましたが、結果がありません。フォームファイル名などを変更せずに、動的に変更することはできますか? CActiveForm のソースを読み込もうとしましたが、inputID を取得する場所が見つかりませんでした。

多くの場合、/site/login ページにレイアウト フォームを表示しないことも可能ですが、それは私が考える最良の方法ではありません。

4

3 に答える 3

1

Yii のソースを 3 ~ 4 時間読んだ後、私自身の質問への回答を投稿させてください。生成された JavaScript で最初に変更したいのは、エラーの 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 を送信する (または任意の名前を付ける) 必要があります。コンストラクターを使用して、CForm を拡張して MyForm クラスを作成しました。

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 を変更しました。次に、2 つの同じフォームに対して検証を機能させるために変更する必要があるのは、'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でも要素名でもなく、モデルクラス名を使用しています!

Qiang Xue が何を吸ったかはわかりませんが、1 つのページで 2 つの同じフォームに対して検証 JavaScript を機能させたい場合は、2 つの同じモデルを作成する必要があります。

したがって、JavaScript で「id」を変更したい場合は、次のようにする必要があります。

<?php
class QuickLoginForm extends LoginForm
{
}

(LoginForm は弊社のモデルです) そして、2 番目のフォームを生成するときに使用します。

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

おめでとう!2 つのハックを行った後、検証 JavaScript が 2 つの同じフォームで機能するようになりました。サルのように yii JavaScript ジェネレーターのソース コードを飛び回らずに 1 つのページに 2 つのログイン フォームを作成できない場合、コードの再利用についてどのように話し、Yii を「拡張可能なフレームワーク」と名付けたらよいかわかりません。

于 2012-10-05T12:58:06.150 に答える
1

私たちも同じ問題を抱えていましたが、大規模な調査を行った結果、検証が機能するように Yii が既に InputID の変更をサポートしていることがわかりました。

ただし、ドキュメントはまだ作成されていません。

これを修正するには、属性フィールドに設定した ID に対応するように、エラー フィールドに InputID を設定する必要がありました。このような:

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

この変更に関するドキュメントは、Yii 1.1.14 のリリース後に利用可能になります。それまでの間、私たちが行ったことを実行すれば、うまくいくはずです。

これが同じ問題を抱えている人にとってうまくいくことを願っています。

参考文献:

1 問題の再現方法に関する Qiang Xue の説明。https://github.com/yiisoft/yii/issues/158

2 mdomba ドキュメントを github リポジトリにコミットします。これはコードを修正する方法を説明しています: https://github.com/yiisoft/yii/commit/65b9bd06e885b96cc08922282b79a9c78484a9bd

于 2013-07-15T18:41:21.117 に答える
0

これは機能するはずです:

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

input.id同じことを維持することを忘れないでくださいerror.inputID

于 2012-10-04T21:29:25.390 に答える