O4W Mobile

Applications developed for mobile devices, such as smartphones or tablets, must use different user interface elements that are easier to view and manipulate on the smaller screens of these devices. O4W will automatically convert most user interface elements to more mobile-appropriate ones when your application indicates that it is in “mobile mode” (through the use of the O4WSetMobile API). However, there are additional design changes, and additional API calls, required in your O4W custom stored procedures to fully support the mobile interface.

An example of O4W output that has been optimized for mobile devices might be:

The same output, with the O4W mobile optimizations disabled, would display as:

Mobile Page Design

When using O4W to generate desktop browser output, you normally organize your application using “sections” (defined inside the O4WSectionStart and O4WSectionEnd API calls). Similarly, when using O4W to generate mobile output, your program will rely heavily on sections; in addition, though, you must now indicate the “role” that each section will have.

The output for the mobile device is divided into a series of sections, with each different page to be displayed generated by a section identified with the “page” role. Inside the page section, you can define headers, footers, and toolbars, each identified by the appropriate role (header, footer, and toolbar). By marking the sections with their appropriate role, O4W can “redesign” the output as appropriate for the mobile device.

You indicate the role of a section through the O4WMobileOptions() API call. Other user elements as well (for example, links) can have their “role” set via O4WMobileOptions, and will thus appear more appropriately in the mobile output.

