guides:o4w:examples:example_order

Order Entry Example    

Below is code for a sample Order Entry display screen for use with an O4W application.

Subroutine O4W_ORDER_ENTRY(CtrlEntId, event, request)


*********************************************************************************************************************
* Prompt the user for the order number: allow for lookup, manual entry, or left blank => new order

*

* Main Program flow: CREATE event (to draw form initially)

*

*                    RETURNVALUE event/ONUM if order search button pressed or

*                    LOSTFOCUS event/ONUM if order number entered explicitly

*                    handleOrderNumber {may optionally display dialog if existing record has been changed, and then CLICK\BTN_READ or CLICK\BTN_READ_CANCEL} => loadRecord => retrieveRecord => displayHeader => displayDetails

*

*                    RETURNVALUE event/OCUST if customer search button pressed

*  CHANGE event/OCUST to update the customer name

*  markAsChanged

*

*  CLICK event/BTN_SEARCH_PROD_<line#> if product search button pressed to ask which type of search

*  RETURNVALUE event/ITEM after product search completed

*      CHANGE event/ITEM, QTY, or PRICE to update the order details

* displayDetails => markAsChanged

*

*  CLICK event/BTN_SAVE to save the record

* lockrecord => saverecord => resetpages

*  CLICK event/BTN_DELETE to confirm deletion of record => CLICK event/BTN_DELETE2 to delete the record

* lockrecord => deleterecord => resetpages

*  CLICK event/BTN_CANCEL to reload the original order record

* retrieveRecord => displayHeader => displayDetails => markAsFresh
************************************************************************************************************
* O4W coding example

* Create, edit, or delete records in the ORDERS table

* URL: http://.../oecgi3.exe/O4W_ORDER_ENTRY

* Prompt the user for the order number: allow for lookup, manual entry, or left blank => new order

 

* Insert required equates and commons

$Insert O4WCOMMON

$Insert O4WEQUATES

* Since we're going to check the configuration record, include this equate as well

$Insert O4WConfigEquates

Declare Function Repository

 

* Open our data and dictionary tables, otherwise we have an error

Open "ORDERS" To ORDER.TBL Then

Open "DICT","ORDERS" To @DICT Else

O4WError("Unable to access DICT.ORDERS table")

Return 0

End

End Else

O4WError("Unable to access ORDERS table")

Return 0

End

* define some O4W "styles"

selectedStyle = O4WMarkedOptions("1")

deselectedStyle = O4WMarkedOptions("0")

textReplace = O4WResponseOptions("1")

textReplaceTrigger = O4WResponseOptions("1", "", "1")

borderStyle = O4WTableStyle("", "1", "1")

roStyle = O4WInputOptions("0","1"):O4WColorStyle("", "lightblue")

size10pct = O4WSizeStyle("", "10%")

size50pct = O4WSizeStyle("", "50%")

rtJustn = O4WAlignStyle("", "2")

* retrieve (if set) our unique id

uniqueID = O4WGetValue("O4WUniqueID")

* read the configuration record (using the appropriate repository method)

configRec = Repository("ACCESS", @APPID<1>:"*CONFIG*O4W*CFG_O4W")

Call Set_Status(0)

* determine the "lock procedure" that has been specified in the configuration record

LOCK_PROC = configRec<O4WCONFIG_LOCK_PROC$>

If LOCK_PROC = "" Then LOCK_PROC = "O4WI_LOCKHANDLER"

 

Begin Case

Case EVENT _EQC "CREATE" ; Gosub Create_Event

Case EVENT _eqc "LOSTFOCUS" ; Gosub Lostfocus_Event

Case event _eqc "CHANGE" ; Gosub Change_Event

Case event _eqc "CLICK" ; Gosub Click_Event

Case event _eqc "RETURNVALUE" ; Gosub Returnvalue_Event

End Case

 

Return 0

 

retrieveRecord:

* call the lockhandler routine to read the original record

Call @LOCK_PROC(O4W_LOCKHANDLER_ACTION_READ$, order.tbl, @ID, @RECORD,  UniqueID:"*ORDERS*":@id:"*ORIG")

Return

 

lockRecord:

* call the lockhandler routine to lock (if possible) the original record

* this will verify that the underlying record is unchanged, And we can lock it

error = "" ;* assume success

* load in the current ID and record contents from the browser form

Gosub retrieveCurrentRecord

