See for a B4JS introduction: https://www.b4x.com/android/forum/threads/abmaterial-b4js-0-9.90249/
Note: for this tutorial, I may use some typical ABM things. You can ignore them as they are just to show the result of the code in this tutorial.
-------------------------------------------------------------------------------
This is another one of those fantastic B4X features that I wanted in B4JS: Inline Javascript.
Just like its big brothers, you can easily put javascript functions in a B4JS class. This last part is important: it will ONLY work in a B4JS class. But, as we will see further, you will be able to call the method in your normal ABM Page class.
So, suppose we found a nice method in Javascript to check a credit card. In your B4JS class, you can use #If JAVASCRIPT and #End If to define a javascript region. You can add multiple methods in one block if you want.
The result in the browsers console:
Pretty cool no?
A couple of things we see here in the code (besides the #if JAVASCRIPT part.
1. Calling a javascript function in your B4JS code using Page.B4JSRunInlineJavascriptMethod:
It is VERY important (unlike we are used in B4J, that the method name (here validateCCNum) matches the case. e.g. VAlidateCCNum will NOT work!
2. Calling a B4JS function in your B4JS code using Page.B4JSRunMethod:
And we're back on familiar B4X ground
The case of the method (or class) does not matter as all is lowercased anyway. Why do we have to mention the class, I hear you think. Well this is because we can call a method from ANOTHER B4JS class too!
And moreover, we can also call these methods in our normal ABM webpage!
So the result of method 1 (in the Browser log)
And the result of method 2 (in the B4J log)
In the next tutorial (04 - Running Javascript on the server side) I'll show how you can even run this on the server side, not even needing a browser open.
A final note: #if JAVASCRIPT regions do not really belong to the class. They are shared between all B4JS classes you create.
This concludes this tutorial.
Alwaysbusy
Note: for this tutorial, I may use some typical ABM things. You can ignore them as they are just to show the result of the code in this tutorial.
-------------------------------------------------------------------------------
This is another one of those fantastic B4X features that I wanted in B4JS: Inline Javascript.
Just like its big brothers, you can easily put javascript functions in a B4JS class. This last part is important: it will ONLY work in a B4JS class. But, as we will see further, you will be able to call the method in your normal ABM Page class.
So, suppose we found a nice method in Javascript to check a credit card. In your B4JS class, you can use #If JAVASCRIPT and #End If to define a javascript region. You can add multiple methods in one block if you want.
B4X:
Public Sub InitializeB4JS
Page.B4JSRunMethod("B4JSCalculateDistance", "cHECKCard", Array As String("5105105105105100"))
Page.B4JSRunMethod("B4JSCalculateDistance", "CheckCard", Array As String("111111"))
End Sub
public Sub CheckCard(cardNumber As String)
Dim isValid As Boolean = Page.B4JSRunInlineJavascriptMethod("validateCCNum", Array As Object(cardNumber))
If isValid Then
Log("Card '" & cardNumber & "' is a valid card. Please continue...")
Else
Log("Card '" & cardNumber & "' is NOT valid. Please check the number...")
End If
End Sub
#If JAVASCRIPT
function validateCCNum(ccnum) {
var ccCheckRegExp = /[^\d\s-]/;
var isValid = !ccCheckRegExp.test(ccnum);
var i;
if (isValid) {
var cardNumbersOnly = ccnum.replace(/[\s-]/g,"");
var cardNumberLength = cardNumbersOnly.length;
var arrCheckTypes = ['visa', 'mastercard', 'amex', 'discover', 'dinners', 'jcb'];
for(i=0; i<arrCheckTypes.length; i++) {
var lengthIsValid = false;
var prefixIsValid = false;
var prefixRegExp;
switch (arrCheckTypes[i]) {
case "mastercard":
lengthIsValid = (cardNumberLength === 16);
prefixRegExp = /^5[1-5]/;
break;
case "visa":
lengthIsValid = (cardNumberLength === 16 || cardNumberLength === 13);
prefixRegExp = /^4/;
break;
case "amex":
lengthIsValid = (cardNumberLength === 15);
prefixRegExp = /^3([47])/;
break;
case "discover":
lengthIsValid = (cardNumberLength === 15 || cardNumberLength === 16);
prefixRegExp = /^(6011|5)/;
break;
case "dinners":
lengthIsValid = (cardNumberLength === 14);
prefixRegExp = /^(300|301|302|303|304|305|36|38)/;
break;
case "jcb":
lengthIsValid = (cardNumberLength === 15 || cardNumberLength === 16);
prefixRegExp = /^(2131|1800|35)/;
break;
default:
prefixRegExp = /^$/;
}
prefixIsValid = prefixRegExp.test(cardNumbersOnly);
isValid = prefixIsValid && lengthIsValid;
// Check if we found a correct one
if(isValid) {
break;
}
}
}
if (!isValid) {
return false;
}
// Remove all dashes for the checksum checks to eliminate negative numbers
ccnum = ccnum.replace(/[\s-]/g,"");
// Checksum ("Mod 10")
// Add even digits in even length strings or odd digits in odd length strings.
var checksum = 0;
for (i = (2 - (ccnum.length % 2)); i <= ccnum.length; i += 2) {
checksum += parseInt(ccnum.charAt(i - 1));
}
// Analyze odd digits in even length strings or even digits in odd length strings.
for (i = (ccnum.length % 2) + 1; i < ccnum.length; i += 2) {
var digit = parseInt(ccnum.charAt(i - 1)) * 2;
if (digit < 10) {
checksum += digit;
} else {
checksum += (digit - 9);
}
}
return (checksum % 10) === 0;
}
#End If
The result in the browsers console:
B4X:
Card '5105105105105100' is a valid card. Please continue...
Card '111111' is NOT valid. Please check the number...
Pretty cool no?
A couple of things we see here in the code (besides the #if JAVASCRIPT part.
1. Calling a javascript function in your B4JS code using Page.B4JSRunInlineJavascriptMethod:
B4X:
Dim isValid As Boolean = Page.B4JSRunInlineJavascriptMethod("validateCCNum", Array As Object(cardNumber))
It is VERY important (unlike we are used in B4J, that the method name (here validateCCNum) matches the case. e.g. VAlidateCCNum will NOT work!
2. Calling a B4JS function in your B4JS code using Page.B4JSRunMethod:
B4X:
Page.B4JSRunMethod("B4JSCalculateDistance", "cHECKCard", Array As String("5105105105105100"))
And we're back on familiar B4X ground
And moreover, we can also call these methods in our normal ABM webpage!
B4X:
sub ConnectPage()
...
' method 1: calling our own B4JS sub and handeling the result on thebrowser side
page.B4JSRunMethod("B4JSCalculateDistance", "cHECKCard", Array As String(CardNumber))
' method 2: directly calling the Javascript function and handeling the result on the server side
Dim isValid As Boolean = page.B4JSRunInlineJavascriptMethod("validateCCNum", Array As Object(CardNumber))
If isValid Then
Log("Server Card '" & CardNumber & "' is a valid card. Please continue...")
Else
Log("Server Card '" & CardNumber & "' is NOT valid. Please check the number...")
End If
...
End Sub
So the result of method 1 (in the Browser log)
B4X:
Card '5105105105105100' is a valid card. Please continue...
Card '111111' is NOT valid. Please check the number...
And the result of method 2 (in the B4J log)
B4X:
Server Card '5105105105105100' is a valid card. Please continue...
In the next tutorial (04 - Running Javascript on the server side) I'll show how you can even run this on the server side, not even needing a browser open.
A final note: #if JAVASCRIPT regions do not really belong to the class. They are shared between all B4JS classes you create.
This concludes this tutorial.
Alwaysbusy
Last edited: