wCMF  3.6
 All Classes Namespaces Files Functions Variables Groups Pages
grid.js.php
Go to the documentation of this file.
1 /**
2  * @class wcmf.grid.Grid. Build on Ext.grid.GridPanel
3  */
4 wcmf.grid.Grid = function() {};
5 
6 wcmf.grid.Grid.prototype = {
7  // the displayed type
8  type:null,
9  // the Ext.grid.GridPanel instance
10  grid:null,
11  // the column definitions
12  columnDefs:null,
13  // the row actions
14  actions:null,
15  // the custom parameters
16  customParams:null,
17  // the Ext.data.Store instance
18  ds:null,
19  // the Ext.PagingToolbar instance
20  pagingTb:null,
21  // the page size
22  pageSize:-1,
23 
24  /**
25  * Initialize a grid that displays entities
26  * @param title The title to display
27  * @param type The entity type to display
28  * @param filter A filter string to be used to filter the entities (see StringQuery), maybe obfuscated using Obfuscator
29  * @param columnDefs An array of column definitions for Ext.grid.ColumnModel
30  * @param config An associative array with the following keys: paging[true/false], pagesize[number, default=10], autoheight[true/false], singleSelect[true/false], ddRows[true/false], ddSortCol[columnname], groupBy[columnname]
31  * @param actions An array of wcmf.grid.Action instances for each row (The first on is also used as double click action)
32  * @param customBtns An array of additional button definitions for Ext.Toolbar [optional]
33  * @param customParams An assoziative array of additional values passed to the controller [optional]
34  */
35  init: function(title, type, filter, columnDefs, config, actions, customBtns, customParams) {
36  this.type = type;
37  this.columnDefs = columnDefs;
38  this.actions = actions;
39  this.customParams = customParams;
40 
41  var _this = this;
42 
43  if (config.paging)
44  this.pageSize = (config.pagesize != undefined) ? config.pagesize : 10;
45 
46  // define the mapping used by the JsonReader to deserialize the server response
47  // node: the server uses ArrayOutputStrategy to serialize nodes
48  jsonMapping = [];
49  // store requested node attributes in record fields
50  for (var i=0; i<columnDefs.length; i++)
51  jsonMapping[i] = {name:columnDefs[i].id};
52  // store generic node data in special record fields
53  jsonMapping.push({name:"DATATYPE_ATTRIBUTE", mapping:"values["+dataTypeMapping.DATATYPE_ATTRIBUTE+"]"});
54  jsonMapping.push({name:"DATATYPE_IGNORE", mapping:"values["+dataTypeMapping.DATATYPE_IGNORE+"]"});
55  jsonMapping.push({name:"_properties", mapping:"properties"});
56  jsonMapping.push({name:"_type", mapping:"type"});
57 
58  // create the Data Store
59  var storeConfig = {
60  proxy: new Ext.data.HttpProxy({
61  url:'<?php echo $APP_URL; ?>'
62  }),
63 
64  baseParams:{type:type, controller:'<?php echo $controller; ?>', context:'<?php echo $context; ?>', usr_action:'list', response_format:'JSON', sid:'<?php echo session_id() ?>', filter:filter, renderValues:true},
65 
66  reader:new Ext.data.JsonReader({
67  root:'objects',
68  totalProperty:'totalCount',
69  id:'oid'
70  }, jsonMapping),
71 
72  // turn on remote sorting
73  remoteSort:true
74  };
75  // add grouping information
76  if (config.groupBy) {
77  storeConfig['sortInfo'] = {field:'config.groupBy', direction:"ASC"};
78  storeConfig['groupField'] = config.groupBy;
79  this.ds = new Ext.data.GroupingStore(storeConfig);
80  }
81  else {
82  this.ds = new Ext.data.Store(storeConfig);
83  }
84 
85  // add custom parameters to baseParams
86  if (customParams)
87  for (var i in customParams)
88  this.ds.baseParams[i] = customParams[i];
89 
90  // translate column headers
91  for (var i=0; i<columnDefs.length; i++) {
92  columnDefs[i].header = Message.get(columnDefs[i].header);
93  }
94 
95  // add columns for row actions
96  var allColumns = [];
97  for (var i=0; i<columnDefs.length; i++)
98  allColumns.push(columnDefs[i]);
99  for (var i=0; i<this.actions.length; i++)
100  allColumns.push(this.actions[i]);
101 
102  // the column model has information about grid columns
103  // dataIndex maps the column to the specific data field in
104  // the data store
105  var cm = new Ext.grid.ColumnModel(allColumns);
106 
107  // create the page size toolbar with custom buttons
108  var topTb = new Ext.Toolbar();
109  if (title || config.paging || customBtns) {
110  var items = ['->'];
111  // add additional buttons
112  if (customBtns)
113  items.push(customBtns);
114 
115  // add page size buttons
116  if (config.paging) {
117  items.push('-');
118  items.push([
119  {text:'10', tooltip:Message.get('Display %1% items', [10]), handler:this.setPageSize.createDelegate(this, [10])},
120  {text:'25', tooltip:Message.get('Display %1% items', [25]), handler:this.setPageSize.createDelegate(this, [25])},
121  {text:'50', tooltip:Message.get('Display %1% items', [50]), handler:this.setPageSize.createDelegate(this, [50])},
122  {text:'100', tooltip:Message.get('Display %1% items', [100]), handler:this.setPageSize.createDelegate(this, [100])}
123  ]);
124  }
125 
126  topTb = new Ext.Toolbar({
127  items:items
128  });
129  }
130 
131  // create the paging toolbar
132  this.pagingTb = new Ext.Toolbar();
133  if (config.paging) {
134  this.pagingTb = new Ext.PagingToolbar({
135  store:this.ds,
136  pageSize:this.pageSize,
137  displayInfo:true,
138  displayMsg:Message.get('Displaying {0} - {1} of {2}'),
139  emptyMsg:Message.get('No objects to display')
140  });
141  }
142 
143  // create the grid
144  var autoHeight = (config.autoheight) ? true : false;
145  var ddRows = (config.ddRows) ? true : false;
146  var gridTitle = (config.qtip) ? '<span qtip="'+config.qtip+'">'+title+'</span>' : title;
147  var gridConfig = {
148  ds:this.ds,
149  cm:cm,
150  selModel:new Ext.grid.RowSelectionModel({singleSelect:config.singleSelect}),
151  autoHeight:autoHeight,
152  autoExpandColumn:allColumns[0].id,
153  collapsible:true,
154  animCollapse:false,
155  titleCollapse:true,
156  title:gridTitle,
157  loadMask:true,
158  enableDragDrop:ddRows,
159  ddGroup:'DDGroup',
160  ddText:Message.get('Drop {0} row(s) here'),
161  tbar:topTb,
162  bbar:this.pagingTb,
163  plugins:this.actions
164  }
165  // choose view depending on grouping
166  if (config.groupBy) {
167  gridConfig['view'] = new Ext.grid.GroupingView({
168  forceFit:true,
169  groupTextTpl: '{gvalue} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})',
170  hideGroupedColumn:true,
171  startCollapsed:true
172  });
173  }
174  else {
175  gridConfig['viewConfig'] = {
176  autoFill:true,
177  forceFit:true
178  };
179  }
180  this.grid = new Ext.grid.GridPanel(gridConfig);
181 
182  // add callback method to grid
183  this.grid.actionPerformed = function(record, arg, success) {
184  _this.actionPerformed(record, arg, success);
185  }
186 
187  // add click listener
188  this.grid.on("celldblclick", this.cellDblClicked, this);
189  this.grid.on("expand", this.onExpand, this);
190 
191  if (ddRows) {
192  // drag'n'drop support
193  this.grid.on("render", function(g) {
194  var ddrow = new Ext.ux.dd.GridReorderDropTarget(g, {
195  copy: false,
196  listeners: {
197  beforerowmove: function(objThis, oldIndex, newIndex, records) {
198  // return false to cancel the move
199  },
200  afterrowmove: function(objThis, oldIndex, newIndex, records) {
201  var dist = oldIndex - newIndex;
202  var actionName = (dist > 0) ? 'sortup' : 'sortdown';
203  Action.perform(actionName, {sortoid:records[0]['id'], dist:Math.abs(dist), filter:filter, sortcol:config.ddSortCol}, function(record, arg, success){}, _this);
204  },
205  beforerowcopy: function(objThis, oldIndex, newIndex, records) {
206  // return false to cancel the copy
207  },
208  afterrowcopy: function(objThis, oldIndex, newIndex, records) {
209  }
210  }
211  });
212  Ext.dd.ScrollManager.register(g.getView().getEditorParent());
213  });
214  this.grid.on("beforedestroy", function(g) {
215  Ext.dd.ScrollManager.unregister(g.getView().getEditorParent());
216  });
217  }
218  },
219 
220  /**
221  * Load the grid data
222  */
223  load: function() {
224  var self = this;
225  this.ds.reload({params:{start:0, limit:this.pageSize},
226  callback: function() {
227  self.grid.getView().refresh();
228  }
229  });
230  },
231 
232  /**
233  * Set the page size
234  * @param newPageSize The new page size
235  */
236  setPageSize: function(newPageSize) {
237  this.pageSize = newPageSize;
238  this.pagingTb.pageSize = this.pageSize; // Make sure pagination follows suit
239  this.load();
240  },
241 
242  /**
243  * Get the underlying grid
244  * @return The Ext.grid.GridPanel instance
245  */
246  getGridImpl: function() {
247  return this.grid;
248  },
249 
250  /**
251  * Handler for expand click
252  */
253  onExpand: function(grid) {
254  this.load();
255  },
256 
257  /**
258  * Handler for cell double click
259  */
260  cellDblClicked: function(grid, rowIndex, colIndex, e) {
261  // get the row record
262  var record = this.grid.getStore().getAt(rowIndex);
263  // perform the action
264  if (this.actions.length > 0) {
265  action = this.actions[0];
266  actionNames = action.getSupportedActions();
267  action.performAction(actionNames[0], record);
268  }
269  },
270 
271  /**
272  * Callback
273  */
274  actionPerformed: function(record, arg, success) {
275  this.load();
276  },
277 
278  /**
279  * Default column render function. Displays the id value of the column definition
280  */
281  renderColumnDefault: function(value, cellMeta, record, rowIndex, colIndex, store) {
282  // try to get the value from the object
283  var value = record.data.DATATYPE_ATTRIBUTE[cellMeta.id];
284  if (value) {
285  return value;
286  }
287  else {
288  // or from the realSubject if given
289  var realSubject = record.data._properties.realSubject;
290  if (realSubject)
291  return realSubject.values[dataTypeMapping.DATATYPE_ATTRIBUTE][cellMeta.id];
292  }
293  return '-'
294  }
295 };
get($message, $parameters=null, $domain='', $lang='')
Use the Message class to output messages. You need not instantiate a Message object because the metho...