* call the lockhandler to see if the record is able to be locked, and is unchanged from its original state

stat = Function(@lock_proc(O4W_LOCKHANDLER_ACTION_CHECK$, order.tbl, @id, curr.record, UniqueID:"*ORDERS*":@ID:"*ORIG", O4W_LOCKHANDLER_OPTION_LOCK$))

* check for results from the 'check' call

If stat = O4W_LOCKHANDLER_NO_LOCK$ Then

* couldn't get the lock on this item - let the user choose another ID

error = "Unable to lock order '":@ID:"'"

O4WError(error)

Return

End

 

If stat = O4W_LOCKHANDLER_ITEM_CHANGED$ Then

* someone else changed the record while we worked on it - let the user choose another ID

error = "Order '":@ID:"' has been changed by another user"

* remember to unlock our current record, though

Call @LOCK_PROC(O4W_LOCKHANDLER_ACTION_UNLOCK$, order.tbl, @ID)

O4WError(ERROR)

Return

End

Return

 

saveRecord:

* call the lockhandler routine to save the modified record

Call @LOCK_PROC(O4W_LOCKHANDLER_ACTION_WRITE$, ORDER.TBL, @ID, @RECORD, UniqueID:"*ORDERS*":@ID:"*ORIG")

Return

 

deleteRecord:

* delete the record from the orders table, and release any lock

Delete order.tbl, @ID

* release the record lock

Call @LOCK_PROC(O4W_LOCKHANDLER_ACTION_UNLOCK$, ORDER.TBL, @ID)

Delete O4WTempFile%, UniqueID:"*ORDERS*":@ID:"*ORIG"

return

 

retrieveCurrentRecord:

@ID = O4WGetValue("ONUM")

@RECORD = ""

{CUST_NO} = O4WGetValue("OCUST")

odate = O4WGetValue("ODATE")

* if no date filled in, use todays date

If odate = "" Then

odate = date()

End Else

odate = Iconv(odate,"D")

end

{ORDER_DATE} = odate

items = O4WGetValue("ITEM")

qtys = O4WGetValue("QTY")

prices = O4WGetValue("PRICE")

* trim off any blank lines

num.items = dcount(items, @VM)

For each.item = num.items To 1 step -1

If items<1,each.item> = "" Then

items = Delete(items, 1, each.item, 0)

qtys = Delete(qtys, 1, each.item, 0)

prices = Delete(prices, 1, each.item, 0)

End

Next each.item

{ITEM} = items

{QTY} = qtys

{PRICE} = Iconv(prices, "MD2")

Return

 

resetPages:

* blank out the order number

O4WUpdate("ONUM", "", textReplace)

@RECORD = ""

Gosub displayHeader

* mark as unchanged (as of now)

Gosub markAsFresh

* go to the first tab

O4WGoToTab("orderForm", 1)

return

 

handleOrderNumber:

* do we currently have an 'active' (changed) record in process?

isActive = O4WGetValue("activeRecord")

If isActive <> "" Then

* yes; build our dialog to verify the change of record

O4WSectionStart('specialDialog', selectedStyle:O4WResponseStyle())

* save the newly-entered order ID in the dialog

O4WStore(@ID, "ONUM", "ONUM")

* save the original item ID in the dialog, too

O4WStore(isActive, "ID", "ID")

O4WText("Discard any changes to existing record?")

O4WBreak()

O4WButton("Yes, Discard and Load New Record", "BTN_READ", selectedStyle)

O4WButton("No, Cancel and Keep Current Record", "BTN_CANCEL_READ")

* Notify us when these buttons are pressed with the 'click' event

O4WQualifyEvent("BTN_READ", "CLICK")

O4WQualifyEvent("BTN_CANCEL_READ", "CLICK")

O4WSectionEnd('specialDialog')

* and then show the dialog

O4WDialog('specialDialog', 'Confirm Discard of Any Changes', '', '', 'width:650')

return

End

 

* no, no currently active record - just load in the record for this @ID

Gosub loadRecord

Return

 

loadRecord:

If @ID = "" Then

* new order - get next sequential number

Lock @DICT, "%SK%" Else

O4WError("Unable to lock sequential counter record")

Return

END

 

Read NEXT.NUM From @DICT, "%SK%" Else NEXT.NUM = 1000

@ID = NEXT.NUM

Write NEXT.NUM +1 On @DICT, "%SK%"

