📄 xmlchilddatamodel.js
字号:
/**
* Javascript file for Sugar
*
* SugarCRM is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004 - 2007 SugarCRM Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU General Public License version 3. * * In accordance with Section 7(b) of the GNU General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo. If the display of the logo is not reasonably feasible for * technical reasons, the Appropriate Legal Notices must display the words * "Powered by SugarCRM". */
/**
* @class
* This is an implementation of a DataModel used by the Grid. It works
* with XML data.
* <br>Example schema from Amazon search:
* <pre><code>
* var schema = {
* tagName: 'Item',
* id: 'ASIN',
* fields: ['Author', 'Title', 'Manufacturer', 'ProductGroup']
* };
var childSchema = {
* tagName: 'Item',
* id: 'ASIN',
* fields: ['Author', 'Title', 'Manufacturer', 'ProductGroup']
* };
* </code></pre>
* @extends YAHOO.ext.grid.LoadableDataModel
* @constructor
* @param {Object} schema The schema to use
* @param {Object} childSchema The child schema to use
* @param {XMLDocument} xml An XML document to load immediately
*/
YAHOO.ext.grid.XMLChildDataModel = function(schema, childSchema, xml){
YAHOO.ext.grid.XMLDataModel.superclass.constructor.call(this, YAHOO.ext.grid.LoadableDataModel.XML);
/**@private*/
this.schema = schema;
this.childSchema = childSchema;
this.xml = xml;
if(xml){
this.loadData(xml);
}
};
YAHOO.extendX(YAHOO.ext.grid.XMLChildDataModel, YAHOO.ext.grid.LoadableDataModel);
/**
* Overrides loadData in LoadableDataModel to process XML
* @param {XMLDocument} doc The document to load
* @param {<i>Function</i>} callback (optional) callback to call when loading is complete
* @param {<i>Boolean</i>} keepExisting (optional) true to keep existing data
* @param {<i>Number</i>} insertIndex (optional) if present, loaded data is inserted at the specified index instead of overwriting existing data
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.loadData = function(doc, callback, keepExisting, insertIndex){
this.xml = doc;
var idField = this.schema.id;
var fields = this.schema.fields;
//child fields
var childIdField = this.childSchema.id;
var childFields = this.childSchema.fields;
if(this.schema.totalTag){
this.totalCount = null;
var totalNode = doc.getElementsByTagName(this.schema.totalTag);
if(totalNode && totalNode.item(0) && totalNode.item(0).firstChild) {
var v = parseInt(totalNode.item(0).firstChild.nodeValue, 10);
if(!isNaN(v)){
this.totalCount = v;
}
}
}
var rowData = [];
var nodes = doc.getElementsByTagName(this.schema.tagName);
if(nodes && nodes.length > 0) {
var idCount = 0;
for(var i = 0; i < nodes.length; i++) {
//get the ith parent node
var node = nodes.item(i);
var colData = [];
//here we will add the concept of child nodes
colData.node = node;
colData.id = String(idCount);//this.getNamedValue(node, idField, String(idCount));
colData.isParent = true;
colData.parentId = colData.id;
for(var j = 0; j < fields.length; j++) {
var val = this.getNamedValue(node, fields[j], "");
if(this.preprocessors[j]){
val = this.preprocessors[j](val);
}//fi
colData.push(val);
}//rof
idCount++;
//now that we have the parent data let's try to get the
//child data
//rowData.push(colData);
var childNodes = node.getElementsByTagName(this.childSchema.tagName);
var children = [];
if(childNodes && childNodes.length > 0){
for(var k = 0; k < childNodes.length; k++){
var childNode = childNodes.item(k);
var childData = [];
childData.node = childNode;
childData.id = String(idCount);//this.getNamedValue(childNode, childIdField, String(idCount));
childData.isParent = false;
//alert(colData.id);
//alert("idCount: "+idCount);
childData.parentId = colData.id;
for(var l = 0; l < childFields.length; l++) {
var val = this.getNamedValue(childNode, childFields[l], "");
if(this.preprocessors[l]){
val = this.preprocessors[l](val);
}//fi
childData.push(val);
}//rof
idCount++;
children.push(childData);
//rowData.push(childData);
}//rof
colData.children = children;
}//fi
rowData.push(colData);
if(colData.children){
for(var p = 0; p < colData.children.length; p++){
rowData.push(colData.children[p]);
}//rof
}//fi
}//rof
}
if(keepExisting !== true){
YAHOO.ext.grid.XMLChildDataModel.superclass.removeAll.call(this);
}
if(typeof insertIndex != 'number'){
insertIndex = this.getRowCount();
}
YAHOO.ext.grid.XMLChildDataModel.superclass.insertRows.call(this, insertIndex, rowData);
if(typeof callback == 'function'){
callback(this, true);
}
this.fireLoadEvent();
};
/**
* Overload
* Returns the column data for the specified rows as a
* multi-dimensional array: rows[3][0] would give you the value of row 4, column 0.
* @param {Array} indexes The row indexes to fetch
* @return {Array}
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.getRows = function(indexes){
var data = this.data;
var r = [];
for(var i = 0; i < indexes.length; i++){
r.push(data[indexes[i]]);
if(data[indexes[i]].isParent){
for(var j = 0; j < data[indexes[i]].children.length; j++){
r.push(data[indexes[i]+j+1]);
}//rof
}//fi
}
return r;
};
/**
* Adds a row to this DataModel and syncs the XML document
* @param {String} id The id of the row, if null the next row index is used
* @param {Array} cellValues The cell values for this row
* @return {Number} The index of the new row
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.addRow = function(id, cellValues){
var newIndex = this.getRowCount();
var node = this.createNode(this.xml, id, cellValues);
cellValues.id = id || newIndex;
cellValues.node = node;
YAHOO.ext.grid.XMLChildDataModel.superclass.addRow.call(this, cellValues);
return newIndex;
};
/**
* Inserts a row into this DataModel and syncs the XML document
* @param {Number} index The index to insert the row
* @param {String} id The id of the row, if null the next row index is used
* @param {Array} cellValues The cell values for this row
* @return {Number} The index of the new row
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.insertRow = function(index, id, cellValues){
var node = this.createNode(this.xml, id, cellValues);
cellValues.id = id || this.getRowCount();
cellValues.node = node;
YAHOO.ext.grid.XMLChildDataModel.superclass.insertRow.call(this, index, cellValues);
return index;
};
/**
* Retrieve a row by the id
* @param {String} id The id of the row, if null the next row index is used
* @return {Object} The row with the corresponding id
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.getRowById = function(id){
for(var i = 0; i < this.data.length; i++){
if(this.data[i].id == id){
return this.data[i];
}
}
return null;
};
/**
* Retrieve the row index with the corresponding id
* @param {String} id The id of the row, if null the next row index is used
* @return {Object} The index of the row with the corresponding id
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.getRowIndexById = function(id){
for(var i = 0; i < this.data.length; i++){
if(this.data[i].id == id)
return i;
}
return null;
};
/**
* Removes the row from DataModel and syncs the XML document
* @param {Number} index The index of the row to remove
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.removeRow = function(index){
var node = this.data[index].node;
var rIndex = 0;
if(this.data[index].isParent){
for(var i = 0; i < this.data[index].children.length; i++){
var cNode = this.data[index + 1].node;
if(cNode.parentNode != null)
cNode.parentNode.removeChild(cNode);
YAHOO.ext.grid.XMLChildDataModel.superclass.removeRow.call(this, index + 1, index + 1);
rIndex++;
}//rof
}else{
//this is a child node
var topNode = this.getRowById(this.data[index].parentId);
if(topNode){
var newChildren = [];
for(var i = 0; i < topNode.children.length; i++){
if(this.data[index].id != topNode.children[i].id){
newChildren.push(topNode.children[i]);
}
}//rof
topNode.children = newChildren;
}//fi
}
if(node.parentNode != null)
node.parentNode.removeChild(node);
YAHOO.ext.grid.XMLChildDataModel.superclass.removeRow.call(this, index, index);
};
YAHOO.ext.grid.XMLChildDataModel.prototype.getNode = function(rowIndex){
return this.data[rowIndex].node;
};
/**
* Override this method to define your own node creation routine for when new rows are added.
* By default this method clones the first node and sets the column values in the newly cloned node.
* @param {XMLDocument} xmlDoc The xml document being used by this model
* @param {Array} colData The column data for the new node
* @return {XMLNode} The created node
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.createNode = function(xmlDoc, id, colData){
var template = this.data[0].node;
var newNode = template.cloneNode(true);
var fields = this.schema.fields;
for(var i = 0; i < fields.length; i++){
var nodeValue = colData[i];
if(this.postprocessors[i]){
nodeValue = this.postprocessors[i](nodeValue);
}
this.setNamedValue(newNode, fields[i], nodeValue);
}
if(id){
this.setNamedValue(newNode, this.schema.idField, id);
}
template.parentNode.appendChild(newNode);
return newNode;
};
/**
* Convenience function looks for value in attributes, then in children tags - also
* normalizes namespace matches (ie matches ns:tag, FireFox matches tag and not ns:tag).
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.getNamedValue = function(node, name, defaultValue){
if(!node || !name){
return defaultValue;
}
var nodeValue = defaultValue;
var attrNode = node.attributes.getNamedItem(name);
if(attrNode) {
nodeValue = attrNode.value;
} else {
var childNode = node.getElementsByTagName(name);
if(childNode && childNode.item(0) && childNode.item(0).firstChild) {
nodeValue = childNode.item(0).firstChild.nodeValue;
}else{
// try to strip namespace for FireFox
var index = name.indexOf(':');
if(index > 0){
return this.getNamedValue(node, name.substr(index+1), defaultValue);
}
}
}
return nodeValue;
};
/**
* Convenience function set a value in the underlying xml node.
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.setNamedValue = function(node, name, value){
if(!node || !name){
return;
}
var attrNode = node.attributes.getNamedItem(name);
if(attrNode) {
attrNode.value = value;
return;
}
var childNode = node.getElementsByTagName(name);
if(childNode && childNode.item(0) && childNode.item(0).firstChild) {
childNode.item(0).firstChild.nodeValue = value;
}else{
// try to strip namespace for FireFox
var index = name.indexOf(':');
if(index > 0){
this.setNamedValue(node, name.substr(index+1), value);
}
}
};
/**
* Overrides DefaultDataModel.setValueAt to update the underlying XML Document
* @param {Object} value The new value
* @param {Number} rowIndex
* @param {Number} colIndex
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.setValueAt = function(value, rowIndex, colIndex){
var node = this.data[rowIndex].node;
if(node){
var nodeValue = value;
if(this.postprocessors[colIndex]){
nodeValue = this.postprocessors[colIndex](value);
}
this.setNamedValue(node, this.schema.fields[colIndex], nodeValue);
}
YAHOO.ext.grid.XMLDataModel.superclass.setValueAt.call(this, value, rowIndex, colIndex);
};
/**
* Overrides getRowId in DefaultDataModel to return the ID value of the specified node.
* @param {Number} rowIndex
* @return {Number}
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.getRowId = function(rowIndex){
//alert(rowIndex);
return this.data[rowIndex].id;
};
/**
* Return the number of children in the grid
* @return {Number}
*/
YAHOO.ext.grid.XMLChildDataModel.prototype.getChildrenCount = function(){
var count = 0;
for(var i = 0; i < this.data.length; i++){
if(!this.data[i].isParent)
count++;
}
return count;
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -