B4J Question [ABMaterial] Multi-Column page?

ShaneG30

Well-Known Member
Licensed User
I've read the grids page in the ABMaterial demo, however, I'm confused on how to insert more columns.
 

ShaneG30

Well-Known Member
Licensed User

Gabino A. de la Gala

Active Member
Licensed User
I have prepared a procedure, depending on the number of " columns " desired, generates the cards . On each card would put buttons to add or remove the cart. The problem I have is that I can not capture the press event on the different buttons . How should I? Each row is a container in which I define as many columns as I need at all times. In the example attached rows are 1 , 2, 4 , 6, 12 columns respectively.

B4X:
...
    NRegistros = NRegistros + 1
    ContAux.Cell(1, MyToastId).AddComponent(BuildCard("card"&NRegistros,  "../images/"&"sinfoto.jpg", "Card"&NRegistros))
B4X:
Sub BuildCard(id As String, image As String, title As String) As ABMCard
    ' image card
    Dim card4 As ABMCard
    card4.InitializeAsCard(page, id, title, "linea1<BR>linea2", ABM.CARD_NOTSPECIFIED,"whitetitle")
    card4.Image = image
'    card4.IsReveal=True
    card4.AddAction("Ud. +")
    card4.AddAction("Ud. -")
    Return card4
End Sub
B4X:
Sub card1_LinkClicked(Card As String, Action As String)
    MyToastId = MyToastId + 1
    page.ShowToast("toast" & MyToastId, "toastred", "Clicked on " & Action & "!", 5000)
End Sub

Sub card2_LinkClicked(Card As String, Action As String)
    MyToastId = MyToastId + 1
    page.ShowToast("toast" & MyToastId, "toastred", "Clicked on " & Action & "!", 5000)
End Sub
 

Attachments

alwaysbusy

Expert
Licensed User
I'm posting the solution here as some of you may experience a similar case.

In this particular example, Gabino wanted to create cards at runtime. The cards are in a container together with a button and some text fields. something like this:

upload_2016-3-11_13-45-31.png


Moreover, every time a button is pressed, a new card is added. But each row contains more and more cards: 1,2,3,4,6,12. Like this:

upload_2016-3-11_13-49-47.png


When clicking on the links in the card (or on the blue button) only one event should be raised so we do not have to write an event for each card.

Solution:

1. Note as we will add cards at runtime, and do not have any at startup we need an import line in our BuildPage() method:

B4X:
page.NeedsCards=True
2. The code to build the affect we want. Take special note to when I use AddComponent() and AddArrayComponent(). The code is mixed English/Spanish as I took Gabinos code as a base. But I've added some useful comments to explain what is happening.

B4X:
Sub BtnPulsado_Clicked(ItemId As String)   
    Dim ContAux As ABMContainer
    Dim Cont1 As ABMContainer
    If MyToastId = 0 Then
        Cont1 = page.Component("Cont1")
        ContAux.Initialize(page, "ContAux" & Pasada, "")
        ContAux.AddRowsM(1, True, 0, 0, "").AddCellsOS(NColumnas, 0, 0, 0, 12/NColumnas, 12/NColumnas, 12/NColumnas, "")
        ContAux.BuildGrid
        Cont1.Cell(1,1).AddComponent(ContAux)
    Else
        Cont1 = page.Component("Cont1")
        ContAux = Cont1.Component("ContAux" & Pasada)           
    End If
   
    MyToastId = MyToastId + 1
    NRegistros = NRegistros + 1
       
    ws.Session.SetAttribute("UnidadesEnCarrito", NRegistros)

    ' add a new container ContWithCard (with card, button and texts) to the container contAux
    ' note we use AddComponent, so we can give it a full name: "ContWithCard" & NRegistros
    ContAux.Cell(1, MyToastId).AddComponent(BuildContainerWithCard("ContWithCard" & NRegistros))
   
    ' this refresh should be sufficient
    Cont1.Refresh
    If MyToastId = NColumnas Then
        MyToastId = 0
        Pasada = Pasada + 1
       
        If Pasada = 5 Then Pasada = 6
        If Pasada = 7 Then Pasada = 12
        NColumnas = Pasada
    End If
End Sub

Sub BuildContainerWithCard(id As String) As ABMContainer
    Dim ContainerAux As ABMContainer
    ContainerAux.Initialize(page, id, "")
    ContainerAux.AddRows(1, True, "").AddCellsOS(1,0,0,0,11,11,11,"").AddCellsOS(1,0,0,0,1,1,1,"")
    ContainerAux.AddRows(3, True, "").AddCellsOS(3,0,0,0,4,4,4,"")
    ContainerAux.BuildGrid
   
    ' We want to get the events of the card in one method as an array: Card_LinkClicked() so we use AddArrayComponent
    ' Note if we use AddArrayComponent, we do not use a prefix for the 'id', just NRegistros
    ' In the Card_LinkClicked(card,action) event we will receive Card + NRegistros in the card Param so we know on what has been clicked.
    ContainerAux.Cell(1,1).AddArrayComponent(BuildCard(NRegistros,  "../images/list1.jpg", "Card" & NRegistros), "Card")
   
    Dim BtnTarjeta As ABMButton
    BtnTarjeta.InitializeFloating(page, NRegistros, "mdi-image-exposure-plus-1", "darkred")
    ' We want to get the events of the button in one method as an array: "BtnTarjeta_Clicked() so we use AddArrayComponent
    ' Note if we use AddArrayComponent, we do not use a prefix for the 'id', just NRegistros
    ' In the BtnTarjeta_Clicked(Target) event we will receive BtnTarjeta + NRegistros in the Target Param so we know on what has been clicked.
    ContainerAux.Cell(1, 2).AddArrayComponent(BtnTarjeta, "BtnTarjeta")
   
    ' just in case we want to change the texts later, I've added them also with AddArrayComponent so they are unique for sure.
    ContainerAux.Cell(2, 1).AddArrayComponent(ABMShared.BuildParagraph(page, NRegistros, "{B}" & id & "{/B}"), "par1_")
    ContainerAux.Cell(2, 2).AddArrayComponent(ABMShared.BuildParagraph(page, NRegistros, "{B}Stock:{/B}" & id & " {B}Art.{/B}"&id), "par2_")
    ContainerAux.Cell(2, 3).AddArrayComponent(ABMShared.BuildParagraph(page, NRegistros, "{B}St.{/B}" & id), "par3_")
   
    Return ContainerAux   
End Sub

Sub BuildCard(id As String, image As String, title As String) As ABMCard
    ' image card
    Dim card4 As ABMCard
    card4.InitializeAsCard(page, id, title, "", ABM.CARD_NOTSPECIFIED,"whitetitle")
    card4.Image = image
    card4.AddAction("-")
    Return card4
End Sub   

' card was added as an array component, so we need just prefix_LinkClicked
Sub card_LinkClicked(Card As String, Action As String)
    Log(Card & " " & Action) ' we get something like card1, card2, card3...     in the card param
End Sub

' btntarjeta was added as an array component, so we need just prefix_Clicked
Sub btntarjeta_clicked(Target As String)
    Log(Target)  ' we get something like btntarjeta1, btntarjeta2, btntarjeta3...     in the target param
End Sub
This is an example for a more complicated structure (containers in containers).
 
Top