Unlock @DICT, "%SK%"

* Update the text box with this order number

O4WUpdate("ONUM", @ID, textReplace)

End

* read in the record for this @ID

Gosub RetrieveRecord

* display the header and details

Gosub displayHeader

* Mark this record as unchanged (for now)

Gosub markAsFresh

* make sure we're on the first tab

O4WGoToTab("orderForm", 1)

Return

 

markAsFresh:

* turn off the browser page warning

O4WPlugin("$", "o4wsetConfirmUnload", "false")

* and clear out our own flag that indicates the record has changed

o4wUpdate("activeRecord", "", textReplace)

Return

 

markAsChanged:

* tell the browser that we need the "don't navigate away!" warning message

O4WPlugin("$", "o4wsetConfirmUnload", "true")

* remember what our current record ID is in case someone tries to change it

o4wUpdate("activeRecord", @ID, textReplace)

Return

 

displayHeader:

* load up the header fields

O4WUpdate("OCUST", {CUST_NO}, textReplace)

O4WUpdate("OCUSTNAME", {CUSTOMER_NAME}, textReplace)

O4WUpdate("ODATE", Oconv({ORDER_DATE}, "D"), textReplace)

* and fall through to update the details...

 

displayDetails:

* rebuild the section containing our order details

o4wSectionStart("orderDetails", O4WResponseStyle():deselectedStyle)

* build a table for our order lines

O4WTableStart("tableDetails", borderStyle:O4WSizeStyle("","100%"))

O4WTableHeader("Item", "2", "", size10pct)

O4WTableHeader("Description", "", "", size50pct)

O4WTableHeader("Cost", "", "", size10pct)

O4WTableHeader("Qty", "", "", size10pct)

O4WTableHeader("Ext Cost")

num.items = dcount({ITEM}, @vm) +1 ;* always have one blank row at the end

For each.item = 1 To num.items

O4WSetCell(each.item, 1, '', borderStyle)

O4WButton("?", "BTN_SEARCH_PROD_":each.item)

* display some choices as to what type of popup should be run when this button is pressed

O4WQualifyEvent("BTN_SEARCH_PROD_":each.item, "CLICK")

O4WSetCell('', '', '', borderStyle)

/*

mark these with the 'o4wClearDuplicateVal' and 'o4wClearDuplicateText' styles so that the "Add" button clears out these fields when a new row is added

*/

O4WTextBox({ITEM}<1,EACH.ITEM>, "", "", "ITEM", "ITEM_":each.item, "o4wClearDuplicateVal")

O4WSetCell('','','',borderStyle)

O4WText({DESCRIPTION}<1,EACH.ITEM>, "DESC_":each.item, "o4wClearDuplicateText")

O4WSetCell('','','',borderStyle)

O4WTextBox(Oconv({PRICE}<1,EACH.ITEM>, "MD2,$"), "", "", "PRICE", "PRICE_":each.item, rtJustn:"o4wClearDuplicateVal")

O4WSetCell('','','',borderStyle)

O4WTextBox({QTY}<1,EACH.ITEM>, "", "", "QTY", "QTY_":each.item, rtJustn:"o4wClearDuplicateVal")

O4WSetCell("", "", "", rtJustn:borderStyle)

O4WText(Oconv({EXT_COST}<1,EACH.ITEM>, "MD2,$"), "EXT_":each.item, "o4wClearDuplicateText")

Next each.item

O4WTableEnd("tableDetails")

* build another table to display the sub total

O4WTableStart("tableSummary", O4WSizeStyle("","100%"))

O4WSetCell(1,1,'', O4WSizeStyle("","90%"))

O4WSpace(5)

O4WSetCell(1,2, '', rtJustn:borderStyle)

O4WText(Oconv({SUB_TOTAL}, "MD2,$"))

O4WTableEnd("tableSummary")

O4WButton("Add Row", "BTN_ADD")

O4WButton("Delete Row", "BTN_DEL")

* Automatically add or remove the last row when these buttons are pressed

O4WQualifyEvent("BTN_ADD", "ADDTOTABLE", "tableDetails", "-1")

O4WQualifyEvent("BTN_DEL", "DELETEFROMTABLE", "tableDetails", "-1")

* Notify us when any of the ITEM, QTY, or PRICE field values are changed

O4WQualifyEvent("ITEM", "CHANGE", "textbox")

