1var CSS_GREEN = 'green_t'; 2var CSS_RED = 'red_t'; 3var CSS_BLACK = 'color_black01'; 4 5var stateCssColor = []; 6stateCssColor['success'] = CSS_GREEN; 7stateCssColor['sold'] = CSS_GREEN; 8stateCssColor['error'] = CSS_RED; 9stateCssColor['unsold'] = CSS_BLACK; 10 11var DEFAULT_AUDIO_VOLUME = 1.0; 12var CONNECTION_ISSUE_LOG_COUNT = 0; 13var SUCCESS_CONNECT_COUNT = 0; 14 15var overlayNotificationTimeout = null; 16 17/** 18 * Polyfill for keys() 19 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys 20 */ 21if (!Object.keys) { 22 Object.keys = (function () { 23 'use strict'; 24 var hasOwnProperty = Object.prototype.hasOwnProperty, 25 hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), 26 dontEnums = [ 27 'toString', 28 'toLocaleString', 29 'valueOf', 30 'hasOwnProperty', 31 'isPrototypeOf', 32 'propertyIsEnumerable', 33 'constructor' 34 ], 35 dontEnumsLength = dontEnums.length; 36 37 return function (obj) { 38 if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) { 39 throw new TypeError('Object.keys called on non-object'); 40 } 41 42 var result = [], prop, i; 43 44 for (prop in obj) { 45 if (hasOwnProperty.call(obj, prop)) { 46 result.push(prop); 47 } 48 } 49 50 if (hasDontEnumBug) { 51 for (i = 0; i < dontEnumsLength; i++) { 52 if (hasOwnProperty.call(obj, dontEnums[i])) { 53 result.push(dontEnums[i]); 54 } 55 } 56 } 57 return result; 58 }; 59 }()); 60} 61 62/** 63 * WebSocket Auction Client 64 * @author Amit 65 **/ 66 67function AuctionClient() { 68 this.connection = null; 69 this.connectionErrorCode = 0; 70 this.clientData = null; 71 this.currency = []; 72 73 var webSocket = setting.webSocket; 74 this.defaultSiteName = setting.defaultSiteName; 75 this.siteName = setting.siteName; 76 this.webSocketEndPoint = webSocket.host + (webSocket.port ? ":" + webSocket.port : '') + "/"; 77 78 this.webSocket = window.WebSocket || window.MozWebSocket; 79 this.consoleContent = $('#content'); 80 this.criteoTrackTransactionIndex = -1; 81 82 this.configReserveMet = setting.reserveMet; 83 this.showReserveMetBanner = false; 84 this.foreceDisplayHighestBidderMessage = false; 85 if(this.configReserveMet){ 86 if(this.configReserveMet.met) this.showReserveMetBanner = this.configReserveMet.met.showBanner; 87 if(this.configReserveMet.notMet)this.foreceDisplayHighestBidderMessage = this.configReserveMet.notMet.foreceDisplayHighestBidderMessage; 88 } 89 if (!this.webSocket) { 90 this.appendConsoleContent(i18nTranslate('Sorry, but your browser doesn\'t support WebSockets.')); 91 return false; 92 } 93 94 this.LotSnapshotReason = { 95 UNKNOWN: 0, 96 LOT_STATE_CHANGED: 1, 97 LOT_BID_UPDATED: 2, 98 LOT_BID_RETRACTED: 3, 99 LOT_INCREMENT_CHANGED: 4, 100 LOT_MANUAL_NEXT_BID_APPLIED: 5, 101 LOT_END_TIME_EXTENDED: 6, 102 LOT_RE_OPENED: 7 103 }; 104 105 this.messageType = { 106 UNKNOWN: 0, 107 FAIRWARNING: 1, 108 FIVESECONDWARNING: 2, 109 GENERALMESSAGE: 3 110 }; 111 this.fiveSecondsTimerInstance = null; 112 113 this.soundFiles = { 114 startLot: getUrl('public/sound/chimes.wav'), 115 passLot: getUrl('public/sound/passed.wav'), 116 biddingLot: getUrl('public/sound/place_bid.wav'), 117 bidAccepted: getUrl('public/sound/bid_accepted.wav'), 118 bidReceived: getUrl('public/sound/bid_received.wav'), 119 outBid: getUrl('public/sound/out_bid.mp3'), 120 winLot: getUrl('public/sound/sold_won.wav'), 121 notWonLot: getUrl('public/sound/sold_not_won.wav'), 122 fairWarning: getUrl('public/sound/fair_warning.wav') 123 }; 124 125 this.sound = { 126 startLot: null, 127 passLot: null, 128 biddingLot: null, 129 bidAccepted: null, 130 bidReceived: null, 131 outBid: null, 132 winLot: null, 133 notWonLot: null, 134 fairWarning: null 135 }; 136 137 this.logType = { 138 error: 1, 139 warning: 2, 140 log: 3 141 }; 142 143 var _bidsquareBidderTxt = i18nTranslate(this.defaultSiteName+' Bidder'); 144 var _competingBidderTxt = i18nTranslate('Competing Bidder'); 145 var _bidderTxt = i18nTranslate('Bidder'); 146 /*We are setting bidder text static now, In future we are making dynamic this changes*/ 147 /*WL setting*/ 148 this.bidderSettingWl = { 149 'bidsquare':{ 150 "text" : _competingBidderTxt, 151 'showBidderNo': false 152 }, 153 'wl':{
154 "text" : _bidderTxt, 155 'showBidderNo': true 156 }, 157 'floor':{ 158 "text" : _competingBidderTxt, 159 'showBidderNo': false 160 } 161 }; 162 /*Bidsquare setting*/ 163 this.bidderSettingBidsquare = { 164 'bidsquare':{ 165 "text" : _bidsquareBidderTxt, 166 'showBidderNo': true 167 }, 168 'wl':{ 169 "text" : _competingBidderTxt, 170 'showBidderNo': false 171 }, 172 'floor':{ 173 "text" : _competingBidderTxt, 174 'showBidderNo': false 175 } 176 }; 177 178 /*Clerk setting*/ 179 this.bidderSettingClerk = { 180 'bidsquare':{ 181 "text" : _bidsquareBidderTxt, 182 'showBidderNo': true 183 }, 184 'wl':{ 185 "text" : _bidderTxt, 186 'showBidderNo': true 187 }, 188 'floor':{ 189 "text" : _competingBidderTxt, 190 'showBidderNo': true 191 } 192 }; 193 194 // assert "permission" for sound effects, 195 // note we are not using the Promise then/catch returned since that will only reject on user interaction 196 // if we change it to reject on queue of interaction we then can not fulfill it with a resolve afterwards, Promise Chaining won't work well for that either 197 // the 2 cases that will execute are only onPlaySoundSuccess if we don't need permision granted or first onPlaySoundFailure and then onPlaySoundSuccess after user interacts 198 mediaPlaybackRequiresUserGesture(this.onPlaySoundSuccess.bind(this), this.onPlaySoundFailure.bind(this)); 199 200 this.setVolume(DEFAULT_AUDIO_VOLUME); 201 this.setCriteoTrackTransactionIndex(); 202 203 this.localStorageId = null; 204 this.localStorageDatatimeId = null; 205 206 this.isWidget = false; 207} 208AuctionClient.prototype.eventItemTimerInstance = {}; 209AuctionClient.prototype.appendConsoleContent = function (contentString) { 210 if (setting.webSocket.debug) { 211 console.log(contentString); 212 } 213}; 214 215/*Get Bidder text as per the setting*/ 216/*We believe we can pass */ 217AuctionClient.prototype.getBidderTxt = function (siteId,bidderId,isFloorBid) { 218 /*Get Biddersetting obj as per current site id*/ 219 var bidderSettingObj = this.bidderSettingBidsquare; 220 var isEventClerk = this.isEventClerk(); 221 if (isEventClerk) { 222 bidderSettingObj = this.bidderSettingClerk; 223 } 224 else if (this.clientData.siteID) { 225 bidderSettingObj = this.bidderSettingWl; 226 } 227 228 /*Get Biddersetting as per receive siteid from AE*/ 229 var bidderSetting = bidderSettingObj.bidsquare; 230 if(typeof isFloorBid !=='undefined' && isFloorBid) { 231 var bidderSetting = bidderSettingObj.floor; 232 } 233 else if (typeof siteId !== 'undefined' && siteId) { 234 bidderSetting = bidderSettingObj.wl; 235 } 236 237 if (!isEventClerk && typeof this.clientData.hideBidderNumber !== 'undefined' && this.clientData.hideBidderNumber) { 238 bidderSetting['showBidderNo'] = false; 239 } 240 241 /*Set Bidder Text as per setting*/ 242 var txt = bidderSetting['text']; 243 if(bidderSetting['showBidderNo'] && typeof bidderId !=='undefined' && bidderId) { 244 txt += " " + bidderId; 245 } 246 247 return txt; 248}; 249 250 251AuctionClient.prototype.logError = function (data) { 252 //this.appendConsoleContent('logError > data: ' + data); 253 this.appendConsoleContent('AE connection failed issue logged'); 254 var logOption = data; 255 logOption.uri = 'auction/log'; 256 logOption = $.extend({}, this.clientData, logOption); 257 this.appendConsoleContent('logError > logOption: ' + logOption); 258 phpLog(logOption, this.logType.error); 259}; 260 261AuctionClient.prototype.addAuction = function (auctionID) { 262 this.auctionIDs = this.addIds(auctionID); 263}; 264 265AuctionClient.prototype.addLot = function (lotIDs) { 266 this.lotIDs = this.addIds(lotIDs); 267}; 268 269AuctionClient.prototype.addIds = function (ids) { 270 var storage = []; 271 switch (typeof (ids)) { 272 case 'object': 273 /*for (var e in ids) { 274 storage.push(ids[e]); 275 }*/ 276 storage = ids; 277 break; 278 case 'number': 279 storage.push(ids); 280 break; 281 } 282 283 return storage; 284}; 285 286AuctionClient.prototype.initializeConnection = function () { 287 var hasSuccess = false;
288 this.connection = this.connection || new WebSocket(this.webSocketEndPoint); 289 // this is technically wrong 290 // if we had a previous connection then we want to really track how many connections are open 291 // and show if any connection is not open and clear when all connections are open successfully 292 // for now this is good enough and fixes the issue when we have multiple instances of auctionClient running 293 // i.e. multiple instances can be due to 1 live and 1 timed running on the same page. 294 if (overlayNotificationTimeout) clearTimeout(overlayNotificationTimeout); 295 overlayNotificationTimeout = setTimeout(function() { 296 this.reconnectOverlayNotification('on'); 297 }.bind(this), 3000); 298 this.connection.onopen = function () { 299 this.appendConsoleContent('Connected to AE'); 300 if (this.isWidget) 301 { 302 window.parent.postMessage({BSQMessageType: "bsqAEConnected", bsqAEConnected: true}, '*'); 303 } 304 this.reconnectOverlayNotification('off'); 305 this.publishStoredMessage(); 306 this.publishInitialMessage(); 307 this.clientLogin(); 308 }.bind(this); 309 this.connection.onerror = function (error) { 310 var errorJson = JSON.stringify(error); 311 this.appendConsoleContent('Error: ' + errorJson); 312 }.bind(this); 313 this.connection.onmessage = function (message) { 314 if (!hasSuccess) SUCCESS_CONNECT_COUNT++; 315 hasSuccess = true; 316 try { 317 var json = JSON.parse(message.data); 318 if (json.data !== null) this.processClient(json); 319 } catch (e) { 320 this.appendConsoleContent(e); 321 this.appendConsoleContent('This doesn\'t look like a valid JSON: ' + message.data); 322 return; 323 } 324 }.bind(this); 325 this.connection.onclose = function (e) { 326 if (!e.wasClean) { 327 this.appendConsoleContent('Not connected to AE'); 328 this.connectionErrorCode = e.code; 329 /** 330 * Only throw the "Not Connected. Try re-connecting" popup at live panel 331 */ 332 this.reconnectOverlayNotification('on'); 333 334 /** 335 * Only reconnect when the below error code found 336 * The below listed error codes seems to be safe to reconnect 337 * 338 * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent 339 */ 340 switch (e.code) { 341 case 1005: //No Status Recvd 342 case 1006: //Abnormal Closure 343 case 1009: //Message too big 344 case 1011: //Internal Error 345 case 1012: //Service Restart 346 case 1013: //Try Again Later 347 this.connection = null; 348 this.appendConsoleContent('Trying re-connect'); 349 setTimeout(function(){ 350 // We have to set mergedCallbackForPopulateItemInfo false to ajax call fo fetch item details on reconnecting connection 351 if (typeof this.mergedCallbackForPopulateItemInfo !== 'undefined') { 352 this.mergedCallbackForPopulateItemInfo = false; 353 } 354 this.initializeConnection(); 355 }.bind(this), 500); //Seems like websocket need to some time to completly close the connection. So, try to reconnect after few ms. 356 break; 357 default: 358 this.appendConsoleContent('Please save your bid and refresh the page'); 359 } 360 } 361 }.bind(this); 362}; 363 364AuctionClient.prototype.processClientMessage = function (data, senderTxt) { 365 var message = { 366 signature: "LAE_PROTOCOL", 367 type: "message", 368 version: 1, 369 sender: senderTxt, 370 sendTime: (new Date()).getTime(), 371 data: data 372 }; 373 return message; 374}; 375 376AuctionClient.prototype.sendMessage = function (data, callback) { 377 //this.appendConsoleContent('sendMessage > data: ' + JSON.stringify(data)); 378 var messageOption = data; 379 var clientData = $.extend({}, clientData, this.clientData); 380 var registrationNumbers = {}; 381 if (typeof clientData.registrationNumbers !== 'undefined') { 382 registrationNumbers = clientData.registrationNumbers; 383 delete clientData.registrationNumbers; 384 } 385 if (typeof clientData !== 'undefined') { 386 messageOption = $.extend({}, messageOption, clientData); 387 } 388 if (typeof messageOption.userID !== 'undefined' && typeof messageOption.auctionID !== 'undefined') { 389 if (messageOption.userID > 0) { 390 var bidderNumber = messageOption.userID; 391 if (typeof registrationNumbers[messageOption.userID] !== 'undefined') { 392 if (typeof registrationNumbers[messageOption.userID][messageOption.auctionID] !== 'undefined') { 393 bidderNumber = registrationNumbers[messageOption.userID][messageOption.auctionID]; 394 } 395 } 396 if (typeof messageOption.registeredBidderID !== 'undefined') { 397 bidderNumber = messageOption.registeredBidderID; 398 } 399 messageOption = $.extend({}, messageOption, {registeredBidderID: bidderNumber}); 400 } 401 } 402 //this.appendConsoleContent('sendMessage > messageOption: ' + JSON.stringify(messageOption)); 403 var message = this.processClientMessage(messageOption); 404 var json = JSON.stringify(message); 405 this.appendConsoleContent('MessageSend: ' + json); 406 if (this.connection && this.connection.readyState === 1) { 407 //this.appendConsoleContent('Sending Message to LAE'); 408 this.connection.send(json); 409 if (typeof callback === 'function') { 410 callback(); 411 } 412 } else { 413 var intervalCount = 0; 414 var timeoutInterval = setInterval(function() { 415 if (!this.connection || this.connection.readyState !== 1) { 416 intervalCount += 1; 417 } else { 418 clearInterval(timeoutInterval); 419 this.sendMessage(data, callback); 420 } 421 //Will wait for 15 sec before client put to the timeout 422 if (intervalCount > 15) {
423 if (this.isNonLiveClient()) alert("Trying to reconnect. Please try again."); 424 clearInterval(timeoutInterval); 425 if (typeof callback === 'function') { 426 callback(); 427 } 428 } 429 }.bind(this), 1000); 430 } 431}; 432 433AuctionClient.prototype.addClient = function (clientData) { 434 this.clientData = clientData; 435 436 this.clientData.setIsPaymentVerified = function (verified) 437 { 438 if (typeof this.paymentVerified === 'undefined') 439 { 440 this.paymentVerified = 0; 441 } 442 this.paymentVerified = (typeof verified !== 'undefined') ? verified : 0; 443 }; 444 445 this.clientData.isPaymentVerified = function () 446 { 447 if (typeof this.paymentVerified !== 'undefined') 448 { 449 if (this.paymentVerified === 1) 450 { 451 return true; 452 } 453 } 454 return false; 455 }; 456}; 457 458AuctionClient.prototype.addCurrency = function (eventCurrency) { 459 this.currency = eventCurrency; 460}; 461 462AuctionClient.prototype.validateNumber = function (number) { 463 //var regxNumber = /^\d+(\.\d+)?$/; 464 var regxNumber = /^\d+$/; 465 return regxNumber.test(number); 466}; 467 468AuctionClient.prototype.clientLogin = function () { 469 //this.appendConsoleContent('Inside this.clientLogin()'); 470 var messageOption = { 471 action: "login" 472 }; 473 //this.appendConsoleContent('clientLogin > messageOption: ' + JSON.stringify(messageOption)); 474 //this.appendConsoleContent('clientLogin > sendMessage'); 475 this.sendMessage(messageOption, function () { 476 //this.appendConsoleContent('clientLogin > sendMessage > Message Send.....'); 477 }.bind(this)); 478}; 479 480AuctionClient.prototype.clientSubscription = function () { 481 //this.appendConsoleContent('Inside this.clientSubscription()'); 482 //this.appendConsoleContent('clientSubscription > sendMessage'); 483 if (!this.lotIDs || this.lotIDs.length === 0) { 484 this.sendMessage({ 485 action: "subscribe", 486 auctionIDs: this.auctionIDs, 487 lotIDs: this.lotIDs, 488 subscriptionID: generateUid() 489 }, function () { 490 //this.appendConsoleContent('clientSubscription > sendMessage > Message Send.....'); 491 }.bind(this)); 492 } else { 493 var auctionIDs = Object.keys(this.lotIDs); 494 if (auctionIDs.length > 0) { 495 for (var a in auctionIDs) { 496 var auctionId = auctionIDs[a]; 497 var lotIDs = Object.keys(this.lotIDs[auctionId]); 498 if (lotIDs.length > 0) { 499 var lots = []; 500 for (var l in lotIDs) { 501 lots.push(parseInt(lotIDs[l])); 502 } 503 this.sendMessage({ 504 action: "subscribe", 505 auctionIDs: [parseInt(auctionId)], 506 lotIDs: lots, 507 subscriptionID: generateUid() 508 }, function () { 509 //this.appendConsoleContent('clientSubscription > sendMessage > Message Send.....'); 510 }.bind(this)); 511 } 512 } 513 } 514 } 515}; 516 517AuctionClient.prototype.updateLotStatus = function (lotId, auctionId, soldPice, highestBidder, itemStatus, nextItemID) { 518 //this.appendConsoleContent('Inside this.updateLotSatus()'); 519 //this.appendConsoleContent('updateLotSatus > auctionId: ' + auctionId); 520 //this.appendConsoleContent('updateLotSatus > lotId: ' + lotId); 521 var $this = this; 522 523 var isRestrictedActivityAuction = this.isRestrictedActivityAuction(auctionId); 524 525 var lotIndex = 0; 526 var statType = ''; 527 528 if ($this.isNonLiveClient()) { 529 var buttonStatWrapperSelector = $('#ba_' + lotId + '_' + auctionId); 530 lotIndex = buttonStatWrapperSelector.data('lindex'); 531 statType = buttonStatWrapperSelector.data('stype'); 532 } 533 534 if ($this.isLiveClient()) { 535 statType = 'live_panel_lot_slide'; 536 } 537 538 var urlAjax = getUrl('item/buttonStat/' + lotId + '/' + auctionId + '/' + statType + '/' + lotIndex); 539 urlAjax += "?is_ajax=1&uls=1" + ($this.isWidget ? "&widget=1" : ""); 540 541 /* 542 * Need to send these value with defaulted to "0" (zero), even though they are not available. 543 */ 544 if (typeof soldPice === 'undefined' || soldPice === null || isRestrictedActivityAuction) soldPice = 0;
545 if (typeof highestBidder === 'undefined' || highestBidder === null) highestBidder = 0; 546 if (typeof itemStatus === 'undefined' || itemStatus === null) itemStatus = 0; 547 548 urlAjax += "&soldAmount=" + soldPice; 549 urlAjax += "&highestBidder=" + highestBidder; 550 urlAjax += "&itemStatus=" + itemStatus; 551 552 if (typeof $this.mergedCallbackForPopulateItemInfo !== 'undefined' && $this.mergedCallbackForPopulateItemInfo) { 553 if (typeof nextItemID !== 'undefined') urlAjax += "&mergeItemInfo=1&nextItemId=" + nextItemID; 554 } 555 //this.appendConsoleContent('updateLotSatus > isNonLiveClient() > urlAjax: ' + urlAjax); 556 // On the live panel this whole request belongs to a single lot advance (from the sold lot 557 // to nextItemID) and paints the single shared UI. Rapid skips can leave requests in flight 558 // that resolve out of order, so: (1) abort the prior in-flight live request, and (2) ignore 559 // any response whose advance is no longer current, i.e. its next lot is no longer the panel 560 // target (_panelLotId). This gates the entire callback (both the buttonState render and the 561 // merged item paint) so we never apply a stale response. Non-live pages have a button per 562 // lot writing to per-lot DOM, so they are unaffected and keep the original behavior. 563 var isLivePanel = $this.isLiveClient(); 564 // The lot this advance moves to; null when there is no next lot (last lot) so we don't 565 // gate the final sold lot's status update. 566 var reqNextLotId = (isLivePanel && typeof nextItemID !== 'undefined' && parseInt(nextItemID) > 0) 567 ? parseInt(nextItemID) : null; 568 569 // Abort the prior live buttonStat request (independent of the itemRelatedInfo request's 570 // own abort handle). The handle is not cleared on completion, so it may already be finished 571 // here - aborting a completed jqXHR is a harmless no-op (and the try/catch covers anything 572 // unexpected). 573 if (isLivePanel && $this._buttonStatXhr && typeof $this._buttonStatXhr.abort === 'function') { 574 try { $this._buttonStatXhr.abort(); } catch (e) { /* ignore */ } 575 } 576 577 var jsonData = null; 578 var xhr = $.ajax({ 579 type: 'GET', 580 url: urlAjax, 581 dataType: 'json', 582 success: function (data) { 583 jsonData = data; 584 }, 585 complete: function () { 586 if (!jsonData) return; // aborted (superseded) or failed request 587 // Ignore an out-of-order response for an advance that is no longer current. 588 if (reqNextLotId !== null && reqNextLotId !== $this._panelLotId) return; 589 590 if (typeof jsonData.buttonState !== 'undefined') { 591 var buttonState = jsonData.buttonState; 592 for (var i in buttonState) { 593 var selector = buttonState[i].selector; 594 var renderHtml = buttonState[i].renderHtml; 595 var jqAction = buttonState[i].jqAction; 596 switch (jqAction) { 597 case 'replace': 598 $(selector).html(renderHtml); 599 break; 600 case 'append': 601 $(selector).append(renderHtml); 602 break; 603 case 'replaceWithSelector': // This case only using live panel buttom scroll items 604 if (typeof buttonState[i].jqReplaceSelector !== 'undefined') { 605 for (var s in buttonState[i].jqReplaceSelector) { 606 var jqReplaceSelector = buttonState[i].jqReplaceSelector[s]; 607 $(selector).find(jqReplaceSelector).remove(); 608 } 609 } 610 $(selector).append(renderHtml); 611 $(selector).removeClass("on").addClass("closed"); 612 break; 613 } 614 } 615 } 616 617 if (typeof jsonData.item !== 'undefined') { 618 $this.registeredItemsInfo = jsonData.item; 619 if (typeof $this.populateLotRelatedInfoAjaxCompleteCallback !== 'undefined') { 620 if (isLivePanel) $this.populateLotRelatedInfoAjaxCompleteCallback(auctionId); 621 } 622 } 623 624 // The buttonStat ajax has finished; let the live bid button advance gate know so 625 // it can re-enable once the new lot info/image are also ready. 626 if (isLivePanel && typeof $this._markBidButtonStatDone === 'function') { 627 $this._markBidButtonStatDone(); 628 } 629 } 630 }); 631 if (isLivePanel) $this._buttonStatXhr = xhr; 632}; 633 634AuctionClient.prototype.enableButton = function (buttonElement) { 635 buttonElement.css('opacity', 1); 636 buttonElement.prop('disabled', false); 637}; 638 639AuctionClient.prototype.disableButton = function (buttonElement, dimmed) { 640 buttonElement.prop('disabled', true); 641 var opacity = ""; 642 if (dimmed !== 'undefined' && dimmed) { 643 opacity = "0.5"; 644 } 645 buttonElement.css('opacity', opacity); 646}; 647 648AuctionClient.prototype._displayMessage = function (typeTxt, lotId, auctionId, messageTxt) { 649 var elementSelector = '#msg_' + lotId + '_' + auctionId; 650 if (lotId === null && auctionId === null) { 651 elementSelector = '.ack_bid_msg'; 652 } 653 var elementCssColor = stateCssColor; 654 var messageElement = $(elementSelector); 655 for (var c in elementCssColor) { 656 messageElement.removeClass(elementCssColor[c]); 657 } 658 if (typeof elementCssColor[typeTxt] !== 'undefined') { 659 messageElement.addClass(elementCssColor[typeTxt]); 660 } 661 messageElement.html(i18nTranslate(messageTxt)); 662}; 663 664AuctionClient.prototype.successMessage = function (lotId, auctionId, messageTxt) { 665 this._displayMessage('success', lotId, auctionId, messageTxt); 666}; 667 668AuctionClient.prototype.errorMessage = function (lotId, auctionId, messageTxt) { 669 this._displayMessage('error', lotId, auctionId, messageTxt); 670}; 671 672AuctionClient.prototype.removeMessage = function (lotId, auctionId) { 673 var elementSelector = '#msg_' + lotId + '_' + auctionId; 674 if (lotId === null && auctionId === null) { 675 elementSelector = '.ack_bid_msg'; 676 } 677 var messageElement = $(elementSelector); 678 messageElement.html(''); 679 680 var reserveNMElementSelecter = $('#rnm_' + lotId + '_' + auctionId); 681 reserveNMElementSelecter.html(''); 682}; 683 684AuctionClient.prototype.isLiveClient = function () { 685 var client = false;
686 if (typeof this.clientData.livePanel !== 'undefined' && this.clientData.livePanel) { 687 client = true; 688 } 689 return client; 690}; 691 692AuctionClient.prototype.isEventClerk = function () { 693 var client = false; 694 if (typeof this.isClerk !== 'undefined' && this.isClerk) { 695 client = true; 696 } 697 return client; 698}; 699 700AuctionClient.prototype.isNonLiveClient = function () { 701 var client = false; 702 if (typeof this.clientData.livePanel === 'undefined' || !this.clientData.livePanel) { 703 client = true; 704 } 705 return client; 706}; 707 708AuctionClient.prototype.prefixMessageTxt = function (messageTxt, cacheMessage, preText) { 709 if (typeof cacheMessage === 'undefined') { 710 cacheMessage = false; 711 } 712 if (typeof preText === 'undefined') { 713 preText = '> '; 714 } 715 var messageString = preText + messageTxt; 716 if (cacheMessage) { 717 this.storeConsoleMessage(messageString); 718 this.cacheLastClientMessageDateTime(this.messageDateTimeFormat()); 719 } 720 return messageString; 721}; 722 723AuctionClient.prototype.attachMessageToDom = function (content) { 724 this.consoleContent.prepend(content); 725 this.consoleContent.scrollTop(0); 726}; 727 728AuctionClient.prototype.getMessageWrapper = function (htmlTag) { 729 if (typeof htmlTag === 'undefined') { 730 htmlTag = 'span'; 731 } 732 return $('<' + htmlTag + '/>'); 733}; 734 735AuctionClient.prototype.isRestrictedActivityAuction = function (auctionID) { 736 var isRestrictedActivity = null; 737 if (typeof this.clientData.isRestrictedActivity !== 'undefined' && this.clientData.isRestrictedActivity) { 738 if (typeof auctionID !== 'undefined') { 739 if (typeof this.clientData.isRestrictedActivity[auctionID] !== 'undefined') { 740 isRestrictedActivity = this.clientData.isRestrictedActivity[auctionID]; 741 } 742 } 743 } 744 return isRestrictedActivity; 745}; 746 747AuctionClient.prototype.isRestrictedActivityMessage = function (message, isRestrictedActivityAuction) { 748 var isRestricted = null; 749 if (isRestrictedActivityAuction) { 750 isRestricted = true; 751 switch (message.data.action) { 752 case 'loginReply': 753 case 'lotItemStarted': 754 case 'auctionSnapshot': 755 case 'lotItemSkipped': 756 case 'clientBidRejected': 757 case 'clientBidAck': 758 isRestricted = false; // allow all as these don't have any "sensative" info 759 break; 760 case 'lotItemSold': 761 // not restricted but need to filter some values from the messages manually 762 isRestricted = false; 763 break; 764 case 'auctionLotSnapshot': 765 if (typeof message.data.reason !== 'undefined') { 766 switch (message.data.reason) { 767 case this.LotSnapshotReason.LOT_RE_OPENED: 768 isRestricted = false; 769 break; 770 } 771 } 772 break; 773 } 774 } 775 return isRestricted; 776}; 777 778AuctionClient.prototype.publishMessage = function (message, cacheMessage) { 779 if (typeof cacheMessage === 'undefined') { 780 cacheMessage = true; 781 } 782 // Clear the five second interval after below action only 783 var stopFiveSecondsTimerInstanceActionArr = [ 784 'lotItemSold', 785 'lotItemSkipped', 786 'onlineBidAccepted', 787 'floorBidAccepted', 788 'lotMessageFromAdmin', 789 'lotIncrementChanged', 790 ]; 791 if($.inArray(message.data.action, stopFiveSecondsTimerInstanceActionArr) !== -1) { 792 clearInterval(this.fiveSecondsTimerInstance); 793 } 794 795 var startingSoonAuctionClass = "starting-soon"; 796 797 var isRestrictedActivityAuction = (typeof message.data.auctionID !== 'undefined' ? this.isRestrictedActivityAuction(message.data.auctionID) : false); 798 799 if (isRestrictedActivityAuction) { 800 if (this.isRestrictedActivityMessage(message, isRestrictedActivityAuction)) { 801 return; // if the message is completely restricted then just bail and do nothing, else we'll fall through and "filter" the messages based on isRestrictedActivityAuction var 802 } 803 } 804 805 switch (message.data.action) { 806 case "lotItemStarted": 807 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt("<hr>", cacheMessage, ""))); 808 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt("<span class=\"impt\">" + i18nTranslate("Lot $1 started", message.data.lotNumber) + "</span> (" + message.data.lotName + ")", cacheMessage))); 809 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt("<hr>", cacheMessage, ""))); 810 if (this.isLiveClient()) { 811 this.playSound('startLot'); 812 } 813 break; 814 case "auctionSnapshot": 815 if (this.isLiveClient()) { 816 if (typeof message.data.auctionState !== 'undefined') { 817 switch (message.data.auctionState) { 818 case 1: 819 case 2: 820 if(typeof this.clientData.isBiddingStarted !== 'undefined' && !this.clientData.isBiddingStarted) {
821 var storedMessage = this.getStoredMessage(); 822 // check if any message availble in local storage 823 // If availble then we don't want to show auction starting soon message 824 if(storedMessage.length === 0) { 825 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_RED + ' ' + startingSoonAuctionClass).html(this.prefixMessageTxt(i18nTranslate("Auction starting soon"), cacheMessage))); 826 } 827 } 828 break; 829 830 case 3: 831 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_RED).html(this.prefixMessageTxt(i18nTranslate("AUCTION IS PAUSED. WE WILL RESUME SHORTLY"), cacheMessage))); 832 break; 833 834 case 4: 835 this.attachMessageToDom(this.getMessageWrapper().addClass("impt").html(this.prefixMessageTxt(i18nTranslate("Auction Ended. Thank you for bidding!"), cacheMessage))); 836 break; 837 } 838 } 839 } 840 break; 841 case "auctionLotSnapshot": 842 if (typeof message.data.reason !== 'undefined') { 843 switch (message.data.reason) { 844 case this.LotSnapshotReason.LOT_BID_RETRACTED: 845 if (parseInt(message.data.lotState) === 1) { //Only show bid retracted message to the message console for the active lot 846 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt("===== " + i18nTranslate('Bid retracted') + "=====", cacheMessage))); 847 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt(i18nTranslate("Current Price - $1 Asking Price - $2", formatMoney(message.data.currentBid, this.currency[message.data.auctionID].symbol), formatMoney(message.data.nextBid, this.currency[message.data.auctionID].symbol)), cacheMessage))); 848 } 849 break; 850 case this.LotSnapshotReason.LOT_INCREMENT_CHANGED: 851 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt(i18nTranslate("Increment changed $1 and New asking Price - $2", formatMoney(message.data.increment, this.currency[message.data.auctionID].symbol), formatMoney(message.data.nextBid, this.currency[message.data.auctionID].symbol)), cacheMessage))); 852 break; 853 case this.LotSnapshotReason.LOT_MANUAL_NEXT_BID_APPLIED: 854 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt(i18nTranslate("New asking Price - $1", formatMoney(message.data.nextBid, this.currency[message.data.auctionID].symbol)), cacheMessage))); 855 break; 856 case this.LotSnapshotReason.LOT_RE_OPENED: 857 this.attachMessageToDom(this.getMessageWrapper().addClass("impt deep").html(this.prefixMessageTxt(i18nTranslate("Lot $1 Re-Opened", message.data.lotNumber), cacheMessage))); 858 break; 859 } 860 } 861 if (this.isLiveClient()) { 862 if (typeof message.data.lotState !== 'undefined' && message.data.lotState === 1) { 863 if (message.data.numberOfBids === 0) { 864 if (!isRestrictedActivityAuction) { 865 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt(i18nTranslate("Asking Price - $1", formatMoney(message.data.nextBid, this.currency[message.data.auctionID].symbol))))); 866 } 867 } 868 } 869 } 870 break; 871 case "lotItemSold": 872 case "lotItemResold": 873 874 var isResold = message.data.action === "lotItemResold"; 875 if (isResold) { 876 if (!this.isEventClerk() && !this.isAuctioneerScreen()) { 877 break; // we only want auctioneer screen and clerk to see this message, we will ignore lotItemResold for all user-facing messages 878 } 879 } 880 881 var soldTo = message.data.soldToUserName; 882 var registeredBidderID = soldTo; 883 if (typeof message.data.registeredBidderID !== 'undefined') { 884 registeredBidderID = message.data.registeredBidderID; 885 } 886 var floorBidderNumber = null; 887 if (typeof message.data.floorBidderNumber !== 'undefined' || message.data.floorBidderNumber !== null) { 888 floorBidderNumber = message.data.floorBidderNumber; 889 } 890 var messageContent = {i18nMsg: "Lot $1", args: [message.data.lotNumber]}; 891 if (isRestrictedActivityAuction) { 892 messageContent.i18nMsg += " Closed"; 893 } else { 894 var BidderNumber = (parseInt(soldTo) > 0 ? registeredBidderID : (floorBidderNumber ? floorBidderNumber : "")); 895 var isFloorBid = parseInt(soldTo) > 0 ? false : true; 896 messageContent.args.push(this.getBidderTxt(message.data.siteID, BidderNumber, isFloorBid)); 897 messageContent.args.push(formatMoney(message.data.sellPrice, this.currency[message.data.auctionID].symbol)); 898 messageContent.i18nMsg += " sold to $2 at $3"; 899 } 900 this.attachMessageToDom(this.getMessageWrapper().addClass("impt").html(this.prefixMessageTxt(i18nTranslate(message
900Content), cacheMessage))); 901 if (this.isLiveClient()) { 902 if (parseInt(message.data.soldToUserName) === parseInt(this.clientData.userID)) { 903 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_GREEN).html(this.prefixMessageTxt(i18nTranslate("Congratulations! You are the winner!")))); 904 this.playSound('winLot'); 905 } else { 906 this.playSound('notWonLot'); 907 } 908 } 909 break; 910 case "lotItemSkipped": 911 if (parseInt(message.data.lotState) > 0) { 912 var messageContent = {i18nMsg: "Lot $1", args: [message.data.lotNumber]}; 913 if (isRestrictedActivityAuction) { 914 messageContent.i18nMsg += " Closed"; 915 } else { 916 messageContent.i18nMsg += " Passed"; 917 } 918 if (typeof message.data.makeUnsold === 'undefined' || message.data.makeUnsold) this.attachMessageToDom(this.getMessageWrapper().addClass("impt").html(this.prefixMessageTxt(i18nTranslate(messageContent), cacheMessage))); 919 } 920 if (this.isLiveClient()) { 921 this.playSound('passLot'); 922 } 923 break; 924 case "clientBidRejected": 925 if (this.isLiveClient()) { 926 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_RED).html(this.prefixMessageTxt(i18nTranslate("$1 YOUR BID HAS BEEN REJECTED", formatMoney(message.data.nextBid, this.currency[message.data.auctionID].symbol)) + " [" + i18nTranslate(message.data.errorMsgi18n || message.data.errorMsg) + "]"))); 927 } 928 break; 929 case "onlineBidAccepted": 930 case "floorBidAccepted": 931 var BidderTxt = ''; 932 var BidderNumber = ''; 933 switch (message.data.action) { 934 case "floorBidAccepted": 935 BidderTxt = this.getBidderTxt(message.data.siteID, '', true); 936 // BidderTypeName = 'Competing'; 937 break; 938 case "onlineBidAccepted": 939 BidderNumber = (typeof message.data.registeredBidderID !== 'undefined' ? message.data.registeredBidderID : message.data.userID); 940 941 BidderTxt = this.getBidderTxt(message.data.siteID, BidderNumber); 942 943 if (this.isLiveClient()) { 944 this.playSound('bidAccepted'); 945 } 946 break; 947 } 948 // this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt(formatMoney(message.data.bid, this.currency[message.data.auctionID].symbol) + " - by " + BidderTypeName + " Bidder" + BidderNumber, cacheMessage))); 949 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt(i18nTranslate("$1 - by $2" + (typeof message.data.isCompetingOutbid !== 'undefined' && message.data.isCompetingOutbid ? ' (has Competing Bid)' : ''), formatMoney(message.data.bid, this.currency[message.data.auctionID].symbol), BidderTxt), cacheMessage))); 950 if (this.isLiveClient()) { 951 var userTotalBid = $('#utb'); 952 if (parseInt(userTotalBid.val()) > 0) { 953 if (parseInt(message.data.highestBidder) !== parseInt(this.clientData.userID)) { 954 if (parseInt(message.data.previousMaxBidder) === parseInt(this.clientData.userID)) { 955 var absenteeBidAmount = parseInt($('#user_ab_amount').val().trim()); 956 if (absenteeBidAmount < parseInt(message.data.nextBid)) { 957 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_RED).html(this.prefixMessageTxt(i18nTranslate("YOU HAVE BEEN OUTBID. Please bid again.")))); 958 this.playSound('outBid'); 959 } 960 } 961 } 962 if (parseInt(message.data.userID) === parseInt(this.clientData.userID)) { 963 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_GREEN).html(this.prefixMessageTxt(i18nTranslate("Your $1 bid accepted", formatMoney(message.data.bid, this.currency[message.data.auctionID].symbol))))); 964 } 965 } 966 } 967 break; 968 case "clientBidAck": 969 if (this.isLiveClient()) { 970 var user_last_bid_amount = $("#le_event_item_next_bid"); 971 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_GREEN).html(this.prefixMessageTxt(i18nTranslate("$1 bid submitted", formatMoney(user_last_bid_amount.val(), this.currency[message.data.auctionID].symbol))))); 972 this.playSound('biddingLot'); 973 } 974 break; 975 case "lotMessageFromAdmin": 976 switch (message.data.messageType) { 977 case this.messageType.GENERALMESSAGE: 978 // currently general message doesn't support i18n translations 979 // clerk needs to send multiple messages in multiple languages 980 // as "hack" for now we will attempt to translate the message from the clerk 981 // and if its in our dictionary then it will translate 982 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt(i18nTranslate(message.data.messageText), cacheMessage))); 983 break; 984 case this.messageType.FAIRWARNING: 985 //this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_RED).html(this.prefixMessageTxt(message.data.messageText, cacheMessage))); 986 if (this.isLiveClient()) { 987 this.playSound('fairWarning'); 988 } 989 var i = 2; 990 var countDownMessageTxt = i18nTranslate(message.data.messageText); 991 countDownMessageTxt += " - " + i18nTranslate("Lot is about to close!"); 992 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_RED).html(this.prefixMessageTxt(countDownMessageTxt, cacheMessage))); 993 break; 994 case this.messageType.FIVESECONDWARNING: 995 var i = 4; 996 var $thisClient = this; 997 var fswMessage = message.data.messageText; 998 var fswMessagei18n = message.data.i18nMessageText; 999 var publishFSW = function (count) { 1000 var content = $thisClient.getMessageWrapper(); 1001 var countMsg = null; 1002 // i18n method, we don't embed the html and only send the msg with $1 replacement var 1003 // only support object style i18n messages, else fallback 1004 if (typeof fswMessagei18n !== 'undefined' && fswMessagei18n && typeof fswMessagei18n.i18nMsg !== 'undefined') { 1005 fswMessagei18n.args = ['<span class="impt">' + count + '</span>']; 1006 countMsg = i18nTranslate(fswMessagei18n); 1007 } else { // lagacy method just in case 1008 countMsg = fswMessage.replace(/[0-9]+/, count); 1009 } 1010 content.html($thisClient.prefixMessageTxt(countMsg, cacheMessage)); 1011 $thisClient.attachMessageToDom(content); 1012 } 1013 publishFSW(i + 1); 1014 this.fiveSecondsTimerInstance = setInterval(function () { 1015 publishFSW(i) 1016 i--; 1017 if (i === 0) { 1018 clearInterval(this.fiveSecondsTimerInstance); 1019 } 1020 }.bind(this), 1000); 1021 break; 1022 } 1023 break; 1024 case "lotAdminActionRejected": 1025 this.attachMessageToDom(this.getMessageWrapper().addClass(CSS_RED).html(this.prefixMessageTxt(message.data.errorMsg))); 1026 break; 1027 case "lotIncrementChanged": 1028 var messageTxt = {i18nMsg: "Increment changed $1", args: [formatMoney(message.data.increment, this.currency[message.data.auctionID].symbol)]}; 1029 var askingBid = 0; 1030 if (typeof message.data.currentBid !== 'undefined') { 1031 askingBid = message.data.currentBid; 1032 } 1033 if (typeof message.data.nextBid !== 'undefined') { 1034 askingBid = message.data.nextBid; 1035 } 1036 1037 if (askingBid > 0) { 1038 messageTxt.i18nMsg += " and New asking Price - $2"; 1039 messageTxt.args.push(formatMoney(askingBid, this.currency[message.data.auctionID].symbol)); 1040 } 1041 this.attachMessageToDom(this.getMessageWrapper().html(this.prefixMessageTxt(i18nTranslate(messageTxt), cacheMessage))); 1042 break; 1043 } 1044}; 1045 1046AuctionClient.prototype.setVolume = function (volume) { 1047 this.currentVolume = volume; 1048 for (var soundIndex in this.sound) { 1049 if (this.sound[soundIndex] instanceof Audio) { 1050 this.sound[soundIndex].volume = volume; 1051 } 1052 } 1053}; 1054 1055AuctionClient.prototype.muteAudio = function (mute) { 1056 if (mute === true) { 1057 this.setVolume(0); 1058 } 1059 if (mute === false) { 1060 this.setVolume(DEFAULT_AUDIO_VOLUME); 1061 } 1062}; 1063 1064AuctionClient.prototype.onPlaySoundSuccess = function () { 1065 // do nothing, will be handled by child class override
1066 // should update UI to show sound is enabled/unmuted 1067}; 1068 1069AuctionClient.prototype.onPlaySoundFailure = function () { 1070 // do nothing, will be handled by child class override 1071 // should update UI to show sound is disabled/muted 1072}; 1073 1074AuctionClient.prototype.playSound = function (soundIndex) { 1075 if (typeof soundIndex !== 'undefined' && typeof this.sound[soundIndex] !== 'undefined') { 1076 if (!(this.sound[soundIndex] instanceof Audio)) { 1077 this.sound[soundIndex] = new Audio(this.soundFiles[soundIndex]); 1078 if (typeof this.currentVolume !== 'undefined') this.setVolume(this.currentVolume); // need to make sure volume is set to current state (fixes case were you mute or change volue before we load that sound file) 1079 } 1080 var p = this.sound[soundIndex].play(); 1081 // Promise not supported in IE 1082 try { 1083 if (p instanceof Promise) { 1084 p.catch(function (err) { 1085 // ignore error, need to wait for mediaPlaybackRequiresUserGesture promise is fulfilled for playback 1086 }); 1087 } 1088 } 1089 catch(err) { 1090 // ignore the error if promise not supported in any browser 1091 } 1092 return p; 1093 } 1094}; 1095 1096AuctionClient.prototype.hasReserveMet = function (message, userLastBidAmount) { 1097 //this.appendConsoleContent('hasReserveMet > userLastBidAmount > before: ' + userLastBidAmount); 1098 if (typeof userLastBidAmount === 'undefined' || userLastBidAmount === null) { 1099 userLastBidAmount = 0; 1100 } 1101 //this.appendConsoleContent('hasReserveMet > userLastBidAmount > after: ' + userLastBidAmount); 1102 var currentLotEL = '.el_' + message.data.auctionID; 1103 var disable_reserve_price = $(currentLotEL+' #disable_reserve_price').val(); 1104 var isReserverMet = true; 1105 if(!disable_reserve_price){ 1106 if (typeof message.data.isReservePriceMet !== 'undefined') { 1107 //this.appendConsoleContent('hasReserveMet > has: message.data.isReservePriceMet'); 1108 //this.appendConsoleContent(message.data.isReservePriceMet); 1109 isReserverMet = message.data.isReservePriceMet; 1110 } 1111 1112 if (!isReserverMet && userLastBidAmount > 0) { 1113 //this.appendConsoleContent('hasReserveMet > !isReserverMet && userLastBidAmount > 0'); 1114 isReserverMet = false; 1115 } 1116 if (message.data.numberOfBids === 0 ) isReserveMet = false; 1117 } 1118 1119 return isReserverMet; 1120}; 1121 1122AuctionClient.prototype.onClientBid = function (params, callback) { 1123 //this.appendConsoleContent('Inside onClientBid()'); 1124 //this.appendConsoleContent('onClientBid > params: ' + JSON.stringify(params)); 1125 var auctionId = (typeof params.auctionId !== 'undefined' ? params.auctionId : 0); 1126 var lotId = (typeof params.lotId !== 'undefined' ? params.lotId : 0); 1127 var amount = (typeof params.amount !== 'undefined' ? params.amount : 0); 1128 var clientBidID = (typeof params.clientBidID !== 'undefined' ? params.clientBidID : ""); 1129 var messageOption = { 1130 action: "clientBid", 1131 auctionID: parseInt(auctionId), 1132 lotID: parseInt(lotId), 1133 price: parseFloat(amount), 1134 clientBidID: clientBidID 1135 }; 1136 //this.appendConsoleContent('onClientBid > messageOption: ' + JSON.stringify(messageOption)); 1137 this.sendMessage(messageOption, function () { 1138 if (typeof callback === 'function') { 1139 //this.appendConsoleContent('callback found'); 1140 callback(); 1141 //this.appendConsoleContent('callback called'); 1142 } 1143 }.bind(this)); 1144}; 1145 1146AuctionClient.prototype.onModifyBid = function (params, callback) { 1147 //this.appendConsoleContent('Inside onModifyBid()'); 1148 //this.appendConsoleContent('onModifyBid > params: ' + JSON.stringify(params)); 1149 var auctionId = (typeof params.auctionId !== 'undefined' ? params.auctionId : 0); 1150 var lotId = (typeof params.lotId !== 'undefined' ? params.lotId : 0); 1151 var userId = (typeof params.userID !== 'undefined' ? params.userID : 0); 1152 var amount = (typeof params.amount !== 'undefined' ? params.amount : 0); 1153 var bidReferenceId = (typeof params.bidReferenceId !== 'undefined' ? params.bidReferenceId : ""); 1154 var messageOption = { 1155 action: "modifyBid", 1156 auctionID: parseInt(auctionId), 1157 lotID: parseInt(lotId), 1158 userID: parseInt(userId), 1159 newMaxBid: parseFloat(amount), 1160 bidReferenceID: bidReferenceId 1161 }; 1162 if (typeof params.registeredBidderID !== 'undefined') { 1163 messageOption = $.extend({}, messageOption, {registeredBidderID: params.registeredBidderID}); 1164 } 1165 //this.appendConsoleContent('onModifyBid > messageOption: ' + JSON.stringify(messageOption)); 1166 this.sendMessage(messageOption, function () { 1167 if (typeof callback === 'function') { 1168 callback(); 1169 } 1170 }.bind(this)); 1171}; 1172 1173AuctionClient.prototype.storeConsoleMessage = function (messageTxt) { 1174 //this.appendConsoleContent('Inside storeConsoleMessage()'); 1175 var auctionId = this.auctionIDs[0]; 1176 var localStorageId = this.localStorageId ? this.localStorageId : 'console.msg.' + auctionId; 1177 try { 1178 if (typeof (Storage) !== "undefined") { 1179 if (!localStorage.getItem(localStorageId)) { 1180 localStorage.setItem(localStorageId, JSON.stringify([])); 1181 } 1182 1183 var consoleMessage = JSON.parse(localStorage.getItem(localStorageId)); 1184 if (consoleMessage) { 1185 if (consoleMessage.length > 50) { 1186 consoleMessage.shift(); 1187 } 1188 consoleMessage.push(messageTxt); 1189 localStorage.setItem(localStorageId, JSON.stringify(consoleMessage)); 1190 } 1191 } 1192 } catch (e) { 1193 this.appendConsoleContent(e); 1194 } 1195}; 1196 1197AuctionClient.prototype.getStoredMessage = function () { 1198 var storedMessage = []; 1199 var auctionId = this.auctionIDs[0]; 1200 var localStorageId = this.localStorageId ? this.localStorageId : 'console.msg.' + auctionId; 1201 try { 1202 if (typeof (Storage) !== "undefined") { 1203 if (localStorage.getItem(localStorageId)) { 1204 storedMessage = JSON.parse(localStorage.getItem(localStorageId)); 1205 } 1206 } 1207 } catch (e) { 1208 this.appendConsoleContent(e); 1209 } 1210 return storedMessage; 1211}; 1212 1213AuctionClient.prototype.publishStoredMessage = function () {
1214 var storedMessage = this.getStoredMessage(); 1215 if (storedMessage) { 1216 for (var stMsg in storedMessage) { 1217 this.attachMessageToDom(this.getMessageWrapper().html(storedMessage[stMsg])); 1218 } 1219 } 1220}; 1221 1222AuctionClient.prototype.hasStoredMessage = function () { 1223 var storedMessage = this.getStoredMessage(); 1224 if (storedMessage && storedMessage.length > 0) { 1225 return true; 1226 } 1227 return false; 1228}; 1229 1230AuctionClient.prototype.cacheLastClientMessageDateTime = function (consoleMessageDateTime) { 1231 var auctionId = this.auctionIDs[0]; 1232 var localStorageId = this.localStorageDatatimeId ? this.localStorageDatatimeId : 'console.msg.dateTime.' + auctionId; 1233 try { 1234 if (typeof (Storage) !== "undefined") { 1235 if (!localStorage.getItem(localStorageId)) { 1236 localStorage.setItem(localStorageId, ""); 1237 } 1238 localStorage.setItem(localStorageId, consoleMessageDateTime); 1239 } 1240 } catch (e) { 1241 this.appendConsoleContent(e); 1242 } 1243}; 1244 1245AuctionClient.prototype.getLastClientMessageDateTime = function () { 1246 var auctionId = this.auctionIDs[0]; 1247 var consoleMessageDateTime = ""; 1248 var localStorageId = this.localStorageDatatimeId ? this.localStorageDatatimeId : 'console.msg.dateTime.' + auctionId; 1249 try { 1250 if (typeof (Storage) !== "undefined") { 1251 if (localStorage.getItem(localStorageId)) { 1252 consoleMessageDateTime = localStorage.getItem(localStorageId); 1253 } 1254 } 1255 } catch (e) { 1256 this.appendConsoleContent(e); 1257 } 1258 return consoleMessageDateTime; 1259}; 1260 1261AuctionClient.prototype.messageDateTimeFormat = function () { 1262 var whenConnect = new Date(); 1263 var whenConnectTxt = ""; 1264 var whenConnectHours = padInt(whenConnect.getHours()); 1265 var whenConnectMinutes = padInt(whenConnect.getMinutes()); 1266 var whenConnectDate = padInt(whenConnect.getDate()); 1267 var whenConnectMonth = padInt(whenConnect.getMonth()); 1268 var whenConnectYear = padInt(whenConnect.getFullYear()); 1269 if (whenConnectYear.length > 2) { 1270 whenConnectYear = whenConnectYear.slice(-2); 1271 } 1272 var whenConnectAmPm = "am"; 1273 if (whenConnectHours > 12) { 1274 whenConnectHours = padInt((parseInt(whenConnectHours) - 12)); 1275 whenConnectAmPm = "pm"; 1276 } 1277 whenConnectTxt += whenConnectHours + ":" + whenConnectMinutes + whenConnectAmPm; 1278 whenConnectTxt += " " + padInt(parseInt(whenConnectMonth) + 1) + "/" + whenConnectDate + "/" + whenConnectYear; 1279 //console.log(whenConnectTxt); 1280 return whenConnectTxt; 1281}; 1282 1283AuctionClient.prototype.publishInitialMessage = function () { 1284 if (this.hasStoredMessage()) { 1285 var lastClientMessageTxt = "last client msg at $1"; 1286 this.attachMessageToDom(this.getMessageWrapper().html("== " + i18nTranslate(lastClientMessageTxt, this.getLastClientMessageDateTime()) + " ==")); 1287 } 1288 var whenConnectTxt = ""; 1289 if (this.hasStoredMessage()) { 1290 whenConnectTxt += "re-"; 1291 } 1292 whenConnectTxt += "connected to "+this.siteName+" live center at $1"; 1293 this.attachMessageToDom(this.getMessageWrapper().html("== " + i18nTranslate(whenConnectTxt, this.messageDateTimeFormat()) + " ==")); 1294}; 1295 1296AuctionClient.prototype.getRemainingBidBlance = function (auctionId) { 1297 var jsonData; 1298 var ajaxItemsUrl = getUrl('item/bidlimit/' + auctionId + '?is_ajax=1'); 1299 $.ajax({ 1300 type: 'GET', 1301 url: ajaxItemsUrl, 1302 async: false, 1303 success: function (data, textStatus, jqXHR) { 1304 jsonData = data; 1305 } 1306 }); 1307 return jsonData; 1308}; 1309 1310AuctionClient.prototype.checkBidLimitExceeded = function (amount, auctionId, lotId, action, clientBidFromWidget) { 1311 var error = false; 1312 1313 var hasWidgetBid = false; 1314 if (this.isWidget) 1315 { 1316 if (typeof clientBidFromWidget !== 'undefined' && clientBidFromWidget !== null) 1317 { 1318 hasWidgetBid = true; 1319 } 1320 } 1321 1322 var bidlimitData = this.getRemainingBidBlance(auctionId); 1323 if (parseFloat(bidlimitData.totalBidlimit) > 0) { 1324 var totalConsumed = bidlimitData.totalConsumed; 1325 if (action === 'mb') { 1326 if (!hasWidgetBid) 1327 { 1328 var userLastBidAmountSelector = '#ulba_' + lotId + '_' + auctionId; 1329 if (this.isLiveClient()) { 1330 userLastBidAmountSelector = '#user_last_bid_amount'; 1331 } 1332 var userLastBidAmount = $(userLastBidAmountSelector); 1333 1334 var lastBid = 0; 1335 if (typeof userLastBidAmount.data('bidamt') !== 'undefined') { 1336 lastBid = userLastBidAmount.data('bidamt'); 1337 } else { 1338 lastBid = userLastBidAmount.val(); 1339 } 1340 } else 1341 { 1342 lastBid = clientBidFromWidget.userLastBidAmount; 1343 } 1344 1345 totalConsumed = parseFloat(totalConsumed) - parseFloat(lastBid); 1346 if (parseFloat(totalConsumed) < 0) totalConsumed = 0; 1347 } 1348 if (parseFloat(bidlimitData.totalBidlimit) < (parseFloat(totalConsumed) + parseFloat(amount))) { 1349 error = true; 1350 } 1351 } 1352 return error; 1353} 1354 1355AuctionClient.prototype.sanitizeCurrencyAndSeparator = function (amount, removeDecimal/* = true */) { 1356 var trippedAmount = null; 1357 if (amount) { 1358 if (typeof amount === 'string') { 1359 amount = (amount.trim()).replace(/[$,]+/g, ""); 1360 } 1361 trippedAmount = amount; 1362 } 1363 1364 // Since IE does not support default parameter value 1365 removeDecimal = (typeof removeDecimal !== 'undefined') ? removeDecimal : true; 1366 if (removeDecimal) { 1367 // Math.trunc() is not available in IE, therefore use Math.floor() instead 1368 // Preferred to use trunc(), because sometimes floor() rounding up the number 1369 if (typeof Math.trunc !== 'undefined') { 1370 trippedAmount = Math.trunc(trippedAmount); 1371 } else { 1372 trippedAmount = Math.floor(trippedAmount); 1373 } 1374 } 1375 1376 return trippedAmount; 1377}; 1378 1379AuctionClient.prototype.setCriteoTrackTransactionIndex = function () { 1380 var criteoTrackTransactionIndex = getCriteoTrackTransactionIndex(); 1381 if (criteoTrackTransactionIndex > 0) { 1382 this.criteoTrackTransactionIndex = parseInt(criteoTrackTransactionIndex); 1383 } 1384 //this.appendConsoleContent('setCriteoTrackTransactionIndex > criteoTrackTransactionIndex: ' + this.criteoTrackTransactionIndex); 1385}; 1386 1387AuctionClient.prototype.addCriteoTransaction = function (lotId, soldPrice, transactionId) { 1388 if (typeof this.criteoTrackTransactionIndex !== 'undefined' /*&& this.criteoTrackTransactionIndex > 0*/) { 1389 window.criteo_q = addTransactionToCriteoEvent(this.criteoTrackTransactionIndex, lotId, soldPrice, transactionId); 1390 //this.appendConsoleContent('addCriteoTransaction > window.criteo_q: ' + JSON.stringify(window.criteo_q)); 1391 } 1392}; 1393 1394AuctionClient.prototype.adjustBidAmountUI = function (el,bidText,limit) { 1395 if (typeof limit === 'undefined') { 1396 limit = 13; 1397 } 1398 if(el && bidText) { 1399 var bidLenght = bidText.toString().length; 1400 el.removeClass('dyn-bid-price'); 1401 if(bidLenght >= limit) { 1402 el.addClass('dyn-bid-price'); 1403 } 1404 } 1405}; 1406 1407AuctionClient.prototype.attachReconnectOverlayNotification = function () {
1408 var $overlay = $('body').find('.connect-overlay'); 1409 var reConnectMessage = i18nTranslate("Not connected. Trying to reconnect..."); 1410 if ($overlay.length <= 0) { 1411 $overlay = $("<div class=\"connect-overlay\">" + reConnectMessage + "</div>"); 1412 $('body').append($overlay); 1413 1414 // $overlay.css('width', '200px'); 1415 $overlay.css('height', '18px'); 1416 $overlay.css('background', '#000000'); 1417 $overlay.css('position', 'fixed'); 1418 $overlay.css('z-index', '9999'); 1419 $overlay.css('right', '10px'); 1420 $overlay.css('bottom', '10px'); 1421 $overlay.css('text-align', 'center'); 1422 $overlay.css('line-height', '1.5'); 1423 //$overlay.css('box-shadow', '5px 5px 8px 1px rgba(4, 4, 4, 0.31)'); 1424 $overlay.css('font-size', '12px'); 1425 $overlay.css('border-radius', '10px'); 1426 $overlay.css('font-family', 'klavika-light'); 1427 $overlay.css('opacity', '0.5'); 1428 $overlay.css('color', '#ffffff'); 1429 $overlay.css('padding', '0px 5px'); 1430 } else { 1431 $overlay.off('click.needsRefresh').removeClass('needs-refresh').text(reConnectMessage); 1432 } 1433}; 1434 1435AuctionClient.prototype.detachReconnectOverlayNotification = function () {
1436 var $overlay = $('body').find('.connect-overlay'); 1437 // if (typeof $overlay !== 'undefined') $overlay.remove(); 1438 if (typeof $overlay !== 'undefined') { 1439 if (this.clientData.pageRefreshWarning) { 1440 $overlay.addClass('needs-refresh') 1441 .text(i18nTranslate("Connection was lost, some lots may be outdated. Click to reload")) 1442 .off('click.needsRefresh').on('click.needsRefresh', function () { 1443 if (setting.isMobileWebView) { 1444 window.location.href = window.location.href.split('#')[0]; 1445 window.location.relaod(); 1446 } else { 1447 window.location.reload(); 1448 } 1449 }); 1450 } else { 1451 $overlay.remove(); 1452 } 1453 } 1454}; 1455 1456AuctionClient.prototype.reconnectOverlayNotification = function (action) { 1457 clearTimeout(overlayNotificationTimeout); 1458 if (typeof action === 'undefined') action = "on"; 1459 switch (action) { 1460 case "on": 1461 var attachReconnectOverlayNotification = false; 1462 if (typeof this.clientData.livePanel !== 'undefined' && this.clientData.livePanel) { 1463 attachReconnectOverlayNotification = true; 1464 } else { 1465 if (this.clientData.pageRefreshWarning !== 'undefined' && this.clientData.pageRefreshWarning) { 1466 attachReconnectOverlayNotification = true; 1467 } 1468 } 1469 if (attachReconnectOverlayNotification) { 1470 this.attachReconnectOverlayNotification(); 1471 } 1472 break; 1473 case "off": 1474 this.detachReconnectOverlayNotification(); 1475 break; 1476 } 1477}; 1478 1479AuctionClient.prototype.setDualCurrencyBidAmount = function (el, bidAmount, auctionId) { 1480 if(el.length > 0) { 1481 var convertedData = this.getDualCurrencyBidAmount(bidAmount, auctionId); 1482 if(convertedData.exchange != '') el.data('exchange', convertedData.exchange); 1483 if(convertedData.convertedAmount != '') el.html(convertedData.convertedAmount); 1484 } 1485}; 1486 1487AuctionClient.prototype.getDualCurrencyBidAmount = function (bidAmount, auctionId) { 1488 var result = {exchange: '', convertedAmount : ''}; 1489 if(typeof this.currency[auctionId] != 'undefined') 1490 { 1491 var exchData = {'amount' : bidAmount, 'from_exch_rate' : this.currency[auctionId].exchange_rate, 'from_symbol' : this.currency[auctionId].symbol}; 1492// var userCurrencyData = {'symbol' : exchData.from_symbol, 'exchange_rate' : exchData.from_exch_rate}; 1493// if(typeof this.clientData.userCurrency != 'undefined') userCurrencyData = this.clientData.userCurrency; 1494 var userCurrencyData = this.clientData.userCurrency; 1495 var convertedBidText = convertCurrencyAmount(exchData.amount, exchData.from_exch_rate, exchData.from_symbol, userCurrencyData.exchange_rate, userCurrencyData.symbol); 1496 result.exchange = exchData; 1497 result.convertedAmount = convertedBidText; 1498 } 1499 1500 return result; 1501}; 1502 1503/** 1504 * Logging to the app/log/*.log file about the connection lost and only once 1505 * @param {objuect} options 1506 */ 1507AuctionClient.prototype.logConnectionIssue = function (options) { 1508 if (!this.connection || this.connection.readyState !== 1) { 1509 /* 1510 * The variable CONNECTION_ISSUE_LOG_COUNT is a global variable 1511 * So, if in some page ( like search page ) has both item ( live / time ) 1512 * then we probably end up loggin for once ( depend on which item bid place occurred first ) 1513 * 1514 * So, if the liveEvent client triggered first then it will log and make one increment 1515 * and then if timeEvent client triggered second, it will found " > 0" and will not log 1516 * 1517 * But that should be OK, since we atleast log the connection issue at liveEvent/timeEvent client 1518 */ 1519 if (typeof options !== 'undefined' && CONNECTION_ISSUE_LOG_COUNT === 0) { // Will only log in first try and not logged afterwards 1520 this.appendConsoleContent('Logging failed to connect to AE'); 1521 this.logError({ 1522 code: this.connectionErrorCode, 1523 auctionID: options.auctionId, 1524 lotID: options.lotId, 1525 bidAmountPlaced: options.amount, 1526 successConnectionCount: SUCCESS_CONNECT_COUNT 1527 }); 1528 CONNECTION_ISSUE_LOG_COUNT ++; 1529 } 1530 return true; 1531 } else { 1532 CONNECTION_ISSUE_LOG_COUNT = 0; 1533 } 1534}; 1535 1536/** 1537 * Display the countdown timer at the bid button when connection with AE is lost 1538 * This is only for non-live ( including timed items ) pages. 1539 * @param {object} el 1540 */ 1541AuctionClient.prototype.startConnectionLostCountdownTimer = function (el) { 1542 var $this = this; 1543 var i = 14; 1544 var publishFSW = function (count) { 1545 el.html(i18nTranslate("Please Wait $1 sec", count)); 1546 }; 1547 publishFSW(i + 1); 1548 var thisBtnTextInterval = setInterval(function () { 1549 publishFSW(i); 1550 i--;
1551 if ((i === 0) || ($this.connection.readyState === 1)) { 1552 clearInterval(thisBtnTextInterval); 1553 } 1554 }, 1000); 1555}; 1556 1557AuctionClient.prototype.setIsWidget = function(isWidget) 1558{ 1559 this.isWidget = isWidget; 1560}; 1561 1562AuctionClient.prototype.collectNextBidIfEmptyBid = function(lotId, auctionId, hasWidgetBid, clientBidFromWidget) { 1563 var amount = 0; 1564 1565 // var nextBidPrice = $('#nbp_' + lotId + '_' + auctionId).val().trim(); 1566 var nextBidPrice = $('#amt_' + lotId + '_' + auctionId).data('placeholder_amount'); 1567 if (!nextBidPrice) nextBidPrice = $('#nbp_' + lotId + '_' + auctionId).val().trim(); 1568 if (typeof hasWidgetBid !== 'undefined' && hasWidgetBid) { 1569 if (typeof clientBidFromWidget !== 'undefined') { 1570 nextBidPrice = clientBidFromWidget.nextBidPrice.trim(); 1571 } 1572 } 1573 1574 if (nextBidPrice) { 1575 var userLastBidAmount = $('#ulba_' + lotId + '_' + auctionId); 1576 if (typeof hasWidgetBid !== 'undefined' && hasWidgetBid) { 1577 if (typeof clientBidFromWidget !== 'undefined') { 1578 userLastBidAmount = clientBidFromWidget.userLastBidAmount; 1579 } 1580 } 1581 1582 var bidAmountLast = 0; 1583 if (typeof userLastBidAmount.data('bidamt') !== 'undefined') { 1584 bidAmountLast = userLastBidAmount.data('bidamt'); 1585 } else { 1586 bidAmountLast = userLastBidAmount.val().trim(); 1587 } 1588 1589 amount = bidAmountLast && (parseInt(bidAmountLast) > parseInt(nextBidPrice)) ? bidAmountLast : nextBidPrice; 1590 } 1591 1592 return amount; 1593}; 1594 1595AuctionClient.prototype.onBiddingKeyboardAction = function() { 1596 $(document).off('keypress.bidAmount').on('keypress.bidAmount', 'input[name="bid_amount"]', function (evt) { 1597 var code = evt.keyCode ? evt.keyCode : evt.which; 1598 if (code == 13) { // if "Enter" key pressed 1599 evt.preventDefault(); 1600 let $theInput = $(this); 1601 var $theItemId = $theInput.data('item-id'); 1602 var $theEventId = $theInput.data('event-id'); 1603 1604 if ($theItemId && $theEventId) { 1605 let $theAssociateBidButton = $("#btn_" + $theItemId + "_" + $theEventId); 1606 if (typeof $theAssociateBidButton !== 'undefined') { 1607 $theInput.blur(); 1608 $theAssociateBidButton.click(); 1609 } 1610 } 1611 } 1612 }); 1613 1614 $(document).off('keyup.bidConfirmation').on('keyup.bidConfirmation', function (evt) { 1615 var code = evt.keyCode ? evt.keyCode : evt.which; 1616 if (code == 27) { // if "Escape" key pressed 1617 evt.preventDefault(); 1618 showHidePopup('.bid_confirmation_pop_wrap',false); 1619 } 1620 }); 1621}; 1622 1623AuctionClient.prototype.onBidButtonKeyAction = function(eventName, buttonElement) { 1624 $(document).off(eventName).on(eventName, function (evt) { 1625 var code = evt.keyCode ? evt.keyCode : evt.which; 1626 if (code == 13 && typeof buttonElement !== 'undefined') { 1627 evt.preventDefault(); 1628 buttonElement.first().click(); // click self if Enter key pressed 1629 } 1630 }); 1631}; 1632AuctionClient.prototype.isAuctioneerScreen = function () { 1633 var client = false; 1634 if (typeof this.clientData.auctioneerScreen !== 'undefined' && this.clientData.auctioneerScreen) { 1635 client = true; 1636 } 1637 return client; 1638}; 1639AuctionClient.prototype.isFloorScreen = function () { 1640 var client = false; 1641 if (typeof this.clientData.floorScreen !== 'undefined' && this.clientData.floorScreen) { 1642 client = true; 1643 } 1644 return client; 1645}; 1646 1647AuctionClient.prototype.onBidEnterBidButtonChange = function(auctionType){ 1648 var $this = this; 1649 $(document).on('input', 'input:text[name=bid_amount]', function (evt) { 1650 var auctionId = $(this).data('event-id'); 1651 var lotId = $(this).data('item-id'); 1652 var thisButtonBidConfirm = $('#btn_'+lotId+'_'+auctionId); 1653 var currentAct = thisButtonBidConfirm.data('act'); 1654 1655 if(currentAct === 'sb'){ 1656 1657 var placeNextBidButtonText = '', placeMaxBidbuttonText = ''; 1658 if(auctionType === 'live') 1659 { 1660 placeNextBidButtonText = $this.languageTranslate('placeNextBidButtonTextLive'); 1661 placeMaxBidbuttonText = $this.languageTranslate('placeMaxBidbuttonTextLive') 1662 } 1663 if(auctionType === 'timed') 1664 { 1665 placeNextBidButtonText = $this.languageTranslate('placeNextBidButtonTextTimed'); 1666 placeMaxBidbuttonText = $this.languageTranslate('placeMaxBidButtonTextTimed') 1667 } 1668 var btnText = placeNextBidButtonText; 1669 if($(this).val()){ 1670 btnText = placeMaxBidbuttonText; 1671 } 1672 1673 thisButtonBidConfirm.html(btnText); 1674 } 1675 1676 }) 1677}; 1678AuctionClient.prototype.displayReserveMetBanner = function (lotId, auctionId, displayBanner = false){ 1679 var buttonStatWrapperSelector = $('#re_' + lotId + '_' + auctionId); 1680 if (displayBanner) { 1681 buttonStatWrapperSelector.addClass('reserve-met-banner'); 1682 buttonStatWrapperSelector.html(this.languageTranslate('reserveMetBannerNotification')); 1683 } else { 1684 buttonStatWrapperSelector.removeClass('reserve-met-banner'); 1685 buttonStatWrapperSelector.html(''); 1686 } 1687} 1688
1689AuctionClient.prototype.languageTranslate = function(languageKey, replace) { 1690 if (typeof $.i18n !== 'undefined' && 1691 typeof $.i18n.rawTranslationMap !== 'undefined' && 1692 typeof $.i18n.rawTranslationMap[languageKey] !== 'undefined') { 1693 return i18nTranslate($.i18n.rawTranslationMap[languageKey], replace); 1694 } 1695 return ''; 1696}; 1697AuctionClient.prototype.getBidSuggestionArray = function(bidText,compareWith,eventId){ 1698 var suggestedValues = []; 1699 var maxSuggestions = 20; 1700 compareWith = parseInt(compareWith); 1701 compareWith = compareWith ? compareWith : 0; 1702 var biddingIncrements = this.clientData.biddingIncrements[eventId]; 1703 var $this = this; 1704 if(biddingIncrements !== undefined){ 1705 for(var i = 0; i<= maxSuggestions; i++){ 1706 var incrementValue = 10; 1707 var startingAmount = 0; 1708 $.each(biddingIncrements,function(startAmount,increment){ 1709 if(compareWith >= startAmount){ 1710 startingAmount = parseInt(startAmount); 1711 incrementValue = parseInt(increment); 1712 } 1713 }); 1714 if(compareWith.toString().toLowerCase().indexOf(bidText.toLowerCase())!==-1){ 1715 suggestedValues.push({label:formatMoney(compareWith.toString(), $this.currency[eventId].symbol),value:compareWith}); 1716 } 1717 compareWith = ((startingAmount) + (Math.floor((compareWith - startingAmount) / incrementValue)) * incrementValue); 1718 compareWith = compareWith + incrementValue; 1719 } 1720 } 1721 return suggestedValues; 1722} 1723AuctionClient.prototype.onBiddingAutoCompleteAction = function() { 1724 var $this = this; 1725 if(typeof jQuery.ui !== 'undefined' && this.clientData.biddingIncrements !== undefined) { 1726 $('input[name="bid_amount"]').filter(function(){ 1727 return ($.inArray($(this).data('event-id'),$this.auctionIDs) !== -1); 1728 }).autocomplete({ 1729 minLength:0, 1730 source: function(request,responce){ 1731 var next_bid_price = this.element.data('placeholder_amount'); 1732 var event_id = this.element.data('event-id'); 1733 var item_id = this.element.data('item-id'); 1734 var user_last_bid = $("#ulba_"+item_id+"_"+event_id).val(); 1735 var user_bid_count = $("#utb_"+item_id+"_"+event_id).val(); 1736 if(user_last_bid && user_bid_count > 0){ 1737 next_bid_price = Math.max(next_bid_price,user_last_bid); 1738 } 1739 responce($this.getBidSuggestionArray(request.term,next_bid_price,event_id)); 1740 }, 1741 select: function(event,ui){ 1742 $(this).val(ui.item.value); 1743 var e = jQuery.Event("keypress"); 1744 e.which = 13; 1745 $(this).trigger(e); 1746 return true; 1747 }, 1748 create: function() { 1749 $(this).data('ui-autocomplete')._renderItem = function (ul, item) { 1750 ul.addClass('increment-dropdown'); 1751 return $("<li></li>") 1752 .append(item.label) 1753 .attr("data-value",item.value) 1754 .data("ui-autocomplete-item", item) 1755 .appendTo(ul); 1756 }; 1757 } 1758 }).focus(function() { 1759 $(this).autocomplete('search', $(this).val()) 1760 }) 1761 } 1762};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.