B4J Tutorial Creating a hotel reservation app with BANanoJQM

Hi there

First and foremost, thank you for making a decision to view and even read this thread. Whilst not being an expert in BANano and still learning the ropes, the article is mainly about the UX.

As you might be aware by now, BANano is the engine that knits your front event functionality and make things function well when developing such apps.

I created BANanoJQM due to the simplicity of the JQuery Mobile Web Application framework, besides that websites and webapps are something that are going to be here for a very long time. The HTML5 elements are the same across the board and have been added with 'make-up' by the various css and js plugins that exist.

HotelReservation.gif



BANanoJQM is an HTML5 wrapper on top of BANano to create JQuery Mobile based apps. What however has been done in the attached screen can be done with any potent web framework.

A previous article I posted looked into how I could utilize a rest api using BANano and it went well. I chose JQM for it again due to simplicity and ease of use, besides there are many ways to skin a cat.

The way BANanoJQM is created is such that you are able to create each page as a separate code module and just inject the generated HTML code to the body section of your main page of your SPA (Single Page App).

BANano creates all the needed UX elements during runtime and there are no static components and thus your browser, right click, view page source only provides css and js links and just the skeleton of your page.

BANanoJQM then has various components to enable one to create all the necessary html elements needed for a functional web application. Again, the methodology applied here could be different on how you would do things, either way, lets journey ahead.

You will need...

BANano
BANanoJQM 1.01

Reproduction

  • Create a new UX project in B4J and save it.
  • Reference BANano and reference BANAnoJQM
  • Ensure you unzip the BANanoJQM_Files.zip to your Files folder of your project.
  • I am also using XAMPP as a webserver but this is optional.
Main..

B4X:
Sub Process_Globals
    Public BANano As BANano 'ignore
    Public App As JQMApp
    Public AppName As String = "HotelReservation"
    Public jx As JFX
End Sub

Update your app_start to reference BANAnoJQM library resources.

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    'initialize banano for first use
    BANano.Initialize("BANano", AppName,1)
    'let us not use service workers
    BANano.UseServiceWorker = False
    BANano.HTML_NAME = "index.html"
    BANano.Header.Title = AppName
    'add needed files
    'loop through each file and add it
    modJQM.PrepareResources
    Dim fTot As Int = modJQM.Resources.Size - 1
    Dim fCnt As Int
    For fCnt = 0 To fTot
        Dim sFile As String = modJQM.Resources.GetValueAt(fCnt)
        If sFile.EndsWith(".css") Then
            BANano.Header.addcssfile(sFile)
        else if sFile.EndsWith(".js") Then
            BANano.Header.AddJavascriptFile(sFile)
        End If
    Next
   
    Dim url As String
    #if release
        'save to xampp folder
        BANano.Build("C:\xampp\htdocs")
        url = $"http://127.0.0.1/${AppName}/index.html"$
    #else
        BANano.build(File.dirapp)
        Dim appPath As String = File.Combine(File.DirApp,AppName)
        url = File.GetUri(appPath,"index.html")
    #end if
    jx.ShowExternalDocument(url)
    ExitApplication
End Sub

You can remove the lines that publish to Xampp and just leave BANano.Build(File.DirApp) app if you dont use xampp

Knitting your code.

Create a new code module, I called it reservations and update your main code to build the banano based app to.

B4X:
' HERE STARTS YOUR APP
Sub BANano_Ready()
    App.Initialize(AppName)
    reservations.Create(App)
End Sub

You can create multiple pages for your app and can also add them on the ready method.

Reservations...

Update the Process_Globals...

B4X:
'Static code module
Sub Process_Globals
    Public App As JQMApp
    Public Page As JQMPage
    Public ID As String = "reservations"
End Sub

The id above will be used to identify the page. Each page should have a unique id and each element across the SPA should have a unique id, you have one single html page afterall.

Creating the page...

To create the page, we use the Create sub routine.

