B4J Question [ABMaterial] ABMcombo in a ABMcontainer not showing items

Rob White

Member
Licensed User
I have now tried three differing ways to get a combobox to work in a container.
Can someone give me some sample code or find what i am doing wrong.

Not only do I not see the items listed there does not seem to be a click event generated (see log statements in Page_ParseEvent(Params As Map)) BUT the gotfocus and lostfocus events appear.

Below is my test page :-

B4X:
'How To create a new page:-
'
'1] Use Project | Add new model | Class | ABM web page To create page class.
'    Call this File the same Name As your page Name.
'2] Set Public Name As String = "yourPageName" (top of class File around line 20)
'3] In Main class File add a page :-
'        Dim pregTestPage As pregTest  <<<< This is name of class file        (around line 50)
'        pregTestPage.Initialize
'       
'        Add page To site     myApp.AddPage(pregTestPage.page)    ' <<<<< Add to app (site)

'4] Change these (abt line 130) :-
'            page.PageTitle = "Template"
'            page.PageDescription = "Template"
'
'5] In BuildPage Sub :- Build a grid eg     
'    '
'    page.AddRowsM(2,True,20,0, "").AddCells12MP(1,0,0,0,0,"")   
'
'6] Connect controls eg
'        Dim lblTitle As ABMLabel
'        lblTitle.Initialize(page, "lblobservtitle", ABMShared.TitleStr("Observation"), ABM.SIZE_H3, False, "lbltheme1")
'        lblTitle.SetTooltip("Eunony farming",ABM.POSITION_BOTTOMRIGHT,100)
'

'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 = "Testing"                                              ' <<<<<<- IMPORTANT
    ' will hold the unique browsers window id
    Private ABMPageId As String = ""
    ' your own variables   
    
    Dim calves As List
    Dim mothers As List
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    mothers.Initialize
    calves.Initialize
    Dim M1 As beast
    M1.Initialize
    M1.NLIS = 111111
    M1.EarTag = "111"
    M1.OffspringDOB = 123456
    M1.Sex= "C"
    Dim M2 As beast
    M2.Initialize
    M2.NLIS = 222222
    M2.EarTag = "222"
    M2.OffspringDOB = 123456
    M2.Sex= "C"
    Dim M3 As beast
    M3.Initialize
    M3.NLIS = 333333
    M3.EarTag = "333"
    M3.OffspringDOB = 123456
    M3.Sex= "C"
    Dim M4 As beast
    M4.Initialize
    M4.NLIS = 444444
    M4.EarTag = "444"
    M4.OffspringDOB = 123456
    M4.Sex= "C"
    Dim C1 As beast
    C1.Initialize
    C1.NLIS = 555555
    C1.EarTag = "S55"
    C1.OffspringDOB = 123456
    C1.Sex= "H"
    Dim C2 As beast
    C2.Initialize
    C2.NLIS = 666666
    C2.EarTag ="S66"
    C2.OffspringDOB = 123456
    C2.Sex= "H"
    Dim C3 As beast
    C3.Initialize
    C3.NLIS = 777777
    C3.EarTag = "S77"
    C3.OffspringDOB = 123456
    C3.Sex= "S"
    Dim C4 As beast
    C4.Initialize
    C4.NLIS = 888888
    C4.EarTag = "S88"
    C4.OffspringDOB = 123456
    C4.Sex= "S"

    mothers.Add(M1)
    mothers.Add(M2)
    mothers.Add(M3)
    mothers.Add(M4)

    calves.Add(C1)
    calves.Add(C2)
    calves.Add(C3)
    calves.Add(C4)


    ' 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} raised"$)
    Log("                             Passed params: "&Params)
    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
                    Log($".........................>> ${eventName} has 0 args"$)
                    CallSub(Me, eventName)
                Case 1
                    Log($".........................>> ${eventName} has 1 arg ${Params.Get(eventParams(0))}"$)
                    CallSub2(Me, eventName, Params.Get(eventParams(0)))
                Case 2
                    If Params.get(eventParams(0)) = "abmistable" Then
                        Log($".........................>> 'abmistable' ${Params.Get(eventParams(0))}"$)
                        Dim PassedTables As List = ABM.ProcessTablesFromTargetName(Params.get(eventParams(1)))
                        CallSub2(Me, eventName, PassedTables)
                    Else
                        Log($".........................>> ${eventName} callSub3 ${Params.Get(eventParams(0))} , ${Params.Get(eventParams(1))}"$)
                        CallSub3(Me, eventName, Params.Get(eventParams(0)), Params.Get(eventParams(1)))
                    End If
                Case Else
                    ' cannot be called directly, to many param
                    Log(".........................>> cannot be called directly, to many param")
                    CallSub2(Me, eventName, Params)
            End Select
        End If
    Else
        Log(".........................>> Caller NOT me")
        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
    
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 = "Testing"
    page.PageDescription = "Tests only"
    page.PageKeywords = ""
    page.PageSiteMapPriority = ""
    page.PageSiteMapFrequency = ABM.SITEMAP_FREQ_YEARLY
        
    page.ShowConnectedIndicator = True
                
    ' adding a navigation bar
    ' ABMShared.BuildNavigationBar(page, "My Page","../images/logo.png", "", "", "")   
            

    page.AddRowsM(1,True,20,0, "").AddCells12MP(1,0,0,0,0,"")
    page.AddRowsM(1,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 tstC As ABMCombo
tstC.Initialize(page,"tstc","Test combo",300,"")
    fillSingle(tstC)

'    Dim TBL As ABMTable
'    TBL.Initialize(page,"tbl",True,False,True,"")
'    page.Cell(1,1).AddComponent(TBL)
    'fillTable   

    Dim chk As ABMCheckbox
    chk.Initialize(page,"chk","Tick me",False,"")
    Dim con As ABMContainer
    con.Initialize(page,"con","")
    con.AddRows(1,True,"").AddCellsOS(1,0,0,0,2,2,2,"").AddCellsOS(1,3,3,3,6,6,6,"")
    con.BuildGrid
    con.Cell(1,1).AddComponent(chk)
    con.Cell(1,2).AddComponent(tstC)

    page.Cell(2,1).AddComponent(con)

    ' refresh the page
    page.Refresh
    
    ' Tell the browser we finished loading
    page.FinishedLoading
    
'    fillList

    ' restoring the navigation bar position
    page.RestoreNavigationBarPosition
End Sub
#end region

Sub fillSingle(cmb As ABMCombo)
        For j = 0 To mothers.Size-1
            Dim lab As ABMLabel
            Dim M As beast = mothers.Get(j)
            lab.Initialize(page,"lab"&j,M.EarTag,ABM.SIZE_H6,False,"")
            lab.Tag=M
            cmb.AddItem("m"&j,m.eartag,lab)
        Next
        cmb.SetActiveItemId(-1)
        cmb.Refresh
End Sub


Sub fillTable ' for table
    Dim T As ABMTable = page.Component("tbl")
    T.Clear
    T.IsResponsive=False
    If calves.Size > 0 Then
        For i = 0 To calves.Size-1
            Dim C As beast = calves.Get(i)
            Dim R As List
            R.Initialize
            Dim chk As ABMCheckbox
            chk.Initialize(page,"chkbx"&i,C.EarTag,False,"")
            chk.Tag = C
            R.Add(chk)
            Dim cmb As ABMCombo
            cmb.Initialize(page,"cmb"&i,$"Select mother (${mothers.Size})"$,300,"")
            'cmb.SetRelativePosition(ABM.POSITION_TOPRIGHT,0,-45)
            For j = 0 To mothers.Size-1
                Dim lab As ABMLabel
                Dim M As beast = mothers.Get(j)
                lab.Initialize(page,"lab"&j,M.EarTag,ABM.SIZE_H6,False,"")
                lab.Tag=M
                cmb.AddItem("m"&j,m.eartag,lab)
            Next
            cmb.SetActiveItemId(-1)
            cmb.Refresh
            cmb.RaiseChangedEvent=True
            R.Add(cmb)
            T.AddRow("r"&i,R)
        Next
    Else
        Dim lbl As ABMLabel
        lbl.Initialize(page,"lbl",$"No calves found!"$,ABM.SIZE_H5,False,"")
        T.AddRow("lbl",lbl)
    End If
    T.Refresh
End Sub

Sub fillList ' for list
    Dim L As ABMList = page.Component("LST")
    L.Clear
    
    If calves.Size > 0 Then
        For i = 0 To calves.Size-1
            Dim C As beast = calves.Get(i)
            Dim con As ABMContainer
            con.Initialize(page,"con"&i,"")
            
            Dim chk As ABMCheckbox
            chk.Initialize(page,"chkbx"&i,C.EarTag,False,"")
            chk.Tag = C
            con.AddRows(1,True,"").AddCellsOS(1,0,0,0,2,2,2,"").AddCellsOS(1,3,3,3,10,10,10,"")
            con.BuildGrid
            Dim cmb As ABMCombo
            cmb.Initialize(page,"cmb"&i,$"Select mother (${mothers.Size})"$,300,"")
            cmb.SetRelativePosition(ABM.POSITION_TOPRIGHT,0,-45)
            For j = 0 To mothers.Size-1
                Dim lab As ABMLabel
                Dim M As beast = mothers.Get(j)
                lab.Initialize(page,"lab"&j,M.EarTag,ABM.SIZE_H6,False,"")
                lab.Tag=M
                cmb.AddItem("m"&j,m.eartag,lab)
            Next
            
            cmb.SetActiveItemId(-1)
            cmb.Refresh
            con.Cell(1,1).AddComponent(chk)
            con.Cell(1,2).AddComponent(cmb)
            L.AddItem("I"&i,con)
        Next
    Else
        Dim lbl As ABMLabel
        lbl.Initialize(page,"lbl",$"No calves found!"$,ABM.SIZE_H5,False,"")
        L.AddItem("L-1",lbl)
    End If
    L.Refresh
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
 

Harris

Expert
Licensed User

B4X:
Sub fillSingle    '(cmb As ABMCombo)

Dim cmb As ABMCombo = page.Component("tstc") '<--- ID..."tstc"  'important - as you have done elsewhere....   (why not here????)

        For j = 0 To mothers.Size-1
            Dim lab As ABMLabel
            Dim M As beast = mothers.Get(j)
            lab.Initialize(page,"lab"&j,M.EarTag,ABM.SIZE_H6,False,"")
            lab.Tag=M
            cmb.AddItem("m"&j,m.eartag,lab)
        Next
        cmb.SetActiveItemId(-1)
        cmb.Refresh
End Sub
 

Rob White

Member
Licensed User
Thanks Harris,

Not sure why I did that! I also needed to put the call to fillSingle AFTER the page.FinishedLoading call to avoid a NullPointerException.

Regards

Rob White
 

Harris

Expert
Licensed User
Thanks Harris,

Not sure why I did that! I also needed to put the call to fillSingle AFTER the page.FinishedLoading call to avoid a NullPointerException.

Regards

Rob White
Hey, I am not sure why I do many things (blurred vision)... We often get blinded by what we are trying to accomplish - with our own dim view.
Another set of eyes can often help when you reach out, as you here. At least, it can sometimes lead you in the right direction.

I (sometimes) don't understand why you do things in the manner you do in ABM; that is not the way I was taught. But - if it works - what the hell...

Thanks
 
Top