This repository has been archived by the owner on Mar 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
index.html
223 lines (194 loc) · 10.6 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>CFQueryReader Demos: Custom ExtJS data reader for native ColdFusion query data</title>
<meta name="keywords" content="ColdFusion,Ext JS,ExtJS,Javascript,CFQueryReader" />
<meta name="description" content="CFQueryReader is a custom Ext data reader, to parse the native JSON return of a ColdFusion Query object." />
<meta name="author" content="Steve 'Cutter' Blades" />
<meta name="copyright" content="(c)2008 - 2012 Stephen Blades" />
<link rel="stylesheet" type="text/css" href="/css/default.css" />
<link rel="shortcut icon" href="/favicon_32x32.ico" />
</head>
<body>
<div id="content">
<img src="/images/cfqr-banner-865x160.gif" alt="CFQueryReader Logo" style="width:865px;height:160px;border:0;" /><br /><br />
<ul>
<li><b>Project:</b> - <a href="https://github.com/cutterbl/CFQueryReader" target="_blank">CFQueryReader</a></li>
<li><b>Author:</b> - <a href="http://www.cutterscrossing.com">Steve 'Cutter' Blades</a></li>
<li><b>Version:</b> - 2.2</li>
<li><b>Revised:</b> - 17 May, 2012</li>
<li><b>Tags:</b> - <a href="http://www.adobe.com/products/coldfusion" target="_blank">ColdFusion</a>, <a href="http://www.sencha.com/products/extjs/" target="_blank">Ext JS</a>, JavaScript, Development</li>
</ul><br />
<p style="font-style: italic;"><b>Note:</b> CFQueryReader has now been upgraded for Ext JS 4.x, and no further work will be done to support past versions. The last working version for Ext JS 2 & 3 is version 1.2. See our <a href="https://github.com/cutterbl/CFQueryReader" target="_blank">GitHub repository</a> for previous versions. Special thanks to Sencha's Ed Spencer for some of this verbiage, and to the whole Sencha team for Ext JS and SenchaTouch. Links to demos, using Ext JS 2, 3 and 4, can be found at the bottom of this page.</p><br />
<p>The CFQueryReader custom ExtJS Data Reader is used by a Proxy to read a ColdFusion server response that is sent back in JSON format. This usually happens as a result of loading a Store - for example we might create something like this:</p>
<pre><code>
Ext.define('User', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'email']
});
var store = Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url : '/some/cfc/path.cfc',
extraParams: {
method: 'someMethod',
returnFormat: 'json'
},
reader: {
type: 'cfquery'
}
}
});
</code></pre>
<p>The example above creates a 'User' model. Models are explained in the <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model" target="_blank">Model</a> docs if you're not already familiar with them.</p>
<p>We created the simplest type of CFQueryReader possible by simply telling our <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Store" target="_blank">Store</a>'s <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.Proxy" target="_blank">Proxy</a> that we want a CFQueryReader. The Store automatically passes the configured model to the Store, so it is as if we passed this instead:</p>
<pre><code>
reader: {
type : 'cfquery',
model: 'User'
}
</code></pre>
<p>The reader we set up is ready to read data from our server - at the moment it will accept a response like this:</p>
<pre><code>
{
"COLUMNS":["ID","NAME","EMAIL"],
"DATA":[
[1,"Ed Spencer","ed@sencha.com"],
[2,"Abe Elias","abe@sencha.com"],
[3,"Cutter","no@address.giv"]
]
}
</code></pre>
<p>CFQueryReader will also, natively, treat output from a ColdFusion <a href="http://www.cfquickdocs.com/cf9/#queryconvertforgrid" target="_blank">QueryConvertForGrid</a> function call. That function returns a ColdFusion struct, which is then serialized into a JSON object like this:</p>
<pre><code>
{
"TOTALROWCOUNT":3,
"QUERY":{
"COLUMNS":["ID","NAME","EMAIL"],
"DATA":[
[1,"Ed Spencer","ed@sencha.com"],
[2,"Abe Elias","abe@sencha.com"],
[3,"Cutter","no@address.giv"]
]
}
}
</code></pre>
<p>Reading this response is automatic for the CFQueryReader, with minimal configuration:</p>
<pre><code>
reader: {
type: 'cfquery'
}
</code></pre>
<p><u>Reading other JSON formats</u></p>
<p>If you already have your JSON format defined and it doesn't look quite like what we have above, you can usually pass CFQueryReader a couple of configuration options to make it parse your format. For example, we can use the {@link #query} configuration to parse data that comes back like this:</p>
<pre><code>
{
"recordCount":3,
"success":true,
"message":"",
"activeUsers":{
"COLUMNS":["ID","NAME","EMAIL"],
"DATA":[
[1,"Ed Spencer","ed@sencha.com"],
[2,"Abe Elias","abe@sencha.com"],
[3,"Cutter","no@address.giv"]
]
}
}
</code></pre>
<p>To parse this we just pass in a <em>query</em> configuration that matches the serialized query object above:</p>
<pre><code>
reader: {
type: 'cfquery',
query: 'activeUsers',
totalProperty: 'recordCount',
successProperty: 'success',
messageProperty: 'message'
}
</code></pre>
<p><u>Response MetaData</u></p>
<p>The server can return metadata in its response, in addition to the record data, that describe attributes of the data set itself or are used to reconfigure the Reader. To pass metadata in the response you simply add a `metaData` attribute to the root of the response data. The metaData attribute can contain anything, but supports a specific set of properties that are handled by the Reader if they are present:</p>
<ul>
<li><em>query</em>: the property name of the query response node containing the serialized ColdFusion query object</li>
<li><a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader-cfg-idProperty" target="_blank">idProperty</a>: property name for the primary key field of the data</li>
<li><a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader-cfg-totalProperty" target="_blank">totalProperty</a>: property name for the total number of records in the data</li>
<li><a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader-cfg-successProperty" target="_blank">successProperty</a>: property name for the success status of the response</li>
<li><a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader-cfg-messageProperty" target="_blank">messageProperty</a>: property name for an optional response message</li>
<li><a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model-cfg-fields" target="_blank">fields</a>: Config used to reconfigure the Model's fields before converting the response data into records</li>
</ul>
<p>An initial Reader configuration containing all of these properties might look like this ("fields" would be included in the Model definition, not shown):</p>
<pre><code>
reader: {
type : 'cfquery',
query : 'data',
idProperty : 'id',
totalProperty : 'total',
successProperty: 'success',
messageProperty: 'message'
}
</code></pre>
<p>If you were to pass a response object containing attributes different from those initially defined above, you could use the `metaData` attribute to reconifgure the Reader on the fly. For example:</p>
<pre><code>
{
"count": 3,
"ok": true,
"msg": "Users found",
"users":{
"COLUMNS":["ID","NAME","EMAIL"],
"DATA":[
[1,"Ed Spencer","ed@sencha.com"],
[2,"Abe Elias","abe@sencha.com"],
[3,"Cutter","no@address.giv"]
]
},
"metaData": {
"root": "users",
"idProperty": 'id',
"totalProperty": 'count',
"successProperty": 'ok',
"messageProperty": 'msg'
}
}
</code></pre>
<p>You can also place any other arbitrary data you need into the `metaData` attribute which will be ignored by the Reader, but will be accessible via the Reader's <a href="http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.reader.Reader-property-metaData" target="_blank">metaData</a> property (which is also passed to listeners via the Proxy's <a href="http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.proxy.Proxy-event-metachange" target="_blank">metachange</a> event (also relayed by the <a href="http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.AbstractStore-event-metachange" target="_blank">store</a>). Application code can then process the passed metadata in any way it chooses.</p>
<p>A simple example for how this can be used would be customizing the fields for a Model that is bound to a grid. By passing the `fields` property the Model will be automatically updated by the Reader internally, but that change will not be reflected automatically in the grid unless you also update the column configuration. You could do this manually, or you could simply pass a standard grid <a href="http://docs.sencha.com/ext-js/4-1/#!/api/Ext.grid.Panel-cfg-columns" target="_blank">column</a> config object as part of the `metaData` attribute and then pass that along to the grid. Here's a very simple example for how that could be accomplished:</p>
<pre><code>
// response format:
{
...
"metaData": {
"fields": [
{ "name": "userId", "type": "int" },
{ "name": "name", "type": "string" },
{ "name": "birthday", "type": "date", "dateFormat": "Y-j-m" },
],
"columns": [
{ "text": "User ID", "dataIndex": "userId", "width": 40 },
{ "text": "User Name", "dataIndex": "name", "flex": 1 },
{ "text": "Birthday", "dataIndex": "birthday", "flex": 1, "format": 'Y-j-m', "xtype": "datecolumn" }
]
}
}
</code></pre>
<p>The Reader will automatically read the meta fields config and rebuild the Model based on the new fields, but to handle the new column configuration you would need to handle the metadata within the application code. This is done simply enough by handling the metachange event on either the store or the proxy, e.g.:</p>
<pre><code>
var store = Ext.create('Ext.data.Store', {
...
listeners: {
'metachange': function(store, meta) {
myGrid.reconfigure(store, meta.columns);
}
}
});
</code></pre>
<ul>
<li><a href="/index-5.html" target="_blank">CFQueryReader Demo For ExtJS 4.1.0 - metaData</a></li>
<li><a href="/index-4.html" target="_blank">CFQueryReader Demo For ExtJS 4.1.0</a></li>
<li><a href="/index-3.html" target="_blank">CFQueryReader Demo For ExtJS 3.x</a></li>
<li><a href="/index-2.html" target="_blank">CFQueryReader Demo For ExtJS 2.x</a></li>
</ul>
</div>
</body>
</html>