自定义ExtJS控件之下拉树和下拉表格附源码

简介

  在Ext官方的例子中只有下拉列表控件,但是在实际业务中只有下拉列表无法满足需求的,像下拉树和下拉表格都是很常见的控件,对于刚使用Ext的人来说,自定义一个控件好难,其实多读官方的源码有些事情就不会那么难了。下面是下拉树的代码:

  

复制代码 代码如下:

  Ext.define('ComboTreeBox',{

  extend : 'Ext.form.field.ComboBox',

  multiSelect : true,

  createPicker : function(){

  var me = this;

  //创建树控件

  var picker = Ext.create('Ext.tree.Panel', {

  store: me.store,

  rootVisible: false,

  selModel: {

  mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'

  },

  floating: true,

  hidden: true,

  focusOnToFront: false

  });

  //注册事件用于选择用户选择的值

  me.mon(picker, {

  itemclick: me.onItemClick,

  refresh: me.onListRefresh,

  scope: me

  });

  me.mon(picker.getSelectionModel(), {

  beforeselect: me.onBeforeSelect,

  beforedeselect: me.onBeforeDeselect,

  selectionchange: me.onListSelectionChange,

  scope: me

  });

  this.picker = picker;

  return picker;

  },

  onItemClick: function(picker, record){

  /*

  * If we're doing single selection, the selection change events won't fire when

  * clicking on the selected element. Detect it here.

  */

  var me = this,

  selection = me.picker.getSelectionModel().getSelection(),

  valueField = me.valueField;

  if (!me.multiSelect && selection.length) {

  if (record.get(valueField) === selection[0].get(valueField)) {

  // Make sure we also update the display value if it's only partial

  me.displayTplData = [record.data];

  me.setRawValue(me.getDisplayValue());

  me.collapse();

  }

  }

  }

  });

  下拉树的代码很简单,只要集成Ext.form.field.ComboBox类,然后重写createPicker方法就可以了,同理下拉表格也是如此,下面是下拉表格的代码:

  

复制代码 代码如下:

  Ext.define('ComboGridBox',{

  extend : 'Ext.form.field.ComboBox',

  multiSelect : true,

  createPicker : function(){

  var me = this;

  var picker = Ext.create('Ext.grid.Panel', {

  title : '下拉表格',

  store: me.store,

  frame : true,

  resizable : true,

  columns : [{

  text : '#ID',

  dataIndex : 'id'

  },{

  text : '名称' ,

  dataIndex : 'name'

  },{

  text : '描述' ,

  dataIndex : 'desc'

  }],

  selModel: {

  mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'

  },

  floating: true,

  hidden: true,

  width : 300,

  columnLines : true,

  focusOnToFront: false

  });

  me.mon(picker, {

  itemclick: me.onItemClick,

  refresh: me.onListRefresh,

  scope: me

  });

  me.mon(picker.getSelectionModel(), {

  beforeselect: me.onBeforeSelect,

  beforedeselect: me.onBeforeDeselect,

  selectionchange: me.onListSelectionChange,

  scope: me

  });

  this.picker = picker;

  return picker;

  },

  onItemClick: function(picker, record){

  /*

  * If we're doing single selection, the selection change events won't fire when

  * clicking on the selected element. Detect it here.

  */

  var me = this,

  selection = me.picker.getSelectionModel().getSelection(),

  valueField = me.valueField;

  if (!me.multiSelect && selection.length) {

  if (record.get(valueField) === selection[0].get(valueField)) {

  // Make sure we also update the display value if it's only partial

  me.displayTplData = [record.data];

  me.setRawValue(me.getDisplayValue());

  me.collapse();

  }

  }

  },

  matchFieldWidth : false,

  onListSelectionChange: function(list, selectedRecords) {

  var me = this,

  isMulti = me.multiSelect,

  hasRecords = selectedRecords.length > 0;

  // Only react to selection if it is not called from setValue, and if our list is

  // expanded (ignores changes to the selection model triggered elsewhere)

  if (!me.ignoreSelection && me.isExpanded) {

  if (!isMulti) {

  Ext.defer(me.collapse, 1, me);

  }

  /*

  * Only set the value here if we're in multi selection mode or we have

  * a selection. Otherwise setValue will be called with an empty value

  * which will cause the change event to fire twice.

  */

  if (isMulti || hasRecords) {

  me.setValue(selectedRecords, false);

  }

  if (hasRecords) {

  me.fireEvent('select', me, selectedRecords);

  }

  me.inputEl.focus();

  }

  console.log(me.getValue());

  },

  doAutoSelect: function() {

  var me = this,

  picker = me.picker,

  lastSelected, itemNode;

  if (picker && me.autoSelect && me.store.getCount() > 0) {

  // Highlight the last selected item and scroll it into view

  lastSelected = picker.getSelectionModel().lastSelected;

  itemNode = picker.view.getNode(lastSelected || 0);

  if (itemNode) {

  picker.view.highlightItem(itemNode);

  picker.view.el.scrollChildIntoView(itemNode, false);

  }

  }

  }

  });

  下拉表格也是继承了Ext.form.field.ComboBox这个类,重写了createPicker方法。

  开发下拉树和下拉表格看起来so easy,只要研究透了Ext的运行机制,一切都会so easy

  控件效果

自定义ExtJS控件之下拉树和下拉表格附源码

自定义ExtJS控件之下拉树和下拉表格附源码

  实例下载

  实例中的资源为myeclipse项目,导入即可运行,自己添加ext的js和css文件,实例中没有ext的基础文件。

  下载地址