B4J Tutorial SithasoDaisy TailwindCSS UI Toolkit: Q & A

Hi there

NB: Where possible, please include a simple project that demonstrates your use case.

Do you have any questions about SithasoDaisy UI Toolkit?

You can shoot it here and we will oblige.

Thanks in advance?


Join on Telegram


Check $5 WebApps

 
Last edited:

Ilya G.

Active Member
Licensed User
Longtime User
Hi Mashiane

1. Is it possible to drag table elements?
2.How will I receive library updates after payment?
 

Mashiane

Expert
Licensed User
Longtime User
Hi Mashiane

1. Is it possible to drag table elements?
2.How will I receive library updates after payment?
Thank you so much for your questions. Here are the responses..

1 - This can be implemented.
2 - On purchase one gets instructions with a permanent link of where to get the library and future updates. This is the same with Gumroad purchases.

Kind regards
Mashy
 

MichalK73

Well-Known Member
Licensed User
Longtime User
I have called Toast SDUIToast. It shows up, but how to hide it e.g. after 2 seconds, I don't see a parameter for that. Doing the Timer does not show the Toast at all.
How do I solve this?
 

MichalK73

Well-Known Member
Licensed User
Longtime User
Ok solved.

proces global:
Sub Process_Globals
...
    Private t1 As SDUIToast
    Private tick As Timer
...

End Sub

B4X:
Private Sub btnsend_Click (e As BANanoEvent)
...
        t1.AddToast(Me, page.CellID(1, 1), "t1", "A new message has arrived!")
        t1.Alert.Info
        t1.TopRight
        t1.Show

        tick.Initialize("tick", 2000)
        tick.Enabled=True
        Log("tick on")
...
End Sub

B4X:
Sub tick_Tick
    t1.Hide
    Log("tick hide")
    tick.Enabled = False
End Sub


However, it would be useful to have a time parameter when calling Toast so that it disappears after a given time without writing additional code.
 

Mashiane

Expert
Licensed User
Longtime User
I have called Toast SDUIToast. It shows up, but how to hide it e.g. after 2 seconds, I don't see a parameter for that. Doing the Timer does not show the Toast at all.
How do I solve this?
This is not a built in feature. TailwindCSS is mostly a UI layer and one has to add the needed javascript to make this and that work.

Thanks a lot for the code, I will will this right along and it will be available in the next release.

If there is anything else, please keep it coming.

Update: The lib code has been updated. So as long a .TimeOut is set to something like 2000 (2 seconds) etc, it will do it.

B4X:
Sub Show
    Root.Hidden(False)
    If sTimeOut <> "" Then
        SDUIShared.StartTimerAfter(Me, "hide", sTimeOut)
    End If
End Sub

Sub Hide
    Root.Hidden(True)
End Sub

Timer.gif
 
Last edited:

MichalK73

Well-Known Member
Licensed User
Longtime User
Welcome.
Neither in the code nor in the book did I find values for the colours.
B4X:
Private Sub SDUILabel1_Click (e As BANanoEvent)
    Log("click")
    If click Then
        SDUILabel1.textColor("red")
        click=False
    Else
        SDUILabel1.textColor("blue")
        click=True
    End If
End Sub
 

MichalK73

Well-Known Member
Licensed User
Longtime User
Welcome.
Neither in the code nor in the book did I find values for the colours.
B4X:
Private Sub SDUILabel1_Click (e As BANanoEvent)
    Log("click")
    If click Then
        SDUILabel1.textColor("red")
        click=False
    Else
        SDUILabel1.textColor("blue")
        click=True
    End If
End Sub

