EditorGrid.js (9765B)
1 /** 2 * This class extends a regular GridPanel with the following features: 3 * 4 * - Buttons to add/delete items 5 * - Enable/Disable the delete button if an item is selected 6 * - Search field 7 * - Paging Toolbar 8 */ 9 Ext.define('PartKeepr.EditorGrid', { 10 extend: 'PartKeepr.BaseGrid', 11 alias: 'widget.EditorGrid', 12 13 /** 14 * @cfg {String} text The text for the "delete" button 15 */ 16 deleteButtonText: i18n("Delete Item"), 17 18 /** 19 * @cfg {String} text The path to the 'delete' icon 20 */ 21 deleteButtonIcon: '', 22 23 /** 24 * @cfg {String} text The CSS class for the 'delete' icon 25 */ 26 deleteButtonIconCls: 'web-icon delete', 27 28 /** 29 * @cfg {String} text The text for the "add" button 30 */ 31 addButtonText: i18n("Add Item"), 32 33 /** 34 * @cfg {String} text The path to the 'add' icon 35 */ 36 addButtonIcon: '', 37 38 /** 39 * @cfg {String} text The CSS class for the 'add' icon 40 */ 41 addButtonIconCls: 'web-icon add', 42 43 /** 44 * @cfg {Boolean} boolean Specifies whether to enable the top toolbar or not 45 */ 46 enableTopToolbar: true, 47 48 /** 49 * @cfg {String} text Defines if the "add"/"delete" buttons should show their text or icon only. If "hide", the 50 * button text is hidden, anything else shows the text. 51 */ 52 buttonTextMode: 'hide', 53 54 /** 55 * @cfg {Boolean} boolean Defines if the grid should automatically calculate it's page size 56 */ 57 automaticPageSize: false, 58 59 /** 60 * @cfg {Integer} integer Defines the row height with which the calculator should assume 61 */ 62 automaticPageSizeRowHeight: 21, 63 64 /** 65 * @cfg {Boolean} boolean Defines if the list should be read-only, or if the list can be edited. Defaults to true. 66 */ 67 enableEditing: true, 68 69 /** 70 * @cfg {Boolean} boolean Defines if the edit event should pass the object (true) or as id (false) 71 */ 72 editItemAsObject: false, 73 74 /** 75 * @cfg {String} Specifies the system property which defines all fields to be searched 76 */ 77 searchFieldSystemPreference: null, 78 79 /** 80 * @cfg {Array} Specifies the default fields to be searched 81 */ 82 searchFieldSystemPreferenceDefaults: [], 83 84 /** 85 * @cfg {String} Specifies the system property which defines if the search terms should be splitted 86 */ 87 splitSearchTermSystemPreference: null, 88 89 /** 90 * @cfg {String} Specifies the default for search term splitting 91 */ 92 splitSearchTermSystemPreferenceDefaults: true, 93 94 /** 95 * @cfg {String} The title property 96 */ 97 titleProperty: null, 98 99 listeners: { 100 'reconfigure': 'onReconfigure' 101 }, 102 103 /** 104 * @event itemSelect 105 * Fires if a record was selected within the grid. 106 * @param {Object} Ext.data.Record The selected record 107 */ 108 initComponent: function () { 109 110 /** 111 * @event itemDeselect 112 * Fires if a record was deselected within the grid. 113 * @param {Object} record The deselected record 114 */ 115 116 /** 117 * @event itemEdit 118 * Fires if a record should be edited. 119 * @param {Object} record The record to edit 120 */ 121 122 /** 123 * @event itemDelete 124 * Fires if the delete button was clicked. 125 */ 126 127 /** 128 * @event itemAdd 129 * Fires if the add button was clicked. 130 */ 131 132 this.on("itemclick", this._onItemEdit, this); 133 134 this.deleteButton = Ext.create("Ext.button.Button", { 135 text: (this.buttonTextMode !== "hide") ? this.deleteButtonText : '', 136 tooltip: this.deleteButtonText, 137 icon: this.deleteButtonIcon, 138 iconCls: this.deleteButtonIconCls, 139 handler: Ext.bind(function () { 140 this.fireEvent("itemDelete"); 141 }, this), 142 disabled: true 143 }); 144 145 this.addButton = Ext.create("Ext.button.Button", { 146 text: (this.buttonTextMode !== "hide") ? this.addButtonText : '', 147 tooltip: this.addButtonText, 148 icon: this.addButtonIcon, 149 iconCls: this.addButtonIconCls, 150 handler: Ext.bind(function () { 151 this.fireEvent("itemAdd"); 152 }, this) 153 }); 154 155 var targetField = this.titleProperty; 156 157 this.searchField = Ext.create("PartKeepr.form.field.SearchField", { 158 store: this.store, 159 targetField: targetField, 160 searchFieldSystemPreference: this.searchFieldSystemPreference, 161 searchFieldSystemPreferenceDefaults: this.searchFieldSystemPreferenceDefaults, 162 splitSearchTermSystemPreference: this.splitSearchTermSystemPreference, 163 splitSearchTermSystemPreferenceDefaults: this.splitSearchTermSystemPreferenceDefaults 164 }); 165 166 var topToolbarItems = []; 167 168 if (this.enableEditing) 169 { 170 topToolbarItems.push(this.addButton); 171 topToolbarItems.push(this.deleteButton); 172 } 173 174 topToolbarItems.push({xtype: 'tbfill'}); 175 topToolbarItems.push(this.searchField); 176 177 this.topToolbar = Ext.create("Ext.toolbar.Toolbar", { 178 dock: 'top', 179 enableOverflow: true, 180 items: topToolbarItems 181 }); 182 183 this.bottomToolbar = Ext.create("PartKeepr.PagingToolbar", { 184 store: this.store, 185 enableOverflow: true, 186 dock: 'bottom', 187 displayInfo: false, 188 grid: this 189 }); 190 191 this.appliedFiltersToolbar = Ext.create("PartKeepr.Grid.AppliedFiltersToolbar", { 192 dock: 'bottom', 193 targetStore: this.store 194 }); 195 196 this.notificationBar = Ext.create("Ext.panel.Panel", { 197 dock: 'top', 198 hidden: true, 199 ui: 'notification' 200 }); 201 202 this.dockedItems = new Array(); 203 204 this.dockedItems.push(this.bottomToolbar); 205 this.dockedItems.push(this.appliedFiltersToolbar); 206 207 if (this.enableTopToolbar) 208 { 209 this.dockedItems.push(this.topToolbar); 210 } 211 212 if (!Ext.isArray(this.plugins)) 213 { 214 this.plugins = []; 215 } 216 217 this.callParent(); 218 219 this.addDocked(this.notificationBar); 220 this.getSelectionModel().on("select", this._onItemSelect, this); 221 this.getSelectionModel().on("deselect", this._onItemDeselect, this); 222 this.getView().on("itemkeydown", this._onItemKeyPress, this); 223 this.getStore().on("filterchange", this._onFilterChange, this); 224 225 if (this.automaticPageSize) 226 { 227 this.on("resize", this.reassignPageSize, this); 228 } 229 }, 230 _onFilterChange: function () { 231 var filters = this.getStore().getFilters(); 232 233 if (filters.length > 0) 234 { 235 this.bottomToolbar.down("#resetFilter").show(); 236 } else 237 { 238 this.bottomToolbar.down("#resetFilter").hide(); 239 } 240 241 this.appliedFiltersToolbar.updateFilters(filters); 242 243 }, 244 /** 245 * Sets a notification which is displayed on the grid's top dock 246 * @param message 247 */ 248 setNotification: function (message) { 249 this.notificationBar.setHtml(message); 250 this.notificationBar.show(); 251 }, 252 /** 253 * Removes a previously set notification 254 */ 255 removeNotification: function () { 256 this.notificationBar.hide(); 257 }, 258 /** 259 * Re-calculates and re-assigns the page size for the assigned store. 260 * 261 * Automatically reloads the store. 262 */ 263 reassignPageSize: function () { 264 if (this.store.isLoading()) 265 { 266 return; 267 } 268 if (this.getView().getHeight() === 0) 269 { 270 return; 271 } 272 273 var numRecords = Math.floor(this.getView().getHeight() / this.automaticPageSizeRowHeight); 274 275 if (numRecords < 1) 276 { 277 numRecords = 1; 278 } 279 280 var oldStartIndex = this.store.pageSize * this.store.currentPage; 281 282 this.store.pageSize = numRecords; 283 284 var newStartPage = Math.floor(oldStartIndex / numRecords); 285 286 if (newStartPage < 1) 287 { 288 newStartPage = 1; 289 } 290 291 this.store.loadPage(newStartPage); 292 }, 293 onReconfigure: function (me, store) { 294 this.searchField.setStore(store); 295 this.bottomToolbar.setStore(store); 296 297 }, 298 syncChanges: function () { 299 // Simply reload the store for now 300 this.store.load(); 301 }, 302 /** 303 * Called when an item was selected. Enables/disables the delete button. 304 */ 305 _updateDeleteButton: function () { 306 /* Right now, we support delete on a single record only */ 307 if (this.getSelectionModel().getCount() == 1) 308 { 309 this.deleteButton.enable(); 310 } else 311 { 312 this.deleteButton.disable(); 313 } 314 }, 315 _onItemKeyPress: function (view, record, item, index, e) { 316 if (e.getKey() == e.ENTER || e.getKey() == e.TAB) 317 { 318 this._onItemEdit(view, record); 319 } 320 }, 321 /** 322 * Called when an item should be edited 323 */ 324 _onItemEdit: function (view, record) { 325 if (this.editItemAsObject) 326 { 327 this.fireEvent("itemEdit", record); 328 } else 329 { 330 this.fireEvent("itemEdit", record.getId()); 331 } 332 }, 333 /** 334 * Called when an item was selected 335 */ 336 _onItemSelect: function (selectionModel, record) { 337 this._updateDeleteButton(selectionModel, record); 338 this.fireEvent("itemSelect", record); 339 }, 340 /** 341 * Called when an item was deselected 342 */ 343 _onItemDeselect: function (selectionModel, record) { 344 this._updateDeleteButton(selectionModel, record); 345 this.fireEvent("itemDeselect", record); 346 } 347 });