B4J Question [ABMaterial] ABMRadioGroup and Click Event [Solved]

Anser

Well-Known Member
Licensed User
Longtime User
Hi,
In one of my page I have ABMRadioGroup. I am unable to capture the click event. I do not understand why the click event is not fired. I have used ABMRadioGroup in another page and is working fine. I am going nuts why this is not working on this particular page.

Here is the code of the page. There is nothing other than the RadioGroup in this particular page.
B4X:
'Class module
Sub Class_Globals
    Private ws As WebSocket 'ignore
    ' will hold our page information
    Public page As ABMPage
    ' page theme
    Private theme As ABMTheme
    ' to access the constants
    Private ABM As ABMaterial 'ignore   
    ' name of the page, must be the same as the class name (case sensitive!)
    Public Name As String = "TargetService"  '<-------------------------------------------------------- IMPORTANT
    ' will hold the unique browsers window id
    Private ABMPageId As String = ""
    ' your own variables
    Private nUserID,cApptype As String
    Private myToastId As Int = 1
    Private nTargetType As Int = 0
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    ' build the local structure IMPORTANT!
    BuildPage       
End Sub

#Region ABM
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)   
    Log("Connected")
        
    ws = WebSocket1       
    
    ABMPageId = ABM.GetPageID(page, Name,ws)
    
    Dim session As HttpSession = ABM.GetSession(ws, ABMShared.SessionMaxInactiveIntervalSeconds)
    If session.IsNew Then
        session.Invalidate
        ABMShared.NavigateToPage(ws, "", "./")
        Return
    End If
        
    If ABMShared.NeedsAuthorization Then
        If session.GetAttribute2("IsAuthorized", "") = "" Then
            ABMShared.NavigateToPage(ws, ABMPageId, "../")
            Return
        End If
    End If       
    ABM.UpdateFromCache(Me, ABMShared.CachedPages, ABMPageId, ws)       
    If page.ComesFromPageCache Then
        ' when we have a page that is cached it doesn't matter if it comes or not from a new connection we serve the cached version.
        Log("Comes from cache")       
        page.Refresh       
        page.FinishedLoading       
    Else
        If page.WebsocketReconnected Then
            Log("Websocket reconnected")
            ' when we have a client that doesn't have the page in cache and it's websocket reconnected and also it's session is new - basically when the client had internet problems and it's session (and also cache) expired before he reconnected so the user has content in the browser but we don't have any on the server. So we need to reload the page.
            ' when a client that doesn't have the page in cache and it's websocket reconnected but it's session is not new - when the client had internet problems and when he reconnected it's session was valid but he had no cache for this page we need to reload the page as the user browser has content, reconnected but we have no content in cache
            ABMShared.NavigateToPage (ws, ABMPageId, "./" & page.PageHTMLName)
        Else
            ' when the client did not reconnected it doesn't matter if the session was new or not because this is the websockets first connection so no dynamic content in the browser ... we are going to serve the dynamic content...
            Log("Websocket first connection")
            page.Prepare
            ConnectPage           
        End If
    End If
    Log(ABMPageId)       
End Sub

Private Sub WebSocket_Disconnected
    Log("Disconnected")
End Sub

Sub Page_ParseEvent(Params As Map)
    Dim eventName As String = Params.Get("eventname")
    Dim eventParams() As String = Regex.Split(",",Params.Get("eventparams"))
    
    'log(eventName)
    
    If eventName = "beforeunload" Then
        Log("preparing for url refresh")
        ABM.RemoveMeFromCache(ABMShared.CachedPages, ABMPageId)
        Return
    End If
    Dim caller As Object = page.GetEventHandler(Me, eventName)
    If caller = Me Then
        If SubExists(Me, eventName) Then
            Params.Remove("eventname")
            Params.Remove("eventparams")
            If eventName = "page_dropped" Then
                page.ProcessDroppedEvent(Params)
            End If
            Select Case Params.Size
                Case 0
                    CallSub(Me, eventName)
                Case 1
                    CallSub2(Me, eventName, Params.Get(eventParams(0)))
                Case 2
                    If Params.get(eventParams(0)) = "abmistable" Then
                        Dim PassedTables As List = ABM.ProcessTablesFromTargetName(Params.get(eventParams(1)))
                        CallSub2(Me, eventName, PassedTables)
                    Else
                        CallSub3(Me, eventName, Params.Get(eventParams(0)), Params.Get(eventParams(1)))
                    End If
                Case Else
                    ' cannot be called directly, to many param
                    CallSub2(Me, eventName, Params)
            End Select
        End If
    Else
        CallSubDelayed2(caller, "ParseEvent", Params) 'ignore
    End If
End Sub

public Sub BuildTheme()
    ' start with the base theme defined in ABMShared
    theme.Initialize("pagetheme")
    theme.AddABMTheme(ABMShared.MyTheme)

    ' add your specific page themes
    ' the page theme
    theme.Page.BackColor = ABM.COLOR_GREY
    theme.Page.BackColorIntensity =  ABM.INTENSITY_LIGHTEN3
End Sub

public Sub BuildPage()
    ' initialize the theme
    BuildTheme
    
    ' initialize this page using our theme
    page.InitializeWithTheme(Name, "/ws/" & ABMShared.AppName & "/" & Name, False, ABMShared.SessionMaxInactiveIntervalSeconds, theme)
    page.ShowLoader=True
    page.PageHTMLName = "index.html"
    page.PageTitle = "Target vs Achievements (Service)"
    page.PageDescription = "Target vs Achievements (Service)"
    page.PageKeywords = ""
    page.PageSiteMapPriority = ""
    page.PageSiteMapFrequency = ABM.SITEMAP_FREQ_YEARLY
        
    page.ShowConnectedIndicator = True
    
    ' adding a navigation bar
    ABMShared.BuildNavigationBar(page, "Target vs Achv (Service)","../images/logosmall.jpg", "", "", "")
            
    ' create the page grid
    page.AddRowsM(2,True,20,0, "").AddCells12MP(1,0,0,0,0,"")
    
    page.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components       
End Sub

public Sub ConnectPage()           
    '    connecting the navigation bar
    ' ABMShared.ConnectNavigationBar(page)

    Dim RadioTrgtType As ABMRadioGroup
    RadioTrgtType.Initialize(page,"RadioTrgtType","pagetheme")
    RadioTrgtType.AddRadioButtonNoLineBreak("Volume", True)
    RadioTrgtType.AddRadioButtonNoLineBreak("Income", True)
    RadioTrgtType.SetActive(1)
    page.Cell(1,1).AddComponent(RadioTrgtType)

    
    ' refresh the page
    page.Refresh
    
    ' Tell the browser we finished loading
    page.FinishedLoading
    ' restoring the navigation bar position
    page.RestoreNavigationBarPosition   
End Sub
#end region

'The following sub is not raised
Sub RadioTrgtType_Clicked(Target As String)
    
    Dim RadioTargetType As ABMRadioGroup = page.Component("RadioTrgtType")
    nTargetType = RadioTargetType.GetActive()
    
    Log("Target is " & Target)
    page.ShowToast("toast" & myToastId, "toastorange", "Clicked on "& nTargetType, 5000, False)

End Sub

#Region ABMPage
' clicked on the navigation bar
Sub Page_NavigationbarClicked(Action As String, Value As String)
    ' saving the navigation bar position
    page.SaveNavigationBarPosition
    If Action = "LogOff" Then
        ABMShared.LogOff(page)
        Return
    End If

    ABMShared.NavigateToPage(ws, ABMPageId, Value)
End Sub

Sub Page_DebugConsole(message As String)
    Log("---> " & message)
End Sub

#end region

Any help will be appreciated
 

Anser

Well-Known Member
Licensed User
Longtime User
I am also getting runtime errors when I try to access the ABMRadioGroup control from another sub. As the RadioGroup event click event was not firing, I kept an ABM button for the user to click ie after clicking and selecting the RadioGroup option, the user will click the ABMbutton to process
B4X:
Sub BtnProcess_Clicked(Target As String)
    
    Dim RadioTrgtType As ABMRadioGroup = page.Component("RadioTrgtType")
    'The following line is giving me run time error
    nTargetType = RadioTrgtType.GetActive()
    ws.Session.SetAttribute("TargetType", nTargetType )
    
    Log("Target is " & Target)
    page.ShowToast("toast" & myToastId, "toastorange", "Clicked on "& nTargetType, 5000, False)
    
    ' refresh the page
    page.Refresh
