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.
The B4JS class B4JSInputChecker:
And creating the components in ConnectPage():
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:
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
-------------------------------------------------------------------------------
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.
The B4JS class B4JSInputChecker:
B4X:
'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 String) As 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!", 3000, False)
' 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 16, 17, 18
' 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", 3000, False)
' 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...", 3000, False)
' 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!", 3000, False)
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!", 3000, False)
HasError = True
End If
If HasError = False Then
ToastID = ToastID + 1
Page.B4JSShowToast("CheckboxInput" & ToastID, "green", "All looks OK, well done!", 3000, False)
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", 3000, False)
Else
Page.B4JSShowToast("SwitchToast" & ToastID, "green", "Switch is OFF", 3000, False)
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", 3000, False)
Else
Page.B4JSShowToast("CheckboxToast" & ToastID, "red", "Checkbox OFF", 3000, False)
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, 3000, False)
' 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():
B4X:
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", 10, 20, 0, 100, 1, "")
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:
B4X:
public Sub InputDown(Key As String) As 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