Solved.
Private Sub SDUILabel1_Click (e As BANanoEvent) Log("click") If click Then SDUILabel1.textColor("#FF0000") click=False Else SDUILabel1.textColor("#0000FF") click=True End If End Sub:
Private Sub SDUILabel1_Click (e As BANanoEvent)
    Log("click")
    If click Then
        SDUILabel1.textColor("#FF0000")
        click=False
    Else
        SDUILabel1.textColor("#0000FF")
        click=True
    End If
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
Solved.
Private Sub SDUILabel1_Click (e As BANanoEvent) Log("click") If click Then SDUILabel1.textColor("#FF0000") click=False Else SDUILabel1.textColor("#0000FF") click=True End If End Sub"click") If click Then SDUILabel1.textColor("#FF0000") click=False Else SDUILabel1.textColor("#0000FF") click=True End If End Sub:
Private Sub SDUILabel1_Click (e As BANanoEvent)
    Log("click")
    If click Then
        SDUILabel1.textColor("#FF0000")
        click=False
    Else
        SDUILabel1.textColor("#0000FF")
        click=True
    End If
End Sub
I also find it easy just to use the hex codes.
 

MichalK73

Well-Known Member
Licensed User
Longtime User
I have a problem with SDUIFetch.
I send the header to the server but the server does not see it. I even do locally in Debug server and client.
B4X:
    Dim j As SDUIFetch
    j.Initialize("http://localhost:8080/api/login/")
    j.AddHeader("token","12345")
    j.NoCors=True
    j.fetchWait(j.GetWait)
   
    banano.Await(j)
    Log(j.Success) ' -> False
    Log(j.Status) ' -> empty
    If j.ErrorMessage <> "" Then
        Log(j.ErrorMessage)
    End If
    If j.Success Then
        Dim mas As Map = j.Response
        Log(mas.Get("message"))
    Else
        Dim mas As Map = j.Response
        Log(mas.Get("message")) ' -> undefined
    End If

I have these Headers read from the connection on the server.

B4X:
http://localhost:8080/api/login/
Accept: */*
Connection: keep-alive
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36 Edg/108.0.1462.54
Referer: http://localhost/
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Sec-Fetch-Mode: no-cors
sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108", "Microsoft Edge";v="108"
sec-ch-ua-mobile: ?1
sec-ch-ua-platform: "Android"
Accept-Language: pl,en;q=0.9,en-GB;q=0.8,en-US;q=0.7
Log from console browser.
1673099488260.png


What am I doing wrong ??
 

MichalK73

Well-Known Member
Licensed User
Longtime User
Try Banano.await(j.getwait)
This is not it.
I know why it doesn't work, but I don't know quite how to set it up.
Paramaters pass fine.
Headers will not pass if the browser gets a "Sec-Fetch-Site: same-site" header. The URL and port must match. Locally it is not possible to run the 'Laragon' server and the API server in B4X on the same port.
So if one or both do not match, the browser will not add headers to the API server. This is a general security safeguard for all browsers.

The solution is:
1. force / set the web server to give 'Sec-Fetch-Site: none', but I don't know how to trigger this. Adding to the manifest.json generated by the Sithasodaisy Framework and uploaded to the server does not help, still the browser does not see the entry correctly.

2. make a local API with static web files (web page) and then it will go from the same address and port. (I have not tested this)

3) There is an option to disable all Chromium-based browser security as a startup parameter. Then the browser should ignore security and headers will be added to the API request. (I have not tested this)
 

MichalK73

Well-Known Member
Licensed User
Longtime User
[SOLVED]

It took me 2 days to solve the fetchAPI and header connection.

1. start the browser with security disabled.
brave.exe --disable-web-security --user-data-dir="d:\banano\temp"

2 I failed to upload the headers from SDUIFetch. I used pure BANanoFetch.

B4X:
' 
    Dim response As BANanoFetchResponse
    Dim error As BANanoObject
    Dim data As BANanoJSONParser
  
    ' insert with a POST
    Dim fetch2Options As BANanoFetchOptions
    fetch2Options.Initialize
    fetch2Options.Method = "POST"
    fetch2Options.Headers = CreateMap("token": "12345")
    fetch2Options.ReferrerPolicy="unsafe-url" '->important you must add
 
    Dim fetch2 As BANanoFetch
    fetch2.Initialize("http://localhost/api/login", fetch2Options)
    fetch2.Then(response)
    fetch2.Return(response.Json)
    fetch2.Then(data)
    Dim m As Map = data.NextObject
    Log(m.Get("message"))
    fetch2.Else(error)
    Log(error.ToString)
    fetch2.End

Result of read headers by B4X server (API):

B4X:
http://localhost/api/login -> URL
--------------------------------------
Cookie: GO=node0pyvnfrr6v5pfk6zaadahfl9k1.node0 -> Appeared
Accept: */*
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Safari/537.36
Referer: http://localhost:8080/
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Host: localhost
Accept-Encoding: gzip, deflate, br
token: 12345           -> It appeared, and this is the most important !!!!!
Sec-Fetch-Mode: cors
Sec-GPC: 1
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
Content-Length: 0
--------------------------------------

Adding headers for the B4X API server:
    resp.ContentType = "application/json"
    resp.SetHeader("Access-Control-Allow-Origin","*")
    resp.SetHeader("Access-Control-Allow-Methods" ,"GET, POST, UPDATE, DELETE, OPTIONS")
    resp.SetHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, api_key, token")
    resp.SetHeader("mode", "no-cors")
    resp.SetHeader("Content-Security-Policy", "script-src http://localhost")


B4X:
Sub login(req As ServletRequest, resp As ServletResponse) 'ignore
    If username <> "" Then
        resp.Status=200
        resp.Write($"{"message":"ok"}"$)
        ABMShared.AddLog(username, "zalogowany na urzadzeniu")
        DBM.SQLUpdate("update user set lastlogin=? where username=?", Array As String(ABMShared.dataiczas, username))
        Return
    End If
End Sub

1673201995196.png


1673202414411.png


This is how we can locally exercise the API with headers to bypass browser security.
Obviously they will not be needed as in the production version when URL fetch is compatible with the URL API.

Hopefully someone will find the solution useful. It took me 2 days to understand how it works and how to get around it. 😄😁
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
[SOLVED]

It took me 2 days to solve the fetchAPI and header connection.

1. start the browser with security disabled.
brave.exe --disable-web-security --user-data-dir="d:\banano\temp"

2 I failed to upload the headers from SDUIFetch. I used pure BANanoFetch.

B4X:
'
    Dim response As BANanoFetchResponse
    Dim error As BANanoObject
    Dim data As BANanoJSONParser
 
    ' insert with a POST
    Dim fetch2Options As BANanoFetchOptions
    fetch2Options.Initialize
    fetch2Options.Method = "POST"
    fetch2Options.Headers = CreateMap("token": "12345")
    fetch2Options.ReferrerPolicy="unsafe-url" '->important you must add
 
    Dim fetch2 As BANanoFetch
    fetch2.Initialize("http://localhost/api/login", fetch2Options)
    fetch2.Then(response)
    fetch2.Return(response.Json)
    fetch2.Then(data)
    Dim m As Map = data.NextObject
    Log(m.Get("message"))
    fetch2.Else(error)
    Log(error.ToString)
    fetch2.End

Result of read headers by B4X server (API):

B4X:
http://localhost/api/login -> URL
--------------------------------------
Cookie: GO=node0pyvnfrr6v5pfk6zaadahfl9k1.node0 -> Appeared
Accept: */*
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Safari/537.36
Referer: http://localhost:8080/
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Host: localhost
Accept-Encoding: gzip, deflate, br
token: 12345           -> It appeared, and this is the most important !!!!!
Sec-Fetch-Mode: cors
Sec-GPC: 1
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7
Content-Length: 0
--------------------------------------

Adding headers for the B4X API server:
    resp.ContentType = "application/json"
    resp.SetHeader("Access-Control-Allow-Origin","*")
    resp.SetHeader("Access-Control-Allow-Methods" ,"GET, POST, UPDATE, DELETE, OPTIONS")
    resp.SetHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, api_key, token")
    resp.SetHeader("mode", "no-cors")
    resp.SetHeader("Content-Security-Policy", "script-src http://localhost")


B4X:
Sub login(req As ServletRequest, resp As ServletResponse) 'ignore
    If username <> "" Then
        resp.Status=200
        resp.Write($"{"message":"ok"}"$)
        ABMShared.AddLog(username, "zalogowany na urzadzeniu")
        DBM.SQLUpdate("update user set lastlogin=? where username=?", Array As String(ABMShared.dataiczas, username))
        Return
    End If
End Sub

View attachment 137866

View attachment 137867

This is how we can locally exercise the API with headers to bypass browser security.
Obviously they will not be needed as in the production version when URL fetch is compatible with the URL API.

Hopefully someone will find the solution useful. It took me 2 days to understand how it works and how to get around it. 😄😁
Thanks fo the update, very useful.

SDUIFetch is nothing special but just a "pesonal simplified" vesion of BANanoFetch based on a combination of code AB provided as a solution to someone and then some tweaking to meet my needs and hopefully everyone else.

This is the base method which is called by GetWait, PostWait, DeleteWait, PatchWait, PutWait

Example

B4X:
Public Sub PostWait
    fetchWait("POST")
End Sub

B4X:
Sub fetchWait(method As String)
    'reset some variables
    Success = False
    mError = ""
    OK = False
    Status = ""
    StatusText = ""
    '
    Dim fetch As BANanoFetch
    Dim fetchOptions As BANanoFetchOptions
    Dim fetchResponse As BANanoFetchResponse
    Dim obaseURL As String = baseURL
   
    jsonMap.Initialize
    Dim Error As String
 
    fetchOptions.Initialize
    fetchOptions.Method = method
    If bNoCors Then
        fetchOptions.Mode = "no-cors"
    End If
    If headers.Size <> 0 Then
        fetchOptions.Headers = headers
    End If
    '
    If data.Size <> 0 Then
        Dim jsonData As String = BANano.ToJson(data)
        fetchOptions.Body = jsonData
    End If
   
    If parameters.Size <> 0 Then
        Dim sparameters As String = SDUIShared.URLQueryStringFromMap(parameters)
        obaseURL = $"${baseURL}?${sparameters}"$
    End If
   
    fetch.Initialize(obaseURL, fetchOptions)
    Try
        ' wait for the response
        fetchResponse = BANano.Await(fetch)
        OK = fetchResponse.OK
        Status = fetchResponse.Status
        StatusText = fetchResponse.StatusText
        If OK Then jsonMap = BANano.Await(fetchResponse.Json)
        Success = OK
    Catch(Error)
        mError = Error
    End Try
End Sub

So this should work still

B4X:
Dim j As SDUIFetch
    j.Initialize("http://localhost:8080/api/login")
    j.AddHeader("token","12345")
    j.ReferrerPolicy="unsafe-url"   ' will be added on next release.
    BANano.Await(j.PostWait)
    log(j.Response)

Thanks you so much for the useful input.
 

Enrico Fuoti

Active Member
Licensed User
Longtime User
Hello Mashiane,
I just tested Sithaso 1.19, I have a problem pocketbase user login that stopped working with the new version.
Something changed in code or is a bug?
It works with version 1.18 but refuses login or registration with 1.19.
 

Mashiane

Expert
Licensed User
Longtime User
Hello Mashiane,
I just tested Sithaso 1.19, I have a problem pocketbase user login that stopped working with the new version.
Something changed in code or is a bug?
It works with version 1.18 but refuses login or registration with 1.19.
Hi, Please include any errors in console log.

Which version of PocketBase are you using? Did you migrate to the latest version?

The only thing updated are the js files for pocketbase.

Thx..
 
Top