End Sub

Here is the error log. ( java.lang.NullPointerException ) while reaching the code nTargetType = RadioTrgtType.GetActive()
B4X:
Waiting for value (17 ms)
TargetService5489132a-daf6-4277-b7cf-ab353d88b2a4
Event raised is
btnprocess_clicked
Waiting for value (1 ms)
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NullPointerException
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:119)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
    at anywheresoftware.b4j.object.WebSocketModule$Adapter$1.run(WebSocketModule.java:126)
    at anywheresoftware.b4a.keywords.SimpleMessageLoop.runMessageLoop(SimpleMessageLoop.java:30)
    at anywheresoftware.b4a.StandardBA.startMessageLoop(StandardBA.java:26)
    at anywheresoftware.b4j.object.WebSocketModule$Adapter$ThreadHandler.run(WebSocketModule.java:191)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NullPointerException
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:496)
    at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:442)
    at com.ab.template.targetservice._page_parseevent(targetservice.java:651)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
    ... 10 more
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:119)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:487)
    ... 17 more
Caused by: java.lang.NullPointerException
    at com.ab.abmaterial.ABMRadioGroup.GetActive(Unknown Source)
    at com.ab.template.targetservice._btnprocess_clicked(targetservice.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
    ... 18 more
Event raised is
page_visibilitystate
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Hummm,
I use ABMradiogroup on a page and in a container. (of the same page)
Events fire, target looks good and the active is reported correctly...
Version 4.03



B4X:
'Debug log:

'event name and params: rgsd1_clicked  target  (page parse_event).
'ABM Version: 4.03
 'rgsd1_clicked was processed (on a page): Target Result [ rgsd1 ]  What is Active?: 0
 'event name and params: rg1_clicked  target
 'rg1_clicked was processed (inside a container): Target Result [ cnt1-rg1 ] What is Active?: 1
 'event name and params: rg1_clicked  target
 'rg1_clicked was processed (inside a container): Target Result [ cnt1-rg1 ] What is Active?: 0
 'event name and params: rgsd1_clicked  target
'ABM Version: 4.03
 'rgsd1_clicked was processed (on a page): Target Result [ rgsd1 ]  What is Active?: 1
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
I copied ABM v 4.51 Template folder and created a new project. Nothing complicated, just added a RadioGroup in the template page in the ConnectPage() as given below and added an event to capture the click event of radio. Unfortunately I am unable to capture the RadioGroup's click event.
B4X:
public Sub ConnectPage()          
    '    connecting the navigation bar
    ABMShared.ConnectNavigationBar(page)
   
   
    Dim myradio As ABMRadioGroup
    myradio.Initialize(page,"myradio","")
    myradio.AddRadioButtonNoLineBreak("Option 1",True)
    myradio.AddRadioButtonNoLineBreak("Option 2",True)
    myradio.SetActive(1)
   
    page.Cell(1,1).AddComponent(myradio)

    ' refresh the page
    page.Refresh
   
    ' Tell the browser we finished loading
    page.FinishedLoading
    ' restoring the navigation bar position
    page.RestoreNavigationBarPosition  

End Sub

Sub myradio_Clicked(Target As String)
    Log("Target is " & Target)
    page.ShowToast("toast" & myToastId, "toastorange", "Clicked on Radio", 2000, False)
End Sub
In the Page_ParseEvent()
Log("eventName is " & eventName) does not display anything when the radio is clicked
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
I just tried exactly the same with the template and I get a log in ParseEvent() + the toast message. In Chrome, press F12 and check the console/network for missing stuff.

upload_2018-11-27_10-13-26.png
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
In Chrome, press F12 and check the console/network for missing stuff.
Yes, I see the following error message in Chrome (F12), Console
Console.png


Here is the animated GIF of the scenario. See no even is raised while clicking the radio
Test.gif
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
I do not understand the reason for the error shown in Chrome(F12) console ie Uncaught ReferenceError: radioclickarray is not defined
at HTMLInputElement.onclick ((index):1)

Is this error something due to the way I defined and used the ABMRadioGroup ? May I know, where I have went wrong ?

I just tried exactly the same with the template and I get a log in ParseEvent() + the toast message.
Would you mind pasting your code here.
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
Your Template is working fine here. I mean the Radio Click event is fired properly as expected

This is the download link for my Template project
https://we.tl/t-9DLjjteFsS

I am really puzzled. Can't understand what is going on.:confused:

I copied the following following folders ( www\cs, www\js, www\font ) from the template that you shared in your previous post to my template project. This was done to find out whether by copying the www solves the problem or not. If solved then I could copy this www\js,cs,font to my real project and then continue with my work.
Even with the copied ( www\cs, www\js, www\font ) folders the radio is not working here for me in my Template Project.

One thing that I noticed is that in your template project that you shared just now, the radio buttons appear in Blue color, in mine it appears in Green color.

As I already told in the first post, there is already a RadioGroup working fine in the same real project of mine, but when I try to create the radio in another page in the same project, then it is not working. There also I noticed that the Radio that I have problem appears in Green color, whereas the working one appears in Blue color:)

EDIT:- The only difference is that the working radio in my project was created with the previous version of ABM, to create the new page I am using the latest ver of ABM

By the way any idea why is the error in Chrome console ie Uncaught ReferenceError: radioclickarray is not defined at HTMLInputElement.onclick ((index):1)
 
Last edited:
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
Not sure whther this particular problem has something to do with the lib versions. Here is the screen snap shot
LibVer.jpg
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
I think that I getting a clue now.
When I build the application, the file copymewithjar.needs is not getting generated.

To find out what is wrong between your template project and my template project, I was checking all files one by one, then I noticed that my template project does not have the file copymewithjar.needs. I copied this file from your template project to my template project. Then it worked.

After comparing so many things this is what I understood.

In my original project too, the file copymewithjar.needs is not updated after 19-Nov-2018. If I am not wrong, this is the day that I updated to ABM ver 4.51

I assume that this is the reason why the radio is working fine in another page of the same project and not working on a new page that I created with the latest ABM ver 4.51 in the same project. Then I created this thread.

If you download the Template which I already shared with you in post #13, you will not find the file copymewithjar.needs in the objects folder

Is this a bug with the ABM version 4.51 ?
 
Last edited:
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
Modified the file copymewithjar.needs of my real project and added the following line.
B4X:
MyPageName:NeedsRadio
Then the Radio in my real project started working.:)

Hope this issue with the copymewithjar.needs will be resolved
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
In my original project too, the file copymewithjar.needs is not updated after 19-Nov-2018
If you add a new ABM component (not used in your project before), does the copymewithjar.needs get updated / created?
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
Hope this issue with the copymewithjar.needs will be resolved
It does work, but you probably immidiately ran it in Release mode. Note that the copymewithjar.needs file ONLY gets generated when running in debug mode.

Reason:

1. In debug mode ABM is sure you have the source code
2. So it analyses the source code, finds that it will need the libraries for a radiogroup and writes it in the copymewithjar.needs file

Now suppose we have uploaded the app to our server: at this point, our app does not have the source code anymore
But that is ok, as it knows from the copymewithjar.needs file, previously generated from the debug run, what it needs: in this case the libraries for the radiogroup.

So general rule to be safe could be: when you made a change in the code, run it at least once in Debug mode

This is something I'm so used to do,that I forgot this could've been the problem :rolleyes:

If you add a new ABM component (not used in your project before), does the copymewithjar.needs get updated / created?
So yes, IF you run your app in debug mode at least once.
 
Upvote 0

Anser

Well-Known Member
Licensed User
Longtime User
So general rule to be safe could be: when you made a change in the code, run it at least once in Debug mode
This is a new information to me. I wonder how the needs file generated for me all these times. May be at some point of time, I must have accidentally compiled the app in debug mode. Thanks for this valuable information.

Wouldn't it be nice that the needs file gets generated on every compilation irrespective of whether it is in debug/release/release (obfuscated) mode

The template project (to demonstrate the issue to you) too was compiled ONLY in release mode:)

I am not used with the debug mode (I am weird right ?:)) , so I don't use it and haven't used it till now. I remember that on Nov-15th, I reloaded my Windows operating system and after reloading I installed B4J. When I compiled the ABM application for the first time after the re installation, the app was compiled in Debug mode, I believe that Debug mode is the default option in B4J. Then I changed it back to Release mode.

Anyways the issue is resolved and learned a valuable lesson. Thank you very much:)
 
Upvote 0
Top