123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
- <style type="text/css">
- .highlight { display: block; background-color: #ddd; }
- </style>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-tree-Panel'>/**
- </span> * The TreePanel provides tree-structured UI representation of tree-structured data.
- * A TreePanel must be bound to a {@link Ext.data.TreeStore}. TreePanel's support
- * multiple columns through the {@link #columns} configuration.
- *
- * Simple TreePanel using inline data:
- *
- * @example
- * var store = Ext.create('Ext.data.TreeStore', {
- * root: {
- * expanded: true,
- * children: [
- * { text: "detention", leaf: true },
- * { text: "homework", expanded: true, children: [
- * { text: "book report", leaf: true },
- * { text: "alegrbra", leaf: true}
- * ] },
- * { text: "buy lottery tickets", leaf: true }
- * ]
- * }
- * });
- *
- * Ext.create('Ext.tree.Panel', {
- * title: 'Simple Tree',
- * width: 200,
- * height: 150,
- * store: store,
- * rootVisible: false,
- * renderTo: Ext.getBody()
- * });
- *
- * For the tree node config options (like `text`, `leaf`, `expanded`), see the documentation of
- * {@link Ext.data.NodeInterface NodeInterface} config options.
- */
- Ext.define('Ext.tree.Panel', {
- extend: 'Ext.panel.Table',
- alias: 'widget.treepanel',
- alternateClassName: ['Ext.tree.TreePanel', 'Ext.TreePanel'],
- requires: ['Ext.tree.View', 'Ext.selection.TreeModel', 'Ext.tree.Column', 'Ext.data.TreeStore'],
- viewType: 'treeview',
- selType: 'treemodel',
- treeCls: Ext.baseCSSPrefix + 'tree-panel',
- deferRowRender: false,
- <span id='Ext-tree-Panel-cfg-rowLines'> /**
- </span> * @cfg {Boolean} rowLines
- * False so that rows are not separated by lines.
- */
- rowLines: false,
- <span id='Ext-tree-Panel-cfg-lines'> /**
- </span> * @cfg {Boolean} lines
- * False to disable tree lines.
- */
- lines: true,
- <span id='Ext-tree-Panel-cfg-useArrows'> /**
- </span> * @cfg {Boolean} useArrows
- * True to use Vista-style arrows in the tree.
- */
- useArrows: false,
- <span id='Ext-tree-Panel-cfg-singleExpand'> /**
- </span> * @cfg {Boolean} singleExpand
- * True if only 1 node per branch may be expanded.
- */
- singleExpand: false,
- ddConfig: {
- enableDrag: true,
- enableDrop: true
- },
- <span id='Ext-tree-Panel-cfg-animate'> /**
- </span> * @cfg {Boolean} animate
- * True to enable animated expand/collapse. Defaults to the value of {@link Ext#enableFx}.
- */
- <span id='Ext-tree-Panel-cfg-rootVisible'> /**
- </span> * @cfg {Boolean} rootVisible
- * False to hide the root node.
- */
- rootVisible: true,
- <span id='Ext-tree-Panel-cfg-displayField'> /**
- </span> * @cfg {String} displayField
- * The field inside the model that will be used as the node's text.
- */
- displayField: 'text',
- <span id='Ext-tree-Panel-cfg-root'> /**
- </span> * @cfg {Ext.data.Model/Ext.data.NodeInterface/Object} root
- * Allows you to not specify a store on this TreePanel. This is useful for creating a simple tree with preloaded
- * data without having to specify a TreeStore and Model. A store and model will be created and root will be passed
- * to that store. For example:
- *
- * Ext.create('Ext.tree.Panel', {
- * title: 'Simple Tree',
- * root: {
- * text: "Root node",
- * expanded: true,
- * children: [
- * { text: "Child 1", leaf: true },
- * { text: "Child 2", leaf: true }
- * ]
- * },
- * renderTo: Ext.getBody()
- * });
- */
- root: null,
- // Required for the Lockable Mixin. These are the configurations which will be copied to the
- // normal and locked sub tablepanels
- normalCfgCopy: ['displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible', 'scroll'],
- lockedCfgCopy: ['displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible'],
-
- isTree: true,
- <span id='Ext-tree-Panel-cfg-hideHeaders'> /**
- </span> * @cfg {Boolean} hideHeaders
- * True to hide the headers.
- */
- <span id='Ext-tree-Panel-cfg-folderSort'> /**
- </span> * @cfg {Boolean} folderSort
- * True to automatically prepend a leaf sorter to the store.
- */
-
- <span id='Ext-tree-Panel-cfg-store'> /**
- </span> * @cfg {Ext.data.TreeStore} store (required)
- * The {@link Ext.data.TreeStore Store} the tree should use as its data source.
- */
- constructor: function(config) {
- config = config || {};
- if (config.animate === undefined) {
- config.animate = Ext.isDefined(this.animate) ? this.animate : Ext.enableFx;
- }
- this.enableAnimations = config.animate;
- delete config.animate;
- this.callParent([config]);
- },
- initComponent: function() {
- var me = this,
- cls = [me.treeCls],
- view;
- if (me.useArrows) {
- cls.push(Ext.baseCSSPrefix + 'tree-arrows');
- me.lines = false;
- }
- if (me.lines) {
- cls.push(Ext.baseCSSPrefix + 'tree-lines');
- } else if (!me.useArrows) {
- cls.push(Ext.baseCSSPrefix + 'tree-no-lines');
- }
- if (Ext.isString(me.store)) {
- me.store = Ext.StoreMgr.lookup(me.store);
- } else if (!me.store || Ext.isObject(me.store) && !me.store.isStore) {
- me.store = new Ext.data.TreeStore(Ext.apply({}, me.store || {}, {
- root: me.root,
- fields: me.fields,
- model: me.model,
- folderSort: me.folderSort
- }));
- } else if (me.root) {
- me.store = Ext.data.StoreManager.lookup(me.store);
- me.store.setRootNode(me.root);
- if (me.folderSort !== undefined) {
- me.store.folderSort = me.folderSort;
- me.store.sort();
- }
- }
- // I'm not sure if we want to this. It might be confusing
- // if (me.initialConfig.rootVisible === undefined && !me.getRootNode()) {
- // me.rootVisible = false;
- // }
- me.viewConfig = Ext.apply({}, me.viewConfig);
- me.viewConfig = Ext.applyIf(me.viewConfig, {
- rootVisible: me.rootVisible,
- animate: me.enableAnimations,
- singleExpand: me.singleExpand,
- node: me.store.getRootNode(),
- hideHeaders: me.hideHeaders
- });
- me.mon(me.store, {
- scope: me,
- rootchange: me.onRootChange,
- clear: me.onClear
- });
- me.relayEvents(me.store, [
- <span id='Ext-tree-Panel-event-beforeload'> /**
- </span> * @event beforeload
- * @inheritdoc Ext.data.TreeStore#beforeload
- */
- 'beforeload',
- <span id='Ext-tree-Panel-event-load'> /**
- </span> * @event load
- * @inheritdoc Ext.data.TreeStore#load
- */
- 'load'
- ]);
- me.mon(me.store, {
- <span id='Ext-tree-Panel-event-itemappend'> /**
- </span> * @event itemappend
- * @inheritdoc Ext.data.TreeStore#append
- */
- append: me.createRelayer('itemappend'),
- <span id='Ext-tree-Panel-event-itemremove'> /**
- </span> * @event itemremove
- * @inheritdoc Ext.data.TreeStore#remove
- */
- remove: me.createRelayer('itemremove'),
- <span id='Ext-tree-Panel-event-itemmove'> /**
- </span> * @event itemmove
- * @inheritdoc Ext.data.TreeStore#move
- */
- move: me.createRelayer('itemmove', [0, 4]),
- <span id='Ext-tree-Panel-event-iteminsert'> /**
- </span> * @event iteminsert
- * @inheritdoc Ext.data.TreeStore#insert
- */
- insert: me.createRelayer('iteminsert'),
- <span id='Ext-tree-Panel-event-beforeitemappend'> /**
- </span> * @event beforeitemappend
- * @inheritdoc Ext.data.TreeStore#beforeappend
- */
- beforeappend: me.createRelayer('beforeitemappend'),
- <span id='Ext-tree-Panel-event-beforeitemremove'> /**
- </span> * @event beforeitemremove
- * @inheritdoc Ext.data.TreeStore#beforeremove
- */
- beforeremove: me.createRelayer('beforeitemremove'),
- <span id='Ext-tree-Panel-event-beforeitemmove'> /**
- </span> * @event beforeitemmove
- * @inheritdoc Ext.data.TreeStore#beforemove
- */
- beforemove: me.createRelayer('beforeitemmove'),
- <span id='Ext-tree-Panel-event-beforeiteminsert'> /**
- </span> * @event beforeiteminsert
- * @inheritdoc Ext.data.TreeStore#beforeinsert
- */
- beforeinsert: me.createRelayer('beforeiteminsert'),
- <span id='Ext-tree-Panel-event-itemexpand'> /**
- </span> * @event itemexpand
- * @inheritdoc Ext.data.TreeStore#expand
- */
- expand: me.createRelayer('itemexpand', [0, 1]),
- <span id='Ext-tree-Panel-event-itemcollapse'> /**
- </span> * @event itemcollapse
- * @inheritdoc Ext.data.TreeStore#collapse
- */
- collapse: me.createRelayer('itemcollapse', [0, 1]),
- <span id='Ext-tree-Panel-event-beforeitemexpand'> /**
- </span> * @event beforeitemexpand
- * @inheritdoc Ext.data.TreeStore#beforeexpand
- */
- beforeexpand: me.createRelayer('beforeitemexpand', [0, 1]),
- <span id='Ext-tree-Panel-event-beforeitemcollapse'> /**
- </span> * @event beforeitemcollapse
- * @inheritdoc Ext.data.TreeStore#beforecollapse
- */
- beforecollapse: me.createRelayer('beforeitemcollapse', [0, 1])
- });
- // If the user specifies the headers collection manually then dont inject our own
- if (!me.columns) {
- if (me.initialConfig.hideHeaders === undefined) {
- me.hideHeaders = true;
- }
- me.addCls(Ext.baseCSSPrefix + 'autowidth-table');
- me.columns = [{
- xtype : 'treecolumn',
- text : 'Name',
- width : Ext.isIE6 ? null : 10000,
- dataIndex: me.displayField
- }];
- }
- if (me.cls) {
- cls.push(me.cls);
- }
- me.cls = cls.join(' ');
- me.callParent();
-
- view = me.getView();
- me.relayEvents(view, [
- <span id='Ext-tree-Panel-event-checkchange'> /**
- </span> * @event checkchange
- * Fires when a node with a checkbox's checked property changes
- * @param {Ext.data.NodeInterface} node The node who's checked property was changed
- * @param {Boolean} checked The node's new checked state
- */
- 'checkchange',
- <span id='Ext-tree-Panel-event-afteritemexpand'> /**
- </span> * @event afteritemexpand
- * @inheritdoc Ext.tree.View#afteritemexpand
- */
- 'afteritemexpand',
- <span id='Ext-tree-Panel-event-afteritemcollapse'> /**
- </span> * @event afteritemcollapse
- * @inheritdoc Ext.tree.View#afteritemcollapse
- */
- 'afteritemcollapse'
- ]);
- // If the root is not visible and there is no rootnode defined, then just lets load the store
- if (!view.rootVisible && !me.getRootNode()) {
- me.setRootNode({
- expanded: true
- });
- }
- },
-
- onClear: function(){
- this.view.onClear();
- },
- <span id='Ext-tree-Panel-method-setRootNode'> /**
- </span> * Sets root node of this tree.
- * @param {Ext.data.Model/Ext.data.NodeInterface/Object} root
- * @return {Ext.data.NodeInterface} The new root
- */
- setRootNode: function() {
- return this.store.setRootNode.apply(this.store, arguments);
- },
- <span id='Ext-tree-Panel-method-getRootNode'> /**
- </span> * Returns the root node for this tree.
- * @return {Ext.data.NodeInterface}
- */
- getRootNode: function() {
- return this.store.getRootNode();
- },
- onRootChange: function(root) {
- this.view.setRootNode(root);
- },
- <span id='Ext-tree-Panel-method-getChecked'> /**
- </span> * Retrieve an array of checked records.
- * @return {Ext.data.NodeInterface[]} An array containing the checked records
- */
- getChecked: function() {
- return this.getView().getChecked();
- },
- isItemChecked: function(rec) {
- return rec.get('checked');
- },
-
- <span id='Ext-tree-Panel-method-expandNode'> /**
- </span> * Expands a record that is loaded in the tree.
- * @param {Ext.data.Model} record The record to expand
- * @param {Boolean} [deep] True to expand nodes all the way down the tree hierarchy.
- * @param {Function} [callback] The function to run after the expand is completed
- * @param {Object} [scope] The scope of the callback function.
- */
- expandNode: function(record, deep, callback, scope) {
- return this.getView().expand(record, deep, callback, scope || this);
- },
- <span id='Ext-tree-Panel-method-collapseNode'> /**
- </span> * Collapses a record that is loaded in the tree.
- * @param {Ext.data.Model} record The record to collapse
- * @param {Boolean} [deep] True to collapse nodes all the way up the tree hierarchy.
- * @param {Function} [callback] The function to run after the collapse is completed
- * @param {Object} [scope] The scope of the callback function.
- */
- collapseNode: function(record, deep, callback, scope) {
- return this.getView().collapse(record, deep, callback, scope || this);
- },
- <span id='Ext-tree-Panel-method-expandAll'> /**
- </span> * Expand all nodes
- * @param {Function} [callback] A function to execute when the expand finishes.
- * @param {Object} [scope] The scope of the callback function
- */
- expandAll : function(callback, scope) {
- var me = this,
- root = me.getRootNode(),
- animate = me.enableAnimations,
- view = me.getView();
- if (root) {
- if (!animate) {
- view.beginBulkUpdate();
- }
- root.expand(true, callback, scope || me);
- if (!animate) {
- view.endBulkUpdate();
- }
- }
- },
- <span id='Ext-tree-Panel-method-collapseAll'> /**
- </span> * Collapse all nodes
- * @param {Function} [callback] A function to execute when the collapse finishes.
- * @param {Object} [scope] The scope of the callback function
- */
- collapseAll : function(callback, scope) {
- var me = this,
- root = me.getRootNode(),
- animate = me.enableAnimations,
- view = me.getView();
- if (root) {
- if (!animate) {
- view.beginBulkUpdate();
- }
- scope = scope || me;
- if (view.rootVisible) {
- root.collapse(true, callback, scope);
- } else {
- root.collapseChildren(true, callback, scope);
- }
- if (!animate) {
- view.endBulkUpdate();
- }
- }
- },
- <span id='Ext-tree-Panel-method-expandPath'> /**
- </span> * Expand the tree to the path of a particular node.
- * @param {String} path The path to expand. The path should include a leading separator.
- * @param {String} [field] The field to get the data from. Defaults to the model idProperty.
- * @param {String} [separator='/'] A separator to use.
- * @param {Function} [callback] A function to execute when the expand finishes. The callback will be called with
- * (success, lastNode) where success is if the expand was successful and lastNode is the last node that was expanded.
- * @param {Object} [scope] The scope of the callback function
- */
- expandPath: function(path, field, separator, callback, scope) {
- var me = this,
- current = me.getRootNode(),
- index = 1,
- view = me.getView(),
- keys,
- expander;
- field = field || me.getRootNode().idProperty;
- separator = separator || '/';
- if (Ext.isEmpty(path)) {
- Ext.callback(callback, scope || me, [false, null]);
- return;
- }
- keys = path.split(separator);
- if (current.get(field) != keys[1]) {
- // invalid root
- Ext.callback(callback, scope || me, [false, current]);
- return;
- }
- expander = function(){
- if (++index === keys.length) {
- Ext.callback(callback, scope || me, [true, current]);
- return;
- }
- var node = current.findChild(field, keys[index]);
- if (!node) {
- Ext.callback(callback, scope || me, [false, current]);
- return;
- }
- current = node;
- current.expand(false, expander);
- };
- current.expand(false, expander);
- },
- <span id='Ext-tree-Panel-method-selectPath'> /**
- </span> * Expand the tree to the path of a particular node, then select it.
- * @param {String} path The path to select. The path should include a leading separator.
- * @param {String} [field] The field to get the data from. Defaults to the model idProperty.
- * @param {String} [separator='/'] A separator to use.
- * @param {Function} [callback] A function to execute when the select finishes. The callback will be called with
- * (bSuccess, oLastNode) where bSuccess is if the select was successful and oLastNode is the last node that was expanded.
- * @param {Object} [scope] The scope of the callback function
- */
- selectPath: function(path, field, separator, callback, scope) {
- var me = this,
- root,
- keys,
- last;
- field = field || me.getRootNode().idProperty;
- separator = separator || '/';
- keys = path.split(separator);
- last = keys.pop();
- if (keys.length > 1) {
- me.expandPath(keys.join(separator), field, separator, function(success, node){
- var lastNode = node;
- if (success && node) {
- node = node.findChild(field, last);
- if (node) {
- me.getSelectionModel().select(node);
- Ext.callback(callback, scope || me, [true, node]);
- return;
- }
- }
- Ext.callback(callback, scope || me, [false, lastNode]);
- }, me);
- } else {
- root = me.getRootNode();
- if (root.getId() === last) {
- me.getSelectionModel().select(root);
- Ext.callback(callback, scope || me, [true, root]);
- } else {
- Ext.callback(callback, scope || me, [false, null]);
- }
- }
- }
- });
- </pre>
- </body>
- </html>
|