summaryrefslogtreecommitdiff
path: root/frontend/beta/js/YUI-extensions/data/XMLDataModel.js
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
commitef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (unidiff)
treec403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/beta/js/YUI-extensions/data/XMLDataModel.js
parent597ecfbc0249d83e1b856cbd558340c01237a360 (diff)
downloadclipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2
First version of the newly restructured repository
Diffstat (limited to 'frontend/beta/js/YUI-extensions/data/XMLDataModel.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/YUI-extensions/data/XMLDataModel.js274
1 files changed, 274 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/data/XMLDataModel.js b/frontend/beta/js/YUI-extensions/data/XMLDataModel.js
new file mode 100644
index 0000000..e312a9e
--- a/dev/null
+++ b/frontend/beta/js/YUI-extensions/data/XMLDataModel.js
@@ -0,0 +1,274 @@
1/**
2 * @class YAHOO.ext.grid.XMLDataModel
3 * This is an implementation of a DataModel used by the Grid. It works
4 * with XML data.
5 * <br>Example schema from Amazon search:
6 * <pre><code>
7 * var schema = {
8 * tagName: 'Item',
9 * id: 'ASIN',
10 * fields: ['Author', 'Title', 'Manufacturer', 'ProductGroup']
11 * };
12 * </code></pre>
13 * @extends YAHOO.ext.grid.LoadableDataModel
14 * @constructor
15 * @param {Object} schema The schema to use
16 * @param {XMLDocument} xml An XML document to load immediately
17*/
18YAHOO.ext.grid.XMLDataModel = function(schema, xml){
19 YAHOO.ext.grid.XMLDataModel.superclass.constructor.call(this, YAHOO.ext.grid.LoadableDataModel.XML);
20 /**@private*/
21 this.schema = schema;
22 this.xml = xml;
23 if(xml){
24 this.loadData(xml);
25 }
26 this.idSeed = 0;
27};
28YAHOO.extendX(YAHOO.ext.grid.XMLDataModel, YAHOO.ext.grid.LoadableDataModel, {
29
30 getDocument: function(){
31 return this.xml;
32 },
33
34 /**
35 * Overrides loadData in LoadableDataModel to process XML
36 * @param {XMLDocument} doc The document to load
37 * @param {<i>Function</i>} callback (optional) callback to call when loading is complete
38 * @param {<i>Boolean</i>} keepExisting (optional) true to keep existing data
39 * @param {<i>Number</i>} insertIndex (optional) if present, loaded data is inserted at the specified index instead of overwriting existing data
40 */
41 loadData: function(doc, callback, keepExisting, insertIndex){
42 this.xml = doc;
43 var idField = this.schema.id;
44 var fields = this.schema.fields;
45 if(this.schema.totalTag){
46 this.totalCount = null;
47 var totalNode = doc.getElementsByTagName(this.schema.totalTag);
48 if(totalNode && totalNode.item(0) && totalNode.item(0).firstChild) {
49 var v = parseInt(totalNode.item(0).firstChild.nodeValue, 10);
50 if(!isNaN(v)){
51 this.totalCount = v;
52 }
53 }
54 }
55 var rowData = [];
56 var nodes = doc.getElementsByTagName(this.schema.tagName);
57 if(nodes && nodes.length > 0) {
58 for(var i = 0; i < nodes.length; i++) {
59 var node = nodes.item(i);
60 var colData = [];
61 colData.node = node;
62 colData.id = this.getNamedValue(node, idField, String(++this.idSeed));
63 for(var j = 0; j < fields.length; j++) {
64 var val = this.getNamedValue(node, fields[j], "");
65 if(this.preprocessors[j]){
66 val = this.preprocessors[j](val);
67 }
68 colData.push(val);
69 }
70 rowData.push(colData);
71 }
72 }
73 if(keepExisting !== true){
74 YAHOO.ext.grid.XMLDataModel.superclass.removeAll.call(this);
75 }
76 if(typeof insertIndex != 'number'){
77 insertIndex = this.getRowCount();
78 }
79 YAHOO.ext.grid.XMLDataModel.superclass.insertRows.call(this, insertIndex, rowData);
80 if(typeof callback == 'function'){
81 callback(this, true);
82 }
83 this.fireLoadEvent();
84 },
85
86 /**
87 * Adds a row to this DataModel and syncs the XML document
88 * @param {String} id The id of the row, if null the next row index is used
89 * @param {Array} cellValues The cell values for this row
90 * @return {Number} The index of the new row (if the model is sorted this index may not be accurate)
91 */
92 addRow: function(id, cellValues){
93 var node = this.createNode(this.xml, id, cellValues);
94 cellValues.id = id || ++this.idSeed;
95 cellValues.node = node;
96 return YAHOO.ext.grid.XMLDataModel.superclass.addRow.call(this, cellValues);
97 },
98
99 /**
100 * Inserts a row into this DataModel and syncs the XML document
101 * @param {Number} index The index to insert the row
102 * @param {String} id The id of the row, if null the next row index is used
103 * @param {Array} cellValues The cell values for this row
104 * @return {Number} The index of the new row (if the model is sorted this index may not be accurate)
105 */
106 insertRow: function(index, id, cellValues){
107 var node = this.createNode(this.xml, id, cellValues);
108 cellValues.id = id || ++this.idSeed;
109 cellValues.node = node;
110 return YAHOO.ext.grid.XMLDataModel.superclass.insertRow.call(this, index, cellValues);
111 },
112
113 /**
114 * Removes the row from DataModel and syncs the XML document
115 * @param {Number} index The index of the row to remove
116 */
117 removeRow: function(index){
118 var node = this.data[index].node;
119 node.parentNode.removeChild(node);
120 YAHOO.ext.grid.XMLDataModel.superclass.removeRow.call(this, index, index);
121 },
122
123 getNode: function(rowIndex){
124 return this.data[rowIndex].node;
125 },
126
127 /**
128 * Override this method to define your own node creation routine for when new rows are added.
129 * By default this method clones the first node and sets the column values in the newly cloned node.
130 * In many instances this will not work and you will have to create the node manually.
131 * @param {XMLDocument} xmlDoc The xml document being used by this model
132 * @param {String/Number} id The row id
133 * @param {Array} colData The column data for the new node
134 * @return {XMLNode} The created node
135 */
136 createNode: function(xmlDoc, id, colData){
137 var template = this.data[0].node;
138 var newNode = template.cloneNode(true);
139 var fields = this.schema.fields;
140 for(var i = 0, len = fields.length; i < len; i++){
141 var nodeValue = colData[i];
142 if(this.postprocessors[i]){
143 nodeValue = this.postprocessors[i](nodeValue);
144 }
145 this.setNamedValue(newNode, fields[i], nodeValue);
146 }
147 if(id){
148 this.setNamedValue(newNode, this.schema.idField, id);
149 }
150 template.parentNode.appendChild(newNode);
151 return newNode;
152 },
153
154 /**
155 * @private
156 * Convenience function looks for value in attributes, then in children tags - also
157 * normalizes namespace matches (ie matches ns:tag, FireFox matches tag and not ns:tag).
158 */
159 getNamedValue: function(node, name, defaultValue){
160 if(!node || !name){
161 return defaultValue;
162 }
163 var nodeValue = defaultValue;
164 var attrNode = node.attributes.getNamedItem(name);
165 if(attrNode) {
166 nodeValue = attrNode.value;
167 } else {
168 var childNode = node.getElementsByTagName(name);
169 if(childNode && childNode.item(0) && childNode.item(0).firstChild) {
170 nodeValue = childNode.item(0).firstChild.nodeValue;
171 }else{
172 // try to strip namespace for FireFox
173 var index = name.indexOf(':');
174 if(index > 0){
175 return this.getNamedValue(node, name.substr(index+1), defaultValue);
176 }
177 }
178 }
179 return nodeValue;
180 },
181
182 /**
183 * @private
184 * Convenience function set a value in the underlying xml node.
185 */
186 setNamedValue: function(node, name, value){
187 if(!node || !name){
188 return;
189 }
190 var attrNode = node.attributes.getNamedItem(name);
191 if(attrNode) {
192 attrNode.value = value;
193 return;
194 }
195 var childNode = node.getElementsByTagName(name);
196 if(childNode && childNode.item(0) && childNode.item(0).firstChild) {
197 childNode.item(0).firstChild.nodeValue = value;
198 }else{
199 // try to strip namespace for FireFox
200 var index = name.indexOf(':');
201 if(index > 0){
202 this.setNamedValue(node, name.substr(index+1), value);
203 }
204 }
205 },
206
207 /**
208 * Overrides DefaultDataModel.setValueAt to update the underlying XML Document
209 * @param {Object} value The new value
210 * @param {Number} rowIndex
211 * @param {Number} colIndex
212 */
213 setValueAt: function(value, rowIndex, colIndex){
214 var node = this.data[rowIndex].node;
215 if(node){
216 var nodeValue = value;
217 if(this.postprocessors[colIndex]){
218 nodeValue = this.postprocessors[colIndex](value);
219 }
220 this.setNamedValue(node, this.schema.fields[colIndex], nodeValue);
221 }
222 YAHOO.ext.grid.XMLDataModel.superclass.setValueAt.call(this, value, rowIndex, colIndex);
223 },
224
225 /**
226 * Overrides getRowId in DefaultDataModel to return the ID value of the specified node.
227 * @param {Number} rowIndex
228 * @return {Number}
229 */
230 getRowId: function(rowIndex){
231 return this.data[rowIndex].id;
232 },
233
234 addRows : function(rowData){
235 for(var j = 0, len = rowData.length; j < len; j++){
236 var cellValues = rowData[j];
237 var id = ++this.idSeed;
238 var node = this.createNode(this.xml, id, cellValues);
239 cellValues.node=node;
240 cellValues.id = cellValues.id || id;
241 YAHOO.ext.grid.XMLDataModel.superclass.addRow.call(this,cellValues);
242 }
243 },
244
245 insertRows : function(index, rowData){
246 // copy original array so it is not reversed
247 rowData = rowData.slice(0).reverse();
248 for(var j = 0, len = rowData.length; j < len; j++){
249 var cellValues = rowData[j];
250 var id = ++this.idSeed;
251 var node = this.createNode(this.xml, id, cellValues);
252 cellValues.id = cellValues.id || id;
253 cellValues.node = node;
254 YAHOO.ext.grid.XMLDataModel.superclass.insertRow.call(this, index, cellValues);
255 }
256 }
257});
258
259YAHOO.ext.grid.XMLQueryDataModel = function(){
260 YAHOO.ext.grid.XMLQueryDataModel.superclass.constructor.apply(this, arguments);
261};
262YAHOO.extendX(YAHOO.ext.grid.XMLQueryDataModel, YAHOO.ext.grid.XMLDataModel, {
263 getNamedValue: function(node, name, defaultValue){
264 if(!node || !name){
265 return defaultValue;
266 }
267 var nodeValue = defaultValue;
268 var childNode = cssQuery(name, node);
269 if(childNode && childNode[0]) {
270 nodeValue = childNode[0].firstChild.nodeValue;
271 }
272 return nodeValue;
273 }
274});