O4WQualifyEvent("PRICE","CHANGE", "textbox")

O4WQualifyEvent("QTY",  "CHANGE", "textbox")

o4wSectionEnd("orderDetails")

Return

 

   

*****************************************************************************************

CREATE_EVENT:

* Generate the base form

* Since no template has been explicitly specified, use the default template

O4WForm()

* Save this variable in the web page

O4WStore("", "activeRecord", "activeRecord")

* After the O4WForm call, the unique ID has been created - load it in

uniqueID = O4WGetValue("O4WUniqueID")

 

* Display a header

O4WHeader("Order Entry/Inquiry", 3)

* Establish the tabs

O4WTabs("orderForm", "orderHeader":@VM:"orderDetails", "Header":@VM:"Details")

 

* Create the header section

O4WSectionStart("orderHeader", deselectedStyle)

* and a table to contain the order header information

O4WTableStart("tableHeader")

O4WSetCell(1,1)

O4WText("Order Number: ")

O4WSetCell()

O4WButton("?", "BTN_SEARCH_ORDERS")

* Associate a popup with this button

O4WPopup("Order Search", O4W_LINKTYPE_POPUP$, "ORDER_POPUPS", "", "orderpopup", "BTN_SEARCH_ORDERS")

O4WTextbox("", "", "", "ONUM","ONUM")

* Tell O4W we want to be notified when the ONUM textbox has lost focus

o4wqualifyevent("ONUM", "LOSTFOCUS")

O4WSetCell(4, 1)

O4WText("Customer Number: ")

O4WSetCell()

O4WButton("?", "BTN_SEARCH_CUST")

* Associate a popup with this button too

O4WPopup("Customer Search", O4W_LINKTYPE_POPUP$, "CUSTOMER_ID_POPUP", "", "custpopup", "BTN_SEARCH_CUST")

O4WTextbox("", "", "", "OCUST", "OCUST")

* Tell O4W we want to be notified when the OCUST textbox has changed

o4wqualifyevent("OCUST", "CHANGE", "textbox")

O4WSetCell()

O4WSetCell(5, 2, "", O4WTableCellOptions(2))

* Display a textbox, but mark it as "read only" and style it so that it looks different

O4WTextbox("", "40", "", "OCUSTNAME", "OCUSTNAME", roStyle)

O4WSetCell(6,1)

O4WText("Order Date: ")

O4WSetCell()

O4WDatePicker("","12","1","","ODATE", "ODATE")

O4WTableEnd("tableHeader")

O4WSectionEnd("orderHeader")

 

O4WSectionStart("orderDetails", deselectedStyle)

* Can't fill in the order details yet (without an order being selected), but set up this section as a placeholder

O4WText("Please select an existing or new order...")

O4WSectionEnd("orderDetails")

O4WSectionEnd("orderForm")

 

* Define this section for our special dialogs

O4WSectionStart("specialDialog", deselectedStyle)

O4WSectionEnd("specialDialog")

 

* Define the buttoms

O4WButton("Save", "BTN_SAVE")

O4WButton("Delete", "BTN_DELETE")

O4WButton("Cancel", "BTN_CANCEL")

* And set them so they generate the 'click' event

O4WQualifyEvent("BTN_SAVE", "CLICK")

O4WQualifyEvent("BTN_DELETE", "CLICK")

O4WQualifyEvent("BTN_CANCEL", "CLICK")

RETURN

 

LOSTFOCUS_EVENT:

* Generated when a control loses focus (if the appropriate O4WQualifyEvent on that control has been set)

Begin Case

Case ctrlentid _eqc "ONUM"

O4WResponse()

@ID = O4WGetValue("ONUM")

* Load in the value of the ONUM textbox, and call handleOrderNumber to retrieve that record (if appropriate)

Gosub handleOrderNumber

End case

RETURN

 

CHANGE_EVENT:

/*

Generated when a control's value changes (if the appropriate O4WQualifyEvnet on that control has been set)

Note that O4W provides 2 additional values: O4WChangeID (the ID of the control that made the change), and O4WChangeValue (the value it's been changed to)

*/

Begin Case

Case ctrlentid _eqc "OCUST"

* Customer # has changed - update our customer name display

O4WResponse()

@RECORD = ""

@ID = O4WGetValue("ONUM")

{CUST_NO} = O4WGetValue("O4WChangeValue")

O4WUpdate("OCUSTNAME", {CUSTOMER_NAME}, textReplace)

