DisplayController.js (28222B)
1 /** 2 * 3 * 4 * @filename DisplayController.js 5 * @$LastChangedDate: 2004-05-16 19:57:10 +0200 (Sun, 16 May 2004) $ 6 * @author Fabio Serra <faser@faser.net> 7 * @copyright Fabio Serra (The Initial Developer of the Original Code) 8 * @license Mozilla Public License Version 1.1 9 * 10 */ 11 12 /** 13 * Construct a new DisplayController object 14 * @class This class should be used as a Controller between the GUI (View) and the 15 * XMDManager (Data) object. 16 * @final 17 * @constructor 18 * @return A new DisplayController 19 * 20 */ 21 function DisplayController() { 22 //Set windows title 23 window.title = "M A B"; 24 //Search Input 25 this.elSearchTerm = document.getElementById('find-text'); 26 //Main Result Tree 27 this.guiMainTree = document.getElementById('result-tree'); 28 //TreeChildren 29 this.guiListTree = document.getElementById('list-tree'); 30 //Details Box 31 this.guiDetailBox = document.getElementById('detail-box'); 32 //Price Box 33 this.guiPriceBox = document.getElementById('price-box'); 34 //ProductName 35 this.guiProductName = document.getElementById("ProductName"); 36 //Author 37 this.guiAuthor = document.getElementById("Author"); 38 //Manufacturer 39 this.guiManufacturer = document.getElementById("Manufacturer"); 40 //ReleaseDate 41 this.guiReleaseDate = document.getElementById("ReleaseDate"); 42 //List Price 43 this.guiListPrice = document.getElementById("ListPrice"); 44 //OurPrice 45 this.guiOurPrice = document.getElementById("OurPrice"); 46 //UsedPrice 47 this.guiUsedPrice = document.getElementById("UsedPrice"); 48 49 //Image 50 this.guiTheImg = document.getElementById('ImageUrlMedium'); 51 //All Info 52 this.winProductInfo = window.frames[0]; 53 this.guiProductInfo = this.winProductInfo.document.getElementById('allInfoOutput'); 54 //Comment iframe 55 this.winReview = window.frames[1]; 56 this.guiReview = this.winReview.document.getElementById('commentOutput'); 57 this.guiCommentBtn = document.getElementById('comment-button'); 58 //Image 59 this.guiImageSmall = document.getElementById('ImageUrlMedium'); 60 61 //Broadcaster 62 this.isSearchRunning = document.getElementById("isSearchRunning"); 63 64 //Status Bar 65 this.guiRecordStatus = document.getElementById("record-status"); 66 this.guiOutStatus = document.getElementById("out-status"); 67 68 //Hidden xul spacer to mantain the user preferences 69 this.elSettingsSpacer = document.getElementById('settings-spacer'); 70 } 71 72 73 //Columns: Name, Catalog, Locale, OurPrice, Rating, Released, MABLabel, MABTSLastUpdate, Status 74 /** 75 * Build the xul tree 76 * @param {XMDManager} XMDManager 77 * @param {bool} appendItems Indicate if the new elements should be added to the xul 78 * tree or if the tree should be destroyed and completly rebuild 79 * @throws exception if the XMDManager has no Details node in the xml document 80 * @return void 81 */ 82 DisplayController.prototype.buildTree = function(XMDManager,appendItems) { 83 //Default is rebuild the entire tree 84 var append = false; 85 //In case of addItem the new item are added at the top of the tree 86 if(appendItems) {append = true;} 87 88 try { 89 var rows = XMDManager.xmlDoc.getElementsByTagName("Details"); 90 }catch(e){ 91 return; 92 } 93 94 95 var pk = ""; 96 var treeRow = false; 97 var strRow, productName, catalog, country, ourPrice, usedPrice, rating, rank, MABStatus; 98 var releaseDate, lastUpdate, mabLabel, src, srcStatus, res; 99 var today = new Date(); 100 101 for(var i=0;i<rows.length;i++) { 102 103 pk = XMDManager.getSingleElement(rows[i],"MABPrimaryKey"); 104 //Skip rows without primary key 105 if(!pk){continue;} 106 //Check if the record is present in the current tree if it exists update the row 107 if(append == true) { 108 treeRow = document.getElementById(pk); 109 if(treeRow) { 110 res = this.updateRow(treeRow,rows[i],XMDManager); 111 continue; 112 } 113 } 114 115 //Check if product info are expired 116 lastUpdate = XMDManager.getLastUpdate(rows[i]); 117 src = ""; 118 if(lastUpdate > EXPIRED_LONG) { src = "../skin/images/expired.png";} 119 120 //Check status 121 MABStatus = XMDManager.getSingleElement(rows[i],"MABStatus"); 122 srcStatus = ""; 123 if(MABStatus == "unread") { srcStatus = "../skin/images/status_unread.png";} 124 125 productName = XMDManager.getSingleElement(rows[i],"ProductName"); 126 if(!productName) {productName = "";} 127 128 catalog = XMDManager.getSingleElement(rows[i],"Catalog"); 129 if(!catalog) {catalog = "";} 130 131 country = XMDManager.getSingleElement(rows[i],"MABLocale"); 132 if(!country) {country = "";} 133 134 ourPrice = XMDManager.getSingleElement(rows[i],"OurPrice"); 135 if(!ourPrice) {ourPrice = "";} 136 137 usedPrice = XMDManager.getSingleElement(rows[i],"UsedPrice"); 138 if(!usedPrice) {usedPrice = "";} 139 140 rating = XMDManager.getSingleElement(rows[i],"AvgCustomerRating"); 141 if(!rating) {rating = "";} 142 143 rank = XMDManager.getSingleElement(rows[i],"SalesRank"); 144 if(!rank) {rank = "";} 145 146 releaseDate = XMDManager.getSingleElement(rows[i],"ReleaseDate"); 147 if(!releaseDate) {releaseDate = ""}; 148 149 mabLabel = XMDManager.getSingleElement(rows[i],"MABLabel"); 150 if(!mabLabel) {mabLabel = ""} 151 152 153 strRow += ''+ 154 '\n<treeitem>\n' + 155 ' <treerow id="'+ pk +'">\n' + 156 ' <treecell src="'+ src + '" properties="'+ mabLabel +'"/>\n' + 157 ' <treecell src="'+ srcStatus + '" properties="'+ mabLabel +'"/>\n' + 158 ' <treecell label="'+ escapeXML(productName) +'" properties="'+ mabLabel +'"/>\n' + 159 ' <treecell label="'+ escapeXML(catalog) + '" properties="'+ mabLabel +'"/>\n' + 160 ' <treecell label="'+ country.toUpperCase() + '" properties="'+ mabLabel +'"/>\n' + 161 ' <treecell label="'+ escapeXML(ourPrice) + '" properties="'+ mabLabel +'"/>\n' + 162 ' <treecell label="'+ escapeXML(usedPrice) + '" properties="'+ mabLabel +'"/>\n' + 163 ' <treecell label="'+ rating + '" properties="'+ mabLabel +'"/>\n' + 164 ' <treecell label="'+ rank + '" properties="'+ mabLabel +'"/>\n' + 165 ' <treecell label="'+ toYear(releaseDate) + '" properties="'+ mabLabel +'"/>\n' + 166 ' <treecell label="'+ mabLabel + '" properties="'+ mabLabel +'"/>\n' + 167 ' </treerow>\n' + 168 '</treeitem>\n'; 169 170 } 171 172 173 if(append == false) {this.removeTree();} 174 175 if(strRow != "") { innerXML(this.guiListTree,strRow,true,false);} 176 177 //Set the window title to the document name 178 var name = myDocOpened.getCurrentDocumentName(); 179 window.title = "M A B - " + name; 180 181 //Set Focus on the first row 182 if(append == false) {this.setFocusOnRow(0);} 183 184 //Remove sort direction indicator 185 this.clearRowHeader(); 186 187 //Write on status bar how many record are present in the list 188 this.writeRowStatus(); 189 } 190 191 /** 192 * Update a single row 193 * @param {XUL Element} treeRow a reference to a treerow element 194 * @param {XML node} nodeDetail 195 * @param {XMDManager} XMDManager 196 * @return true if the row has been updated, false otherwise 197 * @type bool 198 */ 199 DisplayController.prototype.updateRow = function(treeRow,nodeDetail,XMDManager) { 200 var cells = treeRow.getElementsByTagName("treecell"); 201 var pk = XMDManager.getSingleElement(nodeDetail,"MABPrimaryKey"); 202 //Skip rows without primary key 203 if(!pk){return false;} 204 var mabLabel = XMDManager.getSingleElement(nodeDetail,"MABLabel"); 205 if(!mabLabel) {mabLabel = ""} 206 207 //Set treerow attributes 208 cells.item(0).parentNode.setAttribute("id",pk); 209 210 var lastUpdate = XMDManager.getLastUpdate(nodeDetail); 211 var src = ""; 212 if(lastUpdate > EXPIRED_LONG) { src = "../skin/images/expired.png";} 213 214 cells.item(0).setAttribute("src",src); 215 cells.item(0).setAttribute("properties",mabLabel); 216 217 var status = XMDManager.getSingleElement(nodeDetail,"MABStatus"); 218 var srcStatus = ""; 219 if(status == "unread") { srcStatus = "../skin/images/status_unread.png";} 220 221 cells.item(1).setAttribute("src",srcStatus); 222 cells.item(1).setAttribute("properties",mabLabel); 223 224 var productName = XMDManager.getSingleElement(nodeDetail,"ProductName"); 225 if(!productName) {productName = "";} 226 cells.item(2).setAttribute("label",productName); 227 cells.item(2).setAttribute("properties",mabLabel); 228 229 var catalog = XMDManager.getSingleElement(nodeDetail,"Catalog"); 230 if(!catalog) {catalog = "";} 231 cells.item(3).setAttribute("label",catalog); 232 cells.item(3).setAttribute("properties",mabLabel); 233 234 var country = XMDManager.getSingleElement(nodeDetail,"MABLocale"); 235 if(!country) {country = "";} 236 cells.item(4).setAttribute("label",country.toUpperCase()); 237 cells.item(4).setAttribute("properties",mabLabel); 238 239 var ourPrice = XMDManager.getSingleElement(nodeDetail,"OurPrice"); 240 if(!ourPrice) {ourPrice = "";} 241 cells.item(5).setAttribute("label",ourPrice); 242 cells.item(5).setAttribute("properties",mabLabel); 243 244 var usedPrice = XMDManager.getSingleElement(nodeDetail,"UsedPrice"); 245 if(!usedPrice) {usedPrice = "";} 246 cells.item(6).setAttribute("label",usedPrice); 247 cells.item(6).setAttribute("properties",mabLabel); 248 249 var rating = XMDManager.getSingleElement(nodeDetail,"AvgCustomerRating"); 250 if(!rating) {rating = "";} 251 cells.item(7).setAttribute("label",rating); 252 cells.item(7).setAttribute("properties",mabLabel); 253 254 var rank = XMDManager.getSingleElement(nodeDetail,"SalesRank"); 255 if(!rank) {rank = ""}; 256 cells.item(8).setAttribute("label",rank); 257 cells.item(8).setAttribute("properties",mabLabel); 258 259 var releaseDate = XMDManager.getSingleElement(nodeDetail,"ReleaseDate"); 260 if(!releaseDate) {releaseDate = ""}; 261 cells.item(9).setAttribute("label",toYear(releaseDate)); 262 cells.item(9).setAttribute("properties",mabLabel); 263 264 cells.item(10).setAttribute("label",mabLabel); 265 cells.item(10).setAttribute("properties",mabLabel); 266 267 return true; 268 } 269 270 /** 271 * Syncronize tree with XMDManager mantaining consistence between the model and 272 * the view 273 * @param {XMDManager} XMDManager 274 * @return void 275 */ 276 DisplayController.prototype.syncTree = function(XMDManager) { 277 var myXMDManager = XMDManager; 278 var rows = myXMDManager.xmlDoc.getElementsByTagName("Details"); 279 var treeNode = this.guiMainTree.getElementsByTagName("treerow"); 280 281 var nodeDetail, treeRow; 282 283 for(var i=0;i<rows.length;i++) { 284 nodeDetail = rows[i]; 285 treeRow = treeNode.item(i) 286 this.updateRow(treeRow,nodeDetail,myXMDManager) 287 } 288 } 289 290 /** 291 * Get the correct Amazon URL ff the selected product 292 * @param {XMDManager} XMDManager 293 * @param {string} type The type of link that should be returned (directLink || xmlLink || listManiaLink) 294 * @param {XML nodeDetail} node 295 * @return the correct url or false if no URL can be determined 296 * @type string 297 */ 298 DisplayController.prototype.getProductAmazonUrl = function(XMDManager,type,node) { 299 var myXMDManager = XMDManager; 300 var nodeDetail; 301 if(typeof node == "undefined") { 302 var idx = this.getSelectedRowIndex(); 303 if(idx < 0) {return false;} 304 305 var primaryKey = this.getRowPrimaryKey(idx); 306 if(!primaryKey) {return false;} 307 nodeDetail = myXMDManager.getNodeDetail(primaryKey); 308 } else { 309 nodeDetail = node; 310 } 311 312 var linkType = "xmlLink"; 313 if(type) linkType = type ; 314 315 316 317 var theUrl = false; 318 var locale = ""; 319 if(linkType == "xmlLink") { 320 theUrl = nodeDetail.getAttribute("url"); 321 }else if(linkType == "listManiaLink") { 322 var listId = myXMDManager.getSingleElement(nodeDetail,"ListId"); 323 locale = myXMDManager.getSingleElement(nodeDetail,"MABLocale"); 324 theUrl = AMAZONURL[locale] + "/exec/obidos/tg/listmania/list-browse/-/" + listId + "/" + ASSID[locale] + "/"; 325 }else{ 326 var amazAsin = myXMDManager.getSingleElement(nodeDetail,"Asin"); 327 locale = myXMDManager.getSingleElement(nodeDetail,"MABLocale"); 328 theUrl = AMAZONURL[locale] + "/exec/obidos/ASIN/" + amazAsin + "/" + ASSID[locale] + "/"; 329 } 330 331 if(theUrl) { 332 return theUrl; 333 }else{ 334 return false; 335 } 336 } 337 338 /** 339 * Remove all XUL treeitem from the tree 340 */ 341 DisplayController.prototype.removeTree = function() { 342 //Remove only treeitem 343 while(this.guiListTree.hasChildNodes()) { 344 this.guiListTree.removeChild(this.guiListTree.lastChild); 345 } 346 } 347 348 /** 349 * Remove a row (treeitem ) in tree passing the id to identify the treerow 350 * @param {string} id that correspond to the treerow attribute 351 * @return true if the row has been removed 352 * @type bool 353 */ 354 DisplayController.prototype.removeRow = function(id) { 355 var theRow = document.getElementById(id); 356 if(!theRow) {return false;} 357 this.guiListTree.removeChild(theRow.parentNode); 358 359 //Write on status bar how many record are present in the list 360 this.writeRowStatus(); 361 return true; 362 } 363 364 /** 365 * Clear all GUI elements to reset the status 366 */ 367 DisplayController.prototype.clearAll = function() { 368 this.removeTree(); 369 this.clearRowHeader(); 370 this.clearTextBox(); 371 this.clearInfo(); 372 this.clearReview(); 373 this.clearImage(); 374 this.clearStatusBar(); 375 this.writeRowStatus(); 376 this.elSearchTerm.focus(); 377 } 378 379 /** 380 * Clear all textbox GUI elements 381 */ 382 DisplayController.prototype.clearTextBox = function() { 383 var txtInput = document.getElementsByTagName('textbox'); 384 for(var i=0;i<txtInput.length;i++) { 385 txtInput[i].setAttribute('value',''); 386 } 387 } 388 389 /** 390 * Clear the product information panel 391 */ 392 DisplayController.prototype.clearInfo = function() { 393 //First Panel 394 this.guiProductInfo.innerHTML = ""; 395 } 396 397 /** 398 * Clear the Customer Reviews panel 399 */ 400 DisplayController.prototype.clearReview = function() { 401 //Second Panel 402 this.guiReview.innerHTML = ""; 403 } 404 405 /** 406 * Clear the product image 407 */ 408 DisplayController.prototype.clearImage = function() { 409 this.guiImageSmall.setAttribute("src",""); 410 } 411 412 /** 413 * Clear the sort indicator in the row header 414 */ 415 DisplayController.prototype.clearRowHeader = function() { 416 //Set all sortDirection attribute to normal 417 var treeCol = document.getElementsByTagName("treecol"); 418 for(var i=0; i < treeCol.length;i++) { 419 treeCol[i].setAttribute("sortDirection","normal"); 420 } 421 } 422 423 /** 424 * Clear all info in the status bar 425 */ 426 DisplayController.prototype.clearStatusBar = function() { 427 this.guiRecordStatus.setAttribute('label',''); 428 this.guiOutStatus.setAttribute('label',''); 429 } 430 431 /** 432 * Show details about the selected product in the treerow 433 * @param {XMDManager} XMDManager 434 * @param {int} rowIndex the selected rowIndex is not mandatory 435 * @return false if the selected row cannot be determined 436 * @type bool 437 */ 438 DisplayController.prototype.showDetails = function(XMDManager,rowIndex) { 439 440 var idx = -1; 441 if(typeof rowIndex == 'undefined') { 442 idx = this.getSelectedRowIndex(); 443 } else { 444 idx = rowIndex; 445 } 446 447 if(idx < 0) {return false;} 448 449 var primaryKey = this.getRowPrimaryKey(idx); 450 if(!primaryKey) {return false;} 451 var nodeDetail = XMDManager.getNodeDetail(primaryKey); 452 453 //Populate Detail Box. For compatibility with all product author refer to 454 //Author for books, artist for music, director for movies 455 var author = ""; 456 var authorArray = XMDManager.getArrayElement(nodeDetail,"Author"); 457 if(authorArray.length == 0) authorArray = XMDManager.getArrayElement(nodeDetail,"Artist"); 458 if(authorArray.length == 0) authorArray = XMDManager.getArrayElement(nodeDetail,"Director"); 459 if(authorArray.length > 0) { 460 for(var i=0;i<authorArray.length;i++) { 461 if(i < authorArray.length-1) { 462 author += authorArray[i] + ', '; 463 } else{ 464 author += authorArray[i]; 465 } 466 } 467 } 468 this.guiAuthor.setAttribute('value',author); 469 470 var productName = XMDManager.getSingleElement(nodeDetail,"ProductName"); 471 if(!productName) productName = ""; 472 this.guiProductName.setAttribute("value",productName); 473 474 var manufacturer = XMDManager.getSingleElement(nodeDetail,"Manufacturer"); 475 if(!manufacturer) manufacturer = ""; 476 this.guiManufacturer.setAttribute("value",manufacturer); 477 478 var released = XMDManager.getSingleElement(nodeDetail,"ReleaseDate"); 479 if(!released) released = ""; 480 this.guiReleaseDate.setAttribute("value",released); 481 482 483 //Populate price box 484 var listPrice = XMDManager.getSingleElement(nodeDetail,"ListPrice"); 485 if(!listPrice) listPrice = ""; 486 this.guiListPrice.setAttribute("value",listPrice); 487 488 var ourPrice = XMDManager.getSingleElement(nodeDetail,"OurPrice"); 489 if(!ourPrice) ourPrice = ""; 490 this.guiOurPrice.setAttribute("value",ourPrice); 491 492 var usedPrice = XMDManager.getSingleElement(nodeDetail,"UsedPrice"); 493 if(!usedPrice) usedPrice = ""; 494 this.guiUsedPrice.setAttribute("value",usedPrice); 495 496 //Image Small 497 var imgSrc = XMDManager.getSingleElement(nodeDetail,"ImageUrlMedium"); 498 if(!imgSrc) imgSrc = ""; 499 this.guiImageSmall.setAttribute('src',imgSrc); 500 501 502 //ProductInfo and Reviews Panels 503 var allInfo = this.getFormattedInfo(XMDManager,nodeDetail); 504 505 //Move ScrollBar at the top 506 window.frames[0].scrollTo(0,0); 507 508 if(allInfo) { 509 this.guiProductInfo.innerHTML = allInfo; 510 } else { 511 this.clearInfo(); 512 } 513 514 515 window.frames[1].scrollTo(0,0); 516 //Comments 517 var comments = this.getFormattedReview(XMDManager,nodeDetail); 518 if(comments) { 519 this.guiCommentBtn.setAttribute('disabled','true'); 520 this.guiReview.innerHTML = comments; 521 }else{ 522 this.clearReview(); 523 this.guiCommentBtn.setAttribute('disabled','false'); 524 525 } 526 527 return true; 528 } 529 530 /** 531 * Get all info (Product Info and Customer Reviews) from a product and format them 532 * with a minimal HTML 533 * @param {XMDManager} XMDManager 534 * @param {XML nodeDetail} nodeDetail 535 * @param {string} infoLevel How many formatted info have to be returned can be [base | full ] 536 * @return the requested info with HTML markup 537 * @type string HTML 538 */ 539 DisplayController.prototype.getFormattedInfo = function(XMDManager,nodeDetail,infoLevel) { 540 var myXMDManager = XMDManager; 541 var content = ""; 542 var returnLevel = "full" 543 if(infoLevel) {returnLevel = infoLevel;} 544 545 //BASE INFO 546 547 var amazonURL = this.getProductAmazonUrl(myXMDManager,"directLink",nodeDetail); 548 549 if(amazonURL) {content += "<a href='" + amazonURL + "' target='Amazon' title='Go to the product Amazon homepage'>";} 550 551 var productName = myXMDManager.getSingleElement(nodeDetail,"ProductName"); 552 if(productName) {content += "<strong class='info-head'>"+productName+"</strong>\n"} 553 554 if(amazonURL) { content+= "</a>";} 555 556 content += "<br>"; 557 558 var authorArray = myXMDManager.getArrayElement(nodeDetail,"Author"); 559 if(authorArray.length == 0) authorArray = myXMDManager.getArrayElement(nodeDetail,"Artist"); 560 if(authorArray.length == 0) authorArray = myXMDManager.getArrayElement(nodeDetail,"Actor"); 561 562 if(authorArray.length > 0) { 563 for(var i=0;i<authorArray.length;i++) { 564 content += "<li>"+authorArray[i]+"</li>\n"; 565 //No more than 4 artist 566 if(i == 3) {break;} 567 } 568 } 569 570 var director = myXMDManager.getArrayElement(nodeDetail,"Director"); 571 if(director.length > 0) { 572 for(i=0;i<director.length;i++) { 573 content += "<li>"+director+" (Director)</li>\n"; 574 //No more than 4 director 575 if(i == 3) {break;} 576 } 577 } 578 579 var manufacturer = myXMDManager.getSingleElement(nodeDetail,'Manufacturer'); 580 if(manufacturer) {content += manufacturer +"<br>\n";} 581 582 var releaseDate = myXMDManager.getSingleElement(nodeDetail,'ReleaseDate'); 583 if(releaseDate) { content += releaseDate + "<p/>\n";} 584 585 var ASIN = myXMDManager.getSingleElement(nodeDetail,'Asin'); 586 if(ASIN) { content += "<strong class='info-title'>ASIN: </strong>"+ASIN+"<br>\n";} 587 588 var ISBN = myXMDManager.getSingleElement(nodeDetail,'Isbn'); 589 if(ISBN) {content += "<strong class='info-title'>ISBN: </strong>"+ISBN+"<br>\n";} 590 591 var media = myXMDManager.getSingleElement(nodeDetail,'Media'); 592 if(media) {content += "<strong class='info-title'>Media: </strong>"+media+"<br>\n";} 593 594 var salesRank = myXMDManager.getSingleElement(nodeDetail,'SalesRank'); 595 if(salesRank) {content += "<strong class='info-title'>Sales Rank: </strong>"+salesRank+"<br>\n";} 596 597 var availability = myXMDManager.getSingleElement(nodeDetail,'Availability'); 598 if(availability) {content += "<strong class='info-title'>Availability: </strong>"+availability+"<br>\n";} 599 600 var lastUpdate = myXMDManager.getSingleElement(nodeDetail,"MABTSLastUpdate"); 601 var strLastUpdate = ""; 602 if(lastUpdate) { 603 lastUpdate = new Date(parseInt(lastUpdate)); 604 strLastUpdate = "<strong class='info-title'>MAB Last Update: </strong>" + lastUpdate.toLocaleDateString(); 605 } 606 content += strLastUpdate +"<br>\n"; 607 608 609 var feature = myXMDManager.getArrayElement(nodeDetail,'Feature'); 610 if(feature.length > 0) { 611 content += "<strong class='info-title'>Features:</strong>"; 612 for(i=0;i<feature.length;i++) { 613 content += "<li>"+feature[i]+"</li>\n"; 614 } 615 content += "<br>"; 616 } 617 618 if(returnLevel == "base"){return content;} 619 620 //FULL INFO 621 var productDescription = myXMDManager.getSingleElement(nodeDetail,'ProductDescription'); 622 if(productDescription) {content += "<strong class='info-title'>Product Description: </strong><br>"+productDescription+"<p/>\n"; 623 } 624 625 //Music 626 var track = myXMDManager.getArrayElement(nodeDetail,'Track'); 627 if(track.length > 0) { 628 content += "<strong class='info-title'>Tracks</strong><br/><ol>"; 629 for(i=0;i<track.length;i++) { 630 content += "<li>"+track[i]+"</li>\n"; 631 } 632 content += "</ol><br>\n"; 633 } 634 635 /*Listmania 636 var listMania = this.getProductAmazonUrl(myXMDManager,"listManiaLink"); 637 if(listMania) { 638 content += "<strong class='info-title'>List Mania:</strong>"; 639 content += "<a href='" + listMania + "' target='Amazon' title='Check this ListMania'>View List Mania</a>\n"; 640 } 641 */ 642 643 return content; 644 645 } 646 647 /** 648 * Get the Customers Review and apply a minimum HTML formatting 649 * @param {XMDManage} XMDManager 650 * @param {XML nodeDetail} nodeDetail 651 * @return the customer reviews or a "Not Available" string 652 * @type string 653 */ 654 DisplayController.prototype.getFormattedReview = function(XMDManager,nodeDetail){ 655 var myXMDManager = XMDManager; 656 if(!myXMDManager) {return false;} 657 var content = "<strong class='info-head'>Customer Reviews:</strong><br>"; 658 659 var reviews = myXMDManager.tagExists(nodeDetail,"Reviews"); 660 if(!reviews) {return false;} 661 662 var customerReview = myXMDManager.tagExists(nodeDetail,"CustomerReview"); 663 if(!customerReview) { 664 content += "<strong>Not Available</strong>"; 665 return content; 666 }else{ 667 customerReview = nodeDetail.getElementsByTagName("CustomerReview"); 668 } 669 670 var totReviews = myXMDManager.getSingleElement(nodeDetail,'TotalCustomerReviews'); 671 if(!totReviews) {totReviews = "";} 672 var avgRating = myXMDManager.getSingleElement(nodeDetail,'AvgCustomerRating'); 673 if(!avgRating) {avgRating = "";} 674 675 content += "<i>Average Rating: " + avgRating + " out of " + totReviews + " reviews</i><br><br>"; 676 677 678 679 if(customerReview) { 680 var summary, rating, comment, node, date; 681 for(var i=0;i<customerReview.length;i++) { 682 node = customerReview.item(i); 683 summary = myXMDManager.getSingleElement(node,'Summary'); 684 if(summary) {content += "<strong>"+summary+"<br>"} 685 686 rating = myXMDManager.getSingleElement(node,'Rating'); 687 if(rating) {content += "Rating: "+rating +"</strong><br><br>";} 688 689 comment = myXMDManager.getSingleElement(node,'Comment'); 690 if(comment) {content += comment + "<br>";} 691 692 date = myXMDManager.getSingleElement(node,'Date'); 693 if(date) {content += date;} 694 695 content += "<br>"; 696 } 697 698 } 699 return content; 700 } 701 702 /** 703 * Count how many rows are in the xul tree 704 * @type int 705 */ 706 DisplayController.prototype.getNumberRows = function() { 707 return this.guiMainTree.view.rowCount; 708 } 709 710 /** 711 * Write on the status bar how many rows (products) are currently listed 712 * @return void 713 */ 714 DisplayController.prototype.writeRowStatus = function() { 715 var nrRows = this.getNumberRows(); 716 this.guiRecordStatus.setAttribute('label',nrRows + ' listed products '); 717 } 718 719 /** 720 * Get the id value (the primary key) of a xul treerow by his row index 721 * @param {int} rowIndex 722 * @return the id value or false 723 * @type int 724 */ 725 DisplayController.prototype.getRowPrimaryKey = function(rowIndex) { 726 if(typeof rowIndex == "undefined" || rowIndex < 0) { 727 return false; 728 } else{ 729 var idx = rowIndex; 730 } 731 732 var theRows = this.guiMainTree.getElementsByTagName('treerow'); 733 if(typeof theRows[idx] != "undefined") { 734 var pk = theRows[idx].getAttribute('id'); 735 }else{ 736 return false; 737 } 738 739 return pk; 740 } 741 742 /** 743 * Gets rows index for all selected rows of the tree 744 * @return the array with the rows index 745 * @type array 746 */ 747 DisplayController.prototype.getAllSelectedRowIndex = function() { 748 var indexList = new Array(); 749 var numRanges = this.guiMainTree.view.selection.getRangeCount(); 750 751 var start = {}; 752 var end = {}; 753 for (var t=0; t<numRanges; t++){ 754 this.guiMainTree.view.selection.getRangeAt(t,start,end); 755 for (var v=start.value; v<=end.value; v++){ 756 indexList.push(v); 757 } 758 } 759 return indexList; 760 } 761 762 /** 763 * Return row index of the currently selected row in the tree 764 * @return the index or -1 if it is undefined 765 * @type int 766 */ 767 DisplayController.prototype.getSelectedRowIndex = function() { 768 var idx = this.guiMainTree.currentIndex; 769 if(idx == "undefined") { 770 return -1; 771 }else{ 772 return idx; 773 } 774 } 775 776 /** 777 * Find the correponding row Index 778 * @param {string} id the id attribute 779 * @return the row Index 780 * @type int 781 */ 782 DisplayController.prototype.getRowIndexById = function(id) { 783 var rows = this.guiMainTree.getElementsByTagName("treerow"); 784 var pk; 785 for(var i=0;i<rows.length;i++) { 786 pk = rows[i].getAttribute("id"); 787 if(pk == id) { 788 return i 789 } 790 } 791 792 return -1; 793 } 794 795 /** 796 * Get the search preference 797 * @type string 798 */ 799 DisplayController.prototype.getSearchPreference = function() { 800 return this.elSettingsSpacer.getAttribute("search"); 801 } 802 803 /** 804 * Get how many records should be requested for each connection 805 * @type int 806 */ 807 DisplayController.prototype.getRecordPreference = function() { 808 return this.elSettingsSpacer.getAttribute("nrResult"); 809 } 810 811 /** 812 * Sort rows in the tree 813 * @param {XMDMnager} XMDManager 814 * @param {XUL Element} el the reference to the xul treecol 815 * @param {string} sortTag the xml tag to use for sorting rows 816 * @param {bool} virtualSort apply virtual sort, so the XMDManager model remain untouched. 817 * @return void 818 */ 819 DisplayController.prototype.sort = function(XMDManager,el,sortTag,virtualSort) { 820 //reorder the XML Document 821 var myXMDManager = XMDManager; 822 var sortType = el.getAttribute('class'); 823 //Get only first class style 824 var firstClass = sortType.split(" "); 825 sortType = firstClass[0]; 826 827 var sortDirection = el.getAttribute('sortDirection'); 828 829 this.clearRowHeader(); 830 831 var asc = true; 832 el.setAttribute('sortDirection','ascending'); 833 834 if(sortDirection == "ascending"){ 835 asc = false; 836 el.setAttribute('sortDirection','descending'); 837 }else if (sortDirection == "descending"){ 838 asc = true; 839 el.setAttribute('sortDirection','ascending'); 840 } 841 842 //get Currently selected row 843 var rowSelected = this.getSelectedRowIndex(); 844 var pk = this.getRowPrimaryKey(rowSelected); 845 846 //Set cursor to wait 847 if((typeof window.setCursor != "undefined") && (typeof window.setCursor == "function")) { 848 window.setCursor("wait"); 849 } 850 851 //VirtualSort, the xml document is not really sorted, we sort only the view in the tree 852 if(virtualSort) { 853 var nodeSorted = myXMDManager.virtualSort(sortType,sortTag,asc); 854 var treeNode = this.guiMainTree.getElementsByTagName("treerow"); 855 var treeRow; 856 //Update every rows; 857 for(var i=0; i < nodeSorted.length;i++) { 858 treeRow = treeNode.item(i) 859 this.updateRow(treeRow,nodeSorted[i],myXMDManager); 860 } 861 862 }else{ 863 //sort first the XML document 864 myXMDManager.sort(sortType,sortTag,asc); 865 //Sync tree with the new sorted xml document 866 this.syncTree(myXMDManager); 867 } 868 869 //reset the focus on the previous selected row 870 var newIndex = this.getRowIndexById(pk); 871 if(newIndex) {this.setFocusOnRow(newIndex);} 872 873 //Set cursor to normal 874 if((typeof window.setCursor != "undefined") && (typeof window.setCursor == "function")) { 875 window.setCursor("auto"); 876 } 877 } 878 879 /** 880 * Set Focus on a row ensuring it remains visible if the tree has too many rows 881 * @param {int} index 882 * return void if index < 0 883 */ 884 DisplayController.prototype.setFocusOnRow = function(index) { 885 if(index < 0) {return;} 886 887 this.guiMainTree.view.selection.select(index); 888 this.guiMainTree.focus(); 889 this.guiMainTree.treeBoxObject.ensureRowIsVisible(index); 890 }