开发者社区
第1页:用XML和ASP实现一个灵活的购物车第2页:用XML和ASP实现一个灵活的购物车
列表B
function update() { /* Function: update Creation Date: May 5, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to apply bound Data Island changes to the full Data Island. This is accomplished by matching line numbers in both Data Islands. Once this has been completed the full Data Island is sent to the server via XMLHTTP. Update Date: Programmer: Description: */ var objXMLHTTP; // XMLHTTP request object var reWork = new RegExp('internet explorer','gi'); document.body.style.cursor = 'wait'; // Set cursor for(var i=0;i < objPage.bound.getElementsByTagName('row').length;i++) for(var j=0;j < objPage.full.getElementsByTagName('row').length;j++) if(objPage.bound.getElementsByTagName('line').item(i).firstChild.nodeValue == objPage.full.getElementsByTagName('line').item(j).firstChild.nodeValue) { for(var k=0;k < objPage.bound.getElementsByTagName('row').item(i).childNodes.length;k++) if(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName != '#text') switch(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName.toLowerCase()) { case('quantity'): case('selected'): try { objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).firstChild.nodeValue = objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.nodeValue; } catch(e) { try { objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).appendChild(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.cloneNode(true)); } catch(e) { } } break; } break; } // Send updates if(reWork.test(navigator.appName)) objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP'); else objXMLHTTP = new XMLHttpRequest(); objXMLHTTP.open('GET','xmlServer.asp',true); objXMLHTTP.setRequestHeader('content-type','text/xml'); objXMLHTTP.onreadystatechange = function() { var reWork = new RegExp('internet explorer','gi'); if(objXMLHTTP.readyState == 4) { if(reWork.test(navigator.appName)) objPage.full.XMLDocument.loadXML(unescape(objXMLHTTP.responseText)); else objPage.full.innerHTML = unescape(objXMLHTTP.responseText); //Handle empty page if(objPage.page() > objPage.pagecount()) objPage.showPrevious(); else objPage.showPage(); // Display page info document.getElementById('currentpage').lastChild.nodeValue = objPage.page(); document.getElementById('totalpages').lastChild.nodeValue = objPage.pagecount(); document.body.style.cursor = 'auto'; } } // IE work around try { objPage.full.innerHTML = objPage.full.XMLDocument.xml; } catch(e) { } if(reWork.test(navigator.appName)) objXMLHTTP.setRequestHeader('request',escape(objPage.full.XMLDocument.xml)); else objXMLHTTP.setRequestHeader('request',escape(objPage.full.innerHTML)); objXMLHTTP.send(null); }
在做进一步讲解之前,我会在同一个句子里使用Mozilla和XMLHTTP。有书面的证据表明Mozilla支持XMLHTTP。尽管其句法与Internet Explorer所用的句法稍有不同,但这并不是JavaScript无法处理的东西。完整的客户端解决方案见图A,而ASP见下面的列表C。
图A
列表C
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <title>New Page 2</title> </head> <body> <table cellPadding="0" width="100%" border="0" id="table1"> <tr> <td class="subhead1">Listing C</td> </tr> <tr bgColor="#ff0000"> <td height="1"> <img height="1" src="http://builder.com.com/i/tr/spacer.gif" width="1"></td> </tr> <tr> <td height="5"> <img height="5" src="http://builder.com.com/i/tr/spacer.gif" width="1"></td> </tr> <tr> <td> <%@ Language=JScript %> <% Response.Buffer = true; var strTitle = 'Honest Ed's Adventure Emporium'; Session('shoppingcart') = '<root>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>1</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>W01</item>'; Session('shoppingcart') += '<description>Swept hilt rapier</description>'; Session('shoppingcart') += '<weight>3.6</weight>'; Session('shoppingcart') += '<unitprice>195.95</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>2</line>'; Session('shoppingcart') += '<quantity>2</quantity>'; Session('shoppingcart') += '<item>W02</item>'; Session('shoppingcart') += '<description>Hand-and-a-half sword</description>'; Session('shoppingcart') += '<weight>5.8</weight>'; Session('shoppingcart') += '<unitprice>250.95</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>3</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>W03</item>'; Session('shoppingcart') += '<description>Wood long bow</description>'; Session('shoppingcart') += '<weight>2.7</weight>'; Session('shoppingcart') += '<unitprice>190.00</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>4</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>W04</item>'; Session('shoppingcart') += '<description>Wizard staff</description>'; Session('shoppingcart') += '<weight>3.1</weight>'; Session('shoppingcart') += '<unitprice>89.25</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>5</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>C01</item>'; Session('shoppingcart') += '<description>Gauntlets</description>'; Session('shoppingcart') += '<weight>0.7</weight>'; Session('shoppingcart') += '<unitprice>25.00</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>6</line>'; Session('shoppingcart') += '<quantity>5</quantity>'; Session('shoppingcart') += '<item>C02</item>'; Session('shoppingcart') += '<description>Knee-high boots</description>'; Session('shoppingcart') += '<weight>1.9</weight>'; Session('shoppingcart') += '<unitprice>95.00</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>7</line>'; Session('shoppingcart') += '<quantity>9</quantity>'; Session('shoppingcart') += '<item>C04</item>'; Session('shoppingcart') += '<description>Cloak</description>'; Session('shoppingcart') += '<weight>1.0</weight>'; Session('shoppingcart') += '<unitprice>125.00</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>8</line>'; Session('shoppingcart') += '<quantity>22</quantity>'; Session('shoppingcart') += '<item>C05</item>'; Session('shoppingcart') += '<description>Orc repellent</description>'; Session('shoppingcart') += '<weight>1.0</weight>'; Session('shoppingcart') += '<unitprice>8.95</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>9</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>W05</item>'; Session('shoppingcart') += '<description>Dwarf axe</description>'; Session('shoppingcart') += '<weight>8.0</weight>'; Session('shoppingcart') += '<unitprice>358.95</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>10</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>A01</item>'; Session('shoppingcart') += '<description>Steel cap</description>'; Session('shoppingcart') += '<weight>2.8</weight>'; Session('shoppingcart') += '<unitprice>219.95</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>11</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>A02</item>'; Session('shoppingcart') += '<description>Chainmail shirt</description>'; Session('shoppingcart') += '<weight>15.3</weight>'; Session('shoppingcart') += '<unitprice>487.22</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>12</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>A03</item>'; Session('shoppingcart') += '<description>Mithril shirt</description>'; Session('shoppingcart') += '<weight>0.4</weight>'; Session('shoppingcart') += '<unitprice>87236.03</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>13</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>W07</item>'; Session('shoppingcart') += '<description>Elvish long sword</description>'; Session('shoppingcart') += '<weight>1.9</weight>'; Session('shoppingcart') += '<unitprice>794.99</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>14</line>'; Session('shoppingcart') += '<quantity>1</quantity>'; Session('shoppingcart') += '<item>W08</item>'; Session('shoppingcart') += '<description>Elvish short sword</description>'; Session('shoppingcart') += '<weight>0.8</weight>'; Session('shoppingcart') += '<unitprice>435.99</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '<row>'; Session('shoppingcart') += '<selected></selected>'; Session('shoppingcart') += '<line>15</line>'; Session('shoppingcart') += '<quantity>3</quantity>'; Session('shoppingcart') += '<item>W09</item>'; Session('shoppingcart') += '<description>Short sword</description>'; Session('shoppingcart') += '<weight>1.5</weight>'; Session('shoppingcart') += '<unitprice>89.95</unitprice>'; Session('shoppingcart') += '</row>'; Session('shoppingcart') += '</root>'; %> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title><%=strTitle %></title> <style type="text/css"> TD { FONT-SIZE: 9pt; FONT-FAMILY: Tahoma } XML { WIDTH: 0px; HEIGHT: 0px; DISPLAY: none; } </style> <script language="JavaScript"> <!-- <![CDATA[ function setEvents() { /* Function: setEvents Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to create an instance of the xmlPage object, initialize the object and perform page initialization. Update Date: Programmer: Description: */ objPage = new xmlPage(); // Create instance for(var i=0;i < document.getElementsByTagName('input').length;i++) if(document.getElementsByTagName('input').item(i).getAttribute('type') == 'button') { document.getElementsByTagName('input').item(i).style.height = '26px'; document.getElementsByTagName('input').item(i).style.width = '100px'; document.getElementsByTagName('input').item(i).onmouseover = new Function('this.style.color = '#FF0000''); document.getElementsByTagName('input').item(i).onmouseout = new Function('this.style.color = '#000000''); } // Establish relationships objPage.bound = document.getElementById('xmlWindow'); objPage.full = document.getElementById('xmlFull'); objPage.table = document.getElementById('boundTable'); objPage.length(10); // Set page length objPage.showPage(); // Show first page // Display page info try { document.getElementById('currentpage').removeChild(document.getElementById('currentpage').firstChild); document.getElementById('totalpages').removeChild(document.getElementById('totalpages').firstChild); } catch(e) { } document.getElementById('currentpage').appendChild(document.createTextNode(objPage.page())); document.getElementById('totalpages').appendChild(document.createTextNode(objPage.pagecount())); } function update() { /* Function: update Creation Date: May 5, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to apply bound Data Island changes to the full Data Island. This is accomplished by matching line numbers in both Data Islands. Once this has been completed the full Data Island is sent to the server via XMLHTTP. Update Date: Programmer: Description: */ var objXMLHTTP; // XMLHTTP request object var reWork = new RegExp('internet explorer','gi'); document.body.style.cursor = 'wait'; // Set cursor for(var i=0;i < objPage.bound.getElementsByTagName('row').length;i++) for(var j=0;j < objPage.full.getElementsByTagName('row').length;j++) if(objPage.bound.getElementsByTagName('line').item(i).firstChild.nodeValue == objPage.full.getElementsByTagName('line').item(j).firstChild.nodeValue) { for(var k=0;k < objPage.bound.getElementsByTagName('row').item(i).childNodes.length;k++) if(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName != '#text') switch(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName.toLowerCase()) { case('quantity'): case('selected'): try { objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).firstChild.nodeValue = objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.nodeValue; } catch(e) { try { objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).appendChild(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.cloneNode(true)); } catch(e) { } } break; } break; } // Send updates if(reWork.test(navigator.appName)) objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP'); else objXMLHTTP = new XMLHttpRequest(); objXMLHTTP.open('GET','xmlServer.asp',true); objXMLHTTP.setRequestHeader('content-type','text/xml'); objXMLHTTP.onreadystatechange = function() { var reWork = new RegExp('internet explorer','gi'); if(objXMLHTTP.readyState == 4) { if(reWork.test(navigator.appName)) objPage.full.XMLDocument.loadXML(unescape(objXMLHTTP.responseText)); else objPage.full.innerHTML = unescape(objXMLHTTP.responseText); // Handle empty page if(objPage.page() > objPage.pagecount()) objPage.showPrevious(); else objPage.showPage(); // Display page info document.getElementById('currentpage').lastChild.nodeValue = objPage.page(); document.getElementById('totalpages').lastChild.nodeValue = objPage.pagecount(); document.body.style.cursor = 'auto'; } } // IE work around try { objPage.full.innerHTML = objPage.full.XMLDocument.xml; } catch(e) { } if(reWork.test(navigator.appName)) objXMLHTTP.setRequestHeader('request',escape(objPage.full.XMLDocument.xml)); else objXMLHTTP.setRequestHeader('request',escape(objPage.full.innerHTML)); objXMLHTTP.send(null); } function ieBusTable(objTable) { /* Function: ieBusTable Creation Date: April 30, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to remove the garbage that Microsoft Internet Explorer displays when a table's cell contains null. This porblem only applies to div and span tags. Update Date: Programmer: Description: */ var reWork = new RegExp('internet explorer','gi'); if(reWork.test(navigator.appName)) if(objTable.readyState == 'complete') { for(var i=0;i < objTable.getElementsByTagName('div').length;i++) if(objTable.getElementsByTagName('div').item(i).innerText.length == 0) objTable.getElementsByTagName('div').item(i).innerText = ' '; for(var i=0;i < objTable.getElementsByTagName('span').length;i++) if(objTable.getElementsByTagName('span').item(i).innerText.length == 0) objTable.getElementsByTagName('span').item(i).innerText = ' '; } } function xmlPage() { /* Function: xmlPage Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this class is to define the cross-browser (Mozill & IE) paging object. Update Date: Programmer: Description: */ // Variables var objCommonAncestor = null; // datafld common ancestor var objInitialTable = null; var strBound = null; // XML window data island var strXML = null; // XML full data island var strTable = null; // Bound HTML/XHTML table var intAbsolutePosition = 0; // Window item index var intPage = 1; // Logical page number var intLength = 15; // Logical page length var blnInitialize = false; // Initialize binds // Properties this.bound = null; // XML window data island this.full = null; // XML full data island this.table = null; // Bound HTML/XHTML table // Methods this.length = m_length; // Page length this.page = m_page; // Current page number this.pagecount = m_pageCount; // Calculate page count this.recordcount = m_recordCount; // "ADO recordset" recordcount this.showPage = m_showPage; // Show current page this.showFirst = m_showFirst; // "ADO recordset" movefirst this.showLast = m_showLast; // "ADO recordset" movelast this.showNext = m_showNext; // "ADO recordset" movenext this.showPrevious = m_showPrevious; // "ADO recordset" moveprevious function m_showPage() { /* Function: m_showPage Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to show the current page's information. This is accomplished by cloning the applicable nodes from the "full" Data Island to the "bound" Data Island. Update Date: Programmer: Description: May 13, 2003 Edmond Woychowsky Modified to invoke m_recordCount() to compute current record count. */ var objRoot = document.createElement('root'); var objXML = null; // XML DOM for IE if(!blnInitialize) initialize(this.bound,this.full,this.table); this.full = document.getElementById(strXML); this.bound = document.getElementById(strBound); // Remove existing nodes try { document.getElementById(strTable).innerHTML = objInitialTable.innerHTML; } catch(e) { } try { for(var i=0;i < this.bound.childNodes.length;i++) this.bound.removeChild(this.bound.childNodes.item(i)); } catch(e) { } // Add up to this.length nodes for(var i=intAbsolutePosition;i < (intAbsolutePosition + intLength);i++) if(i > (m_recordCount() - 1)) break; else { try { // Unique Mozilla logic objRoot.appendChild(this.full.getElementsByTagName(objCommonAncestor).item(i).cloneNode(true)); } catch(e) { // Unique IE logic if(i == intAbsolutePosition) { objXML = new ActiveXObject('MSXML.DOMDocument'); objRoot = objXML.createElement('root'); } objRoot.appendChild(this.full.XMLDocument.getElementsByTagName(objCommonAncestor).item(i).cloneNode(true)); } } this.bound.appendChild(objRoot); MozillaDSO(); // Mozilla bind logic } function m_showFirst() { /* Function: m_showFirst Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to show the first logical page. Update Date: Programmer: Description: */ intAbsolutePosition = 0; // Set absolute position m_showPage(); // Show page } function m_showLast() { /* Function: m_showLast Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to show the last logical page. Update Date: Programmer: Description: */ intAbsolutePosition = (m_pageCount() - 1) * m_length(); m_showPage(); // Show page } function m_showNext() { /* Function: m_showNext Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to show the next logical page. Update Date: Programmer: Description: */ if(m_page() < m_pageCount()) intAbsolutePosition += intLength; // Set absolute position m_showPage(); // Show page } function m_showPrevious() { /* Function: m_showPrevious Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to show the previous logical page. Update Date: Programmer: Description: */ if(m_page() > 1) intAbsolutePosition -= intLength; // Set absolute position m_showPage(); // Show page } function m_length() { /* Function: m_length Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to set or get the logical page length. Update Date: Programmer: Description: */ if(arguments.length > 0) intLength = parseInt(arguments[0],10); else return intLength; } function m_page() { /* Function: m_page Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to compute the current logical page number. Update Date: Programmer: Description: */ return (parseInt((intAbsolutePosition / intLength),10) + 1); } function m_recordCount() { /* Function: m_recordCount Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to compute the return the total number of "records" in the "full" XML Data Island. Update Date: Programmer: Description: May 13, 2003 Edmond Woychowsky Modified to recompute due to possible deletes. */ if(!blnInitialize) initialize(this.bound,this.full,this.table); return document.getElementById(strXML).getElementsByTagName(objCommonAncestor).length; } function m_pageCount() { /* Function: m_pageCount Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to compute the return the total number of logical pages. Update Date: Programmer: Description: May 13, 2003 Edmond Woychowsky Modified to invoke m_recordCount() to compute current record count. */ if(!blnInitialize) initialize(this.bound,this.full,this.table); return parseInt((m_recordCount() + (intLength - 1)) / intLength,10); } function initialize(objBound,objXML,objTable) { /* Function: initialize Creation Date: April 25, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to perform the necessary housekeeping before paging can occur. Update Date: Programmer: Description: */ var objNodeName = new collection(); var arrNodeName; switch(true) { case((objBound == null) && (objXML == null) && (objTable == null)): alert('Error: bound, xml and table not set.'); break; case((objBound == null) && (objXML == null)): alert('Error: bound and xml not set.'); break; case((objBound == null) && (objTable == null)): alert('Error: bound and table not set.'); break; case((objXML == null) && (objTable == null)): alert('Error: xml and table not set.'); break; case(objBound == null): alert('Error: bound not set.'); break; case(objXML == null): alert('Error: xml not set.'); break; case(objTable == null): alert('Error: table not set.'); break; default: for(var i=0;i < objTable.getElementsByTagName('input').length;i++) if(objTable.getElementsByTagName('input').item(i).getAttribute('datafld') != null) objNodeName.item(objTable.getElementsByTagName('input').item(i).getAttribute('datafld'),null); for(var i=0;i < objTable.getElementsByTagName('div').length;i++) if(objTable.getElementsByTagName('div').item(i).getAttribute('datafld') != null) objNodeName.item(objTable.getElementsByTagName('div').item(i).getAttribute('datafld'),null); for(var i=0;i < objTable.getElementsByTagName('span').length;i++) if(objTable.getElementsByTagName('span').item(i).getAttribute('datafld') != null) objNodeName.item(objTable.getElementsByTagName('span').item(i).getAttribute('datafld'),null); arrNodeName = objNodeName.keys(); objNodeName = new collection(); for(var i=0;i < arrNodeName.length;i++) objNodeName.item(objXML.getElementsByTagName(arrNodeName[i]).item(0).parentNode.nodeName,null); if(objNodeName.keys().length != 1) alert('Error: unsupported XML document structure.'); else { objCommonAncestor = objNodeName.keys().join(''); blnInitialize = true; } // Store node names strBound = objBound.getAttribute('id'); strXML = objXML.getAttribute('id'); strTable = objTable.getAttribute('id'); // Store initial table objInitialTable = objTable.cloneNode(true); break; } } } function MozillaDSO() { /* Function: MozillaDSO Creation Date: April 16, 2003 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to perform binding of XML Data Islands for Mozilla. The logic herein is bypassed for Microsoft Internet Explorer. Update Date: Programmer: Description: */ // Global variables objXMLDI = new collection(); // XML data island collection objBound = new collection(); // Bound XHTML object collection // Local variables var objDatafld; // Table datafld collection var objRow; // Table row var reWork = new RegExp('internet explorer','gi'); var arrKeys = new Array(); var intKey = 0; // objBound collection key var intRows; // Row count if(!reWork.test(navigator.appName)) { // Locate data islands for(var i=0;i < document.getElementsByTagName('xml').length;i++) objXMLDI.add('#' + document.getElementsByTagName('xml').item(i).getAttribute('id'),document.getElementsByTagName('xml').item(i)); // Locate bound nodes for(var i=0;i < document.getElementsByTagName('table').length;i++) if(document.getElementsByTagName('table').item(i).getAttribute('datasrc') != null) { objBound.add(intKey.toString(),new boundXML()); objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('table').item(i).getAttribute('datasrc'); objBound.item(intKey.toString()).node = document.getElementsByTagName('table').item(i); objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('table').item(i).nodeName; objDatafld = new collection(); // Reset collection; intRows = 0; // Reset row count // Remove all rows if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').length != 0) { for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++) objRow = objBound.item(intKey.toString()).node.lastChild.removeChild(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j)); for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++) objRow = objBound.item(intKey.toString()).node.lastChild.removeChild(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j)); } // Determine bound nodes for(var j=0;j < objRow.getElementsByTagName('input').length;j++) if(!objDatafld.exists(objRow.getElementsByTagName('input').item(j).getAttribute('datafld'))) objDatafld.item(objRow.getElementsByTagName('input').item(j).getAttribute('datafld'),null); for(var j=0;j < objRow.getElementsByTagName('div').length;j++) if(!objDatafld.exists(objRow.getElementsByTagName('div').item(j).getAttribute('datafld'))) objDatafld.item(objRow.getElementsByTagName('div').item(j).getAttribute('datafld'),null); for(var j=0;j < objRow.getElementsByTagName('span').length;j++) if(!objDatafld.exists(objRow.getElementsByTagName('span').item(j).getAttribute('datafld'))) objDatafld.item(objRow.getElementsByTagName('span').item(j).getAttribute('datafld'),null); arrKeys = objDatafld.keys(); // Determine row count for(var j=0;j < arrKeys.length;j++) if(intRows < objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(arrKeys[0]).length) intRows = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(arrKeys[0]).length; for(var j=0;j < intRows;j++) objBound.item(intKey.toString()).node.lastChild.appendChild(objRow.cloneNode(true)); // Rebuild table and bind for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++) for(var k=0;k < objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').length;k++) for(var l=0;l < objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.length;l++) switch(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).nodeName.toLowerCase()) { case('input'): try { if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('type') != 'checkbox') objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).value = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue; else objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).checked = eval(objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue); } catch(e) { } if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('type') != 'checkbox') objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).onchange = new Function('try { objXMLDI.item('' + objBound.item(intKey.toString()).datasrc + '').getElementsByTagName('' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '').item(' + j.toString() + ').firstChild.nodeValue = this.value } catch(e) { objXMLDI.item('' + objBound.item(intKey.toString()).datasrc + '').getElementsByTagName('' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '').item(' + j.toString() + ').appendChild(document.createTextNode(this.value)) };MozillaDSO;'); else objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).onchange = new Function('try { objXMLDI.item('' + objBound.item(intKey.toString()).datasrc + '').getElementsByTagName('' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '').item(' + j.toString() + ').firstChild.nodeValue = this.checked } catch(e) { objXMLDI.item('' + objBound.item(intKey.toString()).datasrc + '').getElementsByTagName('' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '').item(' + j.toString() + ').appendChild(document.createTextNode(this.checked)) };MozillaDSO;'); break; case('div'): case('span'): try { // Text node exists objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).firstChild.nodeValue = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue; } catch(e) { // Create text node try { objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).appendChild(document.createTextNode(objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue)); } catch(e) { } } break; } ++intKey; } // Non-tabular datasrc/datafld for(var i=0;i < document.getElementsByTagName('input').length;i++) if(document.getElementsByTagName('input').item(i).getAttribute('datafld') != null) { objBound.add(intKey.toString(),new boundXML()); if(document.getElementsByTagName('input').item(i).getAttribute('datasrc') != null) objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('input').item(i).getAttribute('datasrc'); objBound.item(intKey.toString()).datafld = document.getElementsByTagName('input').item(i).getAttribute('datafld'); objBound.item(intKey.toString()).node = document.getElementsByTagName('input').item(i); objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('input').item(i).nodeName; ++intKey; } for(var i=0;i < document.getElementsByTagName('div').length;i++) if(document.getElementsByTagName('div').item(i).getAttribute('datafld') != null) { objBound.add(intKey.toString(),new boundXML()); if(document.getElementsByTagName('div').item(i).getAttribute('datasrc') != null) objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('div').item(i).getAttribute('datasrc'); objBound.item(intKey.toString()).datafld = document.getElementsByTagName('div').item(i).getAttribute('datafld'); objBound.item(intKey.toString()).node = document.getElementsByTagName('div').item(i); objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('div').item(i).nodeName; ++intKey; } for(var i=0;i < document.getElementsByTagName('span').length;i++) if(document.getElementsByTagName('span').item(i).getAttribute('datafld') != null) { objBound.add(intKey.toString(),new boundXML()); if(document.getElementsByTagName('span').item(i).getAttribute('datasrc') != null) objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('span').item(i).getAttribute('datasrc'); objBound.item(intKey.toString()).datafld = document.getElementsByTagName('span').item(i).getAttribute('datafld'); objBound.item(intKey.toString()).node = document.getElementsByTagName('span').item(i); objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('span').item(i).nodeName; ++intKey; } arrKeys = objBound.keys(); // Handle non-tabular binds for(var i=0;i < arrKeys.length;i++) switch(objBound.item(arrKeys[i]).nodeName.toLowerCase()) { case('table'): objBound.item(arrKeys[i]).rows = new Array(); break; case('input'): try { if(typeof(objBound.item(arrKeys[i]).datasrc) == 'string') { try { if(objBound.item(arrKeys[i]).node.getAttribute('type') != 'checkbox') objBound.item(arrKeys[i]).node.value = objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue; else objBound.item(arrKeys[i]).node.checked = eval(objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue); } catch(e) { } if(objBound.item(arrKeys[i]).node.getAttribute('type') != 'checkbox') objBound.item(arrKeys[i]).node.onchange = new Function('try { objXMLDI.item(this.getAttribute('datasrc')).getElementsByTagName(this.getAttribute('datafld')).item(0).firstChild.nodeValue = this.value } catch(e) { objXMLDI.item(this.getAttribute('datasrc')).getElementsByTagName(this.getAttribute('datafld')).item(0).appendChild(document.createTextNode(this.value)) };MozillaDSO()'); else objBound.item(arrKeys[i]).node.onclick = new Function('try { objXMLDI.item(this.getAttribute('datasrc')).getElementsByTagName(this.getAttribute('datafld')).item(0).firstChild.nodeValue = this.checked } catch(e) { objXMLDI.item(this.getAttribute('datasrc')).getElementsByTagName(this.getAttribute('datafld')).item(0).appendChild(document.createTextNode(this.checked)) };MozillaDSO()'); } } catch(e) { } break; case('div'): case('span'): if(typeof(objBound.item(arrKeys[i]).datasrc) == 'string') { try { // Text node exists objBound.item(arrKeys[i]).node.firstChild.nodeValue = objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue; } catch(e) { // Create text node try { objBound.item(arrKeys[i]).node.appendChild(document.createTextNode(objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue)); } catch(e) { } } } break; default: alert('Error: Unsupported HTML Element - ' + objBound.item(arrKeys[i]).nodeName.toLowerCase()); break; } } function boundXML() { var datasrc = null; // Data source (string) var datafld = null; // Data field (string) var node = null; // XHTML node (object) var nodeName = null; // Node name (string) } } function collection() { /* Function: collection Creation Date: August 16, 2002 Programmer: Edmond Woychowsky Purpose: The purpose of this class is to define the collection object associative array. Update Date: Programmer: Description: */ // Properties this.objcollection = new Object; // Associative array this.count = 0; // Total numbers of items // Methods this.add = colAdd; // Add method this.exists = colExists; // Exists method this.item = colItem; // Item method this.removeAll = colRemoveAll; // Remove all method this.remove = colRemove; // Remove method this.keys = colKeys; // Keys method function colAdd(strKey,strItem) { /* Function: colAdd Creation Date: August 16, 2002 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to add an item to the collection object. Update Date: Programmer: Description: */ if(typeof(this.objcollection[strKey]) == 'undefined') ++this.count; this.objcollection[strKey] = strItem; } function colExists(strKey) { /* Function: colExists Creation Date: August 16, 2002 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to return a boolean indicating where or not a key exists in the collection object. Update Date: Programmer: Description: */ if(typeof(this.objcollection[strKey]) == 'undefined') return false; else return true; } function colItem(strKey,strItem) { /* Function: colItem Creation Date: August 16, 2002 Programmer: Edmond Woychowsky Purpose: The purpose of this function is to either set or get an item to or from the collection object. Update Date: Programmer: Description: */ if(typeof(strItem) == 'undefined') return this.objcollection[strKey]; else { if(typeof(this.objcollection[strKey]) == 'undefined') ++this.count; this.objcollection[strKey] = strItem; } } function colRemoveAll() { /* Function: colRemoveAll