* make sure we know that something's changed, so we can't just navigate away from this without being prompted to save our changes

Gosub markAsChanged

Case CtrlEntId _eqc "ITEM" Or CtrlEntId _eqc "QTY" Or CtrlEntId _eqc "PRICE"

* One of our detail lines has been added or changed

O4WResponse()

* who changed?  which line, which control?  This way, we can determine who to set the focus to...

whichOne = O4WGetValue("O4WChangeID")

/*

Our controls are defined as "ITEM_1", "ITEM_2", etc.  However, if a new line has been added, it will have a more complex (auto-generated) ID, such as ITEM_3_o4wid_2

*/

If dCount(whichOne, "_") > 1 Then

* More than one "_" in the ID? This must be a newly-added line

changeLine = -1

End Else

changeLine = Field(whichOne, "_", 2)

End

* Load in the current contents of all our fields

Gosub retrieveCurrentRecord

* fill in any defaults, and determine where to set the focus to

items = {ITEM}

qtys = {QTY}

cost = {PRICE}

num.items = dcount(items, @VM)

For each.item = num.items To 1 step -1

* default the quantity and price if they're not set

If qtys<1,each.item> = "" Then

qtys<1,each.item> = 1

End

If cost<1,each.item> = "" then

cost<1,each.item> = Xlate('PRODUCTS',  items<1,each.item>, "PRICE",  "")

end

Next each.item

{ITEM} = items

{QTY} = qtys

{PRICE} = cost

* Update the "order details" section

Gosub displayDetails

* now set the focus as appropriate

If changeLine = -1 Then

* this was a newly-added line, so it's the last value

changeLine = dcount(items,@VM)

end

 

Begin Case

Case CtrlEntId _eqc "ITEM"

O4WFocus("PRICE_":changeLine)

Case CtrlEntId _eqc "PRICE"

O4WFocus("QTY_":changeLine)

Case CtrlEntId _eqc "QTY"

O4WFocus("ITEM_":(changeLine+1))

End Case

* Remember to mark us as having been changed, so we can't navigate away and lose our changes without a verification prompt

Gosub markAsChanged

End Case

RETURN

 

CLICK_EVENT:

* Generated when a button is pressed

Begin Case

Case CtrlEntId _eqc "BTN_CANCEL"

* Throw away any changes, and reload the original contents of the record?

O4WResponse()

* Get the ID

@ID = O4WGetValue("ONUM")

* see if there are any changes, and if there are prompt before reloading

Gosub handleOrderNumber

Case CtrlEntId _EQC "BTN_SAVE"

* called when the 'save' button is pressed

* make sure we can lock the record, and it hasn't been changed by anyone else since we originally read it in

Gosub lockRecord

If error = "" Then

* No problems - write it out

Gosub saveRecord

* Display our "update successful" response

O4WError("Order '":@ID:"' updated", "Save Order")

* blank the fields, mark us as unchanged, and return to first tab

Gosub resetPages

End

Case CtrlEntId _eqc "BTN_DELETE"

* called to delete the record

* put up a dialog box to verify the deletion first

O4WResponse()

* retrieve the item id

@ID = O4WGetValue("ONUM")

* build our dialog to verify the deletion

O4WSectionStart('specialDialog', selectedStyle:O4WResponseStyle())

* save the order ID in the dialog

O4WStore(@ID, "ONUM", "ONUM")

O4WText("Please verify deletion of order '":@ID:"'")

O4WBreak()

O4WButton("Delete", "BTN_DELETE2", selectedStyle)

O4WButton("Cancel", "BTN_DIALOG_CANCEL")

* Notify us when these buttons are pressed

O4WQualifyEvent("BTN_DELETE2", "CLICK")

O4WQualifyEvent("BTN_DIALOG_CANCEL", "CLICK")

O4WSectionEnd('specialDialog')

* and then show the dialog

O4WDialog('specialDialog', 'Confirm Deletion', '', '', 'width:350')

Case CtrlEntId _eqc "BTN_DELETE2"

* called after confirming the delete request

* first, make sure we can lock the record and no one else has changed it since we read it

Gosub lockRecord

If error = "" Then

* no problems - proceed with the deletion

Gosub deleteRecord

* display our 'deletion successful' message

O4WError("Order '":@ID:"' deleted", "Delete Order")

* blank the fields, mark us as unchanged, and return to first tab

