B4J Tutorial [ABMaterial] B4JS - 07 The UI connection (part 2)

Discussion in 'B4J Tutorials' started by alwaysbusy, Mar 22, 2018.

  1. alwaysbusy

    alwaysbusy Expert Licensed User

    See for a B4JS introduction: https://www.b4x.com/android/forum/threads/abmaterial-b4js-0-9.90249/
    -------------------------------------------------------------------------------

    This is the second part of the UI(ABMaterial) Connection. I wanted to do this one before releasing ABM 4.25 because it contains some important concepts on defining the events for B4JS in an ABMPage.

    I've created a B4JS Demo that includes the source code for all the tutorials (so far). It will be included in the download zip.

    One of the major advantages of B4JS is that you can check a lot of the users input before heading to the server. And because we have some events (like KeyDown, KeyUp) that we do not have on the server side, we can even do some 'masking'.

    This example does such a mask for a credit card (every 4 chars a space is inserted en a size check is done). It is not finished (e.g. it does not take into account if the user puts its cursor in the middle), but it shows some concepts of B4JS.

    [​IMG]

    The B4JS class B4JSInputChecker:
    Code:
    'Class module
    Sub Class_Globals
       
    Private Page As ABMPage 'ignore, just to be able to run ABMPage functions
       Private ToastID As Int
       
    Private ABM As ABMaterial 'ignore, just to be able to use ABM constants
    End Sub

    'Initializes the object. You can add parameters to this method if needed.
    Public Sub InitializeB4JS
      
    End Sub

    public Sub InputDown(Key As StringAs Boolean
       
    'Log("Down key: " & Key)
       Dim cardInp As ABMInput 'ignore that it is not initialized, you can't initialize one in B4JS anyway
       cardInp.B4JSUniqueKey = "cardInp001"
       
    Dim CardNumber As String = cardInp.B4JSText
       
    If Key = "Backspace" Then
           
    If CardNumber.SubString2(0,CardNumber.Length-1).EndsWith(" "Then
               CardNumber = CardNumber.SubString2(
    0,CardNumber.Length - 2)
               cardInp.B4JSText = CardNumber  
               CheckCard(CardNumber.Replace(
    " """))
               
    ' consume the event      
               Return True
           
    End If
           
    ' let the Keydown do its thing
           Return False
       
    End If
      
       
    If CardNumber.Length = 19 Then
           CheckCard(CardNumber.Replace(
    " """))
           
    Return True      
       
    End If
      
       
    If Not(IsNumber(Key)) Then
           ToastID = ToastID + 
    1
           
    Page.B4JSShowToast("InputToast" & ToastID, "red""Please only enter numbers!"3000False)
           
    ' consume the event
           Return True
       
    End If
      
       
    ' let the Keydown do its thing
       Return False
    End Sub

    public Sub InputUp(KeyCode As Int) As Boolean
       
    'Log("Up keycode: " & KeyCode)
      
       
    Dim cardInp As ABMInput 'ignore that it is not initialized, you can't initialize one in B4JS anyway
       cardInp.B4JSUniqueKey = "cardInp001"
       
    Dim CardNumber As String = cardInp.B4JSText
      
       
    ' we down't want to raise it for the combination keys
       ' AltGraph, Shift, Ctrl, Alt
       Select Case KeyCode
           
    Case 161718
               
    ' consume the event
               Return True
           
    Case 8 ' and for the backspace, jump out too: we do not want to re-append the space
               ' consume the event
               CheckCard(CardNumber.Replace(" """))
               
    Return True
       
    End Select
      
       
    Select Case CardNumber.Length
           
    Case 4,9,14
               cardInp.B4JSText = CardNumber & 
    " "          
       
    End Select
      
       
    'a valid 4012 8888 8888 1881
       CheckCard(CardNumber.Replace(" """))
      
       
    ' consume the event
       Return True
    End Sub

    public Sub CheckCard(CardNumber As String)
       
    'a valid 4012 8888 8888 1881
       Dim isValid As Boolean = Page.B4JSRunInlineJavascriptMethod("validateCCNum"Array As Object(CardNumber.Replace(" """)))
       
    Dim btnCheck As ABMButton 'ignore
       btnCheck.B4JSUniqueKey = "btnCheck"
       
    ' for our setButtonCSS method we do need the real ID of the button.  We can get this with the Page.B4JSGetComponentIDFromUniqueID() method!
       Dim ID As String = Page.B4JSGetComponentIDFromUniqueID("btnCheck")  
       
    If isValid Then
           btnCheck.B4JSEnabled = 
    True
           
    Page.B4JSRunInlineJavascriptMethod("setButtonCSS"Array As String(ID"background-color: #4caf50 !important"))
       
    Else
           btnCheck.B4JSEnabled = 
    False
           
    Page.B4JSRunInlineJavascriptMethod("setButtonCSS"Array As String(ID"background-color: #F44336 !important"))
       
    End If
    End Sub

    ' every method you want to call with a B4JSOn... call MUST return a boolean
    public Sub InputGotFocus() As Boolean
       ToastID = ToastID + 
    1
       
    Page.B4JSShowToast("InputToast" & ToastID, "red""You are entering the Credit Card"3000False)
       
    ' consume the event
       Return True
    End Sub

    ' every method you want to call with a B4JSOn... call MUST return a boolean
    public Sub InputLostFocus() As Boolean
       ToastID = ToastID + 
    1
       
    Page.B4JSShowToast("InputToast" & ToastID, "red""Leaving the Credit Card field..."3000False)
       
    ' consume the event
       Return True
    End Sub

    ' every method you want to call with a B4JSOn... call MUST return a boolean
    public Sub CheckInput() As Boolean
       
    Dim switch1 As ABMSwitch  'ignore that it is not initialized, you can't initialize one in B4JS anyway
       switch1.B4JSUniqueKey = "switch001"
      
       
    Dim HasError As Boolean = False
      
       ToastID = ToastID + 
    1
       
    If Not(switch1.B4JSState) Then
           
    Page.B4JSShowToast("SwitchToast" & ToastID, "green""Please put the Switch to ON!"3000False)      
           HasError = 
    True
       
    End If
      
       ToastID = ToastID + 
    1
       
    Dim CheckBox1 As ABMCheckbox 'ignore that it is not initialized, you can't initialize one in B4JS anyway
       CheckBox1.B4JSUniqueKey = "CheckBox001"
       
    If Not(CheckBox1.B4JSState) Then
           
    Page.B4JSShowToast("CheckboxToast" & ToastID, "green""Please check the Checkbox!"3000False)
           HasError = 
    True
       
    End If
      
       
    If HasError = False Then  
           ToastID = ToastID + 
    1
           
    Page.B4JSShowToast("CheckboxInput" & ToastID, "green""All looks OK, well done!"3000False)
       
    End If
       
    ' consume the event
       Return True
    End Sub

    ' every method you want to call with a B4JSOn... call MUST return a boolean
    public Sub SwitchClick() As Boolean
       
    Dim switch1 As ABMSwitch  'ignore that it is not initialized, you can't initialize one in B4JS anyway
       switch1.B4JSUniqueKey = "switch001"
      
       ToastID = ToastID + 
    1
       
    If switch1.B4JSState Then
           
    Page.B4JSShowToast("SwitchToast" & ToastID, "green""Switch is ON"3000False)
       
    Else
           
    Page.B4JSShowToast("SwitchToast" & ToastID, "green""Switch is OFF"3000False)
       
    End If
       
    ' consume the event
       Return True
    End Sub

    ' every method you want to call with a B4JSOn... call MUST return a boolean
    public Sub CheckBoxClick() As Boolean
       
    Dim CheckBox1 As ABMCheckbox 'ignore that it is not initialized, you can't initialize one in B4JS anyway
       CheckBox1.B4JSUniqueKey = "CheckBox001"
       ToastID = ToastID + 
    1
       
    If CheckBox1.B4JSState Then
           
    Page.B4JSShowToast("CheckboxToast" & ToastID, "green""Checkbox ON"3000False)
       
    Else
           
    Page.B4JSShowToast("CheckboxToast" & ToastID, "red""Checkbox OFF"3000False)
       
    End If
       
    ' consume the event
       Return True
    End Sub

    ' every method you want to call with a B4JSOn... call MUST return a boolean
    public Sub RadioClick() As Boolean
       
    Dim Radio1 As ABMRadioGroup 'ignore that it is not initialized, you can't initialize one in B4JS anyway
       Radio1.B4JSUniqueKey = "Radio001"
       ToastID = ToastID + 
    1
       
    Page.B4JSShowToast("RadioToast" & ToastID, "green""Active Radio = " &  Radio1.B4JSGetActive, 3000False)
       
    ' example of setting the active radio
       'If Radio1.B4JSGetActive = 0 Then
       '   Radio1.B4JSSetActive(2)
       'End If
       Return True
    End Sub

    public Sub RangeOnChange(start As String, Stop As String, ConsumeEvent As Boolean) As Boolean
       
    Log("B4JS Start: " & start)
       
    Log("B4JS Stop: " & Stop)
       
    Return ConsumeEvent
    End Sub

    #if JAVASCRIPT
    function setButtonCSS(id, val) {
       $('#' + id).attr('style', val);
    }
    #End If
    And creating the components in ConnectPage():
    Code:
    public Sub ConnectPage()
       
    '   connecting the navigation bar
       ABMShared.ConnectNavigationBar(page)
      
       
    page.Cell(1,1).AddComponent(ABMShared.BuildParagraph(page,"par1","This demo is practical example of B4JS. It uses the B4JSInputChecker B4JS class.") )
      
       
    ' input
       Dim cardInp As ABMInput
       cardInp.Initialize(
    page"inp1", ABM.INPUT_TEXT, "Credit Card"False"")
       cardInp.B4JSUniqueKey = 
    "cardInp001"
       
    ' special case, it has to pass at least the pressed key (ABM.B4JS_PARAM_INPUTKEY or ABM.B4JS_PARAM_INPUTKEYCODE) to it!
       cardInp.B4JSOnKeyDown("B4JSInputChecker""InputDown"Array As Object(ABM.B4JS_PARAM_INPUTKEY))  
       cardInp.B4JSOnKeyUp(
    "B4JSInputChecker""InputUp"Array As Object(ABM.B4JS_PARAM_INPUTKEYCODE))
       
    ' some focus stuff
       cardInp.B4JSOnGotFocus("B4JSInputChecker""InputGotFocus"Null)
       cardInp.B4JSOnLostFocus(
    "B4JSInputChecker""InputLostFocus"Null)
       
    page.Cell(2,1).AddComponent(cardInp)
      
       
    ' switch
       Dim switch1 As ABMSwitch
       switch1.Initialize(
    page"switch1""ON""OFF"False"")
       switch1.B4JSUniqueKey = 
    "switch001"
       switch1.B4JSOnClick(
    "B4JSInputChecker""SwitchClick"Null)
       
    page.Cell(3,1).AddComponent(switch1)
      
       
    ' checkbox
       Dim CheckBox1 As ABMCheckbox
       CheckBox1.Initialize(
    page"CheckBox1""B4JS Checkbox"False"")
       CheckBox1.B4JSUniqueKey = 
    "CheckBox001"
       CheckBox1.B4JSOnClick(
    "B4JSInputChecker""CheckBoxClick"Null)
       
    page.Cell(4,1).AddComponent(CheckBox1)
      
       
    ' radiogroup
       Dim Radio1 As ABMRadioGroup
       Radio1.Initialize(
    page"Radio1""")
       Radio1.B4JSUniqueKey = 
    "Radio001"
       Radio1.AddRadioButton(
    "radio 0"True)
       Radio1.AddRadioButton(
    "radio 1"True)
       Radio1.AddRadioButton(
    "radio 2"True)
       Radio1.SetActive(
    1)
       Radio1.B4JSOnClick(
    "B4JSInputChecker""RadioClick"Null)
       
    page.Cell(5,1).AddComponent(Radio1)
      
       
    ' range
       Dim range As ABMRange
       range.Initialize(
    page"range"102001001"")
       range.B4JSUniqueKey = 
    "range001"
       
    ' special case, it has to pass at least ABM.B4JS_PARAM_RANGESTART & ABM.B4JS_PARAM_RANGESTOP!
      
       range.B4JSOnChange(
    "B4JSInputChecker""RangeOnChange"Array As Object(ABM.B4JS_PARAM_RANGESTART, ABM.B4JS_PARAM_RANGESTOP, True))
       
    page.Cell(6,1).AddComponent(range)
      
       
    ' button
       Dim btnCheck As ABMButton
       btnCheck.InitializeFlat(
    page"btnCheck""""""Check""red")
       btnCheck.Enabled = 
    False
       btnCheck.B4JSUniqueKey = 
    "btnCheck"
       btnCheck.B4JSOnClick(
    "B4JSInputChecker""CheckInput"Null)
       
    page.Cell(7,1).AddComponent(btnCheck)  
      
       
    ' refresh the page
       page.Refresh
       
    ' Tell the browser we finished loading
       page.FinishedLoading
       
    ' restoring the navigation bar position
       page.RestoreNavigationBarPosition
    End Sub
    As you see, for every component we want to use in a B4JS class, we have to set the B4JSUniqueKey property.

    We also define some events (B4JSOn...). You notice some of them have special parameters, e.g. the ABMInputs B4JSOnKeyDown event. This event MUST have at least the parameter ABM.B4JS_PARAM_INPUTKEY or ABM.B4JS_PARAM_INPUTKEYCODE to be able to work.

    For the B4JSOnKeyDown event for example, we pass the ABM.B4JS_PARAM_INPUTKEY param. The order of the params is very important!

    In our B4JS class, this is our method definition:
    Code:
    public Sub InputDown(Key As StringAs Boolean
    Here ABM.B4JS_PARAM_INPUTKEY's value will be put into the Key param.

    You can add additional params (if needed) as for example is done in the range.B4JSOnChange event declaration.

    This concludes the tutorial. I'm finishing up the download of ABM 4.25 for the donators today.

    Alwaysbusy
     
  2. little3399

    little3399 Active Member Licensed User

    Wait for the ABM 4.25 ...
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice