B4J Tutorial [BANano] [VuetifyAD3] Small solutions to development hitches (Tricks and tracks)

At the request of several friends, I opened this Thread which explains some problems encountered when developing with Banano and VuetiiFy.

Obviously I will propose the solutions that I have experimented, perhaps they will not be the best, but they are those obtainable with the documentation available at the moment.

INDEX
  1. MAKE A VTextField visible or invisible
  2. CHANGE NUMBER OF COLUMNS AND NAMES IN A TABLE BY CODE
  3. SIDE MENU
  4. CARD, ITERATIVE CYCLES AND .... ELECTRONIC SHOWCASE ( Part-1 , Part-2 , Part-3 , Part-4 , SOURCE CODE )
  5. IN-LINE PHP
  6. LOCAL storage of data or variables
  7. Change properties of vLabel and VTextField from code
  8. VUETABLE- How to insert MinusPlus columns and editable fields
  9. Button inside a VTABLE and event raised
  10. MESSAGE box, INPUTDIALOG and ToastMessage
  11. REGEX SPLIT
  12. From http to https (insecure to secure)
  13. How can I cast form String to number?
  14. Upload file to DB
  15. Viewer image from DB
  16. Upload a file and save it in a folder
  17. List of file
  18. USE the php code from an external application
  19. Using MQTT from Banano VAD3 with a ListView
  20. Cast string into integer
  21. Set and remove focus
  22. Call a JavaScript function from your injected JS source
  23. Calls a sub from JavaScript source
  24. Example of mobile panel and GoogleMaps without Vuetify


PLEASE DO NOT WRITE IN THIS THREAD. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
MAKE A VTextField visible or invisible

I had the need to make a TextFiled visible or invisible based on some need to adapt an input panel that required a field or not.
I thought it was enough to use these commands
B4X:
VTextField1.Show
VTextField1.Hide
In reality they didn't work and after two days of work I figured out how to do it. The Hiodden property must be selected in the Design.
1642328421468.png


Then it will be possible to show or hide it with the Show and Hide commands. I HAVE ATTACHED AN EXAMPLE


_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 

Attachments

  • Sample1.zip
    23.9 KB · Views: 303
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
CHANGE NUMBER OF COLUMNS AND NAMES IN A TABLE

Sometimes you need to customize a grid according to the database you are accessing. A table with fixed fields does not respond well to this need.
How to change from code in number of columns and the relative name of a table? Here is a short example and an attachment.

B4X:
VueTable1.Reset
For Each ColName As String In Cols.Keys
    VueTable1.AddColumn(ColId, ColName)
Next
VueTable1.RefreshHeaders

To populate the table row by row
B4X:
For i=0 To 21
        Dim Row As Map = CreateMap("id":id(i),"name": name(i) "address":address(i),"email":email(i),"tel":tel(i))
        VueTable1.AddItem(Row)
Next

To populate the table from a list of maps
B4X:
Dim Rows As List
Rows.Initialize
For i=0 To 21
        Dim Row As Map = CreateMap("id":id(i),"name": name(i) "address":address(i),"email":email(i),"tel":tel(i))
        Rows.Add(Row)
Next
VueTable1.Reload(Rows)

I HAVE ATTACHED AN EXAMPLE
_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 

Attachments

  • ViewSample2.zip
    20.6 KB · Views: 332
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
SIDE MENU

Now I would go on something more complex. Create a menu with customized pages.
I will take for example a hospital management, obviously only the customized views with some more complex objects such as diagrams, cards and tables
reserved

1642365800320.png


1642365862261.png


I HAVE ATTACHED AN EXAMPLE
_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 

Attachments

  • HospitaSample.zip
    53.6 KB · Views: 310
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
CARD, ITERATIVE CYCLES AND .... ELECTRONIC SHOWCASE (PART#1/4)
When we have multiple items to display often the best method is a table or grid as we have seen in previous POSTs.

Other times, however, each element needs its own space or component that represents it. For example, in an electronic shop window of an e-commerce, each item for sale could be placed inside a frame that contains a photo, a brief description, the price and other details. This component is a Card (Vcard).

It is clear that we cannot design a Card for each article, also because we do not know how many articles our DB contains. So we will use an iterative loop to multiply and populate the CARDs.

LET'S START FROM THE BASICS
You may already know that the container (VContainer) must be the basis of all components in the design.
The container in turn will contain one or more Row (VRow). They will not be hooked like the panels in the design but they just need to be on top of the container and within its perimeter. Each Row contains one or more Col (VCol)

The latter can contain other Row and Col or components, such as Label, TextField, etc ...
This will allow you to neatly arrange the various components that according to the size of the screen (Desktop, Mobile) will arrange the components in the precise order arranged by you thanks to Row / Col.

See the image illustrating the method
1642436773826.png



_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
CARD, ITERATIVE CYCLES AND .... ELECTRONIC SHOWCASE (PART#2/4)
We will see how to create an iterative cycle that multiplies the CARDs. Let's start by saying that what will be multiplied is the column (VCol). So the cards inside the columns will be side by side within a single row (If the row contains them all, otherwise it wraps)
If we multiply the rows, we will get only one card for each row

1642437059404.png


Among the properties of VCol we find V-FOR. Here we will establish the loop by choosing the name of the variable that will be used for each item. I just called it item, but you can choose. The list that contains all the items I have called product.
It would be the correspondent
B4X:
For Each Item as Map in product.
Where product is a list of maps.

We will also declare the Product Variable in the internal code and then we will associate it with the one that is present in the design.
B4X:
Sub Class_Globals
    Public vuetify As VuetifyApp
    Public page As VueComponent
    Public path As String
    Public name As String = "home"
    Private banano As BANano            'ignore

    Dim MyProduct As List
End Sub

Sub Initialize(v As VuetifyApp)                        'ignoreDeadCode
    vuetify = v
    page.Initialize(Me, name)
    page.vuetify = vuetify
    page.StartPage
    path = page.path
    banano.LoadLayout(page.Here, "home")
 
    ' Initialize product
    page.SetData("product", page.NewList)

    vuetify.AddRoute(page)
End Sub

To populate the list at startup we will insert the population code when creating the page.
After creating a list of maps and populating it, we assign it to the Product variable that will be used by Banano
B4X:
Sub created 'ignore
    ' populate MyProduct
    MyProduct.Initialize
    MyProduct.Add(CreateMap("id":"01","name": "Microphone", "price": "€. 11,10", "avatar": "./assets/img1.png"))
    MyProduct.Add(CreateMap("id":"02","name": "Speaker", "price": "€. 32.20", "avatar": "./assets/img2.png"))
    MyProduct.Add(CreateMap("id":"03","name": "Keyboard + mouse", "price": "€. 41.00", "avatar": "./assets/img3.png"))
    MyProduct.Add(CreateMap("id":"04","name": "usb adapter", "price": "€. 8.01", "avatar": "./assets/img4.png"))
    page.SetData("product", MyProduct) ' Set Value product list
End Sub
NOTE#1: I am populating the List with invented data from code, but here it should be populated by drawing from a DB
NOTE#2: In this case the images are copied from the asset and so I put a URI that refers to the asset

PS if you create a sub calling it created, it will be called automatically when the page is created.
Previously it was necessary
B4X:
Page.OnCreated (Me, "created", null)
now this command is not necessary


_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
CARD, ITERATIVE CYCLES AND .... ELECTRONIC SHOWCASE (PART#3/4)
Inside the Conteiner there is now only one row and one column. Now we have to put the components that will be multiplied to insert to the VCol.
Let's start by inserting a Vcard.
In the VCard we will not put any reference to the For loop because it will automatically be multiplied as many times as the VCol will be, as well as all the components contained in the VCard
1642438074896.png



The next step is to insert the product image and for this I use the VAvatar component.
To create a division of the components within the VCard I could use many components but I prefer the VLabel.
This component, even if it is called VLabel, corresponds to different HTML components (DIV, P, A, Form, etc ..) which in turn can contain a text, but it is not mandatory. I will only use it to separate the Avatar from the other components.
1642438580872.png
1642438874127.png


The next step is to insert a VCardText which will contain two VLabels.
These two VLabels must contain the name of the product and the price of the product.
The declaration of these components in the code will be as follows
B4X:
Private VColCicled As VCol
Private VCard1 As VCard
Private VAvatar1 As VAvatar
Private VLabelDescription As VLabel
Private VLabelPrice As VLabel

HOW TO CONNECT COMPONENTS TO THE VARIABLES OF THE FOR CYCLE
In the case of Vlabel, in the CAPTION field, insert the name of the map variable that I called item followed by a dot and the name of the key between double graphic brackets.
1642439654705.png


In the case of VAvatar, in the Image field insert a colon followed by the name of the map variable that I called item followed by a period and the name of the key.
You also see a list of images referenced in the images field.
1642439792820.png

Each component may have a different way of connecting to the variable, so always consult the Vuetify documentation

_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 

Attachments

  • 1642438067206.png
    1642438067206.png
    6.3 KB · Views: 272
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
CARD, ITERATIVE CYCLES AND .... ELECTRONIC SHOWCASE (PART#4/4)
As a last step, you need to insert a button (maybe two) to make the purchase of the product.
The button (VBtn) will be inserted inside a VCardActions.
There are no particular specifications to select by design for the VCardActions nor for the button.

But it will be necessary to add this line from code to allow the passing of values to the button when it is clicked
B4X:
Sub Initialize
'.....
VBtn1.OnClick("item") ' ATTENTION, insert the name chosen in the FOR within VCol in the Design, in my case item
End Sub
When the button is clicked, this sub will be called by the click event
B4X:
Private Sub VBtn1_Click (item As Object)
    Dim M As Map = item
    vuetify.ShowSwal(m.get("id"))
End Sub
Or alternative
B4X:
VBtn1.OnClick("item.name")
B4X:
Private Sub VBtn1_Click (item As Object)
    vuetify.ShowSwal(item)
End Sub
_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
CARD, ITERATIVE CYCLES AND .... ELECTRONIC SHOWCASE (SOURCE CODE)
Here I attach the source of the example of the cards with the for loop.
I also added a small gift. A TextField (VTextField) that allows you to filter articles by name. It will be easy to understand how it works.

Have fun

1642443536984.png


I HAVE ATTACHED AN EXAMPLE
_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 

Attachments

  • ecommerce.zip
    83.4 KB · Views: 295
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
IN-LINE PHP
Some parts of the code must be executed on the server side, both because the source is not visible to a savvy user who examines the source of the page, and because some data should not be exposed to the client.
An example of this can be the verification of credentials by comparing them with the DB. It would not be smart to send the list of credentials to the client for verification, but it is more logical to send the credentials entered by the user encrypted to the server that verifies its validity.

HOW TO DO
Insert the PHP code at the bottom of the following code of the B4J source. I suggest putting the PHP source inside a static module (I usually put it in the pgIndex module). If the same PHP function will be called by several modules, it will not have to be rewritten, just once inside a single module and it will be accessible by all.
B4X:
#IF PHP
 function funcmd5($value) {
    echo md5($value);
   }
#END IF

To execute the php code and obtain the result, call the CallInLinePHPWait or CallInLinePHP method.
CallInLinePHPWait Corresponds to a WAIT FOR (function) COMPLETE (RES as String), the result is that the line of execution will go up one level (the caller if there is one) until PHP returns the result and returns to the point where he had stopped.
If you access the DBs I always suggest to use CallInLinePHPWait so it waits until it has the query results that are not immediate.
B4X:
Dim res As String = banano.CallInlinePHPWait("funcmd5", CreateMap("value": "mytext"))

An example of PHP to verify passwords is the following. (obviously you can also use the php functions to access the DB available on VuetifyAd3)
The Client sends through php the username and a second parameter which is the md5 encoding of the username with password,
B4X:
Dim security As String = vuetify.Md5Hash(user & pass, Null, False)
Dim res As String = banano.CallInlinePHPWait("access", CreateMap("username": user,"security":security))
Vuetify.ShowSwal(res)
The PHP code searches for the username, recalculates the sum in MD5 with the data in its possession and compares it with the one received from the client.
B4X:
#IF PHP
 function access($username, $security) {
    $servername = "www.myservername.org";
    $username = "StarDust";
    $password = "12345678";
    $dbname = "DBStar";

    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }
    $result = $conn->query("SELECT * FROM usertable WHERE user='". $username. "' ");
    if ($result->num_rows > 0) {
        // output data of each row
        $row = $result->fetch_assoc();
        $pass=$row["password"];
        $crypto=md5($account. $pass.);
 
        if ($crypto==$security) {
            echo "Welcome ". $row["name"];;
        } else {
             echo "Sorry wrong Credential";
        }
    } else {
        echo "Sorry wrong Credential";
    }
    $conn->close();
 }
#END IF
NOTE #1: This PHP code allows me to access the database's "usertable" table and verify the user and password.
NOTE #2: You must correctly configure BANano.PHPHost in the Main module so that it accesses the PHP file. The server must support PHP

IMPORTANT For security reasons, I believe that in the md5 string, in addition to USER and PASSWORD, a different TOKEN must be added to each connection. So the resulting string is always different.
If it were always the same by a malicious user who spies on the connection, he could reuse the resulting md5 string for other accesses without even having to decode.

I HAVE ATTACHED AN EXAMPLE


_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 

Attachments

  • Php.zip
    14.8 KB · Views: 289
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
LOCAL storage of data or variables
Some data may need to be saved locally with the browser. For example, I used it to save the login so that on subsequent accesses it is not necessary to re-enter it.
The commands are as follows:
B4X:
banano.GetLocalStorage("variablename")
banano.SetLocalStorage("variablename",value)

It could occur when the page is mounted if the value has been previously memorized
B4X:
Sub onmounted 'ignoreDeadCode
    Dim user As String = banano.GetLocalStorage("data")
 
    If Not(banano.IsEmpty(user)) Then
        txtuser.SetValue(page,user)
    End If
End Sub
To memorize
B4X:
Dim value as string = txtuser.GetValue(page)
banano.SetLocalStorage("data",value)

If you have used templates to link components to variables
In the example you see txtuser is linked to the variable (map) user to the key name

1642503937434.png

It could occur when the page is mounted if the value has been previously memorized
B4X:
Sub onmounted 'ignoreDeadCode
    Dim user As String = banano.GetLocalStorage("data")
 
    If Not(banano.IsEmpty(user)) Then
        Dim M As Map = CreateMap("name":user)
        page.SetData("user",M) ' By setting the name key of the user variable, txtuser will automatically receive the value.
    End If
End Sub
To memorize
B4X:
Dim user As Map = page.GetData("user") ' This retrieves the variable (of type map) connected to the vTextField components
banano.SetLocalStorage("data",user.Get("name")) 'Stores the name value locally so that it can be retrieved on the next login



_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Change properties of VLabel from code
In order to modify the text inside a label we will act by setting the Caption property by inserting the name of the variable from which the component will draw the value and enabling USE CAPTION, as in the example
1642625644507.png

The code to change the value of the variable will be this:
B4X:
page.SetData("message1","New text")
All components that are associated with that variable will change

METHOD #2
If you don't want to use a variable from code you can use the UpdateCaption command
B4X:
VLabel2.UpdateCaption("New Text")
Obviously, in Design, Use Caption must always be checked


Change properties of VTextField from code
Editing a TextField from code is simple, just use the SetValue command
B4X:
VTextField1.SetValue(page,"New TextField message")
To know the value of a TextField use this command
B4X:
VTextField1.GetValue(page)


I HAVE ATTACHED AN EXAMPLE
_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 

Attachments

  • Propriety.zip
    14.8 KB · Views: 277
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
VUETABLE- How to insert MinusPlus columns and editable fields.
In a table to be able to set a field as Numeric MinusPlus it is necessary to specify it in the Design, in the example below the field is called level
1642660426534.png

The event raised with each click will take on the name of the field:
B4X:
Private Sub VueTable1_level_Minus (item As Map)
    Dim Liv As Int = item.Get("level")
    Liv=Max(1,Liv-1)
    VueTable1.UpdateItem("id", item.Get("id"), CreateMap("level":Liv))
End Sub

Private Sub VueTable1_Level_Plus (item As Map)
    Dim Liv As Int = item.Get("level")
    Liv=Min(5,Liv+1)
    VueTable1.UpdateItem("id", item.Get("id"), CreateMap("level":Liv))
End Sub

________________________________________________________________________________________________________________________________________
If we wanted to allow a column of the table to be editable from the table itself, we will select the fields chosen as text fields
1642660676312.png


If the changes are modified, the change event will be raised which will also take the name of the field as in the example below.
ATTENTION, if you open the change but do not make any changes to the content, the event will not be raised.
B4X:
Private Sub VueTable1_user_Change (item As Map)
    Dim mess As String = banano.ToJson(item)
    vuetify.ShowSwal(mess)
End Sub

Private Sub VueTable1_email_Change (item As Map)
    VueTable1.UpdateItem("id", item.get("id"), CreateMap("email":item.Get("email")))
    ' or     VueTable1.UpdateItem("id", item.get("id"), item))
End Sub


1642661146929.png

I HAVE ATTACHED AN EXAMPLE
_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 

Attachments

  • Table.zip
    15.5 KB · Views: 277
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Button inside a VTABLE and event raised

Sometimes you need to insert buttons inside the grid of the table.
1642940244947.png


Let's start with what to set in the Design properties:
1642940252155.png


Enter the field name and title:
1642940273530.png


To intercept the event, use the field name for the event
B4X:
Private Sub VueTable1_reset (item As Map)
    Dim S As String = banano.ToJson(item)
    vuetify.ShowSwal(S)
End Sub

I HAVE ATTACHED AN EXAMPLE
_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial


Attachments​

 

Attachments

  • Table2.zip
    15.5 KB · Views: 259

Star-Dust

Expert
Licensed User
Longtime User
MESSAGE box, INPUTDIALOG and ToastMessage
An important aspect are the MessageBoxes and DialogBoxes.
Although they can be customized, I personally prefer the standard ones because they can be inserted without too many problems and you have to create a specific Layout.

Here's how to send a messageBox
B4X:
vuetify.ShowSwal("WARNING, I don't remember my name")

Here's how to send a ToastMessage
B4X:
vuetify.ShowSwalToastError("Temporary message",1000) ' Message , Time in millisec
vuetify.ShowSwalToastInfo("Temporary message",1000)
vuetify.ShowSwalToastSuccess("Temporary message",1000)
vuetify.ShowSwalToastWarning("Temporary message",1000)
vuetify.ShowSnackBar("Snack Bar")

Finally a DialogMessage to insert a text field
B4X:
Dim user As String = vuetify.ShowSwalInputWait("Insert user name","User name","Confirm","Cancel")
If user<>"" Then
    ' your code
End If

_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
REGEX SPLIT
I have found it very difficult to get SPLIT and REGEX generally seems like a complicated thing.
You will find following code suggested in several posts to get REGEX functions

From here
B4X:
    Dim str As String = "This is a test I'm doing to split a sentence into words."
    Dim RegExp As BANanoRegEx
    RegExp.InitializePattern("/\b[^\s]+\b/g")
    Dim found As String = RegExp.Exec(str)
    Do While found <> Null
        Log(found)
        found = RegExp.Exec(str)
    Loop

From here
B4X:
Dim splList As List = BANano.Split(".", "alain.is.here")
For i = 0 To splList.Size - 1
        Log(splList.Get(i))
Next

To obtain the SPLIT, I created a function that I insert in a static class, usually pgIndex
B4X:
Public Sub Split(Pattern As String, str As String) As String()
    Dim I As Int = 0
    Dim F As Int = 0
    Dim Le As Int = Pattern.Length
    Dim L As List
 
    'l=BANano.Split(".", "alain.is.here")
    L.Initialize
    F=str.IndexOf2(Pattern,0)
    Do While F>-1
        L.Add(str.SubString2(I,F))
        I=F+Le
        F=str.IndexOf2(Pattern,i)
    Loop
 
    If l.Size=0 Then
        Return Array As String()
    Else
        Dim Rs(l.Size) As String
        For i=0 To L.Size-1
            Dim S As String = L.Get(I)
            Rs(I)=S.Trim
        Next
    
        Return Rs
    End If
End Sub

_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
From HTTP to HTTPS
If you have a site you do not want them to access your pages in the clear, especially if the pages send and receive data or are pages for authentication of credentials.

How to redirect an unencrypted page request to a safe one?
Let's start with a JAVA method
Clearly it is better that this code is found at the montage of the page or before (sub beforeMount)
B4X:
Sub onmounted
    banano.Eval($"if (location.protocol !== "https:"){location.replace(window.location.href.replace("http:", "https:"));}"$)
End Sub

_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
How can I cast form String to number?
JS is not strongly typed, so you may have problems when doing such an operation
B4X:
Dim I as String = "1"
Sum = I + 1 ' Result "11" but you want result 2

Solution
B4X:
' SOLUTION 1'
Dim Num1 As Int = banano.parseInt("1")
Dim Num2 As Int = banano.parseInt(item.Get("Key"))

' SOLUTION 2'
Dim Num1 As Int = 1 * "1"
Dim Num2 As Int = 1 * item.Get("Key")

' SOLUTION 3'
Dim Num1 As Int = "1" - 0
Dim Num2 As Int = item.Get("Key") - 0

In these three ways the strings will be treated as numbers

_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Upload image file to DB

This method uses php for loading the image into the DB. We start by inserting VFileInput into views within a vRow or vCol

1652761884442.png


Insert this code in the Change event:
B4X:
Private Sub VFileInput1_Change (fileObj As Object)
    If banano.IsNull(fileObj) Or banano.IsUndefined(fileObj) Then Return
    VFileInput1.UpdateLoading(Page, True)
 
    Dim fileDet As FileObject
    fileDet = BANanoShared.GetFileDetails(fileObj)
    Dim Myfilename As String = fileDet.FileName
 
   fileDet=BANanoShared.UploadFileWait(fileObj)
    Dim sstatus As String = fileDet.Status
 
    Select Case sstatus
        Case "error"
            vuetify.ShowSwalNotificationError($"file ${fnr} don't uploaded"$,10000)
        Case "success"
            ' VImg1.SetImage(Page,$"./assets/${Myfilename }"$) ' preview image to VImg elements
             banano.CallInlinePHPWait("writeimagedb", CreateMap("table": "product","field":"image","id":id_product,"filename":$"./assets/${Myfilename }"$))
    End Select
 
    VFileInput1.UpdateLoading(Page, False)
End Sub

finally add this php code in the same module or pgIndex (I prefer pgIndex). This code stores the bytes in string format so it could use a Blob or even text field
PHP:
 function writeimagedb($table,$field,$id,$filename) {
    $servername = "";
    $username = "";
    $password = "";
    $dbname = "";

    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }
 
        //check If File Is Not empty
        If(!empty($filename)) {
            //File info
            $img_content = addslashes(file_get_contents($filename));

            //now run update query  
            $query = $conn->query("UPDATE ". $table. " SET ". $field. " = '$img_content' WHERE id=". $id);

             //check If successfully inserted
            If($query){
                echo "ok";
            }else{
                echo "Something went wrong when uploading image!!!";
            }
        } else {
            echo "Empty";
        }
 
    $conn->close();
 }

NB. I use the update and not the insert in the DB. So you must already have the unique key of the record which in the example is the ID.
But you can change the example as you like and hope it works just as well

_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Viewer image from DB

In this post we will see how to read an image saved in a field in Base64 format and insert it into a view.
This time we start from the php code to be inserted for reading the field
PHP:
 function readimagedb($table,$field,$id) {
    $servername = "";
    $username = "";
    $password = "";
    $dbname = "";
 
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
         die("Connection failed: " . $conn->connect_error);
    }
 
    $result = $conn->query("SELECT ". $field. " FROM ". $table. " WHERE id=". $id);
    $row = $result->fetch_assoc();
    //check If File Is Not empty
    If(!empty($row[$field])) {
        echo base64_encode($row[$field]);
    } else {
        echo "";
    }
  
    $conn->close();
  }

The b4j code to read the image will be as follows
B4X:
Dim img As String = banano.CallInlinePHPWait("readimagedb", CreateMap("table":"product" ,"field":"image","id":id_product))
VImg1.SetImage(Page,$"data:image/jpg;charset=utf8;base64,${img}"$) ' image is Base64

_________________________________________________________________________________________________________________________________________
PLEASE DO NOT WRITE IN THIS THREAD
. If you have any questions or comments, open a dedicated threads, but don't post your posts here.
If you want to propose some other solution, open your specific tutorial
 
Last edited:
Top