블로그 이미지

카테고리

데꾸벅 (194)
Publisher (39)
Scripter (97)
Programmer (1)
Designer (30)
Integrator (18)
Pattern Searcher (4)
News (2)
강좌 및 번역 (3)

최근에 올라온 글

최근에 달린 댓글



기본적으로 grid의 View에 editor와 같이 다른 컴포넌트를 붙이기는 기존 소스보다 컴포넌트를 붙이는 소스가 더 많이 들어가는 경우가 있다.
데꾸벅의 경우도 프로젝트중 각각의 그리드 Row마다 progress bar를 붙여야 하는 경우가 생겼었는데..
포럼글을 뒤지다가 다음과 같은 좋은 사용자 플러그인이 있어 분석을 위해 소스를 까 보았다.



위 그림에서 보는바와 같이 그리드위에 버튼을 만들어 올릴때 new Ext.button이 아닌 new Ext.Action을 사용하여 사용자 플러그인을 사용한 소스이다.
소스 API  및 관련 포럼글 

HTML
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <link rel="stylesheet" type="text/css" href="./css/icons.css">
 <link rel="stylesheet" type="text/css" href="./css/Ext.ux.grid.RowActions.css">
    <link rel="stylesheet" type="text/css" href="../../ext/ext-2.2/resources/css/ext-all.css" />
    <script type="text/javascript" src="../../ext/ext-2.2/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../../ext/ext-2.2/ext-all.js"></script>
 <script type="text/javascript" src="./js/Ext.ux.grid.RowActions.js"></script>
 <script type="text/javascript" src="./js/Ext.ux.Toast.js"></script>
 <script type="text/javascript" src="rowactions.js"></script>
</head>
<body></body>
</html>





JS

Ext.BLANK_IMAGE_URL = '';
Ext.ns('Example');
Example.version = '1.0';

Example.Grid = Ext.extend(Ext.grid.GridPanel, {

  initComponent:function() {

   // Create RowActions Plugin
   this.action = new Ext.ux.grid.RowActions({
    header:'Actions'
   ,autoWidth:true
   ,keepSelection:true
   ,actions:[{
     iconIndex:'action1'
    ,qtipIndex:'qtip1'
    ,iconCls:'icon-open'
    ,tooltip:'Open'
   },{
     iconCls:'icon-wrench'
    ,tooltip:'Configure'
    ,qtipIndex:'qtip2'
    ,iconIndex:'action2'
    ,hideIndex:'hide2'
   },{
     iconIndex:'action3'
    ,qtipIndex:'qtip3'
    ,iconCls:'icon-user'
    ,tooltip:'User'
    ,style:'background-color:yellow'
   }]
   ,groupActions:[{
     iconCls:'icon-del-table'
    ,qtip:'Remove Table'
   },{
     iconCls:'icon-add-table'
    ,qtip:'Add Table - with callback'
    ,callback:function(grid, records, action, groupId) {
     Ext.ux.Message.msg('Callback: icon-add-table'
         , 'Group: <b>{0}</b>, action: <b>{1}</b>, records: <b>{2}</b>'
         , groupId
         , action
         , records.length);
    }
   },{
     iconCls:'icon-graph'
    ,qtip:'View Graph'
    ,align:'left'
   }]
   ,callbacks:{
    'icon-plus':function(grid, record, action, row, col) {
     Ext.ux.Message.msg('Callback: icon-plus'
         , 'You have clicked row: <b>{0}</b>, action: <b>{0}</b>'
         , row
         , action);
    }
   }
  });

  this.action.on({
   action:function(grid, record, action, row, col) {
    Ext.ux.Message.msg('Event: action', '클릭한 Row: <b>{0}</b>, 액션: <b>{1}</b>'
        , row
        , action);
   }
   ,beforeaction:function() {
    Ext.ux.Message.msg('Event: beforeaction', '핸들러에서 false반환시 액션취소.');
   }
   ,beforegroupaction:function() {
    Ext.ux.Message.msg('Event: beforegroupaction', '핸들러에서 false반환시 액션취소');
   }
   ,groupaction:function(grid, records, action, groupId) {
    Ext.ux.Message.msg('Event: groupaction', 'Group: <b>{0}</b>, action: <b>{1}</b>, records: <b>{2}</b>', groupId, action, records.length);
   }
  });

  Ext.apply(this, {
    store:new Ext.data.Store({
    reader:new Ext.data.JsonReader({
      id:'company'
     ,totalProperty:'totalCount'
     ,root:'rows'
     ,fields:[
      {name: 'company'}
        ,{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
        ,{name: 'industry'}
        ,{name: 'desc'}
        ,{name: 'action1', type: 'string'}
        ,{name: 'action2', type: 'string'}
        ,{name: 'action3', type: 'string'}
        ,{name: 'qtip1', type: 'string'}
        ,{name: 'qtip2', type: 'string'}
        ,{name: 'qtip3', type: 'string'}
        ,{name: 'hide2', type: 'boolean'}
     ]
    })
    ,proxy:new Ext.data.HttpProxy({url:'jsonData.json'})
    ,sortInfo:{field:'company', direction:'ASC'}
    ,listeners:{
     load:{scope:this, fn:function() {
      this.getSelectionModel().selectFirstRow();
     }}
    }
   })
   ,columns:[
    {id:'company',header: "Company", width: 40, sortable: true, dataIndex: 'company'}
    ,{header: "Industry", width: 20, sortable: true, dataIndex: 'industry'}
    ,{header: "Last Updated", width: 20, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
    ,this.action
   ]
   ,plugins:[this.action]
   ,loadMask:true
   ,viewConfig:{forceFit:true}
  });

  this.bbar = new Ext.PagingToolbar({
    store:this.store
   ,displayInfo:true
   ,pageSize:10
  });

  Example.Grid.superclass.initComponent.apply(this, arguments);
 }


 ,onRender:function() {
  Example.Grid.superclass.onRender.apply(this, arguments);
  this.store.load({params:{start:0, limit:10}});
 }
});

//컴포넌트 등록
Ext.reg('techbuggrid', Example.Grid);

Ext.onReady(function() {
    Ext.QuickTips.init();

    var win = new Ext.Window({
         width:600
  ,minWidth:320
        ,id:'agwin'
        ,height:400
        ,layout:'fit'
        ,border:false
  ,plain:true
        ,closable:false
        ,title:"그리드 Row Action 처리하기"
  ,items:{xtype:'techbuggrid',id:'actiongrid'}
    });
    win.show();
});




사용자 플러그인.JS

Ext.ns('Ext.ux.grid');
if('function' !== typeof RegExp.escape) {
 RegExp.escape = function(s) {
  if('string' !== typeof s) {
   return s;
  }
  return s.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1');
 };
}

Ext.ux.grid.RowActions = function(config) {
 Ext.apply(this, config);
 this.addEvents(
   'beforeaction'
  ,'action'
  ,'beforegroupaction'
  ,'groupaction'
 );
 Ext.ux.grid.RowActions.superclass.constructor.call(this);
};

Ext.extend(Ext.ux.grid.RowActions, Ext.util.Observable, {
  actionEvent:'click'
 ,autoWidth:true
 ,dataIndex:''
 ,header:''
 ,keepSelection:false
 ,menuDisabled:true
 ,sortable:false
 ,tplGroup:
   '<tpl for="actions">'
  +'<div class="ux-grow-action-item<tpl if="\'right\'===align"> ux-action-right</tpl> '
  +'{cls}" style="{style}" qtip="{qtip}">{text}</div>'
  +'</tpl>'
 ,tplRow:
   '<div class="ux-row-action">'
  +'<tpl for="actions">'
  +'<div class="ux-row-action-item {cls} <tpl if="text">'
  +'ux-row-action-text</tpl>" style="{hide}{style}" qtip="{qtip}">'
  +'<tpl if="text"><span qtip="{qtip}">{text}</span></tpl></div>'
  +'</tpl>'
  +'</div>'
 ,hideMode:'visiblity'
 ,widthIntercept:4
 ,widthSlope:21
 ,init:function(grid) {
  this.grid = grid;
  if(!this.tpl) {
   this.tpl = this.processActions(this.actions);
  }
  if(this.autoWidth) {
   this.width =  this.widthSlope * this.actions.length + this.widthIntercept;
   this.fixed = true;
  }
  var view = grid.getView();
  var cfg = {scope:this};
  cfg[this.actionEvent] = this.onClick;
  grid.afterRender = grid.afterRender.createSequence(function() {
   view.mainBody.on(cfg);
   grid.on('destroy', this.purgeListeners, this);
  }, this);

  if(!this.renderer) {
   this.renderer = function(value, cell, record, row, col, store) {
    cell.css += (cell.css ? ' ' : '') + 'ux-row-action-cell';
    return this.tpl.apply(this.getData(value, cell, record, row, col, store));
   }.createDelegate(this);
  }

  if(view.groupTextTpl && this.groupActions) {
   view.interceptMouse = view.interceptMouse.createInterceptor(function(e) {
    if(e.getTarget('.ux-grow-action-item')) {
     return false;
    }
   });
   view.groupTextTpl =
     '<div class="ux-grow-action-text">' + view.groupTextTpl +'</div>'
    +this.processActions(this.groupActions, this.tplGroup).apply()
   ;
  }

  if(true === this.keepSelection) {
   grid.processEvent = grid.processEvent.createInterceptor(function(name, e) {
    if('mousedown' === name) {
     return !this.getAction(e);
    }
   }, this);
  }
  
 }
 ,getData:function(value, cell, record, row, col, store) {
  return record.data || {};
 }

 ,processActions:function(actions, template) {
  var acts = [];

  Ext.each(actions, function(a, i) {
   if(a.iconCls && 'function' === typeof (a.callback || a.cb)) {
    this.callbacks = this.callbacks || {};
    this.callbacks[a.iconCls] = a.callback || a.cb;
   }

   var o = {
     cls:a.iconIndex ? '{' + a.iconIndex + '}' : (a.iconCls ? a.iconCls : '')
    ,qtip:a.qtipIndex ? '{' + a.qtipIndex + '}' : (a.tooltip || a.qtip ? a.tooltip || a.qtip : '')
    ,text:a.textIndex ? '{' + a.textIndex + '}' : (a.text ? a.text : '')
    ,hide:a.hideIndex
     ? '<tpl if="' + a.hideIndex + '">'
      + ('display' === this.hideMode ? 'display:none' :'visibility:hidden') + ';</tpl>'
     : (a.hide ? ('display' === this.hideMode ? 'display:none' :'visibility:hidden;') : '')
    ,align:a.align || 'right'
    ,style:a.style ? a.style : ''
   };
   acts.push(o);

  }, this);

  var xt = new Ext.XTemplate(template || this.tplRow);
  return new Ext.XTemplate(xt.apply({actions:acts}));

 }
 ,getAction:function(e) {
  var action = false;
  var t = e.getTarget('.ux-row-action-item');
  if(t) {
   action = t.className.replace(/ux-row-action-item /, '');
   if(action) {
    action = action.replace(/ ux-row-action-text/, '');
    action = action.trim();
   }
  }
  return action;
 }
 ,onClick:function(e, target) {

  var view = this.grid.getView();

  var row = e.getTarget('.x-grid3-row');
  var col = view.findCellIndex(target.parentNode.parentNode);
  var action = this.getAction(e);

  if(false !== row && false !== col && false !== action) {
   var record = this.grid.store.getAt(row.rowIndex);

   if(this.callbacks && 'function' === typeof this.callbacks[action]) {
    this.callbacks[action](this.grid, record, action, row.rowIndex, col);
   }

   if(true !== this.eventsSuspended && false === this.fireEvent('beforeaction', this.grid, record, action, row.rowIndex, col)) {
    return;
   }
   else if(true !== this.eventsSuspended) {
    this.fireEvent('action', this.grid, record, action, row.rowIndex, col);
   }

  }

  t = e.getTarget('.ux-grow-action-item');
  if(t) {
   var group = view.findGroup(target);
   var groupId = group ? group.id.replace(/ext-gen[0-9]+-gp-/, '') : null;

   var records;
   if(groupId) {
    var re = new RegExp(RegExp.escape(groupId));
    records = this.grid.store.queryBy(function(r) {
     return r._groupId.match(re);
    });
    records = records ? records.items : [];
   }
   action = t.className.replace(/ux-grow-action-item (ux-action-right )*/, '');

   if('function' === typeof this.callbacks[action]) {
    this.callbacks[action](this.grid, records, action, groupId);
   }

   if(true !== this.eventsSuspended && false === this.fireEvent('beforegroupaction', this.grid, records, action, groupId)) {
    return false;
   }
   this.fireEvent('groupaction', this.grid, records, action, groupId);
  }
 }

});

Ext.reg('rowactions', Ext.ux.grid.RowActions);




요기 괜찮은 사용자 플러그인도 함 보세요





















'Scripter > EXTJS' 카테고리의 다른 글

Extjs Core 3.0 Beta 릴리즈  (4) 2009.04.07
Examples Of ExtJS in Action  (2) 2009.03.31
extjs 2.2의 IE에서 iframe document load 버그패치  (0) 2009.01.21
Extjs 3.0 Roadmap  (10) 2008.11.12
Ext2.2 Release  (11) 2008.08.07
Post by 넥스트리소프트 데꾸벅(techbug)
, |