]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * Provides indentation and folder structure markup for a Tree taking into account\r | |
3 | * depth and position within the tree hierarchy.\r | |
4 | */\r | |
5 | Ext.define('Ext.tree.Column', {\r | |
6 | extend: 'Ext.grid.column.Column',\r | |
7 | alias: 'widget.treecolumn',\r | |
8 | \r | |
9 | tdCls: Ext.baseCSSPrefix + 'grid-cell-treecolumn',\r | |
10 | \r | |
11 | autoLock: true,\r | |
12 | lockable: false,\r | |
13 | draggable: false,\r | |
14 | hideable: false,\r | |
15 | \r | |
16 | iconCls: Ext.baseCSSPrefix + 'tree-icon',\r | |
17 | checkboxCls: Ext.baseCSSPrefix + 'tree-checkbox',\r | |
18 | elbowCls: Ext.baseCSSPrefix + 'tree-elbow',\r | |
19 | expanderCls: Ext.baseCSSPrefix + 'tree-expander',\r | |
20 | textCls: Ext.baseCSSPrefix + 'tree-node-text',\r | |
21 | innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-treecolumn',\r | |
22 | customIconCls: Ext.baseCSSPrefix + 'tree-icon-custom',\r | |
23 | isTreeColumn: true,\r | |
24 | \r | |
25 | cellTpl: [\r | |
26 | '<tpl for="lines">',\r | |
27 | '<div class="{parent.childCls} {parent.elbowCls}-img ',\r | |
28 | '{parent.elbowCls}-<tpl if=".">line<tpl else>empty</tpl>" role="presentation"></div>',\r | |
29 | '</tpl>',\r | |
30 | '<div class="{childCls} {elbowCls}-img {elbowCls}',\r | |
31 | '<tpl if="isLast">-end</tpl><tpl if="expandable">-plus {expanderCls}</tpl>" role="presentation"></div>',\r | |
32 | '<tpl if="checked !== null">',\r | |
33 | '<div role="button" {ariaCellCheckboxAttr}',\r | |
34 | ' class="{childCls} {checkboxCls}<tpl if="checked"> {checkboxCls}-checked</tpl>"></div>',\r | |
35 | '</tpl>',\r | |
36 | '<tpl if="icon"><img src="{blankUrl}"<tpl else><div</tpl>',\r | |
37 | ' role="presentation" class="{childCls} {baseIconCls} {customIconCls} ',\r | |
38 | '{baseIconCls}-<tpl if="leaf">leaf<tpl else><tpl if="expanded">parent-expanded<tpl else>parent</tpl></tpl> {iconCls}" ',\r | |
39 | '<tpl if="icon">style="background-image:url({icon})"/><tpl else>></div></tpl>',\r | |
40 | '<tpl if="href">',\r | |
41 | '<a href="{href}" role="link" target="{hrefTarget}" class="{textCls} {childCls}">{value}</a>',\r | |
42 | '<tpl else>',\r | |
43 | '<span class="{textCls} {childCls}">{value}</span>',\r | |
44 | '</tpl>'\r | |
45 | ],\r | |
46 | \r | |
47 | // fields that will trigger a change in the ui that aren't likely to be bound to a column\r | |
48 | uiFields: {\r | |
49 | checked: 1,\r | |
50 | icon: 1,\r | |
51 | iconCls: 1\r | |
52 | },\r | |
53 | \r | |
54 | // fields that requires a full row render\r | |
55 | rowFields: {\r | |
56 | expanded: 1,\r | |
57 | loaded: 1,\r | |
58 | expandable: 1,\r | |
59 | leaf: 1,\r | |
60 | loading: 1,\r | |
61 | qtip: 1,\r | |
62 | qtitle: 1,\r | |
63 | cls: 1\r | |
64 | },\r | |
65 | \r | |
66 | initComponent: function() {\r | |
67 | var me = this;\r | |
68 | \r | |
69 | me.rendererScope = me.scope;\r | |
70 | me.setupRenderer();\r | |
71 | \r | |
72 | // This always uses its own renderer.\r | |
73 | // Any custom renderer is used as an inner renderer to produce the text node of a tree cell.\r | |
74 | me.innerRenderer = me.renderer;\r | |
75 | \r | |
76 | me.renderer = me.treeRenderer;\r | |
77 | \r | |
78 | me.callParent();\r | |
79 | \r | |
80 | me.scope = me;\r | |
81 | \r | |
82 | me.hasCustomRenderer = me.innerRenderer && me.innerRenderer.length > 1;\r | |
83 | },\r | |
84 | \r | |
85 | treeRenderer: function(value, metaData, record, rowIdx, colIdx, store, view){\r | |
86 | var me = this,\r | |
87 | cls = record.get('cls'),\r | |
88 | rendererData;\r | |
89 | \r | |
90 | // The initial render will inject the cls into the TD's attributes.\r | |
91 | // If cls is ever *changed*, then the full rendering path is followed.\r | |
92 | if (metaData && cls) {\r | |
93 | metaData.tdCls += ' ' + cls;\r | |
94 | }\r | |
95 | \r | |
96 | rendererData = me.initTemplateRendererData(value, metaData, record, rowIdx, colIdx, store, view);\r | |
97 | \r | |
98 | return me.getTpl('cellTpl').apply(rendererData);\r | |
99 | },\r | |
100 | \r | |
101 | initTemplateRendererData: function(value, metaData, record, rowIdx, colIdx, store, view) {\r | |
102 | var me = this,\r | |
103 | innerRenderer = me.innerRenderer,\r | |
104 | data = record.data,\r | |
105 | parent = record.parentNode,\r | |
106 | rootVisible = view.rootVisible,\r | |
107 | lines = [],\r | |
108 | parentData;\r | |
109 | \r | |
110 | while (parent && (rootVisible || parent.data.depth > 0)) {\r | |
111 | parentData = parent.data;\r | |
112 | lines[rootVisible ? parentData.depth : parentData.depth - 1] =\r | |
113 | parentData.isLast ? 0 : 1;\r | |
114 | parent = parent.parentNode;\r | |
115 | }\r | |
116 | \r | |
117 | return {\r | |
118 | record: record,\r | |
119 | baseIconCls: me.iconCls,\r | |
120 | customIconCls: (data.icon || data.iconCls) ? me.customIconCls : '',\r | |
121 | iconCls: data.iconCls,\r | |
122 | icon: data.icon,\r | |
123 | checkboxCls: me.checkboxCls,\r | |
124 | checked: data.checked,\r | |
125 | elbowCls: me.elbowCls,\r | |
126 | expanderCls: me.expanderCls,\r | |
127 | textCls: me.textCls,\r | |
128 | leaf: data.leaf,\r | |
129 | expandable: record.isExpandable(),\r | |
130 | expanded: data.expanded,\r | |
131 | isLast: record.isLastVisible(),\r | |
132 | blankUrl: Ext.BLANK_IMAGE_URL,\r | |
133 | href: data.href,\r | |
134 | hrefTarget: data.hrefTarget,\r | |
135 | lines: lines,\r | |
136 | metaData: metaData,\r | |
137 | // subclasses or overrides can implement a getChildCls() method, which can\r | |
138 | // return an extra class to add to all of the cell's child elements (icon,\r | |
139 | // expander, elbow, checkbox). This is used by the rtl override to add the\r | |
140 | // "x-rtl" class to these elements.\r | |
141 | childCls: me.getChildCls ? me.getChildCls() + ' ' : '',\r | |
142 | value: innerRenderer ? innerRenderer.apply(me.rendererScope, arguments) : value\r | |
143 | };\r | |
144 | },\r | |
145 | \r | |
146 | shouldUpdateCell: function(record, changedFieldNames) {\r | |
147 | // For the TreeColumn, if any of the known tree column UI affecting fields are updated\r | |
148 | // the cell should be updated in whatever way.\r | |
149 | // 1 if a custom renderer (not our default tree cell renderer), else 2.\r | |
150 | var me = this,\r | |
151 | i = 0,\r | |
152 | len, field;\r | |
153 | \r | |
154 | if (changedFieldNames) {\r | |
155 | len = changedFieldNames.length;\r | |
156 | \r | |
157 | for (; i < len; ++i) {\r | |
158 | field = changedFieldNames[i];\r | |
159 | // Check for fields which always require a full row update.\r | |
160 | if (me.rowFields[field]) {\r | |
161 | return 1;\r | |
162 | }\r | |
163 | \r | |
164 | // Check for fields which require this column to be updated.\r | |
165 | // The TreeColumn's treeRenderer is not a custom renderer.\r | |
166 | if (me.uiFields[field]) {\r | |
167 | return 2;\r | |
168 | }\r | |
169 | }\r | |
170 | }\r | |
171 | \r | |
172 | return me.callParent([record, changedFieldNames]);\r | |
173 | }\r | |
174 | });\r |