Share My Creation Pen&Paper: PWCT for Basic ABMaterial WebApps

Mashiane

Expert
Licensed User
Longtime User
MyMaterial.Show: What's New

Calling php scripts that access MySQL


My current android apps use MySQL and I am accessing that via PHP. At the moment I dont have the time to run throught the database functionality built into ABMaterial, so I decided to explore if I can call my php scripts inside a generated MyMaterial.Show project. Well, I can it seems.

Well, I'm not sure how safe this method is but for now it works and I will settle for it for now.

This is what I needed to do.

Download the OkHttpUtils2 library.
NB: Reference OkHttpUtils2_NONUI library in my project. I later built this into the generated code of MyMaterial.Show
Referenced json library and also jStringUtils library. These two libraries I am using for some method I am using.

In my ABMShared, defined a variable to hold the php server path that I will refer to when I call my http methods.
Added the following methods to my ABMShared that I will use across my app...

B4X:
' download an image from the server, handle result with job.getbitmap (not tested yet)
Sub GetImageFromServer(page As Object, iLink As String, JobName As String, phpTag As String)
    Dim job As HttpJob
    job.Initialize(JobName, page)
    job.Tag = phpTag
    Log(iLink)
    job.Download(iLink)
End Sub

' convert a json string to a list
Sub Json2List(jsonTxt As String) As List
    Dim root As List
    root.Initialize
    Try
        Dim parser As JSONParser
        parser.Initialize(jsonTxt)
        root = parser.NextArray
        Return root
    Catch
        Return root
    End Try
End Sub

' runs a php scripts at the server
Sub ExecutePHP(page As Object, pQuery As Map, JobName As String, phpFile As String, phpTag As String)
    Dim job As HttpJob
    Dim scommand As String
    Dim json As String
    job.Initialize(JobName, page)
    job.Tag = phpTag
    json = Map2QueryString(pQuery)
    If Len(json) = 0 Then
        scommand = PhpPath & phpFile
    Else
        scommand = PhpPath & phpFile & "?" & json
    End If
    Log(scommand)
    job.Download(scommand)
End Sub

' converts a map to a querystring
Sub Map2QueryString(sm As Map) As String
    ' convert a map to a querystring string
    Dim SU As StringUtils
    Dim iCnt As Int
    Dim iTot As Int
    Dim sb As StringBuilder
    Dim mValue As String
    sb.Initialize
   
    ' get size of map
    iTot = sm.Size - 1
    iCnt = 0
    For Each mKey As String In sm.Keys
        mValue = sm.Get(mKey)
        mValue = SU.EncodeUrl(mValue, "UTF8")
        mKey = mKey.Trim
        If mKey.EndsWith("=") = False Then mKey = mKey & "=" 
        sb.Append(mKey).Append(mValue)
        If iCnt < iTot Then sb.Append("&")
        iCnt = iCnt + 1
    Next
    Return sb.ToString
End Sub

Added these variables and method on the ABMTemplate file

B4X:
Public JobList As List
    Public JobMap As Map
    Public JobCnt As Int
    Public JobTot As Int
    Public JobTag As String
    Public myToastId As Int
    Public dbAction As Map

B4X:
Sub JobDone(job As HttpJob)
    If job.Success = True Then
        Select job.JobName
        Case "checkemail"
            JobList = ABMShared.Json2List(job.GetString)
            JobTag = job.Tag
            job.release
            Log(JobList)
        End Select
    Else
        myToastId = myToastId + 1   
        page.ShowToast("toast" & myToastId, "toastred", job.errormessage, 5000)
        job.release
    End If
End Sub

To test this, I updated my cmdLogin script to be like this...

B4X:
Sub cmdLogin_Clicked(Target As String)
    Dim m As Map
    m = frmLoginGetContents
    If frmLoginValidate(m) = False Then
        Return
    End If
    ' check if a record exists in the database with this email address and return it
    Dim sEmail As String
    sEmail = m.Get("email")
    dbAction.Initialize
    dbAction.Put("action", "getemail")
    dbAction.Put("email", sEmail)
    ABMShared.ExecutePHP(Me,dbAction, "checkemail", "users.php", sEmail)
End Sub

Figure 1: Update MyMaterial.Show to reflect the php server path...



The Log results of my php script...



Excited for days...
 

Mashiane

Expert
Licensed User
Longtime User
MyMaterial.Show: What's Happening...?

Well, finally I have managed to get myself around the ABMList component. This is one of the most interesting components in creating mobile apps. I like the fact that this ABMList is flexible, but I guess until I master the grid, I could also add some more interesting components to the list.

This has been limited to what is in the example, i.e. adding ImageTitle, ImageTitleDescription and Card.

What I have done is to create methods within the ABMShared module to handle these.

B4X:
Sub ListItemCard(page As ABMPage, id As String, image As String, title As String, description As String, Theme As String) As ABMCard
    ' image card
    Dim card4 As ABMCard
    card4.InitializeAsCard(page, "card4", title, description, ABM.CARD_NOTSPECIFIED, Theme)
    card4.Image = image
    Return card4
End Sub

Sub ListItemImageTitle(page As ABMPage, id As String, icon As String, Title As String, Theme As String) As ABMLabel
    Dim lbl As ABMLabel
    If icon <> "" Then
        lbl.Initialize(page, id, Title, ABM.SIZE_H6, False, Theme)
    Else
        lbl.Initialize(page, id, Title, ABM.SIZE_H6, True, "")
    End If
    lbl.VerticalAlign = True
    lbl.IconName = icon
    Return lbl
End Sub

Sub ListItemImageTitleDescription(page As ABMPage, id As String, image As String, Title As String, Subtitle As String, TitleTheme As String, DescriptionTheme As String, bIsCircular As Boolean) As ABMContainer
    Dim ItemCont As ABMContainer
    ItemCont.Initialize(page, id, "")   
    ItemCont.AddRowsM(1,False,6,0, "").AddCellsOSMP(1,0,0,0,3,2,2,0,0,16,0,"").AddCellsOS(1,0,0,0,9,10,10,"")
    ItemCont.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components
   
    Dim SubItemCont As ABMContainer
    SubItemCont.Initialize(page, id & "SubItemCont", "")   
    SubItemCont.AddRowsM(1,False, 0,0,"").AddCells12MP(1,-6,0,0,0,"").AddCells12(1,"")
    SubItemCont.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components
   
    ItemCont.Cell(1,2).AddComponent(SubItemCont)
   
    Dim img As ABMImage
    img.Initialize(page, id & "img", image, 1)
    img.SetFixedSize(48,48)
    img.IsCircular = bIsCircular
    img.IsResponsive = True
   
    ItemCont.Cell(1,1).AddComponent(img)
   
    Dim lbl1 As ABMLabel
    lbl1.Initialize(page, id & "lbl1", Title, ABM.SIZE_H6, False, TitleTheme)
    lbl1.VerticalAlign = True
   
    SubItemCont.Cell(1,1).AddComponent(lbl1)
   
    Dim lbl2 As ABMLabel
    lbl2.Initialize(page, id & "lbl2", Subtitle, ABM.SIZE_H6, False, DescriptionTheme)
    lbl2.VerticalAlign = True
   
    SubItemCont.Cell(1,2).AddComponent(lbl2)
   
    Return ItemCont
End Sub

As you will note, these are no so different as to what is in the demo with the exception that you have more control in terms of the content. For example
  • The Description has its own theme.
  • You can indicate whether you want your images circular or not
  • The Card Title, Description and Theme are easily customizable.

I have noted that these methods are similar to the ABMCombo methods, so that will also be completed soon.



There is still a lot to learn here, for example I want an ImageTitle with own custom image, even for the SubItems.
 

Mashiane

Expert
Licensed User
Longtime User
MyMaterial.Show: Creating an ABMListComponent

The ABMList, ABMListItem and ABMListSubItem components are under the Components menu.

1. Select the Page that you want to add the component to, then Components > ABMList, Figure 1 below is an example.

Figure 1



When you specify the Max Height, the list will be initialize with max height. You can create a theme that will be applicable to the list and specify it here.

The next step is to add ABMListItem and possibly ABMListSubItem to the list.

Components > ABMListItem, Figure 2 below is an example of an ABMListItem, you can add three types of items for now, ListItemImageTitle, ListItemImageTitleDescription and ListItemCard, meaning a list item with an image and a title, a list item with an image, title and description and then a list item that is a card.

Figure 2



The component id is the ItemId that will be returned when the list item is clicked. With MyMaterial.Show, you can specify an external URL or an internal page that you want to navigate to when the item is selected. You can also paste your source code in the provided space for the code to run when that item is selected.

Figure 3: ListItemTitleDescription



With this you can specify the image location or choose an internal image from the list provided, indicate if the image should be circular, specify too where to navigate too. MyMaterial.Show will build the source code for your for navigation.

After you have added your List Items, you can add subitems by Components > ABMListSubItem, Figure 4 below shows an example.

Figure 4



For the sub-item, you need to select the parent List Item. I have left the screens to be identical due to future changes and more additions that might happen here. I like flexibility.

As indicated earlier on, you can add a Card Item to the list.

Figure 5.



This is made by changing the Item Type to ListItemCard. You will note the types here are closed linked to the ABMShared methods in the previous posts. This means we can add more methods and add more types linked together easily.

For my example, I created the ABMList in the previous post with MyMaterial.Show generated source code like this..

B4X:
Dim list1 As ABMList
list1.Initialize(page, "list1", ABM.COLLAPSE_EXPANDABLE, "list1theme")
list1.AddItem("H1", ABMShared.ListItemImageTitle(page, "list1H1", "mdi-communication-business", "Google", "lightblue"))
list1.AddSubItem("H1", "S1", ABMShared.ListItemImageTitle(page, "H1S1", "", "Mom", "green"))
list1.AddSubItem("H1", "S2", ABMShared.ListItemImageTitle(page, "H1S2", "", "Dad", "green"))
list1.AddSubItem("H1", "S3", ABMShared.ListItemImageTitle(page, "H1S3", "", "Son", "green"))
list1.AddItem("H11", ABMShared.ListItemImageTitleDescription(page, "list1H11", "../images/list1.jpg", "Family", "A family business", "lightblue", "lightblue", True))
list1.AddItem("H2", ABMShared.ListItemImageTitle(page, "list1H2", "fa fa-apple", "Colleagues", "lightblue"))
list1.AddItem("H21", ABMShared.ListItemImageTitleDescription(page, "list1H21", "../images/list2.jpg", "Colleagues", "An apple, nice!", "lightblue", "lightblue", False))
list1.AddItem("H3", ABMShared.ListItemImageTitle(page, "list1H3", "mdi-content-sort", "Friends", "lightblue"))
list1.AddItem("H4", ABMShared.ListItemImageTitle(page, "list1H4", "mdi-toggle-radio-button-on", "Others", "lightblue"))
page.Cell(2,1).AddComponent(list1)
 

Mashiane

Expert
Licensed User
Longtime User
Continuation from Post #83 and #84

The code for the ABMList click event for my case, will look something like this... you can then add your code to indicate what should be done by your app.

B4X:
'An ABMList item has been clicked
Sub list1_Clicked(ItemId As String)
Select Case ItemId
Case "H1"
Case "S1"
ABMShared.NavigateToPage(ws, "http://www.google.com")
Case "S2"
Case "S3"
Case "H11"
ABMShared.NavigateToPage(ws, "../frmWelcome/frmWelcome.html")
Case "H2"
Case "H21"
Case "H3"
Case "H4"
End Select
Log(ItemId)
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
MyMaterial.Show: ABMCombo Update

As noted from the previous post about ABMList, the definition of items for the combobox are almost identical with the exception of the Padding property. For now, this works, so we will leave it as is. The only difference between the screens is the InputText. The previous post spoke in dept about ListItems and will not be repeated as it follows the same principle.

You can also fire a navigate to event when an item is clicked. This is just example code..

B4X:
An ABMCombo has been clicked
Sub cboPeople_Clicked(itemId As String)
  Dim cboPeople As ABMCombo = page.Component("cboPeople")
Select Case cboPeople.GetActiveItemId
Case "brother"
ABMShared.NavigateToPage(ws, "../mycheckboxes/mycheckboxes.html")
Case "mom"
Case "dad"
Case "sister"
End Select
End Sub

Figure 1 & 2: ComboItem definitions





And the event code..

B4X:
'An ABMCombo has been clicked
Sub cbo_Clicked(itemId As String)
    Dim cbo As ABMCombo = page.Component("cbo")
Select Case cbo.GetActiveItemId
Case "S1"
Case "S2"
Case "S3"
Case "S4"
End Select
End Sub

'An ABMCombo has been clicked
Sub cboPeople_Clicked(itemId As String)
    Dim cboPeople As ABMCombo = page.Component("cboPeople")
Select Case cboPeople.GetActiveItemId
Case "brother"
ABMShared.NavigateToPage(ws, "../mycheckboxes/mycheckboxes.html")
Case "mom"
Case "dad"
Case "sister"
End Select
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
MyMaterial.Show: ABMBadge

The ABMList component designer now includes a ABMBadge designer. This has been achieved with adding this method on ABMShared.

B4X:
Sub ListItemBadge(page As ABMPage, id As String, text As String, messages As String, isnew As Boolean, Theme As String) As ABMContainer
    Dim ItemCont As ABMContainer
    ItemCont.Initialize(page, id, "")   
    ItemCont.AddRowsM(1,False,0,0, "").AddCellsOSMP(1,0,0,0,10,10,10,6,0,0,0,"").AddCellsOSMP(1,0,0,0,2,2,2,6,0,0,0,"")
    ItemCont.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components
   
    Dim lbl As ABMLabel
    lbl.Initialize(page, id & "lbl", text, ABM.SIZE_PARAGRAPH, False, Theme)
    ItemCont.Cell(1,1).AddComponent(lbl)
   
    Dim badge As ABMBadge
    badge.Initialize(page, id & "badge", messages,  isnew, "")
    ItemCont.Cell(1,2).AddComponent(badge)
   
    Return ItemCont
End Sub

The example of the definition is below...







As noted above, only the ListItemType has been changed and the ABMListItem properties changed to meet badge requirements by changing Text, Message and Is New properties.
 

Harris

Expert
Licensed User
Longtime User
Posted in conversation...

Also, as I have found with this tidbit - it is one of those things that is better learned than taught.

EVERYTHING I know about (practically) anything was self-taught. This way you experience it (retained) rather than be shown it (quickly lost) and can hold on to fundamentals - the important bits...

like common to all - we know

if, then else
select case
do while
for next
etc...

Yet, ABMaterial is a (wee bit) different - but not so far off the B4X track. It has to be for what it is accomplishing! I FREAKIN LOVE IT!
 

Mashiane

Expert
Licensed User
Longtime User

Damn, I FREAKEN LOVE IT TOO!!! Thing is I needed to use it as soon as possible due to client demands on apps and I only thought about it as a way that will quickckly help me. The nice thing you develop once and it works on the different devices, I could explain my way out of it not being native and above all its the thrill that its giving me right now. We share the same traits, I am a BComm graduate who fell into computer programming and everything I know so far has been self taught too. I respect people like that. You have my 10 votes!!!

I just got reminded of my ExtJS days. Then I had not learned their touch framework, but the excitement I got when I first developed and published my first ASP.NET MSSQL app using the ExtJS framework buit into FineUI.

Sadly, not everyone is talking about ABMaterial here, it's like people are reluctant to use it or something or they are just keeping mum. Or perhaps its fear of the unknown. I also had that at first with ABMaterial, but then I decided to dive in. The journey has been interesting. I cant wait for @alwaysbusy designer, that should be interesting and will open doors here. Thanks to him for this amazing wonderful framework. It's time that I send in my 3rd donation anyway in support of this. Yes they are small donations but as a struggling self employed individual, I want to do all I can about this even if its two cents. Thanks for the inbox about the grid to both of you, will print it out and study it. Please bear with me, I ask a lot of questions.
 

Mashiane

Expert
Licensed User
Longtime User
MyMaterial.Show: What's New

Resources Menu

I have added a resources menu. With this, you select the folders that have your Images, PDF and Audio files. These get copied to your project directly and when you compile your MyMaterial ABMaterial app, these are copied to the www\project\images... \pdf ...\audio folder. I intend to have a link to such within MyMaterial so that you dont type your image, audio, pdf paths but just select a file.
 

imbault

Well-Known Member
Licensed User
Longtime User
@Mashiane Thank you for sharing your project
But I've a few problems:

first, which version of ABMaterial do I have to refer (for the www.zip creation), I actually have 1.20 version of ABM, I also tried with public 1.12

Then your app hangs off with the line below when I try to make a new project or opening the MyMaterial.Show.db

java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such table: FontAwesome)

Help would be appreciated

Thanks

Patrick
 

Mashiane

Expert
Licensed User
Longtime User
@imbault Thanks for showing interest in MyMaterial.Show. I am using version 1.20 of the ABMaterial Framework. Thanks for pointing this MyMateria.Show bug out for me. The attached MyMaterial.Show.db database on the first post does have the FontAwesome table, you are right, when creating a new project that table I forgot to port over. I will fix that in the next post (that will be in the first post).
 

Mashiane

Expert
Licensed User
Longtime User
MyMaterial.Show: What's New

Thanks to @imbault , there was a bug with MyMaterial.Show when creating a new project. I had added FontAwersome fonts later in my tool and then missed changing my code for creating new projects to address this. As a consequence, I have added a project.db in the files as a blank project that include all fontawesome fonts (this is not the latest though). So when creating a new project, the blank project is copied and any updates to its structure are done internally as this tool needs to be flexible as possible.
 

imbault

Well-Known Member
Licensed User
Longtime User
you have just to add this table creation in your PrepareDatabase sub, correct?
 

Mashiane

