[size=large][/size]
这个标题非常拗口,但应该能帮助遇到同样问题的朋友baidu到这里。baidu+google了一下午都没找到答案,发这文章时国内似乎还没有人碰到这个问题,至少没有发相关的帖子出来。但国外被这螃蟹噎到的ExtJs用户已经数不胜数了,还是google见多识广啊~
症状:
当使用add方法在formPanel中动态添加FieldSet时,尽管控件重绘正常,但form.isValid()只会返回true,打印form.items.length时也显示没有新的组件添加进来,但实际上无论render还是submit都是正常的,唯独validate不正常。问题代码如下:
JavaScript代码
//Create the Form
testForm = new Ext.form.FormPanel({
name: "form1",
frame:true,
width: 350,
items: [{
xtype: "textfield",
name: "nom",
fieldLabel: "nom",
allowBlank: false
}]
});
//Render the form
testForm.render(Ext.get('idForm'));
//Create the fieldset
testFieldSet = new Ext.form.FieldSet({
name: 'testFieldSet',
autoHeight: true,
items: [{
xtype : "textfield",
name : "testtextvalid",
fieldLabel: "testDyn",
allowBlank: false
}]
});
testForm.add(testFieldSet); //add the fieldset to the formpanel
testFieldSet.doLayout();
testForm.doLayout();
关于这个bug的解析和解决办法如下(原文地址:http://extjs.com/forum/showthread.php?t=41093):
Containers need to be aware of what they contain.
Most only need to know their immediate children, and so their add method is sufficient.
However, for example a FormPanel, needs to know when Fields are added and removed at any depth in its Component tree so that it can update the Field Collection in its BasicForm.
There have been bug reports that after dynamic adding of Containers to a FormPanel, or of Fields to nested Containers, the BasicForm does not know about those new fields to load.
So I propose two new template methods starting at the Component class level.
onAdd and onRemove
"Template methods" might not be the best name because they don't bubble up the inheritance chain, they bubble up the ownerCt chain.
so Container would have the following new code in red:
add : function(comp){
if(!this.items){
this.initItems();
}
var a = arguments, len = a.length;
if(len > 1){
for(var i = 0; i < len; i++) {
this.add(a[i]);
}
return;
}
var c = this.lookupComponent(this.applyDefaults(comp));
var pos = this.items.length;
if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
this.items.add(c);
c.ownerCt = this;
this.onAdd(c);
this.fireEvent('add', this, c, pos);
}
return c;
},
insert : function(index, comp){
if(!this.items){
this.initItems();
}
var a = arguments, len = a.length;
if(len > 2){
for(var i = len-1; i >= 1; --i) {
this.insert(index, a[i]);
}
return;
}
var c = this.lookupComponent(this.applyDefaults(comp));
if(c.ownerCt == this && this.items.indexOf(c) < index){
--index;
}
if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
this.items.insert(index, c);
c.ownerCt = this;
this.onAdd(c);
this.fireEvent('add', this, c, index);
}
return c;
},
remove : function(comp, autoDestroy){
var c = this.getComponent(comp);
if(c && this.fireEvent('beforeremove', this, c) !== false){
this.items.remove(c);
delete c.ownerCt;
if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
c.destroy();
}
if(this.layout && this.layout.activeItem == c){
delete this.layout.activeItem;
}
this.onRemove(c);
this.fireEvent('remove', this, c);
}
return c;
},
// private
// Inform all ancestor Containers of an addition to their Component tree
onAdd: function() {
if (this.ownerCt && this.ownerCt.onAdd) {
this.ownerCt.onAdd.apply(this.ownerCt, arguments)
}
},
// private
// Inform all ancestor Containers of a removal from their Component tree
onRemove: function() {
if (this.ownerCt && this.ownerCt.onRemove) {
this.ownerCt.onRemove.apply(this.ownerCt, arguments)
}
}
Then FormPanel would have
// Determine if a Component is usable as a form Field.
isField: function(c) {
return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
},
onAdd : function(c) {
Ext.form.FormPanel.superclass.onAdd.apply(this, arguments);
// If a single form Field, add it
if (this.isField(c)) {
this.form.add(c);
// If a Container, add any Fields it might contain
} else if (c.findBy) {
this.form.add.apply(this.form, c.findBy(this.isField));
}
},
onRemove : function(c) {
Ext.form.FormPanel.superclass.onRemove.apply(this, arguments);
// If a single form Field, remove it
if (this.isField(c)) {
Ext.destroy(c.container.up('.x-form-item'));
this.form.remove(c);
// If a Container, remove any Fields it might contain
} else if (c.findByType) {
Ext.each(c.findBy(this.isField), this.form.remove, this.form);
}
},
Untested code, but that's the principle.
You see that it uses find by type which uses isXType which, as discusses on another thread gives up testing the inheritance chain for an xtype match as soon as it hits a constructor with no xtype...
上面是根本性的解决办法。
但对于大部分用户,我还是建议用以下workaround代替。
解决办法:
XML/HTML代码
//Create the Form
testForm = new Ext.form.FormPanel({
name: "form1",
frame:true,
width: 350,
items: [{
xtype: "textfield",
name: "nom",
fieldLabel: "nom",
allowBlank: false
}]
});
//Render the form
testForm.render(Ext.get('idForm'));
//Create the fieldset
testFieldSet = new Ext.form.FieldSet({
name: 'testFieldSet',
autoHeight: true,
items: [{
xtype : "textfield",
name : "testtextvalid",
fieldLabel: "testDyn",
allowBlank: false
}]
});
testForm.add(testFieldSet); //add the fieldset to the formpanel
testForm.doLayout();
===========this is the workaround============
testFieldSet.form = testForm.getForm();
testForm.initFields.call(testFieldSet);
//delete testForm.form;原来是有这一行的,但加上后连getForm()都不好用了,去掉就没问题了
===========this is the workaround============
OK,一切恢复正常!
分享到:
相关推荐
然而,在实际开发过程中,我们可能会遇到需要动态添加组件到FormPanel中的需求,这就会带来一些验证上的挑战。这篇博客将探讨如何解决EXT JS中关于FormPanel动态添加组件的验证问题。 首先,让我们理解EXT JS ...
在"动态添加表单"这个主题中,我们将深入探讨如何在ExtJS中实现表单的动态创建和管理。 首先,我们要理解表单(Form)在ExtJS中的基本概念。表单是数据输入和验证的核心组件,可以包含各种字段类型,如文本框、下拉...
对于更复杂的需求,如动态添加或删除表单字段,FormPanel 提供了`add`和`remove`方法。同时,`loadRecord`方法可以用来从记录对象中加载表单数据,而`getValues`和`getRecord`则用于获取当前表单的值或转换为记录...
在本篇文章中,我们将深入探讨如何使用Extjs4中的FormPanel组件从后台加载JSON数据,并将其映射到表单的各个字段中进行显示。这是一项非常实用的技术,尤其是在需要动态填充表单的情况下。 ### 一、Extjs4 ...
本文将深入探讨如何在ExtJs中使用`FormPanel`组件结合`form`和`column`布局属性来实现横向布局,即在一个表单中元素能够按照列分布,形成一种更为直观和用户友好的界面设计。 ### 一、理解`FormPanel`及其属性 `...
### Extjs FieldSet 两行两列布局解析 在Extjs框架中,`FieldSet`是一种常见的组件,常用于组织一组相关的表单字段,并通过一个标题来标识这组字段的主题。本文将详细介绍如何使用Extjs实现一个两行两列布局的`...
- **创建表单组件**:首先,定义一个FormPanel,并在其内部添加所需的表单字段,例如`Ext.form.field.Text`、`Ext.form.field.Date`等。 - **配置表单行为**:为FormPanel设置action属性,指定提交的URL,或者在...
extjs验证 extjs验证 extjs验证 extjs验证extjs验证 extjs验证 extjs验证 extjs验证
我们首先从标题"ExtJs动态grid的生成"开始,了解动态生成Grid的基本概念和实现方法。 动态生成Grid意味着在运行时根据需求创建和更新Grid组件,而不是在应用初始化时静态定义。这种灵活性允许开发者更好地响应数据...
在EXTJS4中,FormPanel是一个非常重要的组件,用于创建包含表单元素的用户界面。在某些场景下,我们可能需要一个FormPanel实例能够根据不同的情况提交到不同的URL。这个问题可以通过灵活地设置和操作FormPanel及其...
extjs动态添加tabpanel标签页支持pannel嵌入 逻辑代码在 MyWindow.js里面直接调用 方法 就可以
### Ext的FormPanel组件 #### 综述 `FormPanel`是Ext JS框架中的一个重要组件,主要用于构建复杂的表单界面。它提供了丰富的功能,如数据验证、数据提交以及灵活的布局控制等,使得开发者能够轻松地创建出既美观又...
本文将深入探讨如何在ExtJS的`resultGrids`中动态添加按钮,并结合`SuserInfoRes_js.jsp`文件名称推测可能的实现方法。 动态添加按钮在很多情况下非常有用,比如在表格数据加载后根据特定条件显示或隐藏操作按钮,...
extjs4动态添加表头字段、删除、增加记录!
标题 "FCKeditor结合extjs实例" 描述的是一个实际项目中使用的技术组合,涉及到的主要是两个前端富文本编辑器库:FCKeditor 和 ExtJS。这个实例表明在开发企业级网站时,如何将这两者有效地整合以实现复杂的用户界面...
Extjs动态Grid的生成 htm
### Extjs 表单验证详解 #### 一、引言 在现代Web开发中,确保用户输入的有效性和安全性至关重要。Extjs作为一种强大的JavaScript框架,提供了丰富的功能来帮助开发者轻松实现客户端验证。本文将深入探讨Extjs中的...
动态表头是ExtJS中一个高级特性,它允许开发者根据需要在运行时动态地创建和修改表格的列结构。这在处理数据展示和操作时具有很大的灵活性,尤其在数据字段不确定或需要自定义的情况下非常实用。 标题“extjs 实现...
Accordion布局是ExtJS中的布局类型之一,允许在一个容器内多列垂直堆叠,每次只有一个面板展开。在动态树中,可以将树节点与Accordion布局关联,当点击节点时,对应的Accordion面板展开显示详细信息。 六、优化与...
用Ext自定义一个类似于Fieldset的组件,还有数据绑定昂,跟json数据的交互,和后台交互使用了URLLoader,很强大,之前在网上找了很多,没有找到,后来我师傅给我源码,这里跟大家分享一下,有用到的童鞋们可以参考...