Archive for the 'MySQL' Category

Yahoo web hosting - BC473Chapter 57Application: Transforming XML DataDreams of Other ViewsConfining

Monday, February 4th, 2008

BC473Chapter 57Application: Transforming XML DataDreams of Other ViewsConfining the example to just one type of view a table of numbers should help you graspthe important processes taking place. But with the XML data converted to JavaScript objects, you can build many other views of the same data into the same page. For example, a scriptcould completely hide the numeric table, and generate a different one that draws bar chartsfor each sales representative or each region (see Chapter 55 for a scripted bar chart exam- ple). The horizontal axis would be the four quarters, and the vertical axis would be dollars orquota percentages. Clicking a bar opens a small window or layer to reveal more detail fromthe sales representative s record, such as the name of the person s manager. More selectelements can let the user select any combination of subsets of the data in either bar chart ornumeric table form to facilitate visual comparisons. You might be even more creative anddevise ways of showing the data by way of overlapping positioned elements. The point is that despite the kinds of rendering opportunities afforded by the XSL Transformmechanism (even if you can get comfortable in the syntax and mental model it presents toauthors), JavaScript s detailed access to the DOM offers far more potential. Eventually plentyof content authors will mix the two technologies by embedding JavaScript into XSLstylesheets to supplement XSL features. …

BC472Part VIBonus (Web hosting india) ChaptersappendCell(newRow, Q4 , getPercentage(accumQ4A, accumQ4F) + % );

Sunday, February 3rd, 2008

BC472Part VIBonus ChaptersappendCell(newRow, Q4 , getPercentage(accumQ4A, accumQ4F) + % ); var grandTotalFcst = accumQ1F + accumQ2F + accumQ3F + accumQ4F; var grandTotalActual = accumQ1A + accumQ2A + accumQ3A + accumQ4A; appendCell(newRow, grandTotal , grandTotalFcst +
+ grandTotalActual); appendCell(newRow, grandTotal , getPercentage(grandTotalActual, grandTotalFcst) + % ); } function appendCell(Trow, Cclass, txt) { var newCell = Trow.insertCell(Trow.cells.length); newCell.className = Cclass; newCell.innerHTML = txt; } function deleteRows(tbl) { while (tbl.rows.length > 0) { tbl.deleteRow(0); } } Many standalone statements at the end of the drawTextTable()function are devoted exclu- sively to generating the Grand Total row, in which the accumulated column totals are entered. At the same time, the getPercentage()function, described earlier, is invoked several timesagain to derive the quota percentage for the accumulated grand total values in each quarteras well as the complete year. select controlsTo round out the code listing for this application, the values assigned to the two selectele- ments obviously have a lot to do with the execution of numerous functions in this application. Nothing magic takes place here, but you can see the extent of the detail required in assigningscript-meaningful hidden values, and human-meaningful text for both selectelements. Forexample, dividing lines help organize the long sort key list into three logical blocks.

Sort by:

   Ordered:

BC471Chapter 57Application: Transforming XML Dataheaders (which are hard-wired (Personal web server)

Sunday, February 3rd, 2008

BC471Chapter 57Application: Transforming XML Dataheaders (which are hard-wired in the document s HTML). Composing an 11-column tablerequires a bit of code, and the drawTextTable() s length attests to that fact. You can tell byjust glancing at the code, however, that for big chunks of it, there is a comfortable regularitythat is aided by the JavaScript object that holds the data. Additional calculations take place while the table s elements are being added to the tableelement. Column totals are accumulated during the table assembly (row totals are calculatedas the object is generated and preserved as properties of the object). A large forloop cyclesthrough each (sorted) row of the dbarray; each row of the dbarray corresponds to a row of the table. Class names are assigned to various rows or cells so that they will pick up thestylesheet rules defined earlier in the document. Another subtlety of this version is that theregionproperty of a sales rep is assigned to the titleproperty of a row. If the user pausesthe mouse pointer anywhere in that row, the name of the region pops up briefly. function drawTextTable() { var newRow; var accumQ1F = 0, accumQ1A = 0, accumQ2F = 0, accumQ2A = 0; var accumQ3F = 0, accumQ3A = 0, accumQ4F = 0, accumQ4A = 0; deleteRows(document.getElementById( mainTableBody )); for (var i = 0; i < db.length; i++) { newRow = document.getElementById( mainTableBody ).insertRow(i); newRow.className = db[i].region; newRow.title = db[i].region + Region ; appendCell(newRow, rep , db[i].firstName + + db[i].lastName); appendCell(newRow, Q1 , db[i].sales.Q1_2000.forecast +
+ db[i].sales.Q1_2000.actual); appendCell(newRow, Q1 , db[i].sales.Q1_2000.quotaPct + % ); appendCell(newRow, Q2 , db[i].sales.Q2_2000.forecast +
+ db[i].sales.Q2_2000.actual); appendCell(newRow, Q2 , db[i].sales.Q2_2000.quotaPct + % ); appendCell(newRow, Q3 , db[i].sales.Q3_2000.forecast +
+ db[i].sales.Q3_2000.actual); appendCell(newRow, Q3 , db[i].sales.Q3_2000.quotaPct + % ); appendCell(newRow, Q4 , db[i].sales.Q4_2000.forecast +
+ db[i].sales.Q4_2000.actual); appendCell(newRow, Q4 , db[i].sales.Q4_2000.quotaPct + % ); accumQ1F += db[i].sales.Q1_2000.forecast; accumQ1A += db[i].sales.Q1_2000.actual; accumQ2F += db[i].sales.Q2_2000.forecast; accumQ2A += db[i].sales.Q2_2000.actual; accumQ3F += db[i].sales.Q3_2000.forecast; accumQ3A += db[i].sales.Q3_2000.actual; accumQ4F += db[i].sales.Q4_2000.forecast; accumQ4A += db[i].sales.Q4_2000.actual; appendCell(newRow, repTotal , db[i].totalForecast +
+ db[i].totalActual); appendCell(newRow, repTotal , db[i].totalQuotaPct + % ); } newRow = document.getElementById( mainTableBody ).insertRow(i); newRow.className = QTotal ; newRow.title = Totals ; appendCell(newRow, grandTotalLabel , Grand Total ); appendCell(newRow, Q1 , accumQ1F +
+ accumQ1A); appendCell(newRow, Q1 , getPercentage(accumQ1A, accumQ1F) + % ); appendCell(newRow, Q2 , accumQ2F +
+ accumQ2A); appendCell(newRow, Q2 , getPercentage(accumQ2A, accumQ2F) + % ); appendCell(newRow, Q3 , accumQ3F +
+ accumQ3A); appendCell(newRow, Q3 , getPercentage(accumQ3A, accumQ3F) + % ); appendCell(newRow, Q4 , accumQ4F +
+ accumQ4A);

Cpanel web hosting - BC470Part VIBonus Chaptersreturn (b.sales.Q3_2000.quotaPct - a.sales.Q3_2000.quotaPct); } }

Saturday, February 2nd, 2008

BC470Part VIBonus Chaptersreturn (b.sales.Q3_2000.quotaPct - a.sales.Q3_2000.quotaPct); } } function sortDBByQ4Fcst(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q4_2000.forecast - b.sales.Q4_2000.forecast); } else { return (b.sales.Q4_2000.forecast - a.sales.Q4_2000.forecast); } } function sortDBByQ4Actual(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q4_2000.actual - b.sales.Q4_2000.actual); } else { return (b.sales.Q4_2000.actual - a.sales.Q4_2000.actual); } } function sortDBByQ4Quota(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q4_2000.quotaPct - b.sales.Q4_2000.quotaPct); } else { return (b.sales.Q4_2000.quotaPct - a.sales.Q4_2000.quotaPct); } } function sortDBByTotalFcst(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.totalForecast - b.totalForecast); } else { return (b.totalForecast - a.totalForecast); } } function sortDBByTotalActual(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.totalActual - b.totalActual); } else { return (b.totalActual - a.totalActual); } } function sortDBByTotalQuota(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.totalQuotaPct - b.totalQuotaPct); } else { return (b.totalQuotaPct - a.totalQuotaPct); } } For this application, all sorting functions branch in their execution based on the choice made inthe Ordered selectelement on the page. The relative position of the two array elementsunder test in these simple subtraction comparison statements reverses when the sort order isfrom low to high (increasing) and when it is from high to low (decreasing). This kind of arraysorting is extremely powerful in JavaScript and probably escapes the attention of most scripters. Constructing the tableAs recommended back in Chapter 37 s discussion of tableand related elements, it is oftenconvenient to manipulate the structure of a tableelement by way of the specialized methodsfor tables, rather than mess with nodes and elements. The drawTextTable()function isdevoted to employing those methods to create the rendered contents of the table below the