Gosub resetPages

End

 

* the following 2 controls are displayed on the "record has changed - do you want to discard these changes" dialog box

Case CtrlEntId _eqc "BTN_READ"

* yes, the user wants to discard any changes and load in the new record

O4WResponse()

* dismiss the dialog box

O4WDialog("specialDialog")

* retrieve their new ID

@ID = O4WGetValue("ONUM")

* load in the record

Gosub loadRecord

Case CtrlEntId _eqc "BTN_CANCEL_READ"

* no, the user does _not_ want to throw away their changes to the current record

O4WResponse()

* retrieve the original ID

origID = O4WGetValue("ID")

* dismiss the dialog box

O4WDialog("specialDialog")

* and just reset the value in the order number textbox

O4WUpdate("ONUM", origID, textReplace)

 

* this is generated when the 'search' button is pressed in one of the order detail lines

* the user is given a choice of search methods

Case CtrlEntId[1,16] _eqc "BTN_SEARCH_PROD_"

O4WResponse()

* determine which line the user was on (each button is identified with its line number)

whichOne = CtrlEntId[17, Len(CtrlEntId)]

* build a dialog box to ask what type of search to perform

O4WSectionStart("specialDialog", O4WResponseOptions())

* Note the button contains the line number (so we'll know what to update after the user makes their choice)

O4WButton("Search for product by text", "BTN_SEARCH3_PROD_":whichOne)

* associate an index lookup popup with this button

O4WPopup("Product Search", O4W_LINKTYPE_INDEXLOOKUP$, "", "PRODUCTS":@FM:"DESCRIPTION_XREF":@fm:"ID":@VM:"DESCRIPTION", "prodpopup2", "BTN_SEARCH3_PROD_":whichOne)

O4WText(" or ")

O4WButton("List all products", "BTN_SEARCH2_PROD_":whichOne)

* associate a regular popup with this button

O4WPopup("Product Search", O4W_LINKTYPE_POPUP$, "PRODUCT_POPUP", "", "prodpopup1", "BTN_SEARCH2_PROD_":whichOne)

* Provide a 'cancel' button to dismiss the dialog

O4WBreak()

O4WBreak()

O4WButton("Cancel", "BTN_DIALOG_CANCEL")

* Generate the 'click' event when it's pressed

O4WQualifyEvent("BTN_DIALOG_CANCEL", "CLICK")

O4WSectionEnd("specialDialog")

O4WDialog("specialDialog", "Product Search", '', '', 'width:550')

 

Case CtrlEntId _eqc "BTN_DIALOG_CANCEL"

O4WResponse()

* dismiss the dialog box

O4WDialog("specialDialog")

End Case

RETURN

 

RETURNVALUE_EVENT:

* The user has selected a value from a popup

O4WResponse()

* determine which control had the popup, and what the user selected

callingCtl = O4WGetValue('o4wPopupCtl')

popupValue = O4WGetValue('o4wValue')

Begin Case

Case callingCtl _eqc "BTN_SEARCH_ORDERS"

* this was the order search popup

* update the order number with the selected value

O4WUpdate("ONUM", popupValue, textReplace)

@ID = popupValue

* Fill in the rest of the form based on this record ID

* If "automatic lose focus" is not desired, disable the following line:

Gosub handleOrderNumber

Case callingCtl _eqc "BTN_SEARCH_CUST"

* this was the customer search popup

* update the customer number textbox with the selected value

* note the use of the "textReplaceTrigger" style - this not only replaces the text, but also triggers the "change" event

* the change event (previously defined) will derive the customer name from this value

O4WUpdate("OCUST", popupValue, textReplaceTrigger)

Case callingCtl[1,17] _eqc "BTN_SEARCH2_PROD_" Or callingCtl[1,17] _eqc "BTN_SEARCH3_PROD_"

* this was either of the 2 different product search popups (regular or index lookup)

* first, dismiss the dialog box that asked which type of search to use

O4WDialog("specialDialog")

* determine which line item in the order details called the popup

whichLine = callingCtl[18, Len(callingCtl)]

* update the product on that line of the order details, and trigger the "change" event for that item

O4WUpdate("ITEM_":whichLine, popupValue, textReplaceTrigger)

End case

RETURN
  • guides/o4w/examples/example_order.txt
  • Last modified: 2024/06/19 20:19
  • by 127.0.0.1