B4X:
'create the page
Public Sub Create(thisApp As JQMApp)
    App = thisApp
    'create the page
    Page.Initialize(App,ID)
    Page.Header.Fixed = True
    'add a heading
    Page.Header.AddH1("", "Hotel Room Reservation")
    'add a left button to header
    Page.Header.AddLeftButton("btnl","Left","#main",App.EnumIcons.home,App.EnumIconpos.left,App.EnumTransition.slide,False,"")

A page is linked to the app with the App variable. This is to run universal methods on the application as a whole. We need a fixed header, add a heading to the page and then add a left button to go back to the main page.

We then create a form to add the form components.

B4X:
'add search
    frm.Content.AddSearch1("txtsearch","Search:","",False,True,True,True)
    'add name
    frm.Content.AddTextBox("txtname","Name:","",False,True,False,True)
    'add gender
    Dim gender As JQMSelect
    gender.Initialize(App,"gender","Gender:")
    gender.IsSlider = True
    gender.InFieldContain = True
    gender.AddOption1("male","Male ","Male")
    gender.AddOption1("female","Female ","Female")
    frm.Content.AddSelect(gender)
    'add age
    frm.Content.AddRange1("age","Age:","0","100","10",True,True)
    'hobbies
    Dim hobbies As JQMCheckboxGroup
    hobbies.Initialize(App,"hobbies","Hobbies:")
    hobbies.AddCheckbox("photography","Photography","photography")
    hobbies.AddCheckbox("writing","Writing","writing")
    hobbies.AddCheckbox("swimming","Swimming","swimming")
    hobbies.InFieldContain = True
    frm.Content.AddCheckBoxGroup(hobbies)

The code in Create is nothing else other than building each of the html elements as represented by the JQM framework. Their structure is per definition from the JQM website as they are the creators of JQM.
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Creating the preferences control box

The control box is made up of a collection of select elements with some choices.

B4X:
Dim cg As JQMControlGroup
    cg.Initialize(App,"cg","Preferences:")
    cg.Horizontal = True
    cg.InFieldContain = True
    cg.IsFieldSet = True
    
    Dim roomtype As JQMSelect
    roomtype.Initialize(App,"roomtype","Room Type:")
    roomtype.AddOption1("ordinary","Ordinary Room","ordinary")
    roomtype.AddOption1("luxury","Luxury Room","luxury")
    roomtype.AddOption1("suite","Suite","suite")
    
    Dim food As JQMSelect
    food.Initialize(App,"food","Food:")
    food.AddOption1("breakfast","Breakfast","breakfast")
    food.AddOption1("lunch", "Lunch","lunch")
    food.AddOption1("dinner","Dinner","dinner")
    
    Dim meal As JQMSelect
    meal.Initialize(App,"meal","Meal:")
    meal.AddOption1("veg","Vegetarian","vegetarian")
    meal.AddOption1("nonveg","Non Vegetarian","non vegetarian")
    
    'add preferences
    cg.Content.AddSelect(roomtype)
    cg.Content.AddSelect(food)
    cg.Content.AddSelect(meal)
    frm.Content.AddControlGroup(cg)
    'add submit
    frm.Content.AddInputButton("submit","Submit",True)
    App.AddEvent("submit", "click", "")
    
    'add form to page
    Page.Content.AddForm(frm)
    
    'add footer
    'append page to body
    Dim pgCode As String = Page.ToString
    App.Append("body", pgCode)
    'bind events after the body is updated
    App.BindEvents("sendformEvents", Me)
End Sub

We have room type, food and meal type options. The page html source is generated with Page.ToString and this is appended to already existing #body elements. Remember with JQM each page is defined as a template inside the main index.html page.

After the body element is build, my methodology is then to add events to each element that can have events and then bind them. For this page, all the events are bound to a single subroutine named sendFormEvents, this is defined as..

B4X:
'add events are bound to the same event handler
Sub sendformEvents(event As BANanoEvent)
    Dim actualID As String = App.GetID(event.ID)
    Log(actualID)
    Select Case actualID
        Case "submit"
            'the submit button has been clicked
            
    End Select
End Sub

One can then write the code to .GetValue, .GetChecked that BANano have to get the values and process them as they need.