Expert
Licensed User
Longtime User
you have just to add this table creation in your PrepareDatabase sub, correct?
I have not added it there because by default the table is not empty and is supposed to have content. If you have already created a project using "New Project" in MyMaterial.Show, it will not have this table, so please copy the table i.e. FontAwesome from the attached MyMaterial.db or project.db file to your new project file. Things will be fine going forward.

I think for future changes, let me do that so that one can also import new FontAwesome fonts. Thanks
 

Mashiane

Expert
Licensed User
Longtime User
MyMaterial.Show: What's New (Automatic Generation of SideBarItem and SideBarSubItem items)

Some major updates to the ABMPage definition have been made to enable our what's new topic above.

After studying the SideBarItem of the navigation bars i figured that I can have MyMaterial.Show generate the Side Menu automatically based on what is specified in each page. So far so good. So this is what I had to do.

1. Added "Side Menu" on the tree for the global side menu for your app. Here you can add your own SideBarItems for your app. These SideBarItems can also be generated automatically when you select "Side Menu" depending on what you set up for each page.

On the page designer properties, added

1. Side Bar Item - if the page will be a child of an item in the sidemenu, select the parent side menu item here. You need to create your SideBarItems first to reference them here.
2. On Side Menu - check this if you want this page to be referenced in the side menu. i.e. when selecting Side Menu on the tree, a SideBarItem or SideBarSubItem will be created automatically.
3. Show Sub Menu - check this if you want this page to have the global SideBarItems and SideBarSubItems shown on it.
4. TabIndex - the order of the page in the SideMenu
5. Active - sometimes you design a page but you dont want it to be part of the final app. For the pages to be part of the final app, their active property should be checked.
6. Other changes include the renaming of the Components menus to Components 1,2 and 3
7. Also some minor bugs were fixed that were indicated by MyMaterial.Show users.
8. The SideBarItem and SideBarSubItem are currently generated as static components i.e. I'm not using the ConnectPage method yet, maybe in the future, thus your SideBarItems and SideBarSubItems should have the static property turned on.

To add a side menu item, goto Components 3 > ABMSideBarItem, figure 2 should appear. Type in your properties and can also select the page to navigate to.

Figure 1: The updated treeview with Side Menu..



Figure 2: Definition of the ListView side menu


This is a global definition for the ABMSideBarItem. The return value will be ListView. These usually do not have spaces. The Text to be displayed is List View.
We select an icon name. I have not tested the FontAwesome yet with this. Perhaps you can. We leave the URL blank because we will navigate to an existing page, in this case, the mylist page. We give it a tabindex ie it will appear after the 8th item in the sidebar.

Its Active i.e. generate its source code, static, for now check this. We also indicate whether we want a divider infront of the item and or also at the back and select the theme for the divider. Based on the demo, the divider theme has been blank in the examples for the nav bar. Play around.

Now, lets look at how MyMaterial.Show generates SideBarItems and SideBarSubItems automatically. We need to go back to the page definition for that.

For each of the pages that you want to be linked on the side menu, you need to tell MyMaterial.Show that such a page must be linked to the side menu. Let's look at the figure below.

Figure 3



I also got to play with the TabPane for the first time here too.

Figure 4



As explained above, looking at this example, the myswitch page.

1. We want it to be referenced in the side menu, we checked On Side Menu
2. Because we want this reference to be a SideBarSubItem, we selected the parent SideBarItem, in this case InputComponents. Remember, the SideBarItem InputComponents should be created first.
3. We want the Side Menu to be displayed on this page, so we check this too.
4. We specify the TabIndex, which is the display order in the sidemenu, for this example we left this at zero.
5. The page is active, this we check. Now when all is done, the navigationbar code to be generated for this page will be something like this.

Now you do this for all the pages that you want to be referenced by the SideMenu. After completion, select the "Side Menu" on the tree and wala! Magic happens. Your Side Menu is complete.

In the next posts I will talk about individual Side Menus for your pages. This topic is specific to the Global Side Menu. This is like the demo ABMShared ConnectPage example code.

Please however note, whilst MyMaterial.Show is based on the demo source code, the way that I have designed my ABMShared and Theming functionality is different. Let me explain.

  • For MyMaterial.Show, all themes are globally defined in the ABMShared module. I have no intention of creating themes per page just like the ABMaterial demo.
  • The NavigationBar in the demo is called with ConnectPage in each page, calling a method in ABMShared. In MyMaterial.Show, you create a NavBar per page individually and you can create global navbar side bar items as explained in this post. The end result is the same.
 

imbault

Well-Known Member
Licensed User
Longtime User
Good, but where can we DL our myswitch page ?

Thanks
Patrick
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…