카테고리 없음2012. 11. 18. 16:42

코드성 콤보 박스를 그리드의 에디터와 일반 폼화면에서 사용할 수 있도록 구현한다.



위의 모습은 최종 구현 모습니다.

그리드에 경우 더블클릭하여 콤보박스가 표시되도록 하였고 일반 폼에 경우는 바로 바인딩된 값이 보여지도록 하였다.

일반적인 코드콤보박스는 코드명이 화면에 보여지고 코드가 내부적으로 선택되고 저장되게 된다.

아래 그림은 서버를 통해 가져온 json값이다.  그리드에서는 아래와 같이 코드와 코드명 둘다 가져온다.

코드는 그리드에서 표시하고 코드명은 바인딩된 폼에서 보여주게 된다.

사실 기존에 사용하던 방법이 약간에 문제가 있어 이번에는 모두 해결된 코드를 소개하도록 합니다.

/***
 * Date : 2012.11.17
 * Desc : 본 클래스는 그리드가 렌더링 될 시 렌더러 함수내에서 외부 콤보박스의 
 * 		  store가 로드되지 않은 채로 호출되는 문제를 해결하였다.
 */
Ext.define('pns.common.ComboColumn', {
    extend:'Ext.grid.Column',
    alias: 'widget.pns.combocolumn',
    initComponent: function() {
        var me = this;
        me.callParent();
        // Refreshes grid on store load in order to apply the renderer function
        var editor = this.editor || this.field
            store = editor.store;
        store.on('load', function() { me.up('gridpanel').getView().refresh() });
        // Manages store autoloading
//        if (!store.autoLoad && !store.loaded) store.load();
    },
    renderer: function(value, metaData, record, rowIndex, colIndex, store) {
    	
    	/**
    	 * Date : 2012.11.17
    	 * Desc : 이쪽을 좀 수정했다.
    	 * 		  우리가 원하는 것은 렌더링 시 코드가 코드명으로 보여지고 콤보박스에서 
    	 *   	  수정하면 수정된 코드명이 record에 update 되도록 해야한다.
    	 *   	  이래야 코드와 코드명을 일관되게 서버에 보내고 클라이언트에서 확인 할 수 있다.
    	 */
        var column = this.columns[colIndex],
            editor = column.editor || column.field,
            comboStore = editor.store,
            displayField = editor.displayField;
            index = comboStore.findExact(editor.valueField, value);
            if (index != -1){
            	rs = comboStore.getAt(index).data;
            	record.set(editor.updateNameField, eval('rs.'+displayField)); // 이부분을 통해서 변경된 콤보박스의 코드명이 수정 세팅된다.
            	console.log('변경된 레코드 ', editor.updateNameField,  displayField,  eval('rs.'+displayField), record)
            	return eval('rs.'+displayField);
            }
            return value;
    }
});

/***
 * Date : 2012.11.17
 * Oprt : winkos
 * Desc : 이 클래스는 그리드에서 더블클릭하여 에디터(콤보박스)로 사용되고 폼에서
 * 		  콤보박스로 사용된다.
 * UseCase 
 * 1. 그리드에서 에디터로 사용시
 *    var mst_use_yn = Ext.widget('commonCbx',{
 *    	updateNameField : 'mst_use_yn_nm',
 *    	autoload : true,	// true로 한다. 한번만 서버에 다녀오고 이후 에는 재활용된다.
 *    	group_code : 'A001'
 *    });
 *    // 이하 그리드 컬럼
 *   	columns: [
 *   		        {
 *   				    header: "컬럼",
 *   				    xtype: 'pns.combocolumn',	// 필수
 *   				    dataIndex: 'mst_use_yn',
 *   				    editor : mst_use_yn,	// 그리드에서는 xtype사용하지 않는다 위에서 처럼 하나 만들어서 같이 사용한다. autoload문제도 있다.
 *   				} ,
 *   2. 폼에서 사용 시 
 *   { 
 *    	xtype : 'commonCbx',
 *     	group_code : 'A001',
 *     	allowBlank:false,
 *      fieldLabel: '심사부문 ',
 *     	name: 'mst_use_yn_nm', // 이 클래스는 최초 store를 로드 하지 않게 하였다. 성능문제를 신경쓰다보니. 무조건 코드명이 보여지도록 필드명도 신경쓴다.
 *      codefield: 'mst_use_yn', // 이 부분에 명시된 텍스트로 hiddenfield를 만들고 선택된 값을 자동으로 세팅하게 한다.
 *      emptyText: 'password'
 * }      
		
 */
Ext.define('pns.common.CodeComboBox', {
	extend:'Ext.form.field.ComboBox',
    alias:'widget.commonCbx',
    labelAlign: 'right',
    labelWidth: 75,
	initComponent: function(){
		var me = this;
		// 폼에서 사용 시 코드용 텍스트 필드를 추가해준다.
		var task = new Ext.util.DelayedTask(function(){
			me.codeFieldCreate(me);
		});
		task.delay(1000);
		this.on('select', this.onSelectChanged, this);
		this.store =  Ext.create('Ext.data.Store', {
			autoLoad: this.autoload,
			fields: ['code','code_name','cd_amt'],
			proxy: {
				type: 'ajax',
				url: '/json/code.jsp?codes',
				reader: {
					type:'json',
					root: 'entitys'
				}
			},
			extraParams: {
    			notInCode: this.notInCode,
    			likeCode: this.likeCode,
    			likeCodeDesc:this.likeCodeDesc,
    			group_code: this.groupCode
            }
		});
		 this.callParent(arguments);
		 var store = this.store;
		 this.store.on('load', function() { me.setValue(me.getValue()) });
		 // Manages store autoloading
		 //if (!this.store.autoLoad && !this.store.loaded) this.store.load();
	},
	codeFieldCreate : function(){
		if(!this.codefield)
			return;
		this.up('form').add({
			xtype : 'hiddenfield',
			name : this.codefield
		});
	},
	onSelectChanged: function(combo, t) {
		if(!this.codefield)	// codefield가 없다면 그리드에서 사용한 것이다.
			return;
		// 아래 내용은 코드와 코드명이 뒤바뀌 세팅되는 것을 막기위해 재세팅한다.
		var form = this.up('form').getForm();
		form.findField(this.codefield).setValue(t[0].get('code'));
		form.findField(this.name).setValue(t[0].get('code_name'));
	},
	displayField : 'code_name',
	valueField : 'code',
    typeAhead : true,
    editable : false,
    lazyRender: true
});

// 이하 사용 예
// 에디터 생성
var mst_use_yn = Ext.widget('commonCbx',{
			updateNameField : 'mst_use_yn_nm',
			autoload : true,  // 미리 로딩해야 한번 만 로딩하고 모든 로우가 재활용 한다.
			group_code : 'A001' // 서버쪽에 넘겨줄 상위코드, 이값으로 하위에 코드를 가져온다.
		});
// 그리드 예
items : [{
		        	xtype: 'grid',
		        	columnLines: true,
..
..
{
					    header: "상태",  // 컬럼헤드
					    width: 70, 
					    xtype: 'pns.combocolumn', 
					    dataIndex: 'mst_use_yn',
					    editor : mst_use_yn
					}
// 폼에서 활용.
 { 
                	xtype : 'commonCbx',
                	group_code : 'A001',
                	allowBlank:false, 
                	fieldLabel: '심사부문 ', 
                	name: 'mst_use_yn_nm', 
                	codefield: 'mst_use_yn',
                	emptyText: '심사부문을 선택해주세요'
                }
Posted by 베니94