Function O4WI_FORMDESIGNER_TEMPLATE_XXX(ACTION, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, status) *#!Precompile /* * This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without * written permission from Revelation Technologies, Inc. ! * * VERSION : 1.0 * * * AUTHOR : Revelation Software, Inc. All Rights Reserved. * * CREATED : July 18, 2019 * * ! * * REVISION HISTORY (Most CURRENT first) : * * DATE IMPLEMENTOR FUNCTION * -------- ----------- -------- * */ * $Insert o4wcommon $Insert o4wequates $Insert O4W_COMMUTER_COMMON $Insert O4W_DESIGN_FORM_EQUATES Declare Function Repository, Function, RTI_VERIFY_PROC If Assigned(ACTION) Else ACTION = "" If Assigned(param1) Else param1 = "" If Assigned(param2) Else param2 = "" If Assigned(param3) Else param3 = "" If Assigned(param4) Else param4 = "" If Assigned(param5) Else param5 = "" If Assigned(param6) Else param6 = "" If Assigned(param7) Else param7 = "" If Assigned(param8) Else param8 = "" If Assigned(param9) Else param9 = "" If Assigned(param10) Else param10 = "" If Assigned(param11) Else param11 = "" If Assigned(status) Else status = "" RSLT = "" If Not(Num(ACTION)) Or ACTION < TEMPLATEWIDGET_ACTION_MIN_VALUE$ Or ACTION > TEMPLATEWIDGET_ACTION_MAX_VALUE$ Then rslt = WIDGET_ACTION_INVALID$ End Else On action Gosub doTemplateInfo,doQuickDraw,doCreate,doFormProperties End Return RSLT doTemplateInfo: * no parameters passed in param1 = "Example Code" rslt = "O4WI_FORMDESIGNER_TEMPLATE_XXX" ;* our ID Return doFormProperties: * passed headerInfo (if asked to draw the form for real) or nothing (if just getting the tab IDs and Name(s)) headerInfo = param1 * if we have any overall "form" properties we need for this type of form, we could add them here... If headerInfo = "" Then * looking for the name(s) and tab id(s) of the tab(s) we wish to add rslt<1> = ""; * tab id(s) (@VM delimited) rslt<2> = "" ;* tab name(s) (@VM delimited) End Else * actually draw the tab(s) End Return doQuickDraw: * passed table, fields, tableStyle, textfields, textSearch, textResults, formfields, tabInfo, searchFields, resultFields, metafields) table = param1 fields = param2 tableStyle = param3 textfields = param4 textSearch = param5 textResults = param6 formfields = param7 tabInfo = param8 searchFields = param9 resultFields = param10 metafields = param11 unselectedFields = Xlate("DICT.":table, "%FIELDS%", 3, "X") unselectedFields = Insert(unselectedFields, 1, 1, 0, "@ID") num.fields = dcount(fields, @VM) For each.Field = 1 To num.fields this.Field = fields<1, each.Field> Locate this.Field In unselectedFields<1> using @VM setting dummy Then unselectedFields = Delete(unselectedFields, 1, dummy, 0) End Next each.Field num.unselected = dcount(unselectedFields, @VM) tabOpts = " " tabOpts<2> = "0" tabOpts<1,-1> = "General":@VM:"Next Tab" tabOpts<2,-1> = "-1":@VM:"1" fieldTypes = "Textbox":@VM:"Listbox":@VM:"Checkbox":@VM:"Radio Buttons":@VM:"Text":@VM:"Date Picker":@VM:"Time Picker":@VM:"Toggle":@VM:"None/Not Used" fieldCodes = "1":@VM:"2":@VM:"3":@VM:"4":@VM:"5":@VM:"6":@VM:"7":@VM:"9":@VM:"0" helpID = 1 * draw our quickdraw tables in the qfMain section (if we have more than one page, use o4wtabs with qfMain being the "host" for the tabs) o4wsectionstart("qfMain") O4WHeader("Please select and re-order the form field(s)...", 5) helpText = "Please select the field(s) that you wish to display and/or allow the user to update. Also choose the type of element you wish to use for this field. " helpText := " For fields that offer multiple choices (like list boxes), you can choose the options once the form has been displayed." helpText:= " Arrange the fields in the order you wish them to be displayed; pay particular attention to keep associated multivalue fields together if you wish them to be placed into the same table." helpText:= "You can specify which tab the element should be placed on - the general tab is located above the individual tabs, or you can choose next tab to create a new tab. " helpText := " You can optionally suppress the use of tabs entirely if you wish." helpID += 1; Gosub addQFHelp O4WBreak() o4wtablestart("qfMainTable", tableStyle) o4wtableheader("Field") o4wtableheader("Field Type") o4wtableheader("Put in tab...") passedInfo = textFields; Gosub reArrangeFieldsForWizard For each.Field = 1 To num.sfields this.field = sortedfields<1, each.field> fieldType = formFields<1, each.Field> o4wsetcell(each.Field, 1) o4wtext(this.field) o4wstore(this.Field, "tForm") o4wsetcell() If fieldType = "" then fieldType = "1" dInfo = Xlate("DICT.":table, this.Field, "", "X") If dInfo = "" Then dInfo = Xlate("SYSDICT", this.Field, "", "X") end convCd = dInfo<7> Begin Case Case convCd[1,1] = "D" fieldType = "6" Case convCd[1,2] = "MT" fieldType = "7" Case convCd[1,1] = "B" fieldType = "9" *Case convCd[1,2] = "MR" * fieldType = "8" Case dInfo<1> <> "F" fieldType = "5" End Case end O4WLISTBOXSTART("ftype", "qfMainTable_":each.Field, o4wmarkedoptions("", fieldType)) o4wlistbox(fieldTypes, fieldCodes, "ftype") o4wlistboxend() o4wsetcell() this.tab = tabInfo<1, each.field> o4wlistbox(tabOpts<1>, tabOpts<2>, "ttype", "", "", o4wmarkedoptions("", this.tab)) O4WSetCell("+1") Next each.Field CNTR = num.sfields For each.Field = 1 To num.sunselected cntr+=1 o4wsetcell(cntr) o4wtablemodify(cntr, "", "unselected") this.field = sortedUnusedFields<1, each.field> o4wtext(this.field) o4wstore(this.Field, "tForm") o4wsetcell() O4WLISTBOXSTART("ftype", "qfMainTable_us":each.Field, o4wmarkedoptions("", "0")) o4wlistbox(fieldTypes, fieldCodes, "ftype") o4wlistboxend() o4wsetcell() o4wlistbox(tabOpts<1>, tabOpts<2>, "ttype") Next each.Field o4wsetcell("+1") o4wtableend("qfMainTable") o4wqualifyevent("$", "hide", ".unselected") o4wlink("Show/Hide additional fields", O4W_LINKTYPE_LOCAL$, "#", "", "BTN_TOGGLE") o4wqualifyevent("BTN_TOGGLE", "toggle", ".unselected") o4wbreak() o4wbreak() o4wbreak() o4wbreak() bNoTab = "" If tabInfo = "" And textFields <> "" Then bNoTab = "1" end o4wcheckbox("Don't use tabs", "1", "notabs", "notabs", o4wmarkedoptions(bNoTab)) o4wbreak() promptValue = metaFields<1,1> o4wlistboxstart("metaFields_prompt", "metaFields_prompt_main", o4wmarkedoptions("", promptValue)) o4wlistbox("Put labels next to fields", "prompt_sidexside", "metaFields_prompt") o4wlistbox("Put labels above fields", "prompt_overunder", "metaFields_prompt") o4wlistbox("Use inline prompts (suppress labels)", "prompt_inline", "metaFields_prompt") o4wlistboxend() o4wbreak() bClassic = metaFields<1,2> + 0 o4wcheckbox("Use 'classic' user interface on desktop", "use_classic", "metaFields_ui", "", o4wmarkedOptions(bClassic)) o4wsectionend("qfMain") Return doCreate: * generate the page(s) from the quickdraw results custom_names = "" custom_values = "" custom_names_label = "" custom_values_label = "" Gosub getLayoutValues cntr = 1 maxPage = 1 dim pages(5) mat pages = "" sectionIsMV = 0 linkURL = "" newTabList = "" tabList = "" bInDisplayPage = 0 copyright_text = "(c) ":Field(Oconv(DATE(), "D4/"), "/", 3) overrideLabels = "" makeSubsection = "" * passed newForm, table, varfields, formFields, searchFields, resultFields newForm = param1 table = param2 varfields=param3 formFields=param4 searchFields=param5 resultFields=param6 headerText = TABLE:" Entry Form" num.fields = dcount(varfields<1>, @VM) newForm = "Form Details" newForm = "details" currPage = 1 fields = varFields<1> * organize based on tab information Gosub orgTabs target = formFields<1> tabList = formFields<2> bInDisplayPage = 1 Gosub addFields * add in buttons to save/delete/cancel/etc. btnURL = "" row += 1 btnList = "" ourCol = 0 btnList<1,-1> = "Save" btnList<2,-1> = "BTN_SAVE" btnList<3,-1> = ourCol btnList<4,-1> = 0 ourCol += defGridWidth btnList<1,-1> = "Cancel" btnList<2,-1> = "BTN_CANCEL" btnList<3,-1> = ourCol btnList<4,-1> = 0 ourCol += defGridWidth this.field.name = copyright_text; Gosub addFooterWithButtons * wrap up the form definition newForm = cntr For each.page = 1 To maxPage newForm := @RM:pages(each.page) Next each.page rslt = newForm return addQFHelp: * passed helpText, helpID o4wbreak() o4wlink("Help...", O4W_LINKTYPE_LOCAL$, "#", "", "BTN_HELP":helpID) o4wtext("<<<":@VM, "help":helpID:"_b", "toggleMe":helpID) o4wtext(helpText:@VM:@VM, "help":helpID, "toggleMe":helpID) o4wqualifyevent("$", "hide", "help":helpID:"_b") o4wqualifyevent("$", "hide", "help":helpID) o4wqualifyevent("BTN_HELP":helpID, "toggle", ".toggleMe":helpID) o4wbreak() Return rearrangeFieldsForWizard: * passed: passedInfo (selected values - if any) * returns: updated sortedFields, sortedUnusedFields sortedFields = fields sortedUnusedFields = unselectedFields If passedInfo <> "" Then num.text = dcount(passedInfo, @VM) For each.text = 1 To num.text this.text = passedInfo<1, each.text> Locate this.text In sortedFields<1> using @VM setting dummy Then sortedFields = Delete(sortedFields, 1, dummy, 0) End Else Locate this.text In sortedUnusedFields<1> using @VM setting dummy Then sortedUnusedFields = Delete(sortedUnusedFields, 1, dummy, 0) End Next each.text If sortedFields <> "" Then sortedFields = passedInfo:@VM:sortedFields End Else sortedFields = passedInfo End end num.sFields = dcount(sortedFields, @VM) num.sUnselected = dcount(sortedUnusedFields, @VM) Return addFields: pages(currPage) = OVERALL_FORM_ID$:"_":currpage pages(currPage) = CONTROL_TYPE_DIV$ pages(currPage) = "0":@svm:"0":@svm:"12":@svm:"20" pages(currPage) = "0":@svm:"0" parent = "" tabParent = "" parentID = "" overallParent = OVERALL_FORM_ID$:"_":currpage currParent = overallParent lastTab = "" sizeStack = "" * Put up a header Gosub addHeader addFields2: * Now add in all the other fields assoc = "" row = 1 bDone = 0 If MakeSubSection <> "" Then * make a section, and put these fields inside of it Gosub addSubSection End num.fields = dcount(fields, @VM) For each.Field = 1 To num.fields this.Field.name = fields<1, each.Field> this.field.type = target<1, each.Field> this.field.label = overrideLabels<1, each.Field> this.tab = tabList<1, each.Field> dict.info = "" grid.width = defGridWidth If this.field.type <> "0" then If this.tab <> lastTab Then If parent <> "" Then * tables can't cross tabs - close out any pending table Gosub endTable parent = "" assoc = "" end If lastTab <> "" Then Gosub endSpecificTab End Else * first time through? create our parent element Gosub startTabs end lastTab = this.tab Gosub startSpecificTab currParent = specificTab end dict.info = Xlate("DICT.":table, this.field.name, "", "X") If this.field.label = "" Then this.field.label = dict.info<3> If this.field.label = "" Then this.field.label = this.field.name End end width = dict.info<10> + 0 If width = 0 Then width = 1 screen.part = int(80/width) grid.width = int(12 / screen.part) If grid.width < defGridWidth Then grid.width = defGridWidth end this.assoc = dict.info<36> isMV = 0 Begin Case Case sectionIsMV isMV = 1 Case dict.info<4> _eqc "M" And this.assoc <> "" isMV = 1 Case dict.info<4> _eqc "M" * no association name - is this a control type that supports MV fields? If this.field.type = "2" Or this.field.type = "3" Then * yes, this type can be MV "by itself", not in a table End Else isMV = 1 ;* this must be put in a table * don't let it be associated with anyone else, though this.assoc = this.field.name end End case if isMV Then If parent <> "" And this.assoc <> assoc And Not(sectionIsMV) Then * end the current table and begin a new one Gosub endTable parent = "" end If parent = "" Then * create new parent element Gosub startTable parent = tableID assoc = this.assoc End lPosn = "" ;* label handled specially here Gosub addTableColumn parentID = newColumnID * recalc our width now that we're in a table grid.width = int(12 / screen.part) If grid.width < defGridWidth Then grid.width = defGridWidth end end else parentID = currParent lPosn = newForm If parent <> "" Then * wrap up the parent element from the last MV Gosub endTable * recalc our width now that we're out of the table grid.width = int(12 / screen.part) If grid.width < defGridWidth Then grid.width = defGridWidth end end parent = "" End ourLink = "" ourLinkType = "" If bDone = 0 Then ourLink = linkURL ourLinkType = O4W_LINKTYPE_LOCAL$ End Gosub addField bDone = 1 end Next each.Field If parent <> "" Then * wrap up the parent element from the last MV Gosub endTable End If lastTab <> "" Then Gosub endSpecificTab End If tabParent <> "" Then * wrap up the tab element Gosub endTab End If makeSubSection <> "" Then Gosub endSection makeSubSection = "" end * set 'next posn' for the parent container pages(currPage) = ROW+1 Return addSubSection: * build a sub section of type "makeSubSection"; set our currParent to it parentID = currParent thisID = ELEMENT_PREFIX$:CNTR cntr += 1 bProtected = 0 prop_locn = "" prop_locn<1,1,FORMINFO_POSN_COL$> = "0" prop_locn<1,1,FORMINFO_POSN_ROW$> = row row += 1 prop_locn<1,1,FORMINFO_POSN_HEIGHT$> = DEFAULT_TABLE_HEIGHT$ ;* MAX_GRID_HEIGHT$ prop_locn<1,1,FORMINFO_POSN_WIDTH$> = MAX_GRID_WIDTH$ - 2 bDataBind = 0 type = makeSubSection lPlacement = WIDGET_LABEL_POSN_SXS$ promptText = "" addClass = "" addBefore = "" Gosub addElement saveSectionParent = parentID currParent = thisID parentID = currParent saveSectionRow = row row = 0 ourcol = 0 Return endSection: * make sure all section elements are updated row = saveSectionRow + DEFAULT_TABLE_HEIGHT$ ;* MAX_GRID_HEIGHT$ parentID = saveSectionParent currParent = saveSectionParent Return addField: * given this.field.name, this.field.type, dict.info, parentID, currPage, table, mode, maxID * populate pages(currPage) associated = "" bNeedLabel = 0 thisID = ELEMENT_PREFIX$:CNTR cntr += 1 bProtected = 0 prop_locn = "" lPlacement = newForm this.label = this.field.label convert @VM:@SVM:@TM to " " in this.label prop_locn<1,1,FORMINFO_POSN_COL$> = "0" prop_locn<1,1,FORMINFO_POSN_ROW$> = row prop_locn<1,1,FORMINFO_POSN_WIDTH$> = grid.width bDataBind = 1 ourHeight = defGridHeight Begin Case Case this.field.type = "0" * ignore this one return Case this.field.type = "1" * textbox and label bNeedLabel = 1 type = CONTROL_TYPE_INPUT_TEXT$ Case this.Field.type = "2" * listbox and label bNeedLabel = 1 type = CONTROL_TYPE_SELECT_MENU$ Case this.field.type = "3" * checkbox and label bNeedLabel = 0 ;* don't need label - we get the field set type = CONTROL_TYPE_CHECK_SET$ ourHeight = 3 Case this.field.type = "4" * radio button and label bNeedLabel = 0 ;* don't need label - we get the field set type = CONTROL_TYPE_RADIO_SET$ ourHeight = 3 Case this.field.type = "5" * plain text bNeedLabel = 1 this.label = "^" ;* just show the current value type = CONTROL_TYPE_TEXT$ Case this.field.type = "6" * date picker bNeedLabel = 1 type = CONTROL_TYPE_DATEPICKER$ conv = dict.info<7> delimChar = "" euroFlag = "" If conv[1,1] = "D" Then * do we have a delimiter? delim = "" ccntr = 2 next.char = conv[2,1] If next.char <> "E" And Num(next.char) Then ccntr = 3 next.char = conv[3,1] End If Not(Index("EFGHIJQWASML",NEXT.CHAR,1)) And next.char <> "" Then * yes, this is a delimiter delimChar = next.char ccntr += 1 End If conv[ccntr,1] = "E" Then * European format euroFlag = "1" End End If delimChar <> "" Then custom_names<-1> = WIDGET_MSG_DATE_DELIM$ custom_values<-1> = delimChar End If euroFlag <> "" Then custom_names<-1> = WIDGET_MSG_DATE_EURO$ custom_values<-1> = euroFlag end Case this.field.type = "7" * time picker bNeedLabel = 1 type = CONTROL_TYPE_TIMEPICKER$ show24 = "" showSeconds = "" conv = dict.info<7> If conv[1,2] = "MT" then If indexc(conv, "H", 1) = 0 then * not in 12 hour format - allow for 24 hour def'n show24 = "1" End If indexc(conv, "S", 1) Then * show seconds too showSeconds = "1" End end If show24 <> "" Then custom_names<-1> = WIDGET_MSG_TIME_24HR$ custom_values<-1> = show24 End If showSeconds <> "" Then custom_names<-1> = WIDGET_MSG_TIME_SECONDS$ custom_values<-1> = showSeconds end Case this.field.type = "8" * NOT USED *bNeedLabel = 1 *type = CONTROL_TYPE_INPUT_NUMBER$ Case this.field.type = "9" * toggle bNeedLabel = 0 type = CONTROL_TYPE_M_TOGGLE$ ourHeight = 3 Case this.field.type = "10" * button bNeedLabel = 0 type = CONTROL_TYPE_BUTTON$ Case this.field.type = "11" * file upload bNeedLabel = 1 type = CONTROL_TYPE_INPUT_FILE$ Case this.field.type = "12" * text area bNeedLabel = 1 type = CONTROL_TYPE_INPUT_AREA$ Case this.field.type = "13" * color picker bNeedLabel = 1 type = CONTROL_TYPE_COLORPICKER$ Case this.field.type = "14" * password and label bNeedLabel = 1 type = CONTROL_TYPE_INPUT_TEXT$ custom_names<-1> = WIDGET_MSG_SPECIAL_STYLE$ custom_values<-1> = "password" Case this.field.type = "15" * hidden field bNeedLabel = 0 type = CONTROL_TYPE_INPUT_TEXT$ custom_names<-1> = WIDGET_MSG_SPECIAL_STYLE$ custom_values<-1> = "hidden" Case this.field.type = "16" * image bNeedLabel = 1 type = CONTROL_TYPE_IMAGE$ End Case If IsMV Then * never show label for MV fields - already done in table bNeedLabel = 0 lPlacement = WIDGET_LABEL_POSN_NONE$ End promptText = "" addClass = "" If lPlacement = WIDGET_LABEL_POSN_INLINE$ Then bNeedLabel = 0 promptText = this.label End row += ourHeight prop_locn<1,1,FORMINFO_POSN_HEIGHT$> = ourHeight addBefore = "" Gosub addElement2 ;* we already have our label If bNeedLabel Then posn = newposn ;* remember the location of our data element custom_names = custom_names_label custom_values = custom_values_label elementID = thisID associated = thisID ;* mark the label's associated field bDataBind = 0 Gosub createLabel end Return AddElement: this.label = this.field.label convert @VM:@SVM:@TM to " " in this.label AddElement2: * entry point if this.label is already set names = "" values = "" names<1> = WIDGET_MSG_LABEL$ values<1> = this.label names<2> = WIDGET_MSG_LINK$ If ourLink <> "" Then values<2> = "1" names<3> = WIDGET_MSG_LINK_URL$ values<3> = ourLink names<4> = WIDGET_MSG_LINK_TYPE$ values<4> = ourLinkType End Else values<2> = "0" End names<-1> = WIDGET_MSG_LABEL_PLACEMENT$ VALUES<-1> = lPlacement this.size = dict.info<10> If this.size <> "" then names<-1> = WIDGET_MSG_SIZE$ values<-1> = this.size end If bDataBind Then If table <> "" then names<-1> = WIDGET_MSG_DB_TABLE$ values<-1> = table End If this.field.name <> "" then names<-1> = WIDGET_MSG_DB_FIELD$ values<-1> = this.field.name names<-1> = WIDGET_MSG_NAME$ values<-1> = this.field.name end names<-1> = WIDGET_MSG_DB_RO$ isRO = 0 If (dict.info<1> _eqc "S") And bInDisplayPage Then isRO = 2 ;* make it unchangeable end values<-1> = isRO If dict.info<4> _eqc "M" then names<-1> = WIDGET_MSG_DB_MV$ values<-1> = "1" end names<-1> = WIDGET_MSG_SET_SHOWNONE$ values<-1> = Not(bInDisplayPage) names<-1> = WIDGET_MSG_CONTROL_ALIGN$ values<-1> = "0" ;* assume all controls will left align names<-1> = WIDGET_MSG_FONT_ALIGN$ align = "0" If dict.info<9> = "R" Then align = "2" End Else If dict.info<9> = "C" Or dict.info<9> = "T" Then align = "1" end values<-1> = align If promptText <> "" Then names<-1> = WIDGET_MSG_PROMPT$ values<-1> = promptText End If addClass <> "" Then names<-1> = WIDGET_MSG_CLASS_ADD$ values<-1>= addClass end End names<-1> = custom_names values<-1> = custom_values custom_names = "" custom_values = "" newForm = cntr ;* make sure this is up to date newPosn = o4wi_formdesigner_widget_new(newForm, pages(currPage), thisID, parentID, type, prop_locn, associated, bProtected, addBefore, names, values) * maxID may have changed - be sure to refresh it cntr = newForm Return createLabel: * create the label element If lPosn = "" Then Return ;* don't put the label element on at all thisID = ELEMENT_PREFIX$:CNTR cntr += 1 TYPE = CONTROL_TYPE_TEXT$ prop_locn = pages(currPage) ;* let the label assume the 'landing position' from the user aelement_locn = prop_locn If lPosn = WIDGET_LABEL_POSN_SXS$ Then * side-by-side * Change the size of the label so it's "standard size" prop_locn<1,1,FORMINFO_POSN_WIDTH$> = defGridWidth ;* so everything lines up in the columns * now move the associated element so it's in the right place aelement_locn<1,1, FORMINFO_POSN_COL$> = prop_locn<1,1, FORMINFO_POSN_COL$> + defGridWidth End Else * over/under aelement_locn<1,1, FORMINFO_POSN_ROW$> = prop_locn<1,1, FORMINFO_POSN_ROW$> + prop_locn<1,1,FORMINFO_POSN_HEIGHT$> * adjust our "next position to use" row += prop_locn<1,1,FORMINFO_POSN_HEIGHT$> * and finally set our height to 1 (by default the label should only be 1 high) aelement_locn<1,1,FORMINFO_POSN_HEIGHT$> = 1 End pages(currPage) = aelement_locn bProtected = 0 lPlacement = lPosn promptText = "" addClass = "" addBefore = "1" Gosub addElement pages(currPage) = thisID ;* tell our associated control who we are pages(currPage) = "2" ;* and that they are the "master" Return startTable: * create new table element as parent For these parentID = currParent thisID = ELEMENT_PREFIX$:CNTR cntr += 1 bProtected = 0 prop_locn = "" prop_locn<1,1,FORMINFO_POSN_COL$> = "0" prop_locn<1,1,FORMINFO_POSN_ROW$> = row row += 1 prop_locn<1,1,FORMINFO_POSN_HEIGHT$> = DEFAULT_TABLE_HEIGHT$ ;* MAX_GRID_HEIGHT$ prop_locn<1,1,FORMINFO_POSN_WIDTH$> = MAX_GRID_WIDTH$ - 2 bDataBind = 0 tableID = thisID type = CONTROL_TYPE_TABLE$ lPlacement = WIDGET_LABEL_POSN_SXS$ promptText = "" addClass = "" addBefore = "" Gosub addElement If sectionIsMV = 2 Then * mark this as a multiRecord table names = WIDGET_MSG_TBL_TYPE$ values = "2" Gosub updateTable End saveTableRow = row sizeStack = Insert(sizeStack, 1, 0, 0, defGridWidth) defGridWidth = MAX_GRID_WIDTH$ - 2 Return addTableColumn: * add a new child div To the parent table newColName = this.field.label convert @VM:@SVM:@TM to " " in newColName newColumnID = "" names = "" values = "" names<1> = WIDGET_MSG_TBL_COLUMN_ADD$ values<1> = newColName newForm = cntr ;* make sure this is up to date Gosub updateTable * maxID may have changed - be sure to refresh it cntr = newForm * return our new column ID newColumnID = pInfo * make sure our children are full sized defGridWidth = MAX_GRID_WIDTH$ - 2 * And reset our row to the top of the column row = 0 Return updateTable: * let the element update itself supportName = UCASE(DESIGN_SUPPORT_PREFIX$:CONTROL_TYPE_TABLE$) IF RTI_VERIFY_PROC(supportName, 0, 5) = 0 THEN * failed CALL SET_STATUS(0) END Else pInfo = Function(@supportName(WIDGET_ACTION_UPDATE$, newForm, pages(currPage), tableID, "", names, values)) End return endTable: * make sure all table elements are updated row = saveTableRow + DEFAULT_TABLE_HEIGHT$ ;* MAX_GRID_HEIGHT$ defGridWidth = sizeStack<1> sizeStack = Delete(sizeStack, 1, 0, 0) Return addButton: * passed btn (text), btnID, btnURL (optional), ourCol, Row, btnType parentID = OVERALL_FORM_ID$:"_":currpage addButton2: * entry point for different parents type = btnType thisID = ELEMENT_PREFIX$:CNTR cntr += 1 bProtected = 0 prop_locn = "" prop_locn<1,1,FORMINFO_POSN_COL$> = ourCol prop_locn<1,1,FORMINFO_POSN_ROW$> = row prop_locn<1,1,FORMINFO_POSN_HEIGHT$> = defGridHeight prop_locn<1,1,FORMINFO_POSN_WIDTH$> = defGridWidth bDataBind = 0 associated = "" lPlacement = WIDGET_LABEL_POSN_SXS$ promptText = "" addClass = "" addBefore = "" Gosub addElement * let the element update itself supportName = UCASE(DESIGN_SUPPORT_PREFIX$:type) IF RTI_VERIFY_PROC(supportName, 0, 5) = 0 THEN CALL SET_STATUS(0) END Else names = "" values = "" names<1> = WIDGET_MSG_LABEL$ values<1> = btn names<2> = WIDGET_MSG_LINK$ If btnURL = "" Then values<2> = 0 End else values<2> = 1 names<3> = WIDGET_MSG_LINK_URL$ values<3> = btnURL names<4> = WIDGET_MSG_LINK_TYPE$ values<4> = O4W_LINKTYPE_LOCAL$ End names<-1> = WIDGET_MSG_BTN_DEFAULT$ values<-1> = bDefault newForm = cntr ;* make sure this is up to date pInfo = Function(@supportName(WIDGET_ACTION_UPDATE$, newForm, pages(currPage), thisID, "", names, values)) * maxID may have changed - be sure to refresh it cntr = newForm end Return orgTabs: * reorganize fields so that each tab is sequential In the list * passed: fields, formFields<1> (field types) and formFields<2> (tabs) * sets newTabList, updates formFields, updates fields num.names = dcount(fields, @VM) formTypes = formFields<1> tabList = formFields<2> If tablist = "" Or tablist = str("0":@VM, num.names-1):"0" then * nothing to do here - no tabs formFields<2> = "" Return End newTabList = "" currTabNum = 0 For each.name = 1 To num.names this.name = fields<1, each.name> this.tab = tabList<1, each.name> this.type = formTypes<1, each.name> Begin Case Case this.tab = "0" And newTabList <> "" * unchanged tabNum = currTabNum Case this.tab = "-1" * general TabNum = -1 currTabNum = tabNum Case this.tab = "1" Or newTabList = "" * new tab currTabNum += 1 tabNum = currTabNum End Case Locate tabNum In newTabList<1> by "AR" using @VM setting posn then newTabList<2, posn, -1> = this.name newTabList<3,posn,-1> = this.type End Else newTabList = Insert(newTabList, 1, posn, 0, tabNum) newTabList = Insert(newTabList, 2, posn, 0, this.name) newTabList = Insert(newTabList, 3, posn, 0, this.type) End Next each.name * rebuild the list num.tabs = dcount(newTabList<1>, @VM) nlist = "" list1 = "" list2 = "" tabcntr = 1 For each.tab = 1 To num.tabs this.tab = newTabList<1, each.tab> If this.tab = "-1" Then this.tab = "" End Else this.tab = "Tab ":tabcntr tabcntr += 1 End these.names = newTabList<2, each.tab> these.types = newTabList<3, each.tab> num.names = dcount(these.names, @SVM) Convert @SVM To @VM In these.names Convert @SVM To @VM In these.types nList := these.names:@VM list1 := these.types:@VM list2 := str(this.tab:@VM, num.names) Next each.tab formFields<1> = list1[1, Len(list1)-1] formFields<2> = list2[1, Len(list2)-1] fields = nList[1, Len(nList)-1] Return startTabs: * determine number of tabs, And create parent And children tab elements * passed tabList, newTabList * sets tabParent parentID = currParent thisID = ELEMENT_PREFIX$:CNTR cntr += 1 bProtected = 0 prop_locn = "" prop_locn<1,1,FORMINFO_POSN_COL$> = "0" prop_locn<1,1,FORMINFO_POSN_ROW$> = row row += 1 prop_locn<1,1,FORMINFO_POSN_HEIGHT$> = MAX_GRID_HEIGHT$ prop_locn<1,1,FORMINFO_POSN_WIDTH$> = MAX_GRID_WIDTH$-2 bDataBind = 0 tableID = thisID type = CONTROL_TYPE_TAB$ lPlacement = WIDGET_LABEL_POSN_SXS$ promptText = "" addClass = "" addBefore = "" Gosub addElement tabParent = thisID currParent = thisID savedRow = row Return Return startSpecificTab: * create child tab element * passed lastTab, sets specificTab * let the element update itself supportName = UCASE(DESIGN_SUPPORT_PREFIX$:CONTROL_TYPE_TAB$) IF RTI_VERIFY_PROC(supportName, 0, 5) = 0 THEN * failed CALL SET_STATUS(0) END Else newForm = cntr ;* make sure this is up to date names = WIDGET_MSG_TBL_COLUMN_ADD$ values = lastTab pInfo = Function(@supportName(WIDGET_ACTION_UPDATE$, newForm, pages(currPage), tabParent,"", names, values)) * maxID may have changed - be sure to refresh it cntr = newForm * return our new column ID specificTab = pInfo * and reset our position to top row row = 0 End Return endSpecificTab: * close child tab element * passed lastTab row = savedRow + MAX_GRID_HEIGHT$ Return endTab: * close overall tab element * passed tabParent row = savedRow + MAX_GRID_HEIGHT$ Return getLayoutValues: call Set_Status(0) layoutInformation = Repository("ACCESS", @APPID<1>:"*APPROW**O4WCODES:FORMDESIGNER_LAYOUT") call Set_Status(0) If layoutInformation = "" Then layoutInformation = Xlate("O4WCODES", "FORMDESIGNER_LAYOUT", "", "X") End maxGridWidth = layoutInformation If maxGridWidth = "" Then maxGridWidth = MAX_GRID_WIDTH$ End maxGridHeight = layoutInformation If maxGridHeight = "" Then maxGridHeight = MAX_GRID_HEIGHT$ End defGridWidth = layoutInformation If defGridWidth = "" Then defGridWidth = DEFAULT_GRID_WIDTH$ End defGridHeight = layoutInformation If defGridHeight = "" Then defGridHeight = DEFAULT_GRID_HEIGHT$ End defGridContainerWidth = layoutInformation If defGridContainerWidth = "" Then defGridContainerWidth = DEFAULT_GRID_CONTAINER_WIDTH$ End defGridContainerHeight = layoutInformation If defGridContainerHeight = "" Then defGridContainerHeight = DEFAULT_GRID_CONTAINER_HEIGHT$ End cellHeight = layoutInformation If cellHeight = "" Then cellHeight = DEFAULT_GRID_CELL_HEIGHT$ End Return addFooterWithButtons: * btnList<1,x> = list of button text * btnList<2,x> = associated list of button IDs * btnList<3,x> = associated list of button positions * btnList<4,x> = associated list of "is default button?" flags * this.field.name = footer text * first, create the mobile footer itself save.defGridHeight = defGridHeight defGridHeight = 2 * defGridHeight footer.text = this.field.name this.field.name = "" ;* create without any header text Gosub addFooter2 footerID = thisID defGridHeight = save.defGridHeight * save all the 'real' values save.parentID = parentID save.parent = parent save.tabParent = tabParent save.overallParent = overallParent save.currParent = currParent save.lastTab = lastTab save.row = row * next, make a 'button set' to hold the buttons parentID = footerID type = CONTROL_TYPE_BUTTON_SET$ associated = "" thisID = ELEMENT_PREFIX$:CNTR cntr += 1 bProtected = 0 prop_locn = "" prop_locn<1,1,FORMINFO_POSN_COL$> = "0" prop_locn<1,1,FORMINFO_POSN_ROW$> = 0 prop_locn<1,1,FORMINFO_POSN_HEIGHT$> = defGridHeight prop_locn<1,1,FORMINFO_POSN_WIDTH$> = maxGridWidth this.field.value = "" dict.info = "" dict.info<10> = 5 isMV = 0 bDataBind = 0 ourLink = "" ourLinkType = "" lPlacement = WIDGET_LABEL_POSN_SXS$ promptText = "" addClass = "" addBefore = "" this.field.label = "" Gosub addElement bsetID = thisID * next, put our buttons inside parentID = bsetID row = 0 btnType = CONTROL_TYPE_BUTTON$ num.buttons = dcount(btnList<1>, @VM) save.defGridWidth = defGridWidth defGridWidth = int(maxGridWidth / num.buttons) ourCol = 0 For each.btn = 1 To num.buttons btn = btnList<1, each.btn> btnID = btnList<2, each.btn> * ourCol = btnList<3, each.btn> bDefault = btnList<4, each.btn> Gosub addButton2 ourCol += defGridWidth Next each.btn defGridWidth = save.defGridWidth * finally, put an explicit header inside parentID = footerID type = CONTROL_TYPE_HEADER$ associated = "" thisID = ELEMENT_PREFIX$:CNTR cntr += 1 bProtected = 0 prop_locn = "" prop_locn<1,1,FORMINFO_POSN_COL$> = "0" prop_locn<1,1,FORMINFO_POSN_ROW$> = 1 prop_locn<1,1,FORMINFO_POSN_HEIGHT$> = defGridHeight prop_locn<1,1,FORMINFO_POSN_WIDTH$> = maxGridWidth this.field.value = "" dict.info = "" dict.info<10> = 5 isMV = 0 bDataBind = 0 ourLink = "" ourLinkType = "" lPlacement = WIDGET_LABEL_POSN_SXS$ promptText = "" addClass = "" addBefore = "" this.field.label = footer.text Gosub addElement * restore everything parentID = save.parentID parent = save.parent tabParent = save.tabParent overallParent = save.overallParent currParent = save.currParent lastTab = save.lastTab row = save.row return addFooter: * add in a footer section this.field.name = copyright_text addFooter2: hfRow = row + 5 If hfRow < MAX_GRID_HEIGHT$ Then hfRow = MAX_GRID_HEIGHT$ end hfSize = 5 type = CONTROL_TYPE_M_FOOTER$ custom_names<1,-1> = WIDGET_MSG_MOB_FIXED$ custom_values<1,-1> = "1" Goto addHeaderFooter addHeader: this.field.name = headerText hfRow = "0" hfSize = "3" type = CONTROL_TYPE_M_HEADER$ * fall through addHeaderFooter: * passed type, hfRow, hfSize, this.field.name save.parentID = parentID save.parent = parent save.tabParent = tabParent save.overallParent = overallParent save.currParent = currParent save.lastTab = lastTab associated = "" parentID = OVERALL_FORM_ID$:"_":currpage thisID = ELEMENT_PREFIX$:CNTR cntr += 1 bProtected = 0 prop_locn = "" prop_locn<1,1,FORMINFO_POSN_COL$> = "0" prop_locn<1,1,FORMINFO_POSN_ROW$> = hfRow prop_locn<1,1,FORMINFO_POSN_HEIGHT$> = defGridHeight prop_locn<1,1,FORMINFO_POSN_WIDTH$> = maxGridWidth this.field.value = "" dict.info = "" dict.info<10> = hfSize isMV = 0 bDataBind = 0 ourLink = "" ourLinkType = "" lPlacement = WIDGET_LABEL_POSN_SXS$ promptText = "" addClass = "" addBefore = "" this.field.label = this.field.name Gosub addElement parentID = save.parentID parent = save.parent tabParent = save.tabParent overallParent = save.overallParent currParent = save.currParent lastTab = save.lastTab Return