Ext之扩展Ext.ux.form.LovCombo使用

    最近学习使用Ext做些东西,有时候找到现成的,但却不知道如何使用。比如前几天在项目中有个多选下拉框的要求。由于Ext本身并没有这样的控件,经过在网上搜索,找到一个扩展了Ext.form.ComboBox的控件Ext.ux.form.LovCombo 其可以满足多选。虽然找到了,但不知道怎么用,经过一天多的努力,终于会用了。首先看看其源码。

 

Ext.ux.form.LovCombo源码如下

// add RegExp.escape if it has not been already added
if('function' !== typeof RegExp.escape) {
	RegExp.escape = function(s) {
		if('string' !== typeof s) {
			return s;
		}
		// Note: if pasting from forum, precede ]/\ with backslash manually
		return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
	}; // eo function escape
}

// create namespace
Ext.ns('Ext.ux.form');
/**
 *
 * @class Ext.ux.form.LovCombo
 * @extends Ext.form.ComboBox
 */
Ext.ux.form.LovCombo = Ext.extend(Ext.form.ComboBox, {

	// {{{
    // configuration options
	/**
	 * @cfg {String} checkField name of field used to store checked state.
	 * It is automatically added to existing fields.
	 * Change it only if it collides with your normal field.
	 */
	 checkField:'checked'

	/**
	 * @cfg {String} separator separator to use between values and texts
	 */
    ,separator:','

	/**
	 * @cfg {String/Array} tpl Template for items. 
	 * Change it only if you know what you are doing.
	 */
	// }}}
    // {{{
    ,initComponent:function() {
        
		// template with checkbox
		if(!this.tpl) {
			this.tpl = 
				 ''
				+'
' +'' +'
{' + (this.displayField || 'text' )+ '}
' +'
' +'
' ; } // call parent Ext.ux.form.LovCombo.superclass.initComponent.apply(this, arguments); // install internal event handlers this.on({ scope:this ,beforequery:this.onBeforeQuery ,blur:this.onRealBlur }); // remove selection from input field this.onLoad = this.onLoad.createSequence(function() { if(this.el) { var v = this.el.dom.value; this.el.dom.value = ''; this.el.dom.value = v; } }); } // e/o function initComponent // }}} // {{{ /** * Disables default tab key bahavior * @private */ ,initEvents:function() { Ext.ux.form.LovCombo.superclass.initEvents.apply(this, arguments); // disable default tab handling - does no good this.keyNav.tab = false; } // eo function initEvents // }}} // {{{ /** * clears value */ ,clearValue:function() { this.value = ''; this.setRawValue(this.value); this.store.clearFilter(); this.store.each(function(r) { r.set(this.checkField, false); }, this); if(this.hiddenField) { this.hiddenField.value = ''; } this.applyEmptyText(); } // eo function clearValue // }}} // {{{ /** * @return {String} separator (plus space) separated list of selected displayFields * @private */ ,getCheckedDisplay:function() { var re = new RegExp(this.separator, "g"); return this.getCheckedValue(this.displayField).replace(re, this.separator + ' '); } // eo function getCheckedDisplay // }}} // {{{ /** * @return {String} separator separated list of selected valueFields * @private */ ,getCheckedValue:function(field) { field = field || this.valueField; var c = []; // store may be filtered so get all records var snapshot = this.store.snapshot || this.store.data; snapshot.each(function(r) { if(r.get(this.checkField)) { c.push(r.get(field)); } }, this); return c.join(this.separator); } // eo function getCheckedValue // }}} // {{{ /** * beforequery event handler - handles multiple selections * @param {Object} qe query event * @private */ ,onBeforeQuery:function(qe) { qe.query = qe.query.replace(new RegExp(this.getCheckedDisplay() + '[ ' + this.separator + ']*'), ''); } // eo function onBeforeQuery // }}} // {{{ /** * blur event handler - runs only when real blur event is fired */ ,onRealBlur:function() { this.list.hide(); var rv = this.getRawValue(); var rva = rv.split(new RegExp(RegExp.escape(this.separator) + ' *')); var va = []; var snapshot = this.store.snapshot || this.store.data; // iterate through raw values and records and check/uncheck items Ext.each(rva, function(v) { snapshot.each(function(r) { if(v === r.get(this.displayField)) { va.push(r.get(this.valueField)); } }, this); }, this); this.setValue(va.join(this.separator)); this.store.clearFilter(); } // eo function onRealBlur // }}} // {{{ /** * Combo's onSelect override * @private * @param {Ext.data.Record} record record that has been selected in the list * @param {Number} index index of selected (clicked) record */ ,onSelect:function(record, index) { if(this.fireEvent('beforeselect', this, record, index) !== false){ // toggle checked field record.set(this.checkField, !record.get(this.checkField)); // display full list if(this.store.isFiltered()) { this.doQuery(this.allQuery); } // set (update) value and fire event this.setValue(this.getCheckedValue()); this.fireEvent('select', this, record, index); } } // eo function onSelect // }}} // {{{ /** * Sets the value of the LovCombo * @param {Mixed} v value */ ,setValue:function(v) { if(v) { v = '' + v; if(this.valueField) { this.store.clearFilter(); this.store.each(function(r) { var checked = !(!v.match( '(^|' + this.separator + ')' + RegExp.escape(r.get(this.valueField)) +'(' + this.separator + '|$)')) ; r.set(this.checkField, checked); }, this); this.value = this.getCheckedValue(); this.setRawValue(this.getCheckedDisplay()); if(this.hiddenField) { this.hiddenField.value = this.value; } } else { this.value = v; this.setRawValue(v); if(this.hiddenField) { this.hiddenField.value = v; } } if(this.el) { this.el.removeClass(this.emptyClass); } } else { this.clearValue(); } } // eo function setValue // }}} // {{{ /** * Selects all items */ ,selectAll:function() { this.store.each(function(record){ // toggle checked field record.set(this.checkField, true); }, this); //display full list this.doQuery(this.allQuery); this.setValue(this.getCheckedValue()); } // eo full selectAll // }}} // {{{ /** * Deselects all items. Synonym for clearValue */ ,deselectAll:function() { this.clearValue(); } // eo full deselectAll // }}} }); // eo extend // register xtype Ext.reg('lovcombo', Ext.ux.form.LovCombo); // eof

 

  CSS代码如下:

/** 
 *
 * Ext.ux.form.LovCombo CSS File
 *
 * @author    Ing.Jozef 
 * @copyright (c) 2008.
 * @date      5. April 2008
 * @version   $Id: lovCombo.css,v 1.1.2.1 2009/11/30 02:12:32 xiaozhangqi Exp $
 *
 * @license Ext.ux.form.LovCombo.css is licensed under the terms of the Open Source
 * LGPL 3.0 license. Commercial use is permitted to the extent that the 
 * code/component(s) do NOT become part of another Open Source or Commercially
 * licensed development library or toolkit without explicit permission.
 * 
 * License details: http://www.gnu.org/licenses/lgpl.html
 */

.ux-lovcombo-icon {
	width:16px;
	height:16px;
	float:left;
	background-position: -1px -1px ! important;
	background-repeat:no-repeat ! important;
}
.ux-lovcombo-icon-checked {
	background: transparent url(../ext-plug/resources/images/default/menu/checked.gif);
}
.ux-lovcombo-icon-unchecked {
	background: transparent url(../ext-plug/resources/images/default/menu/unchecked.gif);
}
 
/* eof */

 

 

下面介绍如何使用Ext.ux.form.LovCombo(在这里介绍的是基于JSP,服务器端使用Java)

 

      首先,当然时在你的JSP中引入Ext.ux.form.LovCombo源代码和其CSS文件了,如:

 
"/>

     

     然后,当然是在你的JS中创建一个Ext.ux.form.LovCombo了,在我的代码中的使用方式是在一个JS类中创建一个方 法来专门得到一个Ext.ux.form.LovCombo得实例,当然对于其它控件的获取你也可以这样,其中方法如下:

	this.getMultiSelectComboBox = function(title, url, width, name, editable,
			blank, handler) {
				
		title2 = stringFilter['filterBlank'](blank, title);
		var store = new Ext.data.JsonStore({
					url : url,
					fields : ['label', 'value', 'selected']
				});
		store.load();
		Ext.namespace("Ext.ux.form");
		store.on('load', function(ds, records, o) {
			 var isFirst = true;
             var selectedItems = "";
			for (i = 0; i < records.length; i++) {
				if (records[i].data.selected == 'y') {
					if(isFirst){
					selectedItems = selectedItems+records[i].data.value;
					isFirst =false;
					}else{
						selectedItems=selectedItems+","+records[i].data.value;
					}
				}
			}
			multiSelectComboBox.setValue(selectedItems);
		});
		var multiSelectComboBox = new Ext.ux.form.LovCombo({
					//id : 'lovcombo',
					name : name,
					hiddenName : name,
					fieldLabel : title2,
					width : width,
					listWidth : width,
					hideOnSelect : false,
					maxHeight : 200,
					readOnly : true,
					editable : false,
					store : store,
					displayField : 'label',
					valueField : 'value',
					typeAhead : true,
					allowBlank : blank,
					triggerAction : 'all',
					emptyText : "-=请选择=-",
					mode : 'local'
				});
		return multiSelectComboBox;
	};

          上面代码的URL就是Ajax访问的URL,如“flowInfoConfigAction.do?method=getRoles”(我使用的服务器端 是Struts),

 

  再次是服务器传回的数据格式如下:

[{"value":"1","label":"rootDepart"},{"selected":"y","value":"2","label":"Depart_1"},{"selected":"y","value":"3","label":"Depart_2"}]

   至于如何根据你的实体得到这样的Json数据,这里就不用多说了!

 

   最后的使用效果如下图:

   Ext之扩展Ext.ux.form.LovCombo使用_第1张图片

 

 特别注意:这个组件,在失去焦点后会出现选中的值被清空,要处理这个问题有以下两种方法:

// 第一种方法 override beforeBlur method
   Ext.override(Ext.ux.form.LovCombo, {   
       beforeBlur: Ext.emptyFn   
   }); 
			 
 /*****************************************/
lovCombo = new Ext.ux.form.LovCombo({
    fieldLabel : '多选框',
    id : 'test',
    name : 'test',
    store : fromStore,
    mode : 'local',
    readOnly : true,
    triggerAction : 'all',
    allowBlank : true,
    valueField : "id",
    displayField : "name",
    anchor : '90%',
    beforeBlur : function() {// 第二种方法直接配在定义处. override beforeBlur method}
});

    这种解决办法来自http://blog.csdn.net/avajworm/article/details/6304684#

 

你可能感兴趣的:(ExtJs)