EXTJS记事本 当CompositeField遇上RowEditor_extjs
原因是客户的物料种类非常多,有一千种之多,如果单纯用一个Combobox,那么在实际使用中,很难快速找到一个物料,所以,我使用包含物料分类和物料品牌的两个combobox来组成级联式筛选。问题恰恰出在这儿,如果在roweditor的一个字段中用多个控件,就要处理每个控件的初始化,Change事件。网上目前还未找到有人有好的解决办法。经过3天的调试,我终于解决了问题,把我的代码贴出来:
var editor=new Ext.ux.grid.RowEditor({
saveText: '确定',
cancelText:"放弃",
commitChangesText: '请确定或放弃修改',
errorText: '错误'
});
//当取消时,根据关键字段的值是否为空而删掉空记录
editor.on("canceledit",function(editor,pressed)
{
if(pressed && editor.record.get("materialid")==0)
{
store.remove(editor.record);
}
},this);
/*
afterstart 这个事件是自己加的,因为如果在beforeedit事件中想对自己的控件初始化,那是不可能的,因为beforeedit时,roweditor控件还没有渲染,所以,我加了afterstart事件,该事件在roweditor显示后立即调用,所以,可以在这里进行初始化。
要注意的是通过roweditor控件进行遍历来访问自定义的composite控件
editor.items.items[0],这里并不是我写重了,而是roweditor控件的items竟然不是一个集合,而是一个对象,在这里我也耗了一些时间,最后还是通过firebug输出editor对象发现的
editor.items.items[0]就是compositefield组件,通过该组件的items集合,就可以以标准的形式访问其子组件,接下来,就可以初始化了
因为最后一个combobox的数据是要通过前两个combobox级联选取后载入的,所以,在这里载入其数据进行初始化,但是注意,我是在callback中执行的,因为jsonstore的load动作是异步的,所以,必须通过callback事件的回调在数据载入成功后,再用setValue来初始化值
*/
editor.on("afterstart",function(editor,rowIndex)
{
var record=store.getAt(rowIndex);
editor.items.items[0].items.items[0].setValue(record.get("setid"));
editor.items.items[0].items.items[1].setValue(record.get("category"));
var t_store=editor.items.items[0].items.items[2].getStore();
t_store.load({
params:{category:record.get("category"),setid:record.get("setid")},
callback:function(r,options,success){
if (success)
editor.items.items[0].items.items[2].setValue(record.get("materialid"));
}
});
},this);
/*
validateedit事件是在按了确认时执行的,用来验证roweditor中各控件的值,在这里,我执行了一个自定义的验证动作,因为我不想用户可以添加重复的物料,所以,我通过遍历jsonstore,将每条记录的物料值与用户选择的物料值进行比较,如果发现已经存在,则提示用户不要重复加入
*/
editor.on("validateedit",function(editor,obj,record,rowIndex){
var materialid=editor.items.items[0].items.items[2].getValue();
var exist=false;
Ext.each(store.getRange(),function(o,i){
if(o!=record&&o.get("materialid")==materialid)
{
exist=true;
return(false);
}
});
if(exist)
{
Ext.MessageBox.alert("系统提示","请勿重复添加");
store.remove(record);
}
return(!exist);
},this);
/*
afterEdit是通过验证后执行的,这里最重要的动作是将正在编辑的记录的某些属性赋值,原因是由于采用了compsitefield,所以,roweditor无法将选取的值赋给record的正确属性,需要我们手工将用户的选择赋给相应的字段,materialid就是用户选的物料编号,而model对应是该物料的型号
为什么要赋model呢?因为model是列的值嘛,不赋的话,显示的是空的
*/
editor.on("afteredit",function(editor,obj,record,rowIndex){
record.set("materialid",editor.items.items[0].items.items[2].getValue());
record.set("model",editor.items.items[0].items.items[2].getRawValue());
},this);
以上是roweditor的定义和对事件的处理,接下来,将roweditor作为插件插入到gridpanel
{
xtype:"grid",
title:"产品BOM",
layout:"fit",
store:store,
enableDragDrop: false,
border: false,
frame:false,
autoScroll:true ,plugins:[editor],
sm:sm,
height:340,
clicksToEdit:2,
autoWidth: true,
viewConfig:{forceFit:true,autoFill:true,markDirty:false}
}
接下来,再看看关于gridpanel的列定义,这里,你可以看到composite是如何用的
columns: [{
header: "物料名称/型号",
dataIndex: "model",
width: 200,
menuDisabled: true,
editor:
{
//定义编辑器
xtype:"compositefield",
name:"compositefield",
items:[
{
xtype: "combo",
mode:"local",
name:"sets",
width:80,
fieldLabel: "适用产品品牌",
emptyText:"请选择",
valueField: "id",
lazyInit:false,
value:this.data?this.data.title:"",
hiddenName:"setid",
hiddenValue:this.data?this.data.setid:"",
displayField: "title",
typeAhead: false,
forceSelection: true,
editable:true,
listeners:{
"change":function(combo,newvalue,oldvalue)
{
//处理品牌的change事件,在选取品牌后,重新载入combobox,editor就是前文定义的roweditor的实例
var category=editor.items.items[0].items.items[1];
var material=editor.items.items[0].items.items[2];
var c=category.getValue();
var store=material.getStore();
store.load({
params:{setid:newvalue,category:c},
callback:function(r,options,success){
if (success)
material.setValue("");
}
});
}
},
triggerAction: "all",
store: new Ext.data.JsonStore({
url: "data.asp",
root: "data",autoDestroy:true,
remoteSort: true,
listeners:{"load":function(store,records,option){
var s=Ext.data.Record.create([{name:"id",type:"int"},{name:"title",type:"string"}]);
store.add(new s({id:0,title:"通用"}))
}},
baseParams: {op: "setList"},
totalProperty: "total",
autoLoad: true,
fields: ["title","id"]
})
},
{
xtype: "combo",
mode:"local",width:60,
name:"category",
fieldLabel: "类别",
emptyText:"请选择",
valueField: "category",
lazyInit:false,
value:this.data?this.data.category:"",
displayField: "category",
typeAhead: false,forceSelection: true,
triggerAction: "all",
listeners:{
"change":function(combo,newvalue,oldvalue)
{
//处理类别的change事件,在选取品牌后,重新载入combobox,editor就是前文定义的roweditor的实例
var sets=editor.items.items[0].items.items[0];
var material=editor.items.items[0].items.items[2];
var setid=sets.getValue();
var store=material.getStore();
store.load({
params:{category:newvalue,setid:setid},
callback:function(r,options,success){
if (success)
material.setValue("");
}
});
}
},
store: new Ext.data.JsonStore({
url: "data.asp",
root: "data",autoDestroy:true,
remoteSort: true,
baseParams: {op: "materialCategoryList"},
totalProperty: "total",
autoLoad: true,
fields: ["category"]
})
},
{
xtype: "combo",
forceSelection: true,
editable:true,
mode:"local",
name:"material",
fieldLabel: "物料",
emptyText:"请选择物料",
valueField: "id",
allowBlank:false,
displayField: "model",
width:250,
lazyInit:false,
typeAhead: false,
triggerAction: "all",
listeners:{
"change":function(combo,newvalue,oldvalue)
{
//这里一定要注意!!!如果没有下面这两句,那你选择后,会发现显示的值不会变化,并且,点了确认,也不能更新。为什么呢?因为roweditor是通过检测record的isdirty属性来决定是不是调用validateedito和afteredit的,它是检测每列对应的控件值是否变化来判断的,由于物料型号这列,对应的是compositefield,所以,我们必须让compositefield值发生变化,roweditor才会调用validedit和afteredit,并且,compositefield的值还会被调用来显示在列里
var comp=editor.items.items[0];
comp.setRawValue(combo.getRawValue());
}
},
store: new Ext.data.JsonStore({
url: "data.asp",
root: "data",autoDestroy:true,
remoteSort: true,
baseParams: {op: "materialList"},
totalProperty: "total",
autoLoad: false,
fields: ["model","id"]
})}
]
}
},
{
header: "数量",
dataIndex: "qty",
width: 50,
menuDisabled: true,
editor: {
xtype: 'numberfield',
minValue:1,
allowDecimals:false
}
}
,{
header: "颜色",
dataIndex: "color",
width: 60,
menuDisabled: true
}
,{
header: "尺寸",
dataIndex: "size",
width: 60,
menuDisabled: true
}
]
}
]
谨以此记,分享给有需要的朋友

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

