PDA

View Full Version : [2.2.1][Solved]FormPanelでvalidationエラー時のアイコンが表示されない



kaburk
11 Mar 2009, 7:13 PM
こんにちわ。表題のとおりなんですが、
Ext.form.Field.prototype.msgTarget = 'side' を指定しているにもかかわらず、
datefieldやtimefieldの入力チェックでエラー時はアイコンが表示されます。
textfieldやtextareaの入力チェックでエラー時はアイコンが表示されません。

この違いは何なんでしょう?どなたかご存知ありませんか?
サンプルソースを添付しましたが、layout:'absolute' を指定しているからでしょうか?
そもそももっと基本的なことを勘違いしてるって事でしょうか?:-?

yuki
11 Mar 2009, 10:36 PM
サンプルソースを添付しましたが、layout:'absolute' を指定しているからでしょうか?


ご推測の通り、原因はabsouteを指定しているからです。layoutにformを指定してあげれば(レイアウトはメチャクチャになってしまいましたが)普通にアイコンは表示されました。

ちょと調べたところ、msgTarget:'side' とした場合、そのFieldのエレメント(el)の親ノードの存在を確認して、その親ノードに対してエラーアイコンを挿入しているのですが、その親ノードの条件として、「x-form-element」か「x-form-field-wrap」クラスを持つノードということになっています。

Field.getErrorCt

getErrorCt : function(){
return this.el.findParent('.x-form-element', 5, true) || // use form element wrap if available
this.el.findParent('.x-form-field-wrap', 5, true); // else direct field wrap
}

これは仕様なのかバグなのか微妙ですが、layout:formを指定してあげると、itemsの中のField(とそのサブクラス)のelを「x-form-element」というクラスを持つdivでwrapするという処理を行っているのですが、これがabsoluteだとFieldはwrapされないまま描画されます。

ただ、TriggerFieldのサブクラス(DateFieldとかTimeFieldとか)はそもそも「x-form-field-wrap」というdivでwrapされているので、layout:absoluteであってもアイコンが表示されていたというわけです。

なので、対応としては、layout:formにするか、もしくは、

方法1:Ext.Field.onRenderのオーバーライド
(最後の一行だけです)

Ext.override(Ext.form.Field,{
onRender : function(ct, position){
Ext.form.Field.superclass.onRender.call(this, ct, position);
if(!this.el){
var cfg = this.getAutoCreate();
if(!cfg.name){
cfg.name = this.name || this.id;
}
if(this.inputType){
cfg.type = this.inputType;
}
this.el = ct.createChild(cfg, position);
}
var type = this.el.dom.type;
if(type){
if(type == 'password'){
type = 'text';
}
this.el.addClass('x-form-'+type);
}
if(this.readOnly){
this.el.dom.readOnly = true;
}
if(this.tabIndex !== undefined){
this.el.dom.setAttribute('tabIndex', this.tabIndex);
}

this.el.addClass([this.fieldClass, this.cls]);
this.el.wrap({cls: "x-form-field-wrap"});
}
});
方法2:描画後にwrapする

form.items.each(function(item){
if(item.isFormField){
item.on('render',function(t){
Ext.select('.x-form-field',false,t.body).each(function(el){
if(!el.findParent('.x-form-element', 5, true) && !el.findParent('.x-form-field-wrap', 5, true)){
el.wrap({cls: "x-form-field-wrap"});
}
});
})
}
});

一応両方の方法を試したところ、どちらも普通に動いてました(環境:FF3/OSX)

kaburk
12 Mar 2009, 5:07 PM
自分の環境でも試してみました。ばっちり表示されていました!
詳しい原因もわかってすっきりしました。ありがとうございました=P~
(環境:IE6,IE7,IE8,FF2.0,FF3.0,FF3.1b3,Opera9.64,safari3.2,Chrome2.0/WinXP)