B4J Question B4J ABMaterials get all components within page and change values

Hi,

Im new on this thing and Im trying to change all my objects values and some properties of contained componends in a form (page).

1. How I can get all the elements within a page?
2. How to change a component value? such as calling "Page.Component("mycomponent").vallue = xvalue

any ideas?
 

Harris

Expert
Licensed User
Longtime User
Easy actually... Small example below.

B4X:
Sub SetVisable
   
    ' These three items were created in the ConnectPage().
   '  You must create a local copy to retrieve / update their values.

    Dim cnt1 As ABMContainer = page.Component("cnt1")       '         this is a container "cnt1" on a page
    Dim rgsd As ABMRadioGroup = cnt1.Component("rgsd")     '        this radio group is attached to container, so you must refer to cnt1 to get the component
    Dim rgdefect As ABMRadioGroup = cnt1.Component("rgdefect") ' so is this one....
   
    If reportparams.Get("p1") = "0" Then       '  a global map used to store values...
        cnt1.Row(3).Visibility = ABM.VISIBILITY_HIDE_ALL 
        cnt1.Row(4).Visibility = ABM.VISIBILITY_HIDE_ALL 
    Else
        cnt1.Row(3).Visibility = ABM.VISIBILITY_ALL       ' show or hide components for a row in container...
        cnt1.Row(4).Visibility = ABM.VISIBILITY_ALL 
    End If   

'  Note: I have added many components to the same row / cell, then make them hidden or visible based on the needs..
'  this tactic reduces the number of rows to manage....
   '     combdrv.Visibility = ABM.VISIBILITY_HIDE_ALL   ( hide this component )
   '     combtrl.Visibility = ABM.VISIBILITY_ALL              (and show this one )


    Dim repin As String = reportparams.Get("repfile")               
    Dim combtrl As ABMCombo = cnt1.Component("combtrl")       ' combo items in container, again declare a local copy of component
    Dim combdrv As ABMCombo = cnt1.Component("combdrv")
    Dim rptv As ABMLabel = cnt1.Component("rptv")

    If repin = "edefects" Then
        combdrv.Visibility = ABM.VISIBILITY_HIDE_ALL
        combtrl.Visibility = ABM.VISIBILITY_ALL
        rptv.Text = "Trailer / Vehicle"                         ' set the label text to this!
        Log(" Add trailers")
        rgdefect.Visibility = ABM.VISIBILITY_ALL
    Else
        combdrv.Visibility = ABM.VISIBILITY_ALL
        combtrl.Visibility = ABM.VISIBILITY_HIDE_ALL
        rptv.Text = "Driver / Vehicle"                                ' or - set the labels text to that....
        rgdefect.Visibility = ABM.VISIBILITY_HIDE_ALL

    End If


  cnt1.Refresh   ' refresh the container (or page  - page.refresh) to update the changes... IMPORTANT!!
 
 
End Sub
 
Upvote 0
HEY! many thanks for replaying! Im aware now that you can only get all components within a container, if you want to use this technology you'll need to use containers and use a serialized Containers to place your components, Ill solved doing this:

every page need a group of containers to "group" your components like this:

'Class module
Sub Class_Globals
' to store all proyect pages and included contaners
Private ThisPageContainers as Map (you can populate this from a JSON file wich contains an array of all containers of your project)

End Sub


public Sub ConnectPage()
' call the JSON file and populate ThisPageContainers with json => map

Dim directory As String = "Your json file path"
Dim TheJson As JSONParser

json.Initialize(File.ReadString(directory,"your json file name"))
ThisPageContainers.Initialize
ThisPageContainers= json.NextObject


End Sub

JSON Sample: (this is to predefine your object containers and all of your components on each page needed, run a loop
{
"myapp": {
"pageA": {
"ContanerA1": { ...container properties ...},
"ContanerA2": { ...container properties ...},
"ContanerA3": { ...container properties ...},
"ContanerA4": { ...container properties ...},
"ContanerAN": { ...container properties ...}
}
"pageB": {
"ContanerB1": { ...container properties ...},
"ContanerB2": { ...container properties ...},
"ContanerB3": { ...container properties ...},
"ContanerB4": { ...container properties ...},
"ContanerBN": { ...container properties ...}
}
}
}


Now you can get all items within all containers in your page with a simple loop that runs all the ThisPageContainers map to get all you components
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Sweet ... @Israel Garcia

You know what would be great... - Create a working example ( a simple project ) and contribute to the "ABMaterial For Dummies" lessons.
I could test your example (PM me) prior to posting to ensure it works and is well defined.

We all want to ensure our (community) dummy lessons help others comprehend how to easily use new processes / features.

Building upon ABM is our goal since it promotes all the best of B4X.

Thanks
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
This will fail on you for a couple of reasons:

1. It will not guarantee that the servers java object values are synced with the JavaScript (browser side) objects. Running a .Component("container") method does not only get the java component from the library, it also syncs it with whatever is on the browser side.
2. It will demand from you quite some discipline to make sure you don't have double key values (array components for example). This is something ABM takes care of for you in the background and was one of the hardest parts of ABM to maintain.

It 'could' work in some cases if your map only contains the container IDs and then use the .Component("") method when you need it, NOT the container objects itself. But even then concern 2 still applies. As soon as you use containers within array containers etc this quickly becomes complex so I would advice just to follow the normal ABM rules. Shortcuts seldom work in the long term.
 
Upvote 0
I think that ABMaterial created the containers for some reason, in fact, there is the attribute "GetAllComponents", therefore, if the engineering is designed to have the elements in the containers, your "Pages" should have "Containers" and it is there where your should objects go, in this way you can affect them in a "group" way. Now, how do you build a software without a preview or inventory of the objects it carries? to build a form, because you do not need a lot of work, to build a REAL application like a Payroll and RH app, some CRM. It Works for me on HUGE apps. And yes, indeed, lots of discipline.

hope it helps;)




This will fail on you for a couple of reasons:

1. It will not guarantee that the servers java object values are synced with the JavaScript (browser side) objects. Running a .Component("container") method does not only get the java component from the library, it also syncs it with whatever is on the browser side.
2. It will demand from you quite some discipline to make sure you don't have double key values (array components for example). This is something ABM takes care of for you in the background and was one of the hardest parts of ABM to maintain.




It 'could' work in some cases if your map only contains the container IDs and then use the .Component("") method when you need it, NOT the container objects itself. But even then concern 2 still applies. As soon as you use containers within array containers etc this quickly becomes complex so I would advice just to follow the normal ABM rules. Shortcuts seldom work in the long term.
 
Upvote 0
Top