Web hosting service - BC469Chapter 57Application: Transforming XML Datafunction sortDBByQ1Fcst(a, b) {

Thursday, January 31st, 2008

BC469Chapter 57Application: Transforming XML Datafunction sortDBByQ1Fcst(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q1_2000.forecast - b.sales.Q1_2000.forecast); } else { return (b.sales.Q1_2000.forecast - a.sales.Q1_2000.forecast); } } function sortDBByQ1Actual(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q1_2000.actual - b.sales.Q1_2000.actual); } else { return (b.sales.Q1_2000.actual - a.sales.Q1_2000.actual); } } function sortDBByQ1Quota(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q1_2000.quotaPct - b.sales.Q1_2000.quotaPct); } else { return (b.sales.Q1_2000.quotaPct - a.sales.Q1_2000.quotaPct); } } function sortDBByQ2Fcst(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q2_2000.forecast - b.sales.Q2_2000.forecast); } else { return (b.sales.Q2_2000.forecast - a.sales.Q2_2000.forecast); } } function sortDBByQ2Actual(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q2_2000.actual - b.sales.Q2_2000.actual); } else { return (b.sales.Q2_2000.actual - a.sales.Q2_2000.actual); } } function sortDBByQ2Quota(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q2_2000.quotaPct - b.sales.Q2_2000.quotaPct); } else { return (b.sales.Q2_2000.quotaPct - a.sales.Q2_2000.quotaPct); } } function sortDBByQ3Fcst(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q3_2000.forecast - b.sales.Q3_2000.forecast); } else { return (b.sales.Q3_2000.forecast - a.sales.Q3_2000.forecast); } } function sortDBByQ3Actual(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q3_2000.actual - b.sales.Q3_2000.actual); } else { return (b.sales.Q3_2000.actual - a.sales.Q3_2000.actual); } } function sortDBByQ3Quota(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.sales.Q3_2000.quotaPct - b.sales.Q3_2000.quotaPct); } else {

BC468Part VIBonus Chapterscase byQ2Quota : (Web hosting account) db.sort(sortDBByQ2Quota); break; case

Thursday, January 31st, 2008

BC468Part VIBonus Chapterscase byQ2Quota : db.sort(sortDBByQ2Quota); break; case byQ3Fcst : db.sort(sortDBByQ3Fcst); break; case byQ3Actual : db.sort(sortDBByQ3Actual); break; case byQ3Quota : db.sort(sortDBByQ3Quota); break; case byQ4Fcst : db.sort(sortDBByQ4Fcst); break; case byQ4Actual : db.sort(sortDBByQ4Actual); break; case byQ4Quota : db.sort(sortDBByQ4Quota); break; case byTotalFcst : db.sort(sortDBByTotalFcst); break; case byTotalActual : db.sort(sortDBByTotalActual); break; case byTotalQuota : db.sort(sortDBByTotalQuota); break; } drawTextTable(); } Each specific sorting routine is a function that automatically works repeatedly on pairs ofentries of an array (see Chapter 30). Array entries here (from the dbarray) are objects andrather complex objects at that. The benefit of using JavaScript array sorting is that the sort- ing can be performed on any property of objects stored in the array. For example, sorting onthe lastNameproperty of each dbarray object is based on a comparison of the lastNameproperty for each of the pairs of array entries passed to the sortDBByRep()sort function. But looking down a little further, you can see that the mechanism allows sorting on evenmore deeply nested properties, such as the sales.Q1_2000.forecastproperty of eacharray entry. If a property in an object can be referenced, it can be used as a sorting propertyinside one of these functions. function sortDBByRep(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.lastName < b.lastName) ? -1 : 1; } else { return (a.lastName > b.lastName) ? -1 : 1; } } function sortDBByRegion(a, b) { if (document.getElementById( orderChooser ).value == inc ) { return (a.region < b.region) ? -1 : 1; } else { return (a.region > b.region) ? -1 : 1; } }

BC467Chapter 57Application: Transforming XML DataAssuming that the raw (Photoshop web design)

Wednesday, January 30th, 2008