For example, a simple mobile page could be generated with the following O4W code:

                        * turn our "we're a mobile app" flag

                        o4wSetMobile(1)

                        * use our blank template

                        o4wform("blank")

                       

                        * start a "page" of content, using theme "b"

                        O4WSectionStart("MainMenu", O4WMobileOptions("page", "b"))

                       

                                    * set up a header section

                                    O4WsectionStart("headerSection", O4WMobileOptions(O4W_ROLE_HEADER$))

                                                O4WSectionStart("headerInsideSection")

                                                            o4wimage("Revelation Logo", "../revmobile_images/revlogo.png", "", "", "", "", O4WPositionStyle("", "", "", "", "left"))

                                                            O4WHeader("Revelation Software":@vm:" Mobile", 3, "", O4WAlignStyle("","1"))

                                                O4WSectionEnd("headerInsideSection")

                                    O4WSectionEnd("headerSection")

                       

                                    * build a navbar section

                                    O4WSectionStart("NavBar", O4WMobileOptions("navbar"))

                                    * the navbar is a list of links, so start the list

                                                O4WListStart("0", "navlist")

                                                            O4WListItem()

                                                            O4WLink("Works Login", O4W_LINKTYPE_NORMAL$, "http://www.revelation.com/revelation.nsf/byTitle/Registration+Entry?Open&Login") ;*, "", "", O4WMobileOptions("button"))

                                                            O4WListItem()

                                                            O4WLink("Revelation.com", O4W_LINKTYPE_NORMAL$, "http://www.revelation.com") ;*, "", "", O4WMobileOptions("button"))

                                                O4WListEnd("navlist")

                                                O4WBreak()

                                    O4WSectionEnd("NavBar")

                       

                                    * the main body of this page

                                    O4WSectionStart("main", O4WMobileOptions("content"))

                       

                                    * a list of links

                                    O4WListStart("0", "MainLinks", O4WMobileOptions("listview"))

                                                O4WListItem()

                                                O4WLink("Newsletter", O4W_LINKTYPE_LOCAL$, "Newsletter","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListItem()

                                                O4WLink("eStore", O4W_LINKTYPE_NORMAL$, "https://www.revsecure.com/estore","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListItem()

                                                O4WLink("Conference", O4W_LINKTYPE_LOCAL$, "Conference","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListItem()

                                                O4WLink("Facebook", O4W_LINKTYPE_NORMAL$, "http://m.facebook.com/home.php?refsrc=http%3A%2F","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListEnd("MainLinks")

                                                O4WBreak()

                                    O4WSectionEnd("main")

                        O4WSectionEnd("MainMenu")

Notice the use of “normal” O4W API calls to generate the output, with the addition of various O4W Mobile API calls (O4WMobileOptions, O4WMobileButtonOptions) to enhance the output for the mobile device.

Mobile Application Design

Since mobile applications should try to minimize the amount of data sent to the mobile device, and at the same time perform as quickly, your mobile application should be designed to take advantage of the optimizations that O4W automatically applies to your output. Towards this end, you can design your O4W custom stored procedure in one of two ways:

  1. In the code that responds to the “CREATE” event, you can generate all the pages that your application will require (each page in its own “page” section); the mobile device will then be able to run all of your pages without requesting additional data from the server; or
  1. Each page of your application can be generated by its own O4W custom stored procedure (inside each of these stored procedures, the code that responds to the “CREATE” event will generate only one “page”section)

Design #1 is recommended; even if your application must dynamically change the contents of various pages (in response to user input, for example), you can still use O4WQualifyEvent and O4WResponse to interact and modify the pages on the fly. Design #2 will require loading less data into the mobile device at start up, but is more vulnerable to delays during application use.

An example of a multi-page stored procedure that uses the first design to return static pages might be:

Subroutine O4W_M_REVELATION_COM(ctlentid, event, request)

*

 

/*

*  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     : Robert Catalano

*

*  CREATED    : May, 2011

*

*

!

*

*  REVISION HISTORY           (Most CURRENT first) :

*

*    DATE       IMPLEMENTOR     FUNCTION

*  --------     -----------     --------

*

*

*/

 

$Insert O4WCOMMON

$Insert O4WEQUATES

*

Declare Function Get_All_Types, Get_Repos_Types, Get_repos_entities, get_repos_classes

 

Open'' ,'REVMOBILE_CODES' To REVMOBILE_CODES.FL Else Return 0

 

Begin Case

            Case EVENT _EQC "CREATE"

                        * turn our "we're a mobile app" flag

                        o4wSetMobile(1)

                        * use our blank template

                        o4wform("blank")

                       

                        * start a "page" of content, using theme "b"

                        O4WSectionStart("MainMenu", O4WMobileOptions("page", "b"))

                       

                                    * set up a header section

                                    O4WsectionStart("headerSection", O4WMobileOptions(O4W_ROLE_HEADER$))

                                                O4WSectionStart("headerInsideSection")

                                                            o4wimage("Revelation Logo", "../revmobile_images/revlogo.png", "", "", "", "", O4WPositionStyle("", "", "", "", "left"))

                                                            O4WHeader("Revelation Software":@vm:" Mobile", 3, "", O4WAlignStyle("","1"))

                                                O4WSectionEnd("headerInsideSection")

                                    O4WSectionEnd("headerSection")

                       

                                    * build a navbar section

                                    O4WSectionStart("NavBar", O4WMobileOptions("navbar"))

                                    * the navbar is a list of links, so start the list

                                                O4WListStart("0", "navlist")

                                                            O4WListItem()

                                                            O4WLink("Works Login", O4W_LINKTYPE_NORMAL$, "http://www.revelation.com/revelation.nsf/byTitle/Registration+Entry?Open&Login") ;*, "", "", O4WMobileOptions("button"))

                                                            O4WListItem()

                                                            O4WLink("Revelation.com", O4W_LINKTYPE_NORMAL$, "http://www.revelation.com") ;*, "", "", O4WMobileOptions("button"))

                                                O4WListEnd("navlist")

                                                O4WBreak()

                                    O4WSectionEnd("NavBar")

                       

                                    * the main body of this page

                                    O4WSectionStart("main", O4WMobileOptions("content"))

                       

                                    * a list of links

                                    O4WListStart("0", "MainLinks", O4WMobileOptions("listview"))

                                                O4WListItem()

                                                O4WLink("Newsletter", O4W_LINKTYPE_LOCAL$, "Newsletter","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListItem()

                                                O4WLink("eStore", O4W_LINKTYPE_NORMAL$, "https://www.revsecure.com/estore","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListItem()

                                                O4WLink("Conference", O4W_LINKTYPE_LOCAL$, "Conference","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListItem()

                                                O4WLink("Facebook", O4W_LINKTYPE_NORMAL$, "http://m.facebook.com/home.php?refsrc=http%3A%2F","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListEnd("MainLinks")

                                                O4WBreak()

                                    O4WSectionEnd("main")

                        O4WSectionEnd("MainMenu")

                       

                        * the Newsletter "page" of content

                        * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                        O4WSectionStart("Newsletter", o4wmobileoptions("page", "b"))

                                    * the header for the Newsletter page

                                    * jquery mobile will automatically add the 'back' button

                                    O4WSectionStart("newsletter1", o4wmobileoptions("header"))

                                                O4WHeader("Newsletters", 3)

                                    O4WSectionEnd("newsletter1")

                                    * the main content for the Newsletter page

                                    O4WSectionStart("NewsletterContent", o4wmobileoptions("content"))

                                                O4WBreak()

                                                Read Nrec From REVMOBILE_CODES.FL,'NEWSLETTER' Else Nrec=''

                                                cnt=Dcount(NREC<1>,@vm)

                                                * a list of Newsletter links

                                                O4WListStart("0", "newsletterlinks", O4WMobileOptions("listview"))

                                                For X = 1 To cnt

                                                            O4WListItem()

                                                            O4WLink(NREC<1,X>, O4W_LINKTYPE_NORMAL$, NREC<2,X>,"","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                Next X

                                                O4WListEnd("newsletterlinks")

                                    O4WSectionEnd("NewsletterContent")

                        O4WSectionEnd("Newsletter")

                       

                        O4WSectionStart("Conference", o4wmobileoptions("page", "b"))

                                    * the header for the Conference page

                                    * jquery mobile will automatically add the 'back' button

                                    O4WSectionStart("conferencemain", o4wmobileoptions("header"))

                                                O4WHeader("Conference", 3)

                                    O4WSectionEnd("conferencemain")

                                    * the main content for the Conference page

                                    O4WSectionStart("ConferenceContent", o4wmobileoptions("content"))

                                                O4WText("2011 Conference - Las Vegas")

                                                O4WBreak()

                                                O4WText("Knowledge is Power")

                                                O4WBreak()

                                    O4WSectionEnd("ConferenceContent")

                                    O4WSectionStart("Conferencepage1", O4WMobileoptions("content"))

                                                * a list of Conference links

                                                O4WListStart("0", "conferencelinks", O4WMobileOptions("listview"))

                                                            O4WListItem()

                                                            O4WLink("Exhibitors", O4W_LINKTYPE_LOCAL$, "Exhibitors","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("Speakers", O4W_LINKTYPE_LOCAL$, "Speakers","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WText("", "", O4WMobileOptions("list-divider"))

                                                            o4wlistitem()

                                                            O4WLink("Wednesday", O4W_LINKTYPE_LOCAL$, "Wednesday","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("Thursday", O4W_LINKTYPE_LOCAL$, "Thursday","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("Friday", O4W_LINKTYPE_LOCAL$, "Friday","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListEnd("conferencelinks")

                                    O4WSectionEnd("Conferencepage1")                                                          

                        O4WSectionEnd("Conference")

 

        * the Exhibitor "page" of content

                        * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                        O4WSectionStart("Exhibitors", o4wmobileoptions("page", "b"))

                                    * the header for the Exhibitor page

                                    * jquery mobile will automatically add the 'back' button

                                    O4WSectionStart("exhibitorsmain", o4wmobileoptions("header"))

                                                O4WHeader("Exhibitors", 3)

                                    O4WSectionEnd("exhibitorsmain")

                                    * the main content for the Speakers page

                                    O4WSectionStart("ExhibitorsContent", o4wmobileoptions("content"))

                                                O4WText("2011 Conference - Las Vegas")

                                                O4WBreak()

                                                O4WText("Knowledge is Power")

                                                O4WBreak()

                                    O4WSectionEnd("ExhibitorsContent")

                                    O4WSectionStart("ExhibitorsList", O4WMobileOptions("content"))

                                                Read Nrec From REVMOBILE_CODES.FL,'EXHIBITORS' Else Nrec=''

                                                cnt=Dcount(NREC<1>,@vm)

                                                * a list of Exhibitor links

                                                O4WListStart("0", "exhibitorlinks", O4WMobileOptions("listview"))

                                                            For X = 1 To cnt

                                                                        O4WListItem()

                                                                        O4WLink(NREC<1,X>, O4W_LINKTYPE_LOCAL$, "exhibitor_":X,"","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            Next X

                                                O4WListEnd("exhibitorlinks")

                                    O4WSectionEnd("exhibitorsList")

                        O4WSectionEnd("Exhibitors")

                       

                        * the Exhibitor Detail "page" of content

                        * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                        Read Nrec From REVMOBILE_CODES.FL,'EXHIBITORS' Else Nrec=''

                        cnt=Dcount(NREC<1>,@vm)

                        For X = 1 To cnt

                                    O4WSectionStart("exhibitor_":X, o4wmobileoptions("page", "b"))

                                                * the header for the Exhibitor detail page

                                                * jquery mobile will automatically add the 'back' button

                                                O4WSectionStart("exhibitorsmain_":X, o4wmobileoptions("header"))

                                                            O4WHeader(NREC<1,X>, 3)

                                                O4WSectionEnd("exhibitorsmain_":X)

                                                * the main content for the Speakers page

                                                O4WSectionStart("ExhibitorsContent_":X, o4wmobileoptions("content"))

                                                            O4WText(NREC<2,X>)

                                                            O4WBreak()

                                                O4WSectionEnd("ExhibitorsContent_":X)

                                    O4WSectionEnd("exhibitor_":X)

                        Next X

                       

        * the Speaker "page" of content

                        * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                        O4WSectionStart("Speakers", o4wmobileoptions("page", "b"))

                                    * the header for the Speakers page

                                    * jquery mobile will automatically add the 'back' button

                                    O4WSectionStart("speakersmain", o4wmobileoptions("header"))

                                                O4WHeader("Speakers", 3)

                                    O4WSectionEnd("speakersmain")

                                    * the main content for the Speakers page

                                    O4WSectionStart("SpeakersContent", o4wmobileoptions("content"))

                                                O4WText("2011 Conference - Las Vegas")

                                                O4WBreak()

                                                O4WText("Knowledge is Power")

                                                O4WBreak()

                                    O4WSectionEnd("SpeakersContent")

                                    O4WSectionStart("SpeakersList", O4WMobileOptions("content"))

                                                Read Nrec From REVMOBILE_CODES.FL,'SPEAKERS' Else Nrec=''

                                                cnt=Dcount(NREC<1>,@vm)

                                                * a list of Speaker links

                                                O4WListStart("0", "speakerlinks", O4WMobileOptions("listview"))

                                                            For X = 1 To cnt

                                                                        O4WListItem()

                                                                        O4WLink(NREC<1,X>, O4W_LINKTYPE_LOCAL$, "speaker_":X,"","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            Next X

                                                O4WListEnd("speakerlinks")

                                    O4WSectionEnd("SpeakersList")

                        O4WSectionEnd("Speakers")

                       

                        * the Speaker Detail "page" of content

                        * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                        Read Nrec From REVMOBILE_CODES.FL,'SPEAKERS' Else Nrec=''

                        cnt=Dcount(NREC<1>,@vm)

                        For X = 1 To cnt

                                    O4WSectionStart("speaker_":X, o4wmobileoptions("page", "b"))

                                                * the header for the Speaker detail page

                                                * jquery mobile will automatically add the 'back' button

                                                O4WSectionStart("speakersmain_":X, o4wmobileoptions("header"))

                                                            O4WHeader(NREC<1,X>, 3)

                                                O4WSectionEnd("speakersmain_":X)

                                                * the main content for the Speakers page

                                                O4WSectionStart("SpeakersContent_":X, o4wmobileoptions("content"))

                                                            o4wimage(NREC<1,X>, NREC<3,X>, "", "", "", "", O4WPositionStyle("", "", "", "", "left"))

                                                            O4WText(NREC<2,X>)

                                                            O4WBreak()

                                                O4WSectionEnd("SpeakersContent_":X)

                                    O4WSectionEnd("speaker_":X)

                        Next X

                       

        * the Wednesday "page" of content

                        * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                        O4WSectionStart("Wednesday", o4wmobileoptions("page", "b"))

                                    * the header for the Speakers page

                                    * jquery mobile will automatically add the 'back' button

                                    O4WSectionStart("Wednesdaymain", o4wmobileoptions("header"))

                                                O4WHeader("Wednesday", 3)

                                    O4WSectionEnd("Wednesdaymain")

                                    * the main content for the Speakers page

                                    O4WSectionStart("WednesdayContent", o4wmobileoptions("content"))

                                                O4WText("2011 Conference - Las Vegas")

                                                O4WBreak()

                                                O4WText("Knowledge is Power")

                                                O4WBreak()

                                    O4WSectionEnd("WednesdayContent")

                                    O4WSectionStart("WednesdayList", O4WMobileOptions("content"))

                                                * a list of Wednesday links

                                                O4WListStart("0", "Wednesdaylinks", O4WMobileOptions("listview"))

                                                            O4WListItem()

                                                            O4WLink("8:00 AM", O4W_LINKTYPE_LOCAL$, "WED8","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("9:00 AM", O4W_LINKTYPE_LOCAL$, "WED9","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("10:00 AM", O4W_LINKTYPE_LOCAL$, "WED10","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("11:15 AM", O4W_LINKTYPE_LOCAL$, "WED11","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("12:15 PM", O4W_LINKTYPE_LOCAL$, "WED12","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("1:15 PM", O4W_LINKTYPE_LOCAL$, "WED13","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("2:30 PM", O4W_LINKTYPE_LOCAL$, "WED14","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("3:45 PM", O4W_LINKTYPE_LOCAL$, "WED15","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("4:00 PM", O4W_LINKTYPE_LOCAL$, "WED16","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListEnd("Wednesdaylinks")

                                    O4WSectionEnd("WednesdayList")

                        O4WSectionEnd("Wednesday")

                       

                        For T=8 To 16

                                    * the WedSpeaker "page" of content

                                    * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                                    O4WSectionStart("WED":T, o4wmobileoptions("page", "b"))

                                                * the header for the Speakers page

                                                * jquery mobile will automatically add the 'back' button

                                                STIME=''

                                                Begin Case

                                                            Case T=8

                                                                        STIME='8:00 AM'

                                                            Case T=9

                                                                        STIME='9:00 AM'

                                                            Case T=10

                                                                        STIME='10:00 AM'

                                                            Case T=11

                                                                        STIME='11:15 AM'

                                                            Case T=12

                                                                        STIME='12:15 PM'

                                                            Case T=13

                                                                        STIME='1:15 PM'

                                                            Case T=14

                                                                        STIME='2:30 PM'

                                                            Case T=15

                                                                        STIME='3:45 PM'

                                                            Case T=16

                                                                        STIME='4:00 PM'

                                                End Case          

                                                O4WSectionStart("Wedheader":T, o4wmobileoptions("header"))

                                                            O4WHeader(STIME, 3)

                                                O4WSectionEnd("Wedheader":T)

                                                * the main content for the Speakers page

                                                O4WSectionStart("WedSpeakersContent":T, o4wmobileoptions("content"))

                                                                        O4WText("2011 Conference - Las Vegas")

                                                                        O4WBreak()

                                                                        O4WText("Knowledge is Power")

                                                                        O4WBreak()

                                                O4WSectionEnd("WedSpeakersContent":T)

                                                O4WSectionStart("WedSpeakersList":T, O4WMobileOptions("content"))

                                                            Read Nrec From REVMOBILE_CODES.FL,'WED':T Else Nrec=''

                                                            cnt=Dcount(NREC<1>,@vm)

                                                            * a list of Speaker links

                                                            O4WListStart("0", "Wedspeakerlinks":T, O4WMobileOptions("listview"))

                                                                        For X = 1 To cnt

                                                                                    O4WListItem()

                                                                                    O4WLink(NREC<1,X>:@vm:NREC<2,X>, O4W_LINKTYPE_LOCAL$, "Wedspeaker_":T:X,"","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                                        Next X

                                                            O4WListEnd("Wedspeakerlinks":T)

                                                O4WSectionEnd("WedSpeakersList":T)

                                    O4WSectionEnd("WED":T)

                        Next T

 

                        For T=8 To 16

                                    Read Nrec From REVMOBILE_CODES.FL,'WED':T Else Nrec=''

                                    cnt=Dcount(NREC<1>,@vm)

                                    For x=1 To cnt

                                                * the WedSpeakerdetail "page" of content

                                                * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                                                O4WSectionStart("Wedspeaker_":T:X, o4wmobileoptions("page", "b"))

                                                            * the header for the Speakers page

                                                            * jquery mobile will automatically add the 'back' button

                                                            O4WSectionStart("Wedheader":T:X, o4wmobileoptions("header"))

                                                                        O4WHeader(NREC<1,X>, 3)

                                                            O4WSectionEnd("Wedheader":T:X)

                                                            * the main content for the Speakers page

                                                            O4WSectionStart("WedSpeakersContent":T:X, o4wmobileoptions("content"))

                                                                        O4WText(NREC<2,X>)

                                                                        O4WBreak()

                                                                        O4WBreak()

                                                                        O4WText(NREC<3,X>)

                                                            O4WSectionEnd("WedSpeakersContent":T:X)

                                                O4WSectionEnd("Wedspeaker_":T:X)

                                    Next X

                        Next T

                       

        * the Thursday "page" of content

                        * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                        O4WSectionStart("Thursday", o4wmobileoptions("page", "b"))

                                    * the header for the Speakers page

                                    * jquery mobile will automatically add the 'back' button

                                    O4WSectionStart("Thursdaymain", o4wmobileoptions("header"))

                                                O4WHeader("Thursday", 3)

                                    O4WSectionEnd("Thursdaymain")

                                    * the main content for the Speakers page

                                    O4WSectionStart("ThursdayContent", o4wmobileoptions("content"))

                                                O4WText("2011 Conference - Las Vegas")

                                                O4WBreak()

                                                O4WText("Knowledge is Power")

                                                O4WBreak()

                                    O4WSectionEnd("ThursdayContent")

                                    O4WSectionStart("ThursdayList", O4WMobileOptions("content"))

                                                * a list of Thursday links

                                                O4WListStart("0", "Thursdaylinks", O4WMobileOptions("listview"))

                                                            O4WListItem()

                                                            O4WLink("8:00 AM", O4W_LINKTYPE_LOCAL$, "THU8","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("9:00 AM", O4W_LINKTYPE_LOCAL$, "THU9","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("10:00 AM", O4W_LINKTYPE_LOCAL$, "THU10","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("11:15 AM", O4W_LINKTYPE_LOCAL$, "THU11","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("12:15 PM", O4W_LINKTYPE_LOCAL$, "THU12","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("1:15 PM", O4W_LINKTYPE_LOCAL$, "THU13","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("2:30 PM", O4W_LINKTYPE_LOCAL$, "THU14","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("3:45 PM", O4W_LINKTYPE_LOCAL$, "THU15","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("4:00 PM", O4W_LINKTYPE_LOCAL$, "THU16","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListEnd("Thursdaylinks")

                                    O4WSectionEnd("ThursdayList")

                        O4WSectionEnd("Thursday")

                       

                        For T=8 To 16

                                    * the ThuSpeaker "page" of content

                                    * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                                    O4WSectionStart("THU":T, o4wmobileoptions("page", "b"))

                                                * the header for the Speakers page

                                                * jquery mobile will automatically add the 'back' button

                                                STIME=''

                                                Begin Case

                                                            Case T=8

                                                                        STIME='8:00 AM'

                                                            Case T=9

                                                                        STIME='9:00 AM'

                                                            Case T=10

                                                                        STIME='10:00 AM'

                                                            Case T=11

                                                                        STIME='11:15 AM'

                                                            Case T=12

                                                                        STIME='12:15 PM'

                                                            Case T=13

                                                                        STIME='1:15 PM'

                                                            Case T=14

                                                                        STIME='2:30 PM'

                                                            Case T=15

                                                                        STIME='3:45 PM'

                                                            Case T=16

                                                                        STIME='4:00 PM'

                                                End Case          

                                                O4WSectionStart("Thuheader":T, o4wmobileoptions("header"))

                                                            O4WHeader(STIME, 3)

                                                O4WSectionEnd("Thuheader":T)

                                                * the main content for the Speakers page

                                                O4WSectionStart("ThuSpeakersContent":T, o4wmobileoptions("content"))

                                                                        O4WText("2011 Conference - Las Vegas")

                                                                        O4WBreak()

                                                                        O4WText("Knowledge is Power")

                                                                        O4WBreak()

                                                O4WSectionEnd("ThuSpeakersContent":T)

                                                O4WSectionStart("ThuSpeakersList":T, O4WMobileOptions("content"))

                                                            Read Nrec From REVMOBILE_CODES.FL,'THU':T Else Nrec=''

                                                            cnt=Dcount(NREC<1>,@vm)

                                                            * a list of Speaker links

                                                            O4WListStart("0", "Thuspeakerlinks":T, O4WMobileOptions("listview"))

                                                                        For X = 1 To cnt

                                                                                    O4WListItem()

                                                                                    O4WLink(NREC<1,X>:@vm:NREC<2,X>, O4W_LINKTYPE_LOCAL$, "Thuspeaker_":T:X,"","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                                        Next X

                                                            O4WListEnd("Thuspeakerlinks":T)

                                                O4WSectionEnd("ThuSpeakersList":T)

                                    O4WSectionEnd("THU":T)

                        Next T

 

                        For T=8 To 16

                                    Read Nrec From REVMOBILE_CODES.FL,'THU':T Else Nrec=''

                                    cnt=Dcount(NREC<1>,@vm)

                                    For x=1 To cnt

                                                * the ThuSpeakerdetail "page" of content

                                                * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                                                O4WSectionStart("Thuspeaker_":T:X, o4wmobileoptions("page", "b"))

                                                            * the header for the Speakers page

                                                            * jquery mobile will automatically add the 'back' button

                                                            O4WSectionStart("Thuheader":T:X, o4wmobileoptions("header"))

                                                                        O4WHeader(NREC<1,X>, 3)

                                                            O4WSectionEnd("Thuheader":T:X)

                                                            * the main content for the Speakers page

                                                            O4WSectionStart("ThuSpeakersContent":T:X, o4wmobileoptions("content"))

                                                                        O4WText(NREC<2,X>)

                                                                        O4WBreak()

                                                                        O4WBreak()

                                                                        O4WText(NREC<3,X>)

                                                            O4WSectionEnd("ThuSpeakersContent":T:X)

                                                O4WSectionEnd("Thuspeaker_":T:X)

                                    Next X

                        Next T

 

        * the Friday "page" of content

                        * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                        O4WSectionStart("Friday", o4wmobileoptions("page", "b"))

                                    * the header for the Speakers page

                                    * jquery mobile will automatically add the 'back' button

                                    O4WSectionStart("Fridaymain", o4wmobileoptions("header"))

                                                O4WHeader("Friday", 3)

                                    O4WSectionEnd("Fridaymain")

                                    * the main content for the Speakers page

                                    O4WSectionStart("FridayContent", o4wmobileoptions("content"))

                                                O4WText("2011 Conference - Las Vegas")

                                                O4WBreak()

                                                O4WText("Knowledge is Power")

                                                O4WBreak()

                                    O4WSectionEnd("FridayContent")

                                    O4WSectionStart("FridayList", O4WMobileOptions("content"))

                                                * a list of Friday links

                                                O4WListStart("0", "Fridaylinks", O4WMobileOptions("listview"))

                                                            O4WListItem()

                                                            O4WLink("8:00 AM", O4W_LINKTYPE_LOCAL$, "FRI8","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("9:00 AM", O4W_LINKTYPE_LOCAL$, "FRI9","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("10:00 AM", O4W_LINKTYPE_LOCAL$, "FRI10","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("11:00 AM", O4W_LINKTYPE_LOCAL$, "FRI11","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                            O4WListItem()

                                                            O4WLink("12:00 PM", O4W_LINKTYPE_LOCAL$, "FRI12","","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                O4WListEnd("Fridaylinks")

                                    O4WSectionEnd("FridayList")

                        O4WSectionEnd("Friday")

                       

                        For T=8 To 12

                                    * the FriSpeaker "page" of content

                                    * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                                    O4WSectionStart("FRI":T, o4wmobileoptions("page", "b"))

                                                * the header for the Speakers page

                                                * jquery mobile will automatically add the 'back' button

                                                STIME=''

                                                Begin Case

                                                            Case T=8

                                                                        STIME='8:00 AM'

                                                            Case T=9

                                                                        STIME='9:00 AM'

                                                            Case T=10

                                                                        STIME='10:00 AM'

                                                            Case T=11

                                                                        STIME='11:00 AM'

                                                            Case T=12

                                                                        STIME='12:00 PM'

                                                End Case          

                                                O4WSectionStart("Friheader":T, o4wmobileoptions("header"))

                                                            O4WHeader(STIME, 3)

                                                O4WSectionEnd("Friheader":T)

                                                * the main content for the Speakers page

                                                O4WSectionStart("FriSpeakersContent":T, o4wmobileoptions("content"))

                                                                        O4WText("2011 Conference - Las Vegas")

                                                                        O4WBreak()

                                                                        O4WText("Knowledge is Power")

                                                                        O4WBreak()

                                                O4WSectionEnd("FriSpeakersContent":T)

                                                O4WSectionStart("FriSpeakersList":T, O4WMobileOptions("content"))

                                                            Read Nrec From REVMOBILE_CODES.FL,'FRI':T Else Nrec=''

                                                            cnt=Dcount(NREC<1>,@vm)

                                                            * a list of Speaker links

                                                            O4WListStart("0", "Frispeakerlinks":T, O4WMobileOptions("listview"))

                                                                        For X = 1 To cnt

                                                                                    O4WListItem()

                                                                                    O4WLink(NREC<1,X>:@vm:NREC<2,X>, O4W_LINKTYPE_LOCAL$, "Frispeaker_":T:X,"","",O4WMobileButtonOptions(O4WMOBILE_TRANSITION_SLIDEUP$))

                                                                        Next X

                                                            O4WListEnd("Frispeakerlinks":T)

                                                O4WSectionEnd("FriSpeakersList":T)

                                    O4WSectionEnd("FRI":T)

                        Next T

 

                        For T=8 To 12

                                    Read Nrec From REVMOBILE_CODES.FL,'FRI':T Else Nrec=''

                                    cnt=Dcount(NREC<1>,@vm)

                                    For x=1 To cnt

                                                * the FriSpeakerdetail "page" of content

                                                * jQuery Mobile likes all the pages sent in a single call - it's faster for the user

                                                O4WSectionStart("Frispeaker_":T:X, o4wmobileoptions("page", "b"))

                                                            * the header for the Speakers page

                                                            * jquery mobile will automatically add the 'back' button

                                                            O4WSectionStart("Friheader":T:X, o4wmobileoptions("header"))

                                                                        O4WHeader(NREC<1,X>, 3)

                                                            O4WSectionEnd("Friheader":T:X)

                                                            * the main content for the Speakers page

                                                            O4WSectionStart("FriSpeakersContent":T:X, o4wmobileoptions("content"))

                                                                        O4WText(NREC<2,X>)

                                                                        O4WBreak()

                                                                        O4WBreak()

                                                                        O4WText(NREC<3,X>)

                                                            O4WSectionEnd("FriSpeakersContent":T:X)

                                                O4WSectionEnd("Frispeaker_":T:X)

                                    Next X

                        Next T

                       

End Case

Return 0

Notice the extensive use of the O4WMobileOptions API call on various sections to define the “roles” those sections have in the output.

An example of how you might generate dynamic content using the first design might be:

Subroutine O4W_DESIGN_1(ctlentid, event, request)

 

$Insert O4WCOMMON

$Insert O4WEQUATES

*

 

pageOptions = o4wmobileoptions("page","b"):O4WDataStyle("", "data-add-back-btn", "true")

triggerPageOptions = o4wmobilePageOptions('1','1')

 

BEGIN CASE

            CASE event _eqc "CREATE"

                       

                        * turn our "we're a mobile app" flag

                        o4wsetmobile(1)

                        * use our blank template

                        o4wform("blank")

                       

                        * define initial (dispatch) page

                        O4WSectionStart("menuSection", pageOptions)

                        O4WSectionStart("menuHeader", o4wmobileoptions("header"))

                        o4wheader("O4W Mobile Menu", 3)

                        o4wsectionend("menuHeader")

                        O4WSectionStart("menuBody", o4wmobileoptions("content"))

                        O4WListStart("0", "menuList", O4WMobileOptions("listview"))

                        * define links to 5 more pages

                        for each.item = 1 to 5

                                    O4WListItem("", O4WMobileButtonOptions("fade","forward"))

                                    O4WLink("Menu Option #":each.item, O4W_LINKTYPE_LOCAL$, "#mainSection0":each.item)

                        next each.item

                        O4WListEnd("menuList")

                        O4WSectionEnd("menuBody")

                        O4WSECTIONEND("menuSection")

                       

                        * define the (empty) rest of our pages

                       

                        for each.main = 1 to 5

                                    O4WSectionStart("mainSection0":each.main, pageOptions:triggerPageOptions)

                                    O4WSectionEnd("mainSection0":each.main)

                        next each.main

                       

                        * define a section for our popup

                       

                        O4WSectionStart("popupSection", pageOptions:triggerPageOptions)

                        O4WSectionEnd("popupSection")

                       

                       

            case event _eqc "pageinit"

                        * called when a page is linked to the FIRST TIME ONLY

                        o4wresponse()

                        begin case

                                    case ctlentid[1,11] _eqc "mainsection"

                                                whichSection = ctlentid[12, 2]

                                                o4wsectionstart("mainSection":whichSection, O4WResponseOptions():o4wmobileoptions("page","b"))

                                                o4wsectionstart("mainHeader":whichSection,  o4wmobileoptions("header"))

                                                o4wheader("O4W Mobile Menu - linked page at ":timedate(), 3)

                                                o4wsectionend("mainHeader":whichSection)

                                                O4WSectionStart("mainBody":whichSection, o4wmobileoptions("content"))

                                                O4WText("we got updated at ":timedate())

                                                o4wsectionstart("subBody":whichSection)

                                                o4wsectionend("subBody":whichSection)

                                                O4WLink("link to dialog", O4W_LINKTYPE_LOCAL$, "popupSection", "", "lnkPagePopup", O4WDataStyle("", "data-rel","dialog"):O4WMobileOptions("button"):O4WMobileButtonOptions("","forward"))

                                                O4WSectionEnd("mainBody":whichSection)

                                                o4wSectionEnd("mainSection":whichSection)

                                    case ctlentid _eqc "popupSection"

                                                o4wsectionstart("popupSection", O4WResponseOptions():o4wmobileoptions("page","c"))

                                                o4wsectionstart("popupHeader",  o4wmobileoptions("header"))

                                                o4wheader("O4W Mobile Menu - Popup at ":timedate(), 3)

                                                o4wsectionend("popupHeader")

                                                O4WSectionStart("popupBody", o4wmobileoptions("content"))

                                                O4WText("we got updated at ":timedate())

                                                O4WSectionStart("popupsubBody")

                                                O4WSectionEnd("popupsubBody")

                                                O4WSectionEnd("popupBody")

                                                o4wSectionEnd("popupSection")                            

                        end case

                       

                       

            case event _eqc "pageshow"

                        o4wresponse()

                        * called EVERY TIME the page is shown

                        begin case

                                    case ctlentid[1,11] _eqc "mainsection"

                                                whichSection = ctlentid[12, 2]

                                                O4WSectionStart("subBody":whichSection, o4wresponseoptions())

                                                O4WText("we got updated at ":timedate())

                                                O4WButton("Open dialog", "BTN_OPEN":whichSection)

                                                O4WQualifyEvent("BTN_OPEN":whichSection, "CLICK")

                                                O4WSectionEnd("subBody":whichSection)

                                    case ctlentid _eqc "popupSection"

                                                O4WSectionStart("popupsubBody", o4wresponseoptions())

                                                O4WText("we got updated at ":timedate())

                                                O4WButton("Close dialog", "BTN_CLOSE")

                                                O4WQualifyEvent("BTN_CLOSE", "CLICK")

                                                O4WSectionEnd("popupsubBody")

                        end case

                       

            case event _eqc "CLICK"

                        o4wresponse()

                        if ctlentid[1,8] _eqc "BTN_OPEN" then

                                    O4WDialog("popupSection", "showme")

                        end else

                                    O4WDialog("popupSection")

                        end

                       

end case

 

Return 0

Note the use of O4WQualifyEvent and O4WResponse with the buttons on the pages. In addition, O4W Mobile allows you to specify that your stored procedure should be notified when a page is loaded for the first time, and/or whenever a page is displayed, with the O4WMobilePageOptions API call.

Also note that the different pages are accessed by the user via O4WLink calls; you can also programmatically move to other pages via O4WRedirect, using the ID of the “page” section prefixed by “#” – for example:

O4WRedirect(“#page4”)

O4W Mobile APIs

O4WSetMobile(bMobileFlag)
 Used to inform O4W that this page will be generated for the mobile browser (if bMobileFlag parameter is “1”) or the desktop browser (if bMobileFlag parameter is “0”).  Make this call before O4WForm() to properly configure O4W.
O4WGetMobile()
 Returns “1” if the currently generating page has been set for the mobile browser, or “0” if the page is for the desktop browser.  This routine will check for the presence of the “mobile flag”; if a prior page was set to mobile mode, O4WGetMobile() will return “1”.  For example:
* are we being called while in a mobile environment

bIsMobile = O4WGetMobile()

if bIsMobile = “1” then

   * yes; generate this page in mobile mode as well

   O4WSetMobile(“1”)

End

O4WForm()
O4WMobileOptions(roleName, themeCode)
 O4WMobileOptions defines the “role”  that an element (typically a section) plays in layout on the mobile browser page.  Available options for roleName include “page”, “header”, “footer”, “navbar”, “content”, “listview” (when applied to O4WListStart),  and “fieldcontain”.  O4W will use the role information to determine appropriate layout and styling of the element and its children on the mobild browser.  Themecode may also be specified to designate which “theme swatch” colors should be applied to this element and its children; available codes are “a” through “z”.

Example:

O4WSectionStart(“ourPage”, O4WMobileOptions(“page”, “e”))

O4WSectionStart(“ourHeader”, O4WMobileOptions(“header”))

O4WHeader(“Sample Page”, 3)

O4WSectionEnd(“ourHeader”)

O4WSectionStart(“ourBody”, O4WMobileOptions(“content”))

O4WText(“Mobile content goes here!”)

O4WSectionEnd(“ourBody”)

O4WSectionEnd(“ourPage”)
O4WMobilePageOptions(bDoInitEvent, bDoShowEvent, {mobilePageAndTheme})
 O4WMobilePageOptions is applied to the O4WSectionStart call when in O4W mobile mode and controls whether the mobile browser will send an event when this page section is first loaded (bDoInitEvent = “1”), and/or whenever this page section is displayed (bDoShowEvent = “1”).

If the mobilePageAndTheme parameter is not null, this call will also set the O4WMobileOptions(“page”), passing in this parameter as the theme code (“a” through “z”), thus eliminating the need to call O4WMobileOptions in addition to this call.

Example:

O4WSectionStart("Main page", O4WMobilePageOptions(“1”, “1”, “c”))
O4WMobileButtonOptions(transitionType, iconName, {mobileButtonAndTheme})
 O4WMobileButtonOptions is applied to O4WLink or O4WButton elements when in O4W mobile mode and controls what transition effect is used when the button is pressed, and what icon should be displayed with that button (note that O4W will automatically convert links into buttons when in mobile mode).  Available options for transitionType include “pop”, “slide”, “slideup”, “slidedown”, “flip”, and “fade”.  Available icons include “delete”, “arrow-l”, “arrow-r”, “arrow-u”, “arrow-d”, “plus”, “minus”, “check”, “gear”, “refresh”, “forward”, “back”, “grid”, “star”, “alert”, “info”, “home”, and “search”.

If the mobileButtonAndTheme parameter is not null, this call will also set the O4WMobileOptions(“button”), passing in this parameter as the theme code (“a” through “z”), thus eliminating the need to call O4WMobileOptions in addition to this call.

Example:

O4WLink("Second page", O4W_LINKTYPE_LOCAL$, "subsection1", “”, “”, O4WMobileButtonOptions(“fade”, “forward”))

Mobile Device Orientation

O4W Mobile is also able to customize which styles get applied to different browser elements based on the orientation of your mobile device. It does this by applying either the “landscape” or “portrait” style names to the generated page as appropriate. You can build styles that are applied only in the right circumstance by using O4WMOBILE_STYLE_PORTRAIT$ and O4WMOBILE_STYLE_LANDSCAPE$ equates in your various O4WxxxSTYLE API calls. Simply include the proper equate instead of, or in addition to, the “style name” parameter, and that style definition will only apply in that instance.

For example, to use a red background color when in portrait mode, but a yellow background color when in landscape mode, for a header, you could have the following code:

O4WHeader(“This is the header”, 1, “”, O4WColorStyle(O4WMOBILE_STYLE_PORTRAIT$, “red”):O4WColorStyle(O4WMOBILE_STYLE_LANDSCAPE$, “yellow”))

Like all O4WxxxSTYLE calls, these can also be assigned to a variable and used repeatedly:

portraitColor = O4WColorStyle(O4WMOBILE_STYLE_PORTRAIT$, “red”)

landscapeColor = O4WColorStyle(O4WMOBILE_STYLE_LANDSCAPE$, “yellow”)

O4WHeader(“This is the header”, 1, “”, portraitColor:landscapeColor)

If you wish to use “named” styles, you can apply the O4WMOBILE_STYLE_PORTRAIT$ and O4WMOBILE_STYLE_LANDSCAPE$ equates as the “suffix”:

O4WColorStyle(“headerColor”:O4WMOBILE_STYLE_PORTRAIT$, “red”)

O4WColorStyle(“headerColor”:O4WMOBILE_STYLE_LANDSCAPE$, “yellow”)

O4WHeader(“This is the header”, 1, “”, “headerColor”)

Enhancing User Interface Elements

O4W supports the same user interface elements in mobile mode as in normal desktop mode; however, for added functionality, you may need to apply some additional styles or options. Note that there is no drawback to adding these styles and options to all your O4W routines – including any desktop O4W stored procedures; as newer browsers become available that support HTML5, these additional styles and options will enhance the user experience on the desktop as well.

Grouping Elements Together

Apply the “fieldcontain” role to a section (using the O4WMobileOptions API call) to style associated labels and input controls together. O4W will attempt to draw the elements that are in that section side-by-side, rather than using a 100% width for the elements as it might otherwise do.

Apply the “controlgroup” role to a section (using the O4WMobileOptions API call) to group related elements in your form. For example, the radio buttons in a radio button set, the checkboxes in a checkbox set, or multiple buttons that should appear side-by-side can be grouped in a controlgroup.

Example:

O4WSectionStart(“questionOneSection”, O4WMobileOptions(“fieldcontain”))
O4WText(“Enter your name”)
O4WTextbox(“”, “”, “”, “name”, “q1name”)
O4WSectionEnd(“questionOneSection”)
O4WSectionStart(“buttonSection”, O4WMobileOptions(“controlgroup”))
O4WButton(“Cancel”, “BTN_CANCEL”)
O4WButton(“OK”, “BTN_OK”)
O4WSectionEnd(“buttonSection”)

By default, buttons will be grouped vertically. To group horizontally, apply the “horizontal” option to the “data-group” O4WDataStyle.

Example:

O4WSectionStart(“buttonSection”, O4WMobileOptions(“controlgroup”):O4WDataStyle(“”,”data-type”,”horizontal”))
O4WButton(“Cancel”, “BTN_CANCEL”)
O4WButton(“OK”, “BTN_OK”)
O4WSectionEnd(“buttonSection”)

Accessibility Enhancement

The O4WTextOptions allows you to associate a “label” with an input element, such as a textbox, radio button, etc. This allows the browser to identify which input element is described by the label, and this information can be rendered more appropriately (for example, the label and input control can be kept together even on the smaller mobile screen) or in more accessible ways (for example, if a screen reader is speaking the page aloud).

Example:

O4WSectionStart(“questionOneSection”, O4WMobileOptions(“fieldcontain”))
O4WText(“Enter your name”, “”, O4WTextOptions(“q1name”))
O4WTextbox(“”, “”, “”, “name”, “q1name”)
O4WSectionEnd(“questionOneSection”)

When using a radio button set or checkbox set, the labels that describe each radio button or checkbox are automatically associated with each radio button or checkbox; to set the overall label for the set (rather than for an individual element), O4WFieldsetOptions must be applied to the section that contains the set.

Example:

O4WSectionStart(“questionTwoSection”,O4WMobileOptions(“fieldcontain”))
O4WSectionStart(“questionTwoSet”, O4WFieldsetOptions(“Agree to the terms”))
O4WCheckbox(“I agree”, “1”, “checkbox_1”,”checkbox_1”)
O4WSectionEnd(“questionTwoSet”)
O4WSectionEnd(“questionTwoSection”)

You can apply the O4WfieldSetOptions to a section, in conjunction with the “controlgroup” role, to identify (for accessibility purposes) that these related elements are grouped together in your form. For example, the radio buttons in a radio button set, the checkboxes in a checkbox set, or multiple buttons that should appear side-by-side can be grouped in a fieldset with the controlgroup.

Example:

O4WSectionStart(“questionTwoSection”, O4WMobileOptions(“fieldcontain”))
O4WSectionStart(“qtwoFieldset”, O4WFieldsetOptions(“Agree to the terms”):O4WMobileOptions(“controlgroup”))
O4WCheckbox(“I agree”, “1”, “checkbox_1”,”checkbox_1”)
O4WSectionEnd(“qtwoFieldset”)
O4WSectionEnd(“questionTwoSection”)
O4WSectionStart(“buttonSection”, O4WMobileOptions(“controlgroup”))
O4WButton(“Cancel”, “BTN_CANCEL”)
O4WButton(“OK”, “BTN_OK”)
O4WSectionEnd(“buttonSection”)

Special Textbox Types

HTML5 compliant browsers (including newer mobile browsers) can enhance a textbox - for example, to limit the types of characters that can be typed, or by displaying a custom keyboard for the specific type of input – if the type of input can be specified. O4W provides some specific APIs that already change the “type” of the input (such as O4WPwdBox and O4WNumberBox); you can also use O4W’s O4WInputBoxOptions to specify any additional type of input (such as “email”, “tel”, “number”, “search”).

Example:

O4WSectionStart(“questionThreeSection”, O4WMobileOptions(“fieldcontain”))
O4WText(“Enter your email: “, “”, O4WTextOptions(“emailAdd”))
O4WTextbox(“”, “”, “”, “emailAdd”, “emailAdd”, O4WInputBoxOptions(“email”))
O4WSectionEnd(“questionThreeSection”)
O4WSectionStart(“questionFourSection”, O4WMobileOptions(“fieldcontain”))
O4WText(“Enter your age: “, “”, O4WTextOptions(“age”))
O4WNumberBox(“”, “”, “”, “0”,”120”,””,”1”,”age”,”age”)
O4WSectionEnd(“questionFourSection”)

Enhanced Listboxes

By applying the O4WMobileOptions API with “slider” specified, you can turn a listbox into a “slider”, which is much easier for users to select manually. Note that a slider should contain ONLY two options.

Example:

O4WSectionStart(“sliderSection”, O4WMobileOptions(“fieldcontain”))
O4WText(“Flip switch”, “”, O4WTextOptions(“flipSelect”))
O4WListboxStart(“myslider”, “flipSelect”, O4WMobileOptions(“slider”))
O4WListbox(“No”, “N”, “myslider”, “”, “flipSelect_N”)
O4WListbox(“Yes”, “Y”, “myslider”, “”, “flipSelect_Y”)
O4WListboxEnd()
O4WSectionEnd(“sliderSection”)

Enhanced Lists

Use the O4WMobileOptions “listview” parameter to turn normal O4W lists (controlled by O4WListStart, O4WListItem, and O4WListEnd API calls) into mobile-friendly output; both numbered and unnumbered lists will be converted, and nested lists will be displayed appropriately as well. By using additional mobile API call, it is possible to insert list dividers, counts, etc. into the list output.

Use the O4WMobileOptions API call with the “list-divider” parameter to turn a list item into a divider.

Example:

O4WListStart(“0”, “myList”, O4WMobileOptions(“listview”))
O4WListItem(“”, O4WMobileOptions(“list-divider”))
O4WText(“A”)
O4WListItem()
O4WLink(“Adam”, O4W_LINKTYPE_LOCAL$, “#adam”)
O4WListItem()
O4WLink(“Alan”, O4W_LINKTYPE_LOCAL$, “#alan”)
O4WListItem(“”, O4WMobileOptions(“list-divider”))
O4WText(“B”)
O4WListItem()
O4WLink(“Barry”, O4W_LINKTYPE_LOCAL$, “#barry”)
O4WListItem()
O4WLink(“Betty”, O4W_LINKTYPE_LOCAL$,”#betty”)
O4WListEnd(“myList”)

A list can be made “searchable” by using the O4WDataStyle API with the “data-filter” set to “true”; a textbox will then automatically be added to the start of the list.

Example:

O4WListStart(“0”, “myList”, O4WMobileOptions(“listview”):O4WDataStyle(“”,”data-filter”,”true”))
O4WListItem(“”, O4WMobileOptions(“list-divider”))
O4WText(“A”)
O4WListItem()
O4WLink(“Adam”, O4W_LINKTYPE_LOCAL$, “#adam”)
O4WListItem()
O4WLink(“Alan”, O4W_LINKTYPE_LOCAL$, “#alan”)
O4WListItem(“”, O4WMobileOptions(“list-divider”))
O4WText(“B”)
O4WListItem()
O4WLink(“Barry”, O4W_LINKTYPE_LOCAL$, “#barry”)
O4WListItem()
O4WLink(“Betty”, O4W_LINKTYPE_LOCAL$,”#betty”)
O4WListEnd(“myList”)

To add a “count bubble” to the list item, you need to apply the “ui-li-count” class to the number you want displayed. This is done via the O4WText call inside the list item.

Example:

O4WListStart(“0”, “myList”, O4WMobileOptions(“listview”))
O4WListItem(“”, O4WMobileOptions(“list-divider”))
O4WText(“A”)
O4WText(“2”, “”, “ui-li-count”)
O4WListItem()
O4WLink(“Adam”, O4W_LINKTYPE_LOCAL$, “#adam”)
O4WListItem()
O4WLink(“Alan”, O4W_LINKTYPE_LOCAL$, “#alan”)
O4WListItem(“”, O4WMobileOptions(“list-divider”))
O4WText(“B”)
O4WText(“3”, “”, “ui-li-count”)
O4WListItem()
O4WLink(“Barry”, O4W_LINKTYPE_LOCAL$, “#barry”)
O4WListItem()
O4WLink(“Betty”, O4W_LINKTYPE_LOCAL$,”#betty”)
O4WListItem()
O4WLink(“Bob”, O4W_LINKTYPE_LOCAL$,”#bob”)
O4WListEnd(“myList”)

Mobile Pizza Ordering Application

O4W_MMM_PIZZA
Subroutine O4W_MMM_PIZZA(CTLENTID, EVENT, REQUEST)

$Insert O4WCOMMON

$Insert O4WEQUATES

 

pageOptions = o4wmobileoptions("page","b"):O4WDataStyle("", "data-add-back-btn", "true")

hdrOptions = o4wmobileoptions("header")

contentOptions = o4wmobileoptions("content")

dialogOptions = o4wmobileoptions("dialog","b")

 

Begin Case

            Case EVENT _EQC "CREATE"

                        O4WSetMobile(1)

                        O4WFORM()

 

                        * build first page of mobile application

                        O4WSectionStart("menuPage", pageOptions)

                        O4WSectionStart("menuHdr", hdrOptions)

                        O4WHeader("mmmPizza Menu", 3)

                        * build the navigation bar

                        Gosub makeNav

                        O4WSectionEnd("menuHdr")

                        O4WBreak()

                        O4WBreak()

                        O4WSectionStart("menuContent", O4WMarkedOptions('1'):contentOptions)

                        Gosub buildMenu

                        O4WButton("Submit Order", "BTN_SUBMIT", O4WMarkedOptions('1'))

                        O4WQualifyEvent("BTN_SUBMIT", "CLICK")             

                        O4WSectionEnd("menuContent")

                        O4WSectionEnd("menuPage")

                       

                        * build second page

                        O4WSectionStart("locPage", pageOptions)

                        O4WSectionStart("locHdr", hdrOptions)

                        O4WHeader("mmmPizza Locations", 3)

                        * use same menu bar

                        Gosub makeNav

                        O4WSectionEnd("locHdr")

                        O4WBreak()

                        O4WBreak()

                        O4WSectionStart("locContent", O4WMarkedOptions('1'):contentOptions)

                        * use standard O4W API to build this output

                        O4WTableStart("locTable", o4wmobiletableoptions("1", "", "33"))

                        O4WSetCell(1, 1,'' , o4wtablecelloptions("","","1")) ;* mark as a 'header'

                        O4WText("Location: ")

                        O4WSetCell(1, 2)

                        address = "99 Kinderkamack Rd":@VM:"First Floor":@VM:"Westwood, NJ 07675"

                        * O4WText(address)

                        g_address = Delete(address, 1, 2, 0) ;* remove the 2nd address line for google display

                        Convert @VM To "," In g_address

                        O4WText(address)

                        o4wsetcell(2,2)

                        O4WLink("Map", O4W_LINKTYPE_NORMAL$, "http://maps.google.com/maps?q=":g_address, 'mapDisplayTab','' , O4WMobileButtonOptions('','','b'))

 

                        O4WTableEnd("locTable")

                        O4WSectionEnd("locContent")

                        O4WSectionEnd("locPage")

                       

                        * build a section for any dialogs we want to pop up

                        o4wsectionstart("menuDialogPage", o4wmarkedoptions("0"):dialogOptions)

                        O4WText("Thanks for your order!  Your order number is pending...")

                        o4wsectionend("menuDialogPage")

                       

 

            Case event _eqc "CLICK"

                        O4WResponse()

                        * Load in the submitted order

                        BSTICKS = O4WGetValue("BSTICKS")

                        GBREAD = O4WGetValue("GBREAD")

                        WINGS = O4WGetValue("WINGS")

                        * Display an acknowledgement

                        o4wsectionstart("menuDialogPage", dialogOptions:o4wresponseoptions())

                        O4WSectionStart("dlgHdr", hdrOptions)

                        O4WHeader("mmmPizza Order", 3)

                        O4WSectionEnd("dlgHdr")

                        O4WBreak()

                        O4WBreak()

                        O4WSectionStart("dlgContent", O4WMarkedOptions('0'):contentOptions)

                        * use standard O4W API to build this output

                        O4WText("Thanks for your order!  We're busy baking it right right...your order number is #":DATE():TIME())

                        O4WSectionEnd("dlgContent")

                        o4wsectionend("menuDialogPage")

                        O4WDialog("menuDialogPage", "Order Received")

                       

                       

End Case

 

Return 0

 

makeNav:

                        * create menu bar

                        o4wsectionstart("pizzaNavbar", O4WMobileOptions("navbar"))

                        o4wliststart(0)

                        o4wlistitem()

                        O4WLink("Menu", O4W_LINKTYPE_LOCAL$, "menuPage")

                        o4wlistitem()

                        O4WLink("Location", O4W_LINKTYPE_LOCAL$, "locPage")

                        o4wlistend()

                        o4wsectionend("pizzaNavbar")

Return

 

buildMenu:

            O4WSectionStart("menuGroups", o4wmobileoptions("collapsible-set"):o4wmarkedoptions("0"))

 

            O4WSectionStart("appDetails", o4wmobileoptions("collapsible"):o4wmarkedoptions("0"))

            o4wheader("Appetizers", 3)

            O4WText("Bread Sticks", "", O4WTextOptions("BSTICKS"))

            O4WRadioButton("No", "0", "BSTICKS", "BSTICKS_0", o4wmarkedoptions(1))

            O4WRadioButton("Yes", "1", "BSTICKS", "BSTICKS_1")

            o4wbreak()

            O4WText("Garlic Bread", "", O4WTextOptions("GBREAD"))

            O4WRadioButton("No", "0", "GBREAD", "GBREAD_0", o4wmarkedoptions(1))

            O4WRadioButton("Yes", "1", "GBREAD", "GBREAD_1")

            o4wbreak()

            O4WText("Hot Wings", "", O4WTextOptions("WINGS"))

            O4WListBox("None", "0", "WINGS", "", "WINGS_0", o4wmarkedoptions(1))

            O4WListBox("Half Dozen", "6", "WINGS", "", "WINGS_6")

            O4WListBox("Dozen", "12", "WINGS", "", "WINGS_12")

            O4WListBox("Jumbo", "24", "WINGS", "", "WINGS_24")

            o4wbreak()

            o4wsectionEnd("appDetails")

           

            O4WSectionStart("entreeDetails", o4wmobileoptions("collapsible"):o4wmarkedoptions("0"))

            o4wheader("Entrees", 3)

            O4WText("Pizza", "", O4WTextOptions("PIZZA"))

            O4WListBox("Personal", "1", "PIZZA", "", "PIZZA_1", o4wmarkedoptions(1))

            O4WListBox("Medium", "2", "PIZZA", "", "PIZZA_2")

            O4WListBox("Large", "3", "PIZZA", "", "PIZZA_3")

            o4wbreak()

            o4wsectionstart("toppingsChoices", o4wmobileoptions("fieldcontain"):o4wmarkedoptions("0"))

            opts = O4WFieldsetOptions("Toppings"):O4WMOBILEOPTIONS("controlgroup"):o4wmarkedoptions("0")

            o4wsectionstart("toppingsFieldset", opts)

            O4WCheckBox("Pepperoni", "P", "TOPPINGS", "TOPPINGS_P")

            O4WCheckBox("Sausage", "S", "TOPPINGS", "TOPPINGS_S")

            O4WCheckBox("Ham", "H", "TOPPINGS", "TOPPINGS_H")

            O4WCheckBox("Meatball", "M", "TOPPINGS", "TOPPINGS_M")

            O4WCheckBox("Chicken", "C", "TOPPINGS", "TOPPINGS_C")

            o4wsectionend("toppingsFieldset")

            o4wsectionstart("toppingsChoices")

            o4wbreak()

            O4WText("Sauce", "", O4WTextOptions("SAUCE"))

            O4WRadioButton("Red", "0", "SAUCE", "SAUCE_0", o4wmarkedoptions(1))

            O4WRadioButton("White (Garlic)", "1", "SAUCE", "SAUCE_1")

            o4wbreak()

            o4wsectionEnd("entreeDetails")

 

            O4WSectionStart("drinkDetails", o4wmobileoptions("collapsible"):o4wmarkedoptions("0"))

            o4wheader("Drinks", 3)

            o4wsectionstart("sodaChoices", o4wmobileoptions("fieldcontain"):o4wmarkedoptions("0"))

            o4wsectionstart("sodaFieldset", O4WFieldsetOptions("Soda"):O4WMOBILEOPTIONS("controlgroup"):o4wmarkedoptions("0"))

            O4WCheckBox("Coke", "C", "SODA", "SODA_C")

            O4WCheckBox("Diet Coke", "D", "SODA", "SODA_D")

            O4WCheckBox("Sprite", "S", "SODA", "SODA_S")

            o4wsectionend("sodaFieldset")

            o4wsectionend("sodaChoices")

            o4wbreak()

            o4wsectionstart("juiceChoices", o4wmobileoptions("fieldcontain"):o4wmarkedoptions("0"))

            o4wsectionstart("juiceFieldset", O4WFieldsetOptions("Juices"):O4WMOBILEOPTIONS("controlgroup"):o4wmarkedoptions("0"))

            O4WCheckBox("Apple", "A", "JUICE", "JUICE_A")

            O4WCheckBox("Orange", "O", "JUICE", "JUICE_O")

            O4WCheckBox("Cranberry", "C", "JUICE", "JUICE_C")

            o4wsectionend("juiceFieldset")

            o4wsectionend("juiceChoices")

            o4wbreak()

            o4wsectionEnd("drinkDetails")

 

            O4WSectionStart("dessertDetails", o4wmobileoptions("collapsible"):o4wmarkedoptions("0"))

            o4wheader("Desserts", 3)

            O4WText("Cheesecake", "", O4WTextOptions("CCAKE"))

            O4WRadioButton("No", "0", "CCAKE", "CCAKE_0", o4wmarkedoptions(1))

            O4WRadioButton("Yes", "1", "CCAKE", "CCAKE_1")

            o4wbreak()

            O4WText("Italian Ice", "", O4WTextOptions("ICE"))

            O4WListBox("None", "0", "ICE", "", "ICE_0", o4wmarkedoptions(1))

            O4WListBox("Cherry", "1", "ICE", "", "ICE_1")

            O4WListBox("Lemon", "2", "ICE", "", "ICE_2")

            o4wbreak()

            o4wsectionEnd("dessertDetails")

 

            O4WSectionEnd("menuGroups")

return

Building Paginated tables

The O4W table commands (O4WTableStart, O4WTableEnd, O4WSetCell, etc.) can be used to easily build a table that contains the equivalent of many pages worth of data. For an optimum user experience, however, the table data should be paginated to present only a reasonable subset of that data at any one time. In addition, other table enhancements - including the ability to re-sort the data - enhances the usefulness of the table.

When developing an O4W application, it is certainly possible to explicitly apply a "pagination" plugin to the O4W table you are generating, but O4W includes a standard pagination interface that allows the end user to choose their preferred paginator, and allows developers to create their own pagination routines which can be dynamically selected. The O4W Report Designer, for example, allows the customer designing the report to choose from any pagination routine that complies with the O4W pagination interface. Developers can therefore provide a more customizable application by using the O4WTablePagerStyle with their O4W tables, and designing their O4W stored procedures appropriately.

To use the built-in table pagination routines, you must apply the O4WTablePager style to your table in the O4WTableStart call. For example:

O4WTableStart("myTable", O4WTablePagerStyle("", "-1", "20", "1":@vm:"2", "50", "1"))

The API for the O4WTablePagerStyle call is O4WTablePagerStyle(ID, pagerLocn, rowsperpage, sortablecols, maxrows, currPage, Options, whichPager), where:

ID is the optional name to use when referencing this style;

pagerLocn is a flag indicating where the pagination section should be located (-1 = above the table, 1 = below the table);

rowsperpage is the number of rows to display per page in the table;

sortablecols is an @VM delimited list of which columns should be sorted;

maxrows is the maximum number of rows in the table (if known);

currPage is the current page of the table;

options are any HTML "name/value pairs" you wish the pagination routine to provide to O4W;

whichPager is an optional override to specify an explicit table pagination routine (if not specified, the default value from the configuration record is used)

After starting the table definition process, your code should create the table column headers, and then finish the table with the O4WTableEnd call:

O4WTableStart("myTable", O4WTablePagerStyle("", "-1", "20", "1":@vm:"2", "", "1"))

O4WTableHeader("ID", 1)

O4WTableHeader("Company", 2)

O4WTableHeader("State", 3)

O4WTableHeader("Phone", 4)

O4WTableEnd("myTable")

AT THIS POINT, YOU DO NOT NEED TO DEFINE THE DATA THAT COMPOSES THE TABLE (via O4WSetCell and any other O4W calls). You may, however, wish to generate the results that _will_ be returned when requested, and save this information in a table (for example, the O4WTempFile%) using a key you can associate with this table.

Since different pagination routines will require different amounts of data, you cannot determine how many rows to display initially. Instead, your code must be prepared to recieve the TABLE_BUILD_PAGE event; passed with that event will be the details of how many rows to generate. This style of programming is called "handling a callback". Your code might look like this:

...

BEGIN CASE

   CASE EVENT _EQC "CREATE"

       * Handle initial creation of form

       ...

   CASE EVENT _EQC "TABLE_BUILD_PAGE"

       * Respond to 'build page' request

       whichTable = ctlEntId

       stRow = O4WGetValue("O4WStartRow")

       numRows = O4WGetValue("O4WNumRows")

       rppg = O4WGetValue("O4WRowsPerPage")

       initialCall = O4WGetValue("O4WTableInit")

       if stRow = "-1" then

          * special case - move to last page

       end

       if numRows = "-1" then

          * special case - generate ALL the rows

       end

       currPage = int(stRow/rppg)+1

Note that there are several values available to your routine in the TABLE_BUILD_PAGE callback. These include:

O4WTableInit - a flag (set to "1" if true) indicating that this is the initialization call from the pagination control;

O4WStartRow - the row number in the list of results to start processing from. If set to "-1", the pagination routine wants the "last page" of data;

O4WNumRows - the number of rows to return from the list of results. If set to "-1", the pagination routine wants all the results returned at one time;

O4WRowsPerPage - the number of rows/page. If this is an initialization call, your routine may choose to override this value with any default values you wish. On non-initialization calls, this value may have been changed by the end-user on the browser, and thus should be respected

Your code should generate a "response" for the table, calculated using these values, containing all the relevant rows, and including again the O4WTablePagerStyle (updated as appropriate). For example, assuming that the selected data from the CUSTOMERS table are stored in the O4WTempFile% with a record ID of O4WSessionID%:"*myTable", your code might now look like this:

...

BEGIN CASE

   CASE EVENT _EQC "CREATE"

       * Handle initial creation of form

       ...

   CASE EVENT _EQC "TABLE_BUILD_PAGE"

buildPage: * Respond to 'build page' request

       O4WResponse()

       * which table are we building?

       whichTable = ctlEntId

       * load in the previously-generated list of data

       read rowInfo from O4WTempFile%, O4WSessionID%:"*":whichTable else rowInfo = ""

       * how many rows are there in this data overall?

       rowCount = DCount(rowInfo, @FM)

       * pull in the various passed values from the pagination routine

       stRow = O4WGetValue("O4WStartRow")

       numRows = O4WGetValue("O4WNumRows")

       rppg = O4WGetValue("O4WRowsPerPage")

       initialCall = O4WGetValue("O4WTableInit")

       if initialCall = "1" then rppg = 20 ;* default to 20 rows/page on the paginator

       * was this a special case of the starting row?

       if stRow = "-1" then

          * special case - move to last page

          lastPage = rowCount / rppg

          if lastPage <> int(lastPage) then lastPage = int(lastPage)+1

          stRow = (lastPage-1)*rppg+1

       end

       * was this a special case of the ending row?

       if numRows = "-1" then

          * special case - generate ALL the rows

          stRow = 1

          endRow = rowCount

       end else

          endRow = stRow + rppg

       end

       * sanity check

       if endRow > rowCount then endRow = rowCount

       * determine what our current page is

       currPage = int(stRow/rppg)+1

       * build the table with results

       BEGIN CASE

          CASE whichTable = "myTable"

             * Note that the O4WTablePagerStyle parameters are changed to reflect the current values

             O4WTableStart("myTable", O4WResponseStyle():O4WTablePagerStyle("", "-1", rppg, "1":@vm:"2", rowCount, currPage))

             For each.row = stRow to edRow

                For each.col = 1 to 4

                   O4WSetCell(each.row, each.col)

                   O4WText(rowInfo<each.row, each.col>)

                Next each.col

             Next each.row

             O4WTableEnd("myTable")

       END CASE

The TABLE_BUILD_PAGE event will be called as needed by the relevant pagination plugin to generate one or more pages of results. If the selected paginator handles all sorting and display on the client browser, the TABLE_BUILD_PAGE event may be called only one time for all the results; if the selected paginator handles the sorting and pagination locally (in OpenInsight), the TABLE_BUILD_PAGE event may be called many times.

Similarly, the paginator may generate the TABLE_SORT event when the user clicks on a column that has been marked as sortable. Your code must be prepared to respond to this event also (if column sorting is enabled). The TABLE_SORT event will have specific values passed to it from the paginator, in addition to the values that the TABLE_BUILD_PAGE event generates (in fact, you may choose to handle both events in the same block of code, or at least call a common routine to handle the page redisplay after the sorting event).

The TABLE_SORT event will include the following passed values (in addition to those described with the TABLE_BUILD_PAGE event):

O4WSortCol - the column number to sort;

O4WSortDir - A flag indicating ascending ('1') or descending ('0') sort

Your code should be designed to re-sort the data based on the specified sort column and direction; this might be done via an RLIST SELECT statement, or basic+ SELECT/BY syntax, or handled internally, or via a call to V119. For example, using the V119 routine:

...

Case event _eqc "TABLE_SORT"

   * asked to resort the table

   * which table are we building?

   whichTable = ctlEntId

   * load in the previously-generated list of data

   read rowInfo from O4WTempFile%, O4WSessionID%:"*":whichTable else rowInfo = ""

   * how many rows are there in this data overall?

   rowCount = DCount(rowInfo, @FM)

   * pull in the various passed values from the pagination routine

   sortDir = O4WGetValue("O4WSortDir")

   sortCol = O4WGetValue("O4WSortCol")

   num.sort = dcount(sortCol, @vm)

   * move desired sort field to the front

   sortedRows = ""

   For each.row = 1 To rowCount

      this.row = rowInfo<each.row>

      For each.sort = num.sort to 1 step -1

         this.sortCol = sortCol<1, each.sort>

         sortVal = this.row<1, this.sortcol>

         this.row = sortVal:@FM:this.row

      next each.sort

      sortedRows := this.row:@RM

   Next each.row

   * pass this into V119

   Bys = ""

   Justs = ""

   for each.sort = 1 to num.sort

      this.sortDir = sortDir<1, each.sort>

      If this.sortDir = "1" then

         Bys := "A"

      End Else

         Bys := "D"

      End

      * determine whether this field should be r or l justified

      ...

      if whichJust = "R" then

         Justs := "R"

      End else

         Justs := "L"

      End

   End

   Call V119("S", "", Bys, Justs, sortedRows)

   * rearrange back to normal

   rowInfo = ""

   For each.row = 1 To rowCount

      this.row = Field(sortedRows, @RM, each.row)

      for each.sort = 1 to num.sort

         this.row = Delete(THIS.ROW, 1, 0, 0)

      next each.sort

      rowInfo<-1> = this.row

   Next each.row

   Write rowinfo On O4WTempFile%, O4WSessionID%:"*":whichTable

   * rows are now properly re-sorted; rebuild our page as normal

   Goto buildPage

The TABLE_SORT event will be called as needed by the relevant pagination plugin to sort (or re-sort) the results. If the selected paginator handles all sorting and display on the client browser, the TABLE_SORT event may never be generated; if the selected paginator handles the sorting and pagination locally (in OpenInsight), the TABLE_SORT event may be called many times.

Although coding in this fashion appears to be "extra work", by using the O4WTablePagerStyle in conjunction with your O4WTableStart call, and designing your application to respond to the TABLE_BUILD_PAGE and TABLE_SORT events, you will allow your application to take advantage of any future pagination/sorting plugins that may be developed and distributed for O4W.