Ta!
 

Mashiane

Expert
Licensed User
Longtime User
The second part of this will be a purported SMS Sender.

SendSMS.gif


There are some various elements here just to perform the basic tasks. The backend functionality again has not been included and anyone experienced with BANano can extend the application with another web framework and or perhaps push it to Cordova/PhoneGap to generate an apk. The sky is no longer the limit.

Anyway..

A new code module is created again, i call it sendform..
I set up the basic things needed to reference it...

B4X:
'Static code module
Sub Process_Globals
    Public App As JQMApp
    Public Page As JQMPage
    Public ID As String = "sendform"
End Sub

On create the header is configured including a back button...

B4X:
'create the page
Public Sub Create(thisApp As JQMApp)
    App = thisApp
    'create the page
    Page.Initialize(App,ID)
    Page.Header.Fixed = True
    'add a heading
    Page.Header.AddH1("", "Send SMS")
    'add a left button to header
    Page.Header.AddLeftButton("btnl","Left","#main",App.EnumIcons.home,App.EnumIconpos.left,App.EnumTransition.slide,False,"")
 

Mashiane

Expert
Licensed User
Longtime User
Adding form elements.

In this case, the form elements are hard coded but these can be read from a database directly.

B4X:
'create a form
    Dim frm As JQMForm
    frm.Initialize(App,"sendit")
    'create a combobox
    Dim contact As JQMSelect
    contact.Initialize(App,"contact","Contact:")
    contact.InFieldContain = True
    'create items in the combo
    Dim contacts As List
    contacts.Initialize
    contacts.Add("Bintu Harwani")
    contacts.Add("Chirag")
    contacts.Add("Kelly Martinez")
    contacts.Add("Laura")
    contacts.Add("David")
    contact.AddList(contacts)
    frm.Content.AddSelect(contact)
    'add an email
    frm.Content.AddEmail("email","Email:","",False,True,False,True)
    'add template
    Dim template As JQMSelect
    template.Initialize(App,"template","Select Template")
    template.InFieldContain = True
    template.AddOption1("mhr","Many Happy Returns","Many Happy Returns")
    template.AddOption1("abfe","All the best for Exams","All the best for Exams")
    template.AddOption1("wyhb","Wish you a very Happy Birthday","Wish you a very Happy Birthday")
    template.AddOption1("hanj","Have a nice and safe journey","Have a nice and safe journey")
    template.AddOption1("twbh","Tomorrow will be a Holiday","Tomorrow will be a Holiday")
    frm.Content.AddSelect(template)
    'add message
    frm.Content.AddTextArea("message","Custom Message:","",False,False,False,True,40,8)
    'add date
    frm.Content.AddDate("senddate","Select Date:","",False,True,False,True)
    'add time
    frm.Content.AddTime("sendtime","Select Time:","",False,True,False,True)
    
    Dim sg As JQMRadioGroup
    sg.Initialize(App,"periodtosend","Send")
    sg.InFieldContain = True
    sg.AddRadio("daily","Daily","daily",False)
    sg.AddRadio("monthly","Monthly","monthly",False)
    sg.AddRadio("yearly","Yearly","yearly",False)
    sg.AddRadio("specific","Specific","Specific date & time",True)
    frm.Content.AddRadioGroup(sg)
    'add button
    frm.Content.AddInputButton("submit","Submit",True)
    App.AddEvent("submit", "click", "")
    
    'add form to page
    Page.Content.AddForm(frm)
    
    'add footer
    'append page to body
    Dim pgCode As String = Page.ToString
    App.Append("body", pgCode)
    'bind events after the body is updated
    App.BindEvents("sendformEvents", Me)
End Sub

We have a contact list of people to contact, lets assume these are patrons for the hotel. We have an email section, the message to send to a person, a section to send a custom message, the date and time and the frequency to send text messages.

After the content is defined, its appended to the body of the main index.html page, events added and then bound using code.

One can then use their BANano experience to add setters and getters and backend database as needed.

Ta!
 
Top