本教程向您展示了如何将自定义的Google搜索API集成到您的博客或网站中,提供了比标准WordPress主题搜索功能更精致的搜索体验。 令人惊讶的是简单!您将能够将搜索限制为Y

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

本文系列在2017年中期进行了最新信息和新示例。 在此JSON示例中,我们将研究如何使用JSON格式将简单值存储在文件中。 使用键值对符号,我们可以存储任何类型的

利用轻松的网页布局:8个基本插件 jQuery大大简化了网页布局。 本文重点介绍了简化该过程的八个功能强大的JQuery插件,对于手动网站创建特别有用

核心要点 JavaScript 中的 this 通常指代“拥有”该方法的对象,但具体取决于函数的调用方式。 没有当前对象时,this 指代全局对象。在 Web 浏览器中,它由 window 表示。 调用函数时,this 保持全局对象;但调用对象构造函数或其任何方法时,this 指代对象的实例。 可以使用 call()、apply() 和 bind() 等方法更改 this 的上下文。这些方法使用给定的 this 值和参数调用函数。 JavaScript 是一门优秀的编程语言。几年前,这句话可

jQuery是一个很棒的JavaScript框架。但是,与任何图书馆一样,有时有必要在引擎盖下发现发生了什么。也许是因为您正在追踪一个错误,或者只是对jQuery如何实现特定UI感到好奇

该帖子编写了有用的作弊表,参考指南,快速食谱以及用于Android,BlackBerry和iPhone应用程序开发的代码片段。 没有开发人员应该没有他们! 触摸手势参考指南(PDF) Desig的宝贵资源