BC467Chapter 57Application: Transforming XML DataAssuming that the raw XML database stores only the sales forecast and actual dollar figures, it is up to analysis programs to perform their own calculations, such as how the actual salescompare against the forecasts. As you saw in the illustration of the rendered table, this appli- cation not only displays the percentage differences between the pairs of values, but it alsoprovides sorting facilities on those percentages. To speed the sorting, the percentages arecalculated as the JavaScript database is being accumulated, and the percentages are storedas properties of each object. Percentage calculation is called upon in two different statementsof the getOneSalesRep()function, so that the calculation is broken out to its own function, getPercentage(). In that function, the two passed values are massaged to calculate the per- centage value, and then the string result is formatted to no more than one digit to the right ofthe decimal (by way of a regular expression). The value returned for the property assignmentis converted to a number data type, because sorting on these values needs to be doneaccording to numeric sorting, rather than string sorting. You can already get a glimpse at the contribution JavaScript is making to the scripted represen- tation of the data transmitted in XML form. By virtue of planning for subsequent calculations, the JavaScript object contains considerably more information than was originally delivered, yetall the properties are derived from hard data supplied by the server database. Sorting the JavaScript databaseWith so many sorting keys for the user to choose from, it s no surprise that sorting codeoccupies a good number of script lines in this application. All sorting code consists of twomajor blocks: dispatchingand sorting. The dispatching portion is nothing more than one gigantic switchconstruction that sendsexecution to one of the 17 (!) sorting functions that match whichever sort key is chosen in theselectelement on the page. This dispatcher function, selectSort(), is also invoked fromthe init()function at load time. Thus, if the user makes a choice in the page, navigates toanother page, and then returns with the page still showing the previous selection, the onLoadevent handler will reconstruct the table precisely as it was. When sorting is completed, thetable is drawn, as you see shortly. function selectSort(chooser) { switch (chooser.value) { case byRep : db.sort(sortDBByRep); break; case byRegion : db.sort(sortDBByRegion); break; case byQ1Fcst : db.sort(sortDBByQ1Fcst); break; case byQ1Actual : db.sort(sortDBByQ1Actual); break; case byQ1Quota : db.sort(sortDBByQ1Quota); break; case byQ2Fcst : db.sort(sortDBByQ2Fcst); break; case byQ2Actual : db.sort(sortDBByQ2Actual); break;

BC466Part VIBonus Chapterscorresponding to one of the periods. (Web host sites)

Tuesday, January 29th, 2008

BC466Part VIBonus Chapterscorresponding to one of the periods. Each period also has three properties (a period ID, forecast sales, and actual sales). Thus, the salesproperty is an array of objects. function getOneSalesRep(i) { var oneRecord = new Object(); var oneElem = xDoc.getElementsByTagName( salesrep )[i]; oneRecord.id = oneElem.getElementsByTagName( employeeid )[0].firstChild.data; var contactInfoElem = oneElem.getElementsByTagName( contactinfo )[0]; oneRecord.firstName = contactInfoElem.getElementsByTagName( firstname )[0].firstChild.data; oneRecord.lastName = contactInfoElem.getElementsByTagName( lastname )[0].firstChild.data; oneRecord.eMail = contactInfoElem.getElementsByTagName( email )[0].firstChild.data; oneRecord.phone = contactInfoElem.getElementsByTagName( phone )[0].firstChild.data; oneRecord.fax = contactInfoElem.getElementsByTagName( fax )[0].firstChild.data; oneRecord.manager = new Object(); var oneMgrElem = oneElem.getElementsByTagName( manager )[0]; oneRecord.manager.id = oneMgrElem.getElementsByTagName( employeeid )[0].firstChild.data; oneRecord.manager.firstName = oneMgrElem.getElementsByTagName( firstname )[0].firstChild.data; oneRecord.manager.lastName = oneMgrElem.getElementsByTagName( lastname )[0].firstChild.data; oneRecord.region = oneElem.getElementsByTagName( region )[0].firstChild.data; oneRecord.sales = new Array(); var allPeriods = oneElem.getElementsByTagName( salesrecord )[0].childNodes; var temp; var accumForecast = 0, accumActual = 0; for (var i = 0; i < allPeriods.length; i++) { if (allPeriods[i].nodeType == 1) { temp = new Object(); temp.period = allPeriods[i].getElementsByTagName( id )[0].firstChild.data; temp.forecast = parseInt(allPeriods[i].getElementsByTagName( forecast )[0].firstChild.data); temp.actual = parseInt(allPeriods[i].getElementsByTagName( actual )[0].firstChild.data); temp.quotaPct = getPercentage(temp.actual, temp.forecast); oneRecord.sales[temp.period] = temp; accumForecast += temp.forecast; accumActual += temp.actual; } } oneRecord.totalForecast = accumForecast; oneRecord.totalActual = accumActual; oneRecord.totalQuotaPct = getPercentage(accumActual, accumForecast); return oneRecord; } function getPercentage(actual, forecast) { var pct = (actual/forecast * 100) + ; pct = pct.match(/d*.d/); return parseFloat(pct); }

BC465Chapter 57Application: Transforming XML Datatr.East {background-color:#FFFFCC} (Web site management) tr.Central {background-color:#CCFFFF}

Tuesday, January 29th, 2008

BC465Chapter 57Application: Transforming XML Datatr.East {background-color:#FFFFCC} tr.Central {background-color:#CCFFFF} tr.West {background-color:#FFCCCC} tr.QTotal {background-color:#FFFF00} td.repTotal {background-color:#FFFF00} td.grandTotal{background-color:#00FF00} h1 {font-family: Comic Sans MS ,Helvetica,sans-serif} One stylesheet rule is essential: The one that suppresses the rendering of any XML element. That data is hidden from the user s view. Initialization sequenceAn onloadevent handler invokes the init()function, which sets a lot of machinery inmotion to get the document ready for user interaction. After loading the XML file into thexDocglobal variable (via the loadXMLDoc()function), its most important job is running aforloop that builds the JavaScript database from the XML elements. Next, it sorts thedatabase based on the current choice in the sorting selectelement. The sorting functionends by triggering the rendering of the table. These three actions correspond to the funda- mental operation of the entire application. // initialize global variable that stores JavaScript datavar db = new Array(); // Initialization called by onLoadfunction init() { loadXMLDoc( salesrpt.xml ); if (xDoc) { for (var i = 0; i < xDoc.getElementsByTagName( salesrep ).length; i++) { db[db.length] = getOneSalesRep(i); } selectSort(document.getElementById( sortChooser )); } } Converting the dataThe controlling factor for creating the JavaScript database is the structure of the XML data. Withthe complete XML document stored in the xDocvariable, scripts can use DOM methods to lookfor elements bearing relevant tag names. Data for each sales rep is contained by a salesrepele- ment. The number of salesrepelements determines how many records (JavaScript objects) areto be added to the dbarray. A call to the getOneSalesRep()function creates an object for eachsales representative s data. Despite the length of the getOneSalesRep()function, its operation is very straightfor- ward. Most of the statements do nothing more than retrieve the data inside the variousXML elements within a salesrepcontainer and assign that data to a like-named property of the custom object. Following the structure of the XML example shown earlier in thischapter, you can see where some properties of a JavaScript object representing the dataare, themselves, objects or arrays. For example, one of the properties is called manager, corresponding to the managerelement. But that element has nested items inside. Then, making those nested elements properties of a managerobject is only natural. Similarly, the repetitive nature of the data within each of the four quarterly periods calls for evengreater nesting: The object property named salesis an array, with each item of the array

BC464Part VIBonus ChaptersImplementation PlanClearly all the data needed (Apache web server)

Monday, January 28th, 2008

BC464Part VIBonus ChaptersImplementation PlanClearly all the data needed for numerous sorted and ordered views arrives in one batch fromthe XML file. Despite the element and node referencing properties and methods of the W3CDOM, trying to use the XML elements as the sole data store for scripts to sort the data eachtime would be impractical. For one thing, none of the elements have ID attributes there sno need for it in the XML stored on the server database. And even if they did have IDs, howwould scripts that you desire to write for generalizability make use of them unless the IDswere generated in a well-known sequence? Moreover, after a sales rep s record is rendered inthe table, how easy would it be to dive back into that record and drill down for further infor- mation, such as the name of a representative s manager? A solution that can empower the page author in this case is to use the node-walking proper- ties and methods of the W3C DOM to assemble a JavaScript-structured database while thepage loads. In other words, the conversion is performed just once during page loading, andthe JavaScript version is preserved in an array (of XML records in this case) as a globalvariable. Any transformations on the data can be done from the JavaScript database with thehelp of additional powers of the language. Given that route, the basic operation of the scripting of the page is schematically simple: 1.Convert the XML into an array of objects at load time. 2.Predefine all necessary sorting functions based on properties of those objects. 3.Provide a function that rebuilds the HTML table each time data is sorted. With this sequence in mind, now look into the code that does the job. The CodeRather than work through the long document in source code order, the following descriptionsfollow a more functional order. You can open the actual source code file (salesrpt.htm) to see where the various functions are positioned. To best understand this application, seeing the how rather than the where is more important. Also, many of the code lines (even somesingle expressions) are too wide for the printed page and therefore break unnaturally in the list- ings that follow. Trust the formatting of the source file on the CD-ROM. Style sheetsFor the example provided on the CD-ROM, one set of stylesheet rules is embedded in theHTML document. As you can see from the rule selectors, many are tied to very specificclasses of table-related elements used to render the content. In a production version of thisapplication, I would expect that there would be more and quite different views of the dataavailable to the users, such as bar charts for each salesperson or region. Each view wouldlikely require its own unique set of stylesheet rules. In such a scenario, the proper imple- mentation would be to use the LINK element to bring in a different external stylesheet filefor each view type. All could be linked in at the outset, but only the current styleSheetobject would be enabled.