# Property of Four Js* # (c) Copyright Four Js 1995, 2019. All Rights Reserved. # * Trademark of Four Js Development Tools Europe Ltd # in the United States and elsewhere # # Four Js and its suppliers do not warrant or guarantee that these # samples are accurate and suitable for your purposes. Their inclusion is # purely for information purposes only. IMPORT FGL CityList IMPORT FGL OrderInput IMPORT FGL MsgBox GLOBALS "Globals.4gl" CONSTANT mytitle = "Customer" DEFINE myd ui.Dialog DEFINE cust_new INT MAIN DEFINE deleted INT DEFINE oldcust custrec OPTIONS INPUT WRAP OPEN FORM f_cust FROM "CustOrders3" DISPLAY FORM f_cust CALL cust_loadlist(9) DIALOG ATTRIBUTES(FIELD ORDER FORM, UNBUFFERED) INPUT ARRAY customers FROM custrec.* ATTRIBUTES(INSERT ROW=0) BEFORE ROW CALL order_of_cust(arr_curr()) CALL cust_setup(0) LET oldcust.*=customers[arr_curr()].* AFTER FIELD cust_name IF customers[arr_curr()].cust_name MATCHES "*[@#$%^&]*" THEN ERROR "The customer name contains invalid characters." NEXT FIELD cust_name END IF AFTER FIELD cust_address IF NOT cust_check_address(customers[arr_curr()].cust_address) THEN NEXT FIELD cust_address END IF BEFORE INSERT LET cust_new=1 CALL cust_setup(0) LET oldcust.*=customers[arr_curr()].* CALL order_of_cust(arr_curr()) AFTER ROW --be aware of the temp row... IF arr_curr()<= arr_count() AND NOT deleted THEN IF customers[arr_curr()].cust_city IS NULL AND customers[arr_curr()].cust_zipcode IS NOT NULL THEN ERROR "You must specify a city because zipcode is not null." NEXT FIELD cust_city END IF IF FIELD_TOUCHED(custrec.*) THEN IF cust_new THEN --INSERT INTO .... DISPLAY sfmt("INSERT into DB for name:%1",customers[arr_curr()].cust_name) MESSAGE sfmt("INSERT into DB for name:%1",customers[arr_curr()].cust_name) ELSE --UPDATE DISPLAY sfmt("UPDATE DB for name:%1",customers[arr_curr()].cust_name) MESSAGE sfmt("UPDATE DB for name:%1",customers[arr_curr()].cust_name) END IF IF customers[arr_curr()].cust_name="err" THEN --simulate error CALL mbox_ok("Error","Can't write record to DB","stop") NEXT FIELD cust_name END IF END IF END IF LET deleted=0 LET cust_new=0 BEFORE DELETE IF NOT cust_new THEN IF NOT mbox_yn(mytitle,"Delete current customer?","question") THEN CANCEL DELETE ELSE DISPLAY "DELETE from DB" MESSAGE "DELETED from DB:",customers[arr_curr()].cust_name END IF END IF AFTER DELETE LET deleted=1 CALL cust_setup(0) ON ACTION zoom_city CALL cust_zoom_city() ON ACTION undo DISPLAY BY NAME oldcust.* LET customers[arr_curr()].* = oldcust.* CALL DIALOG.setFieldTouched("custrec.*",FALSE) CALL cust_setup(0) ON ACTION dialogtouched CALL cust_setup(1) END INPUT DISPLAY ARRAY orders TO ordlist.* BEFORE ROW MESSAGE SFMT("Order record %1 / %2", ARR_CURR(), ARR_COUNT()) ON ACTION append CALL ord_append() ON ACTION ord_modify CALL ord_modify() ON ACTION delete CALL ord_delete() END DISPLAY BEFORE DIALOG LET myd=DIALOG ON ACTION cancel IF FIELD_TOUCHED(custrec.*) THEN CASE mbox_ync(mytitle,"Save your changes?","question") WHEN 1 --yes ACCEPT DIALOG --go thru the validation WHEN 2 --no EXIT DIALOG WHEN 3 --cancel CONTINUE DIALOG END CASE END IF EXIT DIALOG END DIALOG LET myd=NULL END MAIN FUNCTION cust_setup(touched) DEFINE touched INT --because the dialogtouched/undo action is only defined in the INPUT ARRAY --may run into an error if we try them to switch off in another context CALL myd.setActionActive("dialogtouched",NOT touched) CALL myd.setActionActive("undo", touched) IF cust_new THEN DISPLAY "Input new customer" TO cust_info ELSE DISPLAY SFMT("Customer record %1 / %2",c_arr_curr(),customers.getLength()) TO cust_info END IF END FUNCTION FUNCTION c_arr_curr() RETURN myd.getCurrentRow("custrec") END FUNCTION FUNCTION o_arr_curr() RETURN myd.getCurrentRow("ordlist") END FUNCTION FUNCTION cust_zoom_city() DEFINE s INTEGER DEFINE name, state STRING CALL select_city(myd.getFieldBuffer("cust_city")) RETURNING s, name, state IF s==0 THEN LET customers[c_arr_curr()].cust_city = name LET customers[c_arr_curr()].cust_state = state CALL myd.setFieldTouched("cust_city",TRUE) CALL myd.setFieldTouched("cust_state",TRUE) CALL cust_setup(1) END IF END FUNCTION FUNCTION cust_verify_address_format(value) DEFINE value STRING DEFINE num STRING, p,x INTEGER IF value IS NULL THEN RETURN TRUE END IF LET p = value.getIndexOf(",", 1) IF p == 0 THEN RETURN FALSE END IF LET num = value.subString(1, p) LET x = num IF x <= 0 THEN RETURN FALSE END IF IF value.getLength() <= p THEN RETURN FALSE END IF RETURN TRUE END FUNCTION FUNCTION cust_check_address(value) DEFINE value STRING IF NOT cust_verify_address_format(value) THEN CALL mbox_ok(mytitle,"Address must hold a number followed by a comma and the street name.","stop") RETURN FALSE END IF RETURN TRUE END FUNCTION FUNCTION order_of_cust(index) DEFINE index INTEGER --MESSAGE SFMT("Customer: %1/%2", cust_curr, customers.getLength()) IF cust_new THEN CALL orders.clear() ELSE CALL ord_loadlist(customers[index].cust_id, (index mod 5) * 3) END IF END FUNCTION -- Dummy function to fill the list of customers (normally, SELECT from database) FUNCTION cust_loadlist(m) DEFINE m,i INTEGER CALL customers.clear() FOR i=1 TO m LET customers[i].cust_id = i LET customers[i].cust_name = "Name " || i LET customers[i].cust_state = "CA" LET customers[i].cust_city = "San Fransisco" LET customers[i].cust_zipcode = 94102 LET customers[i].cust_address = "52, Marlon Street" LET customers[i].cust_checked = i mod 2 END FOR END FUNCTION FUNCTION ord_loadlist(mid,m) DEFINE mid,m,i INTEGER CALL orders.clear() FOR i=1 TO m CALL orders.appendElement() LET orders[i].ord_id = mid * 100 + i LET orders[i].ord_crea = CURRENT YEAR TO SECOND LET orders[i].ord_amount = ( i mod 5 ) * 133.56 END FOR END FUNCTION FUNCTION ord_append() DEFINE r INT LET r=c_arr_curr() CALL ord_input('A', customers[r].cust_id, customers[r].cust_name, 0) END FUNCTION FUNCTION ord_modify() DEFINE r INT LET r=c_arr_curr() IF o_arr_curr()==0 THEN RETURN END IF CALL ord_input('M', customers[r].cust_id, customers[r].cust_name, orders[o_arr_curr()].ord_id) END FUNCTION FUNCTION ord_delete() IF NOT mbox_yn(mytitle,"Delete select order from database?","question") THEN RETURN END IF CALL myd.deleteRow("ordlist",o_arr_curr()) END FUNCTION FUNCTION combo_fill_states(cb) DEFINE cb ui.ComboBox CALL cb.addItem("AK","Alaska") CALL cb.addItem("AL","Alabama") CALL cb.addItem("AR","Arkansas") CALL cb.addItem("AZ","Arizona") CALL cb.addItem("CA","California") CALL cb.addItem("CO","Colorado") CALL cb.addItem("CT","Connecticut") CALL cb.addItem("DC","D.C.") CALL cb.addItem("DE","Delaware") CALL cb.addItem("FL","Florida") CALL cb.addItem("GA","Georgia") CALL cb.addItem("HI","Hawaii") CALL cb.addItem("IA","Iowa") CALL cb.addItem("ID","Idaho") CALL cb.addItem("IL","Illinois") CALL cb.addItem("IN","Indiana") CALL cb.addItem("KS","Kansas") CALL cb.addItem("KY","Kentucky") CALL cb.addItem("LA","Louisiana") CALL cb.addItem("MA","Massachusetts") CALL cb.addItem("MD","Maryland") CALL cb.addItem("ME","Maine") CALL cb.addItem("MI","Michigan") CALL cb.addItem("MN","Minnesota") CALL cb.addItem("MO","Missouri") CALL cb.addItem("MS","Mississippi") CALL cb.addItem("MT","Montana") CALL cb.addItem("NC","North Carolina") CALL cb.addItem("ND","North Dakota") CALL cb.addItem("NE","Nebraska") CALL cb.addItem("NH","New Hampshire") CALL cb.addItem("NJ","New Jersey") CALL cb.addItem("NM","New Mexico") CALL cb.addItem("NV","Nevada") CALL cb.addItem("NY","New York") CALL cb.addItem("OH","Ohio") CALL cb.addItem("OK","Oklahoma") CALL cb.addItem("OR","Oregon") CALL cb.addItem("PA","Pennsylvania") CALL cb.addItem("PR","Puerto Rico") CALL cb.addItem("RI","Rhode Island") CALL cb.addItem("SC","South Carolina") CALL cb.addItem("SD","South Dakota") CALL cb.addItem("TN","Tennessee") CALL cb.addItem("TX","Texas") CALL cb.addItem("UT","Utah") CALL cb.addItem("VA","Virginia") CALL cb.addItem("VT","Vermont") CALL cb.addItem("WA","Washington") CALL cb.addItem("WI","Wisconsin") CALL cb.addItem("WV","West Virginia") CALL cb.addItem("WY","Wyoming") END FUNCTION