UNPKG

extjs-gpl

Version:

GPL licensed version of Sencha Ext JS

212 lines (198 loc) 7.16 kB
/** * This examples shows how heterogeneous models can be read into a TreeStore offering the * ability to have different entity types at different levels of a tree. * * The Model classes at each level of the tree are different types. So you can use associated * but different data types in your trees. The key to this is the `typeProperty` config on * the Proxy's Reader. * * A custom renderer is used to set the `glyph` property in the cell `metaData` to change * the icon depending upon the node type. * * The toolbar is aware of the type of the selected node and knows what kind of new entity * to add. */ Ext.define('KitchenSink.view.tree.HeterogeneousTree', { extend: 'Ext.tree.Panel', xtype: 'heterogeneous-tree', //<example> exampleTitle: 'Heterogeneous Geographical Tree', otherContent: [{ type: 'Store', path: 'classic/samples/store/GeoData.js' },{ type: 'Model', path: 'classic/samples/model/tree/Territory.js' },{ type: 'Model', path: 'classic/samples/model/tree/Country.js' },{ type: 'Model', path: 'classic/samples/model/tree/City.js' },{ type: 'Data', path: 'classic/samples/data/GeoData.js' }], //</example> store: 'GeoData', rootVisible: false, animate: false, frame: true, title: 'Heterogeneous Geographical Tree', width: 650, height: 400, reserveScrollbar: true, columns: [{ xtype: 'treecolumn', text: 'Name', dataIndex: 'name', flex: 1, sortable: true, renderer: function(v, metaData, record) { metaData.glyph = record.glyph; return v; } }, { xtype: 'actioncolumn', glyph: 'xf05a@FontAwesome', width: 25, getTip: function(value, meta, rec, rowIdx, colIdx, store, view) { // Go up from the view to the owning TreePanel var panel = view.up(''); return panel.getActionTip.apply(panel, arguments); }, handler: function(view) { // Go up from the view to the owning TreePanel var panel = view.up(''); panel.onDrillAction.apply(panel, arguments); } }], selModel: { allowDeselect: true, listeners: { selectionchange: function(selModel, selection) { // Go up from the view to the owning TreePanel var panel = selModel.view.up(''); panel.onSelectionChange.apply(panel, arguments); } }, onKeyEnter: function() { // Go up from the view to the owning TreePanel var panel = this.view.up(''); panel.down('#new-name').focus(); } }, bbar: [{ xtype: 'textfield', itemId: 'new-name', enableKeyEvents: true, listeners: { keydown: function(inputField, e) { // Go up from the view to the owning TreePanel var panel = inputField.up('treepanel'); if (e.keyCode === Ext.EventObject.ENTER) { if (!panel.down('#add-button').isDisabled()) { panel.addClick(); } } else if (e.keyCode === Ext.EventObject.TAB && e.shiftKey) { e.stopEvent(); panel.view.focusRow(panel.selModel.getSelection()[0] || 0); } } } }, { itemId: 'add-button', text: 'Add Territory', handler: function(button) { // Go up from the view to the owning TreePanel var panel = button.up('treepanel'); panel.addClick(); } }], addClick: function() { var target = this.selModel.getSelection()[0] || this.getRootNode(), inputField = this.down('#new-name'), value = inputField && inputField.getValue(), store = this.getStore(), node; if (value) { if (store.getNodeById(value)) { Ext.Msg.alert('Error', 'A node with this name already exists.'); return; } node = { name: value }; if (target.isRoot() ) { //Nothing selected -- adding new Territory node.children = []; node.mtype = 'Territory'; } else if (target instanceof KitchenSink.model.tree.Territory) { // Programatically added - must not try to load over Ajax node.children = []; node.mtype = 'Country'; } else if (target instanceof KitchenSink.model.tree.Country) { // Adding to the Country level - that is our leaf level node.leaf = true; node.mtype = 'City'; } node = target.appendChild(node); // User might want to see what they've just added! if (!target.isExpanded()) { target.expand(false); } this.selModel.select(node); inputField.reset(); } }, onSelectionChange: function(selModel, selection) { var button = this.down('#add-button'), selectedNode; if (selection.length) { selectedNode = selection[0]; if (selectedNode instanceof KitchenSink.model.tree.Territory) { this.addClass = KitchenSink.model.tree.Country; button.setText('Add Country'); button.enable(); } else if (selectedNode instanceof KitchenSink.model.tree.Country) { this.addClass = KitchenSink.model.tree.City; button.setText('Add City'); button.enable(); } else { button.disable(); } } else { this.addClass = KitchenSink.model.tree.Territory; button.setText('Add Territory'); button.enable(); } }, getActionTip: function(value, meta, rec, rowIdx, colIdx, store, view) { var dataType; switch (Ext.ClassManager.getName(rec)) { case "KitchenSink.model.tree.Territory": dataType = 'territory'; break; case "KitchenSink.model.tree.Country": dataType = 'country'; break; case "KitchenSink.model.tree.City": dataType = 'city'; } return 'Click for info on ' + dataType; }, onDrillAction: function(view, rowIndex, colIndex, row, event, rec) { var dataType; switch (Ext.ClassManager.getName(rec)) { case "KitchenSink.model.tree.Territory": dataType = 'territory'; break; case "KitchenSink.model.tree.Country": dataType = 'country'; break; case "KitchenSink.model.tree.City": dataType = 'city'; } Ext.Msg.alert('Action', 'Drill into ' + dataType + ' details'); } });