基于Ruby On Rails Extjs Grid的拓展
1.拓展原生Ext GridPanel使其支持后台数据库数据动态构建,所有字段的查询,排序,自定义查询,行编辑器等功能
2.该类Extjs代码:
Ext.QuickTips.init(); Ext.define("Wando.grid.Panel", { extend: "Ext.grid.Panel", alias: "widget.wandogrid", //该配置会自动生成getter setter method config: { plugin: [], features: [], }, split:true, //构造自定义render方法 onRender: function() { this.callParent(arguments); }, constructor: function(cfg) { this.gridConfig = cfg; this.data = this.getColumnData(); //autoLoad 默认为true this.isAutoLoad = cfg.autoLoad == false ? false: true this.isSort = cfg.remoteSort == false ? false: true var store = this.createStore(); var rowEditor = this.createRowEditor(); var features = this.createFilter(); var config = { forceFit: true, plugins: this.gridConfig.rowEditor == false ? []:[rowEditor], features: [features], store: store, bbar: Ext.create('Ext.PagingToolbar', { store: store, displayInfo: true, displayMsg: '显示第 {0} - {1} 条记录,共{2}条', emptyMsg: "没有记录", }) }; Ext.apply(this, config); this.initConfig(cfg); this.callParent(arguments); return this; }, //会被构造器调用,用来初始化数据,配置,绑定事件处理 initComponent: function() { this.callParent(arguments); this.addPagingButton(); }, createStore: function() { me = this; column = me.data.columns; fields = me.data.fields; return Ext.create('Wando.data.Store', { fields: fields, baseParams: { columnsConfig: column }, remoteSort:me.isSort, proxy: { type: 'ajax', url: me.gridConfig.url, reader: { type: 'json', root: 'result' } }, autoLoad: me.isAutoLoad, }); }, getColumnData: function() { var columns = this.gridConfig.columns; var columnsConfig = {}; var fields = []; var filters = []; Ext.each(columns, function(column) { if (!Ext.isEmpty(column.dataIndex)) { columnsConfig[column.columnName] = column.dataIndex; fields.push(column.dataIndex); var type = column.type ? column.type: "string"; filters.push({ dataIndex: column.dataIndex, type: type }); } }); data = { columns: Ext.encode(columnsConfig), fields: fields, filters: filters }; return data; }, createFilter: function() { filters = this.data.filters; return filters = { ftype: 'filters', encode: false, local: true, filters: filters }; }, createRowEditor: function() { return Ext.create('Ext.grid.plugin.RowEditing', { clicksToEdit: 2, clicksToMoveEditor: 1, saveBtnText: '保存/修改', cancelBtnText: '取消', listeners:{ "afteredit":function(){ if (this.whenRowSave){ this.whenRowSave(); } }, scope:this } }) }, addPagingButton: function() { var me = this; this.child('pagingtoolbar').add(['->', { text: me.filters.local ? '本地查询': '远程查询', //tooltip: '查询本地数据或者所有数据', enableToggle: true, handler: function(button, state) { var local = (me.filters.local !== true), text = local ? '本地查询' : '远程查询', newUrl = me.gridConfig.url, store = me.view.getStore(); me.filters.local = local; me.filters.bindStore(store); store.proxy.url = newUrl; button.setText(text); store.load(); } }, { text: '清除查询', scope:this, tooltip: '去掉查询条件,显示所有数据', handler: function() { this.filters.clearFilters(); this.store.reload(); } },{ text: '自定义查询', scope:this, tooltip: '允许用户自定义查询条件', handler: function() { Wando.msg.info("","功能完善中"); } }]) }, getToolbar: function(){ return this.getDockedItems('toolbar[dock="top"]')[0]; } });
3.Ruby代码:
# -*- encoding : utf-8 -*- module WandoGrids # User: Justin # Comment:构造Wando.Grid的后台数据 # date: 2013-03-04 # params: 前台wando_grid默认传入参数,用于数据查找,考虑不需要传该参数 # object: 传入你需要获取数据的 object 名字,object.class必须为ActivityRecord # options: 传入附加的条件 # 返回records的动态表头 def wando_grid params,object,option ={ } order = "" if not params[:sort].nil? JSON.parse(params[:sort]).each do |k| if not object.column_names.include?(k["property"]) order = 'id' + ' ' + k["direction"].to_s else order = k["property"].to_s + " " + k["direction"].to_s end end end default_options = { :order => params[:order], :offset => params[:offeset].to_i, :start => params[:start].to_i || 0, :limit => params[:limit].to_i || 50 } fields = [] column_name = [] result = [] relation = JSON.parse(params[:columnsConfig]) relation.each do |o,e| fields<< e column_name << o end column_name.push("id") offset = default_options[:offeset].to_i + default_options[:start].to_i records = object.where(option).order(order).limit(params[:limit]).offset(offset).search(buildFilterOptions(object,params[:filter])).result(:distinct => true).provide(*column_name) count = object.count records.each do |r| result << Hash[r.map {|k, v| [relation[k], v] }] end render :json => { :success => true, :total => count, :result => result, } end def get_record_by_fields fields,object,option ={ } fields = JSON.parse(fields) unless fields.is_a? Array records = object.where(option).provide(*fields) render :json => { :success => true, :result => records } end def buildFilterOptions(object,filter_hash) return { } if filter_hash.nil? fs = { } filter_hash = filter_hash.delete_if {|key, value| value.blank? } filter_hash.each do |columns, fvals| fs_tmp = { } relation = JSON.parse(params[:columnsConfig]) gf_field = relation.invert[fvals[:field]].downcase.gsub("/","_") gf_type = fvals[:data][:type].downcase gf_value = fvals[:data][:value] gf_comparison = fvals[:data][:comparison] case gf_type when 'numeric' case gf_comparison when 'gt' gf_field += "_gt" when 'lt' gf_field += "_lt" when 'eq' gf_field += "_eq" when 'ne' gf_field += "_neq" end fs_tmp[gf_field.to_sym] = gf_value.to_i when 'string' gf_field += "_cont" fs_tmp[gf_field.to_sym] = gf_value.to_s when 'boolean' gf_value = gf_value.downcase if gf_value == 'true' or gf_value == 'false' gf_field += "_" + gf_value fs_tmp[gf_field.to_sym] = "1" end when 'list' gf_field += "_cont" fs_tmp[gf_field.to_sym] = gf_value.to_s when 'date' case gf_comparison when 'gt' gf_field += '_gt' when 'lt' gf_field += '_lt' when 'eq' gf_field += '_eq' when 'ne' gf_field += '_neq' end fs_tmp[gf_field.to_sym] = gf_value end if not fs_tmp.empty? fs.merge!(fs_tmp) end end fs end end
4.其他Controller通过直接使用wando_grid方法即可自动构造Wando.grid.Panel