|
The Gravey 2.5 Framework and AIM RIA | |||||||
| PREV NEXT | FRAMES NO FRAMES | |||||||
Collection of application level classes.
This collection implements the rich-internet-application tier of
the Auction Module for AIM (Auction Inventory Management),
which is a demonstration of the Gravey framework.
Version: 2.0
Requires:
| Class Summary | |
| ALEDO | This is the abstract base class for Auction/Lot EDOs. |
| ALIndex | This class encapsulates an EDO index for Auctions/Lots. |
| Auction | This class encapsulates an Auction record. |
| AuctionModel | This class encapsulates the data model of a particular Auction. |
| AuctionModelView | This class produces the view of the entire data panel. |
| AuctionSelectionModel | This class encapsulates the data model for "which Auction is currently selected". |
| AuctionSummary | This class encapsulates the identifying attributes of an Auction. |
| AuctionView | This class produces a view of a Auction. |
| BidderLoadReplyCmd | This Command processes the reply of the "load Bidder data" request. |
| BidderMenuCmd | This class implements the bidder menu edit command. |
| Lot | This class encapsulates a Auction "lot" record. |
| LotListView | This class produces a view of a List of Lot EDOs. |
| LotView | This class produces a view of a Lot. |
| NextPhaseCmd | This class implements the Move to Next Auction Phase cmd. |
| PhaseButtonController | This class is a Button Controller that manages the button that "moves" an auction from one phase to the next. |
| Method Summary | |
static Object
|
_ContactsSelected( bidderKey )
|
static void
|
_GetBidderLists( <long> bidderKey )
Load in contacts and shippings list from specified bidder NOTE: this is a Command helper function. NEVER call this from outside the context of a Command object! |
static Object
|
_ShippingSelected( bidderKey )
|
static void
|
onBidderLoadReply( <grvXMLreq> xmlReq )
handle AJAX event for 'reply received from "load Bidder data" server-request' |
static Object
|
onBidderSelect( <event> e, <String> viewID )
handle event for 'user selects from the bidder menu' |
static void
|
onPhaseBtnPressed()
handle event for 'next phase' button press |
// This file uses JSDoc-friendly comments [ http://jsdoc.sourceforge.net/ ] /** * @file aimauction.js * @fileoverview Collection of application level classes.<br/> * This collection implements the rich-internet-application tier of * the Auction Module for AIM (Auction Inventory Management), * which is a demonstration of the Gravey framework. * @author Bruce Wallace (PolyGlotInc.com) * @requires grvEDO.js * @requires grvAJAX.js * @version 2.0 */ //////////////////////////////////////////// //////////// Domain Objects //////////////// //////////////////////////////////////////// Class(AuctionSummary,["unique Key","auction ID","item count"]) .Extends(EDOHolderSelectionItem); /** * @class This class encapsulates the identifying attributes of an Auction. * @extends EDOHolderSelectionItem * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function AuctionSummary() { /** @param {int} theKey unique key of this record * @param {String} theID auction ID * @param {int} itemCount count of items attached to this auction */ this.konstructor = function( theKey, theID, itemCount ) { // define instance variables this.key = theKey; this.bsID = theID; this.count = itemCount; } /** return "this" formatted for main menu item @type String */ this.getDescription = function() { return grvDiamond(this.count)+this.bsID; } /** return "this" as human-readable string @type String */ this.toString = function() { var s = new Array(); s.push( this.key ); s.push( this.bsID ); return s.join( "-" ); } /** set name to given value */ this.updateProperties = function( ID ){ this.bsID = ID; } } Class(ALIndex).Extends(EDOIndex); /** * @class This class encapsulates an EDO index for Auctions/Lots. * @extends EDOIndex * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function ALIndex() { if (!ALIndex.Auction){//keep this line above jsdoc comments! /** Static factory method to generate Auction-flavored index * @param {int} index Auction index * @type ALIndex */ ALIndex.Auction = function() { return new ALIndex(0,null); } /** Static factory method to generate Lot-flavored index * @param {int} index Lot index * @type ALIndex */ ALIndex.Lot = function( index ) { return new ALIndex(0,index); } } /** @param {int} optA index into auctions list for current Auction * @param {int} optL index into lots list for specified Auction * If args not specified or if all are null then this represents "no selection". */ this.konstructor = function( optA,optL ) { // define instance variables this.a = optA===undefined ? null : optA; this.l = optL===undefined ? null : optL; } /** return "this" as event handler arg list string @type String */ this.asEventArgs = function() { return " new ALIndex("+this.a+","+this.l+") "; } this.asString = function() { return this.invoke( this, this._noString, this._lotString ) + this._auctionString( this.a ); } this._noString = function(){ return ""; } /** return auction description @type String */ this._auctionString = function( aindex ){ var a = gAuctionData._getAuction( aindex ); return (a && a[ kStrIdAuctionID ]) ? a[ kStrIdAuctionID ] : "New Auction"; } /** return lot description @type String */ this._lotString = function( lindex ){ lindex -= 0; //type cast to int return "Lot["+(lindex+1)+"] of "; } /** return whether "this" contains a selection @type boolean */ this.hasSelection = function(){ return this.a!=null || this.l!=null; } /** return whether "this" equals given EDOIndex @type boolean */ this.equals = function(x){ return x ? (this.a==x.a && this.l==x.l) : false; } /** Invoke the appropriate method given the index type and * return its result. Methods are expected to have the signature<pre> * self.method(this.subindex,optionalArgument) *</pre> * @param {Object} self the parent object of the method * @param {Function} sMethod method to call if xi is Auction type * @param {Function} lMethod method to call if xi is Lot type * @param {Object} optArg optional extra param to pass to method * @return the result of the called method */ this.invoke = function(self,sMethod,lMethod,optArg){ var aMethod; var i; if (this.l!=null) { aMethod = lMethod; i = this.l; } else { aMethod = sMethod; i = this.a; } return aMethod.call( self, i, optArg ); } } //////////////////////////////////////////////////////////////////////////////// // Constants defining property names for the auction/lot properties //////////////////////////////////////////////////////////////////////////////// var kStrIdAuctionID = 'Auction ID'; var kDateIdCreate = 'Create Date'; var kDateIdLaunch = 'Launch Date'; var kDateIdLockdown = 'Lockdown Date'; var kDateIdCutoff = 'Cutoff Date'; var kDateIdAward = 'Bid Award Date'; var kDateIdClosed = 'Closed Date'; // Lot fields var kIntIdLotNum = 'Lot#'; //should not be null var kStrIdLotName = 'Lot Name'; var kDateIdPayDate = 'Effective Pay Date'; var kDateIdClosed = 'Closed Date'; var kAmtIdExpPerItem = 'Expenses/Item'; var kPctIdActualBid = 'Actual Bid %'; var kPctIdCommission = 'Commission %'; var kPctIdEstTarget = '% of Est Target %'; var kIntIdContactsKey = 'Contact'; var kIntIdShippingKey = 'Shipping'; // transient Lot field(s) var kIntIdBidderKey = 'Bidder'; Class(ALEDO,["parent AuctionModel","item count", "edo Class","property values array", "edit Date","edit User","unique Key"]) .Extends(EDO); /** * @class This is the abstract base class for Auction/Lot EDOs. * @extends EDO * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function ALEDO() { /** * @param {AuctionModel} holder parent EDOHolderModel * @param {int} itemcount how many items are linked to this * @param {Function} CLAZZ this EDO's "class" * @param {array} propValues array of property initial values * @param {String} editDate date of last edit * @param {String} editUser ID of last user to edit * @param {int} theKey unique key of this record * @param {int} optEditStatus optional edit status where the * status codes are: 0=no-change; 1=delete; 2=create; 3=hidden; 4=update * @param {String} optName optional name of this instance */ this.konstructor = function ( holder, itemcount, CLAZZ, propValues, editDate, editUser, theKey, optEditStatus, optName ){ this.souper( CLAZZ, holder, propValues, editDate, editUser, theKey, optEditStatus, optName ); // define instance variables this.itemCount = itemcount; } this.toolTip = function( xi ){ return this.edoToolTip(xi) + " Items="+this.itemCount; } this.toString = function() { return this[ kStrIdAuctionID ]; } this.canDelete = function(){ if (!this.isActive()) return "This is already deleted."; var c = this.itemCount; if (c>0) return "This can't be deleted. It is referenced by " +c+" Item"+(c==1?".":"s."); if (this.isLotZero && this.isLotZero()) return "Lot 0 must always exist."; return null; } /** push into given array all ALEDO-specific fields of the UpdateItem message * formatted as<pre> * "{parentAuctionID}~{property1}~...~{propertyN}" * where the fields are defined as follows... * {parentAuctionID} = "my" parent auction ID * {propertyI} = the i-th editable property of this EDO *</pre> * @param {Array} uFields string array containing Update Msg fields */ this.pushUpdateFields = function( uFields ) { uFields.push( encodeURIComponent(this.holder.getID()) ); this.pushEncodedValues( uFields ); } } Class(Auction,["property values array","edit Date","edit User", "unique Key","parent holder","lot count"]) .Extends(ALEDO); /** * @class This class encapsulates an Auction record. * @extends ALEDO * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function Auction() { // init "static" Class methods/elements if (!Auction.Properties) {//keep this line above jsdoc comments! /** Static factory method to generate blank Auction @type Auction */ Auction.Factory = function(index,holder) { var x = new Auction( null, grvGetTodayAsMMDDYYYY(),kUserID,null,holder,0 ); x[ kDateIdCreate ] = x.date; return x; } // init static member variables Auction.UpdateID = "Auction"; Auction.Properties = [ kStrIdAuctionID, kDateIdCreate, kDateIdLaunch, kDateIdLockdown, kDateIdCutoff, kDateIdAward, kDateIdClosed ]; Auction.EditRules = [ MVCEditRule.kALNO, MVCEditRule.kDATE, MVCEditRule.kDate, MVCEditRule.kDate, MVCEditRule.kDate, MVCEditRule.kDate, MVCEditRule.kDate ]; Auction.States = [ kDateIdCreate, kDateIdLaunch, kDateIdLockdown, kDateIdCutoff, kDateIdAward, kDateIdClosed ]; } /** @param {array} array of editable property values in same order as .Properties * @param {String} editDate date of last edit * @param {String} editUser ID of last user to edit * @param {int} theKey unique key of this record * @param {AuctionModel} holder parent EDOHolderModel * @param {int} itemcount how many Items are linked to this * @param {int} optEditStatus optional edit status * @param {String} optName optional name of this instance */ this.konstructor = function ( propArray, editDate, editUser, theKey, holder, itemcount, optEditStatus, optName ) { //Cant edit ID if items are already assigned to auction Auction.EditRules[0] = (itemcount>0) ? MVCEditRule.kRO : MVCEditRule.kALNO; this.souper( holder, itemcount, Auction, propArray, editDate, editUser, theKey, optEditStatus, optName ); //if new object then init a few fields if (!propArray) this[kDateIdCreate] = editDate; //set up special validations this[ kStrIdAuctionID+MVCAttributeModel.kValidateSuffix ] = this.validateBSID; for (var i=0; i<Auction.States.length; ++i) this[ Auction.States[i]+MVCAttributeModel.kValidateSuffix ] = this.validateDate; } /** custom validation method to verify legality of a phase date * @type String * @return error message or null if no error */ this.validateDate = function( dateID ) { var dateStr = this[ dateID ]; if ( grvIsEmpty(dateStr) ) return null; var date = Date.parse(dateStr); if ( date == null ) return null; switch ( dateID ) { case kDateIdCreate: if (grvAfterNow(dateStr)) return "Create date can't be in the future."; break; case kDateIdLaunch: dateStr = this[kDateIdCreate]; if (grvIsEmpty(dateStr) || grvAfter(dateStr,date+1)) return "Launch date must be after Create date"; break; case kDateIdLockdown: dateStr = this[kDateIdLaunch]; if (grvIsEmpty(dateStr) || grvAfter(dateStr,date+1)) return "Lockdown date must be after Launch date"; break; case kDateIdCutoff: dateStr = this[kDateIdLockdown]; if (grvIsEmpty(dateStr) || grvAfter(dateStr,date+1)) return "Cutoff date must be after Lockdown date"; break; case kDateIdAward: dateStr = this[kDateIdCutoff]; if (grvIsEmpty(dateStr) || grvAfter(dateStr,date+1)) return "Bid Award date must be after Cutoff date"; break; case kDateIdClosed: dateStr = this[kDateIdAward]; if (grvIsEmpty(dateStr) || grvAfter(dateStr,date+1)) return "Close date must be after Bid Award date"; break; default: return "Illegal Auction State"; } return null; //no error } /** return the current auction phase or null if in an illegal state @type String */ this.nextState = function() { if (this.isValid()){ for (var i=0; i<Auction.States.length; ++i){ var stateID = Auction.States[i]; if ( grvIsEmpty(this[stateID]) ) return stateID; } } return null;//illegal state } /** custom validation method to verify uniqueness of auction ID * @type String * @return error message or null if no error */ this.validateBSID = function() { if ( this.hasDuplicateBSID()) return "Duplicate Auction IDs are not allowed."; return null; } /** verify uniqueness of Auction ID (as best we can) * @type boolean * @return true iff our auction ID duplicates any in parent auction summary list */ this.hasDuplicateBSID = function() { var key = this.holder.model.auctionKey( this[kStrIdAuctionID] ); return (key>0) && (key!=this.key); } /** return a clone of this object @type Auction */ this.clone = function() { return new Auction( this.propValues(), this.date, this.whom, this.key, this.holder, this.itemCount, this.editStatus ); } this.canCreate = function(appendFlag) { return this.holder.isTrue() ? "Can't add a new Auction until pending changes have been saved" : null; } /** If created, can we undo creation? @type boolean * @param {boolean} appendFlag if true then append else insert */ this.canUncreate = function(appendFlag){ return false; }//override me } //////////////////////////////////////////////////////////////////////////////// var kSpecialLotName = "special unassigned items lot"; Class(Lot,["property values array","edit Date","edit User", "unique Key","parent holder","item count"]) .Extends(ALEDO); /** * @class This class encapsulates a Auction "lot" record. * @extends ALEDO * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function Lot() { // init "static" Class methods/elements if (!Lot.Properties) {//keep this line above jsdoc comments! /** Static factory method to generate blank Lot @type Lot */ Lot.Factory = function(index,holder) { var x = new Lot( null,grvGetTodayAsMMDDYYYY(),kUserID,null,holder,0 ); x[ kAmtIdExpPerItem ] = 0; x[ kPctIdActualBid ] = 0; x[ kPctIdCommission ] = 0; x[ kPctIdEstTarget ] = 0; x[ kIntIdBidderKey ] = 0; x.expanded = true; return x; } // init static member variables Lot.UpdateID = "Lot"; Lot.Properties = [ kIntIdLotNum, kStrIdLotName, kDateIdPayDate, kDateIdClosed, kAmtIdExpPerItem, kPctIdActualBid, kPctIdCommission, kPctIdEstTarget, kIntIdContactsKey, kIntIdShippingKey, //transient field(s) kIntIdBidderKey ]; Lot.EditRules = [ MVCEditRule.kINT, MVCEditRule.kEdit, MVCEditRule.kDate, MVCEditRule.kDate, MVCEditRule.kDec, MVCEditRule.kDec, MVCEditRule.kDec, MVCEditRule.kDec, MVCEditRule.kInt, MVCEditRule.kInt, //transient field(s) MVCEditRule.kEdit ]; } /** @param {array} array of editable property values in same order as .Properties * @param {String} editDate date of last edit * @param {String} editUser ID of last user to edit * @param {int} theKey unique key of this record * @param {AuctionModel} holder parent EDOHolderModel * @param {int} itemcount how many Items are linked to this * @param {int} optEditStatus optional edit status * @param {String} optName optional name of this instance */ this.konstructor = function ( propArray, editDate, editUser, theKey, holder, itemcount, optEditStatus, optName ) { this.souper( holder, itemcount, Lot, propArray, editDate, editUser, theKey, optEditStatus, optName ); this[ kIntIdLotNum+MVCAttributeModel.kValidateSuffix ] = this.validateLotNum; this.expanded = false; } this.hasLotNum = function( n ){ return n == this[kIntIdLotNum]; } this.isLotZero = function(){ return grvIsEmpty(this[kIntIdLotNum]) ? false : (this[kIntIdLotNum]==0 && this[kStrIdLotName]==kSpecialLotName); } /** custom validation method to verify uniqueness of Lot number * @type String * @return error message or null if no error */ this.validateLotNum = function() { if ( this.isLotZero() ) return null; if ( this[kIntIdLotNum]==0 ) return "Lot number zero is only for special lot."; if ( this.hasDuplicateLotNum()) return "Duplicate Lot numbers are not allowed."; return null; } /** custom validation method to verify uniqueness of Lot number * @type boolean * @return true iff our lot number duplicates any in parent auction */ this.hasDuplicateLotNum = function() { return this.holder.lotCount( this[kIntIdLotNum] ) > 1; } /** return a clone of this object @type Lot */ this.clone = function() { return new Lot( this.propValues(), this.date, this.whom, this.key, this.holder, this.itemCount, this.editStatus ); } this.toString = function() { var s = grvIsEmpty(this[kIntIdLotNum ]) ? "" : ("#"+this[kIntIdLotNum]); var t = grvIsEmpty(this[kStrIdLotName]) ? "" : (" "+this[kStrIdLotName]); return s+t; } /** Is it legal to edit "this"? * @return errmsg or null * @type String */ this.canEdit = function(){ if ( kReadOnly ) return "Not allowed in read-only mode."; if (!this.isActive()) return "This is deleted."; return this.isLotZero() ? "Lot 0 is not editable." : null; } /** mark this entity as having been edited */ this.editMe = function() { this.souper(); _GetBidderLists( this[kIntIdBidderKey] ); } } //////////////////////////////////////////// ////////////// Data Models ///////////////// //////////////////////////////////////////// Class(AuctionModel,["Auction Selection Model"]).Extends(EDOHolderModel); /** * @class This class encapsulates the data model of a particular Auction. * This model subscribes to a {@link AuctionSelectionModel} * so that new Lot lists can be downloaded whenever a new Auction is selected. * <p>NOTE: Other parts of AIM assume that the lot lists will never be null; * zero items is ok though.</p> * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function AuctionModel() { /** @param {AuctionSelectionModel} auctionSelectionModel model of which Auction is selected * @param {String} optName optional name of this instance */ this.konstructor = function( auctionSelectionModel, optName ) { // init static DOM (must do this here instead of at static load time!) if (!AuctionModel.LoadXslDOM) AuctionModel.LoadXslDOM = grvLoadXslDOM( kXSLPath+"AIMaucToJS.xsl" ); var holderName = optName ? optName : "Auction"; this.souper( auctionSelectionModel, AuctionModel.LoadXslDOM, holderName ); // init instance variables this._resetEDOs(); } /** return the parent Auction ID for this model @type String */ this.getID = function(){ return this.auction ? this.auction[kStrIdAuctionID] : null; } /** return whether any EDOs are changed for this model @type boolean */ this.isDirty = function() { if (this.auction && this.auction.inEdit()) return true; if (this.lList.isDirty()) return true; return false; } /** return whether all EDOs are valid for this model @type boolean */ this.isValid = function() { if (!this.auction || !this.auction.isValid()) return false; //special case: if we are deleting auction then other errs dont matter if (this.auction.isDeleted()) return true; return this.lList.isValid(); } /** clear EDOs */ this._resetEDOs = function( optAuction ) { this.auction = optAuction ? optAuction : null; if ( this.lList ) this.lList.reset(); else this.lList = new EDOListModel( Lot ); } /** set our Auction object but dont publish */ this._setAuction = function(o){ this.auction = o; } /** get a new Lot list @type ListModel */ this._newLots = function(){ return this.lList.reset(); } /** return the debug details of "this" @type String */ this.dump = function() { var dStr = new Array(); dStr.push( "AuctionModel>>>[" ); dStr.push( "auction=" +(this.auction ?this.auction .dump():"null") ); dStr.push( "lots=" +(this.lList ?this.lList .dump():"null") ); dStr.push( "]" ); return dStr.join("\n"); } /** create a new item for the selection list from current EDO * @type EDOHolderSelectionItem */ this.createSelectionItem = function() { return new AuctionSummary( this.auction.key, this.auction[kStrIdAuctionID], 0 ); } /** return the updated properties from the current EDO needed for select list update * @return arbitrary value as needed @type Object */ this.getUpdatedProperty = function() { return this.getID(); } /** return how many lots have the given lot number @type int */ this.lotCount = function( lotnum ) { var count = 0; this.lList.iterate( function(i,lot){ if (lot.hasLotNum(lotnum)) ++count; } ); return count; } /** return whether there is currently an EDO @type boolean */ this.hasEDO = function(){ return this.auction!=null; } /** return whether current EDO matches selection item "key" * @type boolean * @param {EDOHolderSelectionItem} item selection menu item */ this.keysMatch = function(item){ return this.auction.key==item.key; } /** return whether current EDO matches selection item "properties" * @type boolean * @param {EDOHolderSelectionItem} item selection menu item */ this.propMatch = function(item){ return this.getID()==item.bsID; } /** push into given array all AJAX SAVE Post params for this model * @param {Array} posts string array containing POST params */ this.pushPosts = function( posts ) { this.auction.pushPosts( posts ); //THIS **MUST** BE FIRST!! this.lList .pushPosts( posts ); } /** return a new blank EDO of the type implied by EDOIndex @type EDO * @param {EDOIndex} xi edo index */ this._newEDO = function(xi) { return xi.invoke( this, Auction.Factory, Lot.Factory, this ); } /** return the specified lot @type Lot * @param {int} i index into lot list */ this._getLot = function( i ) { return (i!=null && i>=0 && i<this.lList.getCount()) ? this.lList.getItem( i ) : null; } /** return the specified auction @type Auction * @param {int} i index into auction list */ this._getAuction = function( i ) { return (i==0 && this.auction) ? this.auction : null; } /** return reference to the specified editable domain object * @param {ALIndex} xi edo index */ this.getEDO = function(xi){ return xi.invoke( this, this._getAuction, this._getLot ); } /** insert a new lot * @param {int} i lot list index * @param {EDO} edo the shipping */ this._insertLot = function( xi ) { this.lList.addBefore( i, edo ); } /** create new EDO which is inserted after selected EDO * @return EDOIndex of new EDO * @type EDOIndex * @param {EDOIndex} xi edo index */ this.createEDO = function(xi){ xi.invoke( this, this._newAuction, this._insertLot, this.newEDO(xi) ); return xi; } /** append a new lot * @return EDOIndex of new EDO * @type EDOIndex * @param {int} i lot list index * @param {EDO} edo the lot */ this._appendLot = function( i, edo ) { return ALIndex.Lot( this.lList.addItem( edo ) ); } /** create a new auction * @return EDOIndex of new EDO * @type EDOIndex * @param {int} i auction list index * @param {EDO} edo the auction */ this._newAuction = function( i, auctionEDO ) { this._resetEDOs( auctionEDO ); //auto-create special lot zero var lotEDO = this.newEDO(ALIndex.Lot(0)); lotEDO[ kIntIdLotNum ] = 0; lotEDO[ kStrIdLotName ] = kSpecialLotName; lotEDO.makeReadOnly(); this._appendLot( 0, lotEDO ); this.updateStamp(); return ALIndex.Auction(); } /** create new EDO which is appended at end of EDO list * @return EDOIndex of new EDO * @type EDOIndex * @param {EDOIndex} xi edo index */ this.appendEDO = function(xi){ return xi.invoke( this, this._newAuction, this._appendLot, this.newEDO(xi) ); } /** toggle the "expanded" flag of the specified EDOs. * @param {boolean} doAllFlag if true, set all of the EDOs to new value * @param {EDOIndex} xi edo index */ this.toggleExpand = function( doAllFlag, xi ) { var edo = this.getEDO(xi); if (doAllFlag) { var newVal = !edo.isExpanded(); this.lList .toggleExpandAll( newVal ); this.auction.toggleExpand ( newVal ); } else edo.toggleExpand(); this.updateStamp(); } } Class(AuctionSelectionModel,["AuctionSummary List Model"]).Extends(EDOHolderSelectionModel); /** * @class This class encapsulates the data model for * "which Auction is currently selected". * @extends EDOHolderSelectionModel * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function AuctionSelectionModel() { /** @param {ListModel} listModel {@link AuctionSummary} list */ this.konstructor = function( listModel ){ this.souper( listModel, "Auction " ); } /** Return the list index of the specified Auction or <0 if not found. @type int */ this.findAuction = function( auctionID, auctionKey ) { var list = this.model; var N = list.getCount(); if (N<1) return -2;//NO DATA IN auction SUMMARY LIST!! for (var i=0; i<N; ++i) if (list.getItem(i).bsID == auctionID || list.getItem(i).key == auctionKey) return i; return -1; } /** return the key of the auction with the given auction ID @type int */ this.auctionKey = function( auctionID ) { var key = -1; this.model.iterate( function(i,ss){ if (ss.bsID==auctionID) key = ss.key; } ); return key; } /** Select the "initially selected" EDOHolder<br> * @param {boolean} selectFirst if selection critera has no match then * if selectFirst==true then select the first in list * else leave selection alone */ this.selectInitial = function( selectFirst ) { var i = this.findAuction( kAuctionID, kAuctionKey ); if (i==-2){ this.selectNothing(); return; }//EMPTY LIST!! if (i>= 0){ this.select(i); return; }//found it if (selectFirst) this.select(0); } } //////////////////////////////////////////// ////////////// Controllers ///////////////// //////////////////////////////////////////// Class(PhaseButtonController,["button text model"]) .Extends(MVCTxtButtonController); /** * @class This class is a Button Controller that manages the button that * "moves" an auction from one phase to the next. * @extends MVCTxtButtonController * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function PhaseButtonController() { /** @param {Auction} auction Auction we are to observe */ this.konstructor = function( auction ) { this.souper( this, "Declare Phase as met", "onPhaseBtnPressed" ); // init instance variables this.auction = auction; this.enabld = false; } /** Return whether this button should be enabled. @type boolean */ this.isEnabled = function() { return kReadOnly ? false : (this.enabld && this.auction.inEdit()); } /** simulate MVCScalarModel interface enough to supply button text @type String */ this.getValue = function() { this.enabld = true; switch ( this.auction.nextState() ) { case kDateIdLaunch: return "Launch Auction"; case kDateIdLockdown: return "Lockdown Auction"; case kDateIdCutoff: return "Cutoff Auction"; case kDateIdAward: return "Award Bids"; case kDateIdClosed: return "Close Auction"; } this.enabld = false; return "N/A"; } } //////////////////////////////////////////// ////////////// Data Views ///////////////// //////////////////////////////////////////// Class(AuctionView,["Auction object"]) .Extends(EDOView); /** * @class This class produces a view of a {@link Auction}. * @extends EDOView * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function AuctionView() { /** @param {Auction} auction Auction we are to observe */ this.konstructor = function( auction ) { this.souper( auction, ALIndex.Auction() ); } this.buildFields = function( HTML ) { HTML.push( this.buildUprField( kStrIdAuctionID, 10, 10, false ) ); HTML.push( this.buildDayField( kDateIdCreate , false ) ); HTML.push( this.buildDayField( kDateIdLaunch , false ) ); HTML.push( this.buildDayField( kDateIdLockdown, false ) ); HTML.push( this.buildDayField( kDateIdCutoff , false ) ); HTML.push( this.buildDayField( kDateIdAward , false ) ); HTML.push( this.buildDayField( kDateIdClosed , false ) ); HTML.push( "<td>"+ this.embedHTML( this.getWidgetID()+".btn", new PhaseButtonController( this.model ) ) +"</td>" ); } } Class(LotView,["Lot object","EDOIndex of Lot"]) .Extends(EDOView); /** * @class This class produces a view of a {@link Lot}. * @extends EDOView * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function LotView() { /** @param {Lot} edo EDO we are to observe * @param {EDOIndex} edoIndex index to EDO */ this.konstructor = function( edo, edoIndex ) { this.souper( edo, edoIndex ); } this.preSelect = function() { var bk = this.model[ kIntIdBidderKey ]; this .sharedMenuSelect( gBidderSelected , kIntIdBidderKey ); this.cascadedMenuSelect( _ContactsSelected(bk), kIntIdContactsKey ); this.cascadedMenuSelect( _ShippingSelected(bk), kIntIdShippingKey ); } this.buildFields = function( HTML ) { var bidderKey = this.model[kIntIdBidderKey]; HTML.push( this.buildStrField( kIntIdLotNum , 3, 3, false ) ); HTML.push( this.buildStrField( kStrIdLotName , 50, 50, false, 3 ) ); // HTML.push( this.buildStrField( kIntIdBidderKey , 10, 10, true ) ); HTML.push( this.buildPopField( kIntIdBidderKey , true, gBidderSelected, 1, "onBidderSelect" ) ); HTML.push( this.buildNulField( false ) ); HTML.push( this.buildDayField( kDateIdPayDate , false ) ); HTML.push( this.buildPctField( kPctIdActualBid , false ) ); HTML.push( this.buildAmtField( kAmtIdExpPerItem , false ) ); // HTML.push( this.buildStrField( kIntIdContactsKey , 10, 10, true ) ); HTML.push( this.buildPopField( kIntIdContactsKey , true, _ContactsSelected(bidderKey),null,null,this.model.contName ) ); HTML.push( this.buildNulField( false ) ); HTML.push( this.buildDayField( kDateIdClosed , false ) ); HTML.push( this.buildPctField( kPctIdCommission , false ) ); HTML.push( this.buildPctField( kPctIdEstTarget , false ) ); // HTML.push( this.buildStrField( kIntIdShippingKey , 10, 10, true ) ); HTML.push( this.buildPopField( kIntIdShippingKey , true, _ShippingSelected(bidderKey),null,null,this.model.shipName ) ); } } Class(LotListView,["EDO ListModel"]) .Extends(EDOListView); /** * @class This class produces a view of a List of Lot EDOs. * @extends EDOListView * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function LotListView() { /** @param {EDOListModel} edoListModel EDO list we are to observe */ this.konstructor = function( edoListModel ) { this.souper( edoListModel, LotView ); } this.itemEDOIndex = function( index ) { return ALIndex.Lot( index ); } } Class(AuctionModelView,["Auction data model"]) .Extends(EDOHolderView); /** * @class This class produces the view of the entire data panel. * @extends EDOHolderView * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function AuctionModelView() { /** @param {AuctionModel} auctionModel Auction/lots we are to observe */ this.konstructor = function( auctionModel ) { this.souper( auctionModel ); } this.buildFields = function( HTML ) { var vwID = this.getWidgetID(); if ( !this.model.auction || this.model.auction.inLimbo() ) { if (!grvWAITING()) HTML.push( EDOView.ShellHTML( ALIndex.Auction(), Auction ) ); } else if ( this.model.auction.isActive() ) { HTML.push( this.embedHTML( vwID+".auctionWdgt", new AuctionView( this.model.auction ) ) ); HTML.push( this.embedHTML( vwID+".lotWdgt", new LotListView( this.model.lList ) ) ); } else HTML.push( '<thead>This Auction is deleted. You must Cancel, Save, or Undo.</thead>' ); } } //////////////////////////////////////////// //////////////// Commands ////////////////// //////////////////////////////////////////// /** Load in contacts and shippings list from specified bidder<br> * NOTE: this is a Command helper function.<br> * NEVER call this from outside the context of a Command object! * @param {long} bidderKey unique key of bidder */ function _GetBidderLists( bidderKey ) { if (_ContactsSelected(bidderKey).loaded) return;//already loaded _gGrvHackStartupInhibitWait = true; EDOHolderModel.AjaxRequest( "Bidder", bidderKey, onBidderLoadReply ); } function _ContactsSelected( bidderKey ) { if (gContactsSelected[bidderKey]){/*already created*/} else { var bs = "#"+bidderKey; var L = new MVCMapModel(bs+":Contacts List"); L.map.addItem( 0, new MVCDecode( "Contact", "0", "", 1 ) ); gContactsSelected[bidderKey] = new MVCSelectionModel( L, bs+":shared contact selection model" ); gContactsSelected[bidderKey].loaded = (bidderKey==0); } return gContactsSelected[bidderKey]; } function _ShippingSelected( bidderKey ) { if (gShippingSelected[bidderKey]){/*already created*/} else { var bs = "#"+bidderKey; var L = new MVCMapModel(bs+":Shipping List"); L.map.addItem( 0, new MVCDecode( "Shipping", "0", "", 1 ) ); gShippingSelected[bidderKey] = new MVCSelectionModel( L, bs+":shared shipping selection model" ); gShippingSelected[bidderKey].loaded = (bidderKey==0); } return gShippingSelected[bidderKey]; } Class(BidderMenuCmd,["view ID"]).Extends(EDOSuperMenuCmd); /** * @class This class implements the bidder menu edit command. * @extends EDOSuperMenuCmd * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function BidderMenuCmd() { /** @param {String} viewID viewID of menu generating this event */ this.konstructor = function( viewID ) { this.souper( viewID ); } this.updateEDO = function( exemplar, isRedo ) { this.edo[ kIntIdContactsKey ] = exemplar[ kIntIdContactsKey ]; this.edo[ kIntIdShippingKey ] = exemplar[ kIntIdShippingKey ]; } this.prefillEDO = function() { _GetBidderLists( this.newValue ); this.updateOtherController( kIntIdContactsKey, 0 ); this.updateOtherController( kIntIdShippingKey, 0 ); } } Class(BidderLoadReplyCmd,["xml request object"]).Extends(MVCAJAXReplyCmd); /** * @class This Command processes the reply of the "load Bidder data" request. * NOTE: It isnt undoable (because we lose all edits!). * @extends MVCAJAXReplyCmd * @see #konstructor * @deprecated ajax call was made synchronous to make undo possible * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function BidderLoadReplyCmd() { /** @param {grvXMLreq} xmlReq the XML request being replied to * @param {String} optName optional name of this instance */ this.konstructor = function( xmlReq, optName ) { if (!BidderLoadReplyCmd.DOM) BidderLoadReplyCmd.DOM = grvLoadXslDOM( kXSLPath+"AIMbidListsToJS.xsl" ); this.souper( xmlReq, BidderLoadReplyCmd.DOM, optName ); } } Class(NextPhaseCmd).Extends(EDOCmd); /** * @class This class implements the Move to Next Auction Phase cmd. * @extends EDOCmd * @see #konstructor * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function NextPhaseCmd() { this.konstructor = function(){ this.souper("move to next phase", gEDOSelected.canEditSelected()); this.auctionEDO = gEDOSelected.getSelected(); this.dateID = this.auctionEDO.nextState(); if (this.dateID==null) this.state = -1; this.dateStr = grvFormatDate( new Date(), "mm/dd/yyyy" ); } this.doit = function(){ this.auctionEDO[ this.dateID ] = this.dateStr; } this.undo = function(){ this.auctionEDO[ this.dateID ] = ""; } } //////////////////////////////////////////// ////////// Static Event Handlers /////////// //////////////////////////////////////////// /** handle event for 'user selects from the bidder menu' * @param {event} e browser event * @param {String} viewID ID of the controller generating this event * @author Bruce Wallace (PolyGlotInc.com) * @version 2.5 */ function onBidderSelect( e, viewID ){ mvcDoCmd( new BidderMenuCmd( viewID ) ); return true; } /** handle AJAX event for 'reply received from "load Bidder data" server-request' * @param {grvXMLreq} xmlReq the XML request being replied to * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function onBidderLoadReply( xmlReq ){ //replace async with sync to allow undo //mvcDoCmd( new BidderLoadReplyCmd( xmlReq ) ); if (!onBidderLoadReply.DOM) onBidderLoadReply.DOM = grvLoadXslDOM( kXSLPath+"AIMbidListsToJS.xsl" ); //translate received XML into javascript (via XSL) and save onBidderLoadReply.script = xmlReq.xform2( onBidderLoadReply.DOM ); if (gGrvTraceEvt) grvDebugWindow( onBidderLoadReply.script ); eval( onBidderLoadReply.script ); } /** handle event for 'next phase' button press * @author Bruce Wallace (PolyGlotInc.com) * @version 2.0 */ function onPhaseBtnPressed(){ mvcDoCmd( new NextPhaseCmd() ); }
|
The Gravey 2.5 Framework and AIM RIA | |||||||
| PREV NEXT | FRAMES NO FRAMES | |||||||