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

Pen&Paper Explained.png



The intension of Pen & Paper is the creation of ABMaterial WebApps as depicted in the drawing above. This was developed as a pet project out of a personal need to create ABMaterial WebApps. So far everything has gone well with the outputs.

1. The ABMaterial Library comes out with an XML file that has vast information about the components (depicted as classed) including their properties (attributes), events and methods. Any Library viewer is able to access these too.
2. These classes are represented as property bags in Pen & Paper so that I can create any component by just changing the various attributes, whether true/false, specifying text etc. The way the components are built, initialized and added to pages/containers/modal sheets has been explained in detail in the ABMaterial Demo, where all of this started.
3&4. On creating an ABM project with Pen & Paper, two databases are created, one to store the project definition (pages and component structures i.e. propertybags) and the other a production one that the data will be stored in. These are both in SQLite. Pen & Paper has functionality to perform a DAO (Data Access Object) link for each backend table and fields you want to link a component to. This is essence creates a CRUD code base. This was inspired by the ABMCRUD generator that produces a structure of ones ABMTable and ABMModal sheet with the specific input components.
5. On Project Build, Pen & Paper produces a complete B4J application including the source code that can be compiled to generate a working version of an ABM Web Application.
6. Pen & Paper does not come bundled with ABMaterial, is not affiliated with ABMaterial and to compile any Pen & Paper project to a fully fledged working ABM Webapp, you need the ABM Libraries. It is just a helper tool to elimitate the repetitive nature of creating projects, pages, containers, modalsheets, etc, in a programming without coding technology fashion. It does NOT in anyway replace ABM or intends to replicate its functionality as it just generates B4J code for your ABM application, this being achieved by use of property bags to create your components and generate the respective source code based on your options, eliminating the need to type code and what anyone gets out is the basic stuff to make ones project work. Not everything ABM is here anyway.

As everything that has a beginning has an end. This personal enjoyment project will stop being maintained as other things will evolve. As on 31 March 2018, there is no intention to advance this any further than what it is. Thanks for B4J this project was possible.

Steps in using Pen & Paper
  • Get everything related to Pen&Paper from this DropBox Link. Get executable from jar folder.
  • See videos below on usage and related articles
  • Please note that not all ABM components are covered with Pen&Paper as yet.

2018 Tutorials

Creating a Sign In Modal Dialog with Options

Interesting Tutorials
2017-12-20

Creating a simple 'Contacts' ABMaterial WebApp - Part 1
Creating a simple 'Contacts' ABMaterial WebApp - Part 2
Creating a simple 'Contacts' ABMaterial WebApp - Part 3

Below are some of the articles touching on code generated by Pen&Paper.

ABMaterial WebApps created with Pen&Paper

Bible.Show

CodeProject Article

Creating the Bible.Show WebApp with ABMaterial

Some YouTube Links


Pen&Paper is built using B4J and distributed with jMashProjectProfile.

NB: You will need the ABMaterial Framework to compile the generated source code.
 

Attachments

  • abmaterial.gif
    abmaterial.gif
    53.1 KB · Views: 13,343
  • MyMaterialLibraries.png
    MyMaterialLibraries.png
    16.4 KB · Views: 1,070
Last edited:

Mashiane

Expert
Licensed User
Longtime User
I recently took on an article about the ABMaterial Themes quick reference, available https://www.b4x.com/android/forum/threads/abmaterial-themes-quick-reference.72423/#content

With MyMaterial.Show, creating themes for your controls is easy as you just select the theme and provide its properties and only the properties that have been changed are generated. Each theme has default properties and changing any of these properties makes the default and the changed properties to be applied to the component. As an example, what I have learned so far can be depicted below. These are accessed by selecting Designers > Themes.

ButtonTheme.bluegrey.png
 
Last edited:

BigBoss123

Member
Licensed User
Longtime User
Hi Mashiane
what you are doing here looks fantastic.

I have downloaded both the Zip file on page 1 and the Dropbox zip file.
So what should I be doing..... follow the guideline on page 1 or use the Dropbox jar file and is this only for ABMaterial 1.22?

Thanks every so much for your help

David
 

Mashiane

Expert
Licensed User
Longtime User
Hi Mashiane
what you are doing here looks fantastic.

I have downloaded both the Zip file on page 1 and the Dropbox zip file.
So what should I be doing..... follow the guideline on page 1 or use the Dropbox jar file and is this only for ABMaterial 1.22?

Thanks every so much for your help

David
Hi David, thanks for the interest shown. MyMaterial now comes up as a precompiled jar file. You can run it and on File > Open project, select the mymaterial.db file and play around. MyMaterial is just a code generator and nothing else to enable one to build ABMaterial UIs, so you will still need to code your app.

I'm planning however to add a section on how to create an app using MyMaterial.Show though soon. Follow the posts, a lot has changed though...
 

Mashiane

Expert
Licensed User
Longtime User
What's New - 17 December 2016

For MyMaterial.Show users, please note that due to the latest developments in the ABMaterial Framework, I also wanted to experience those enhancements in my projects. Well, I have not finished my a project(s) yet however I am getting there, I pause to catch up with the ABMaterial Framework. It's growing to be a very wonderful beast and one has to keep up.

The next version of MyMaterial.Show will be based on ABMaterial 2.17 libraries as the code generated will be compatible to that version going forward. There were just so many useful enhancements to the ABMaterial framework that updating MyMaterial.Show was necessary. It's just so nice presenting a concept with the latest speed enhancements, wonderful. Thanks a million, @alwaysbusy

Remember, you don't have to use MyMaterial.Show. I am also patiently awaiting for the upcoming ABMAD, hopefully soon.

Anyway, I have just finished updating the TopItem, TopSubItems for the Navigation bars. I'm excited with the color schemes for the items. I needed that! I'm currently exploring the BarSideComponent as I need that for my project(s). I need to create a SQLite based ABMaterial WebApp for a presentation that I need to do, so far that is coming alright. Will add database documentation code soon.

My other post about ABMThemes quick reference has helped me a great deal and thus as a matter of flexibility, the theme definitions are no longer hard coded within MyMaterial.Show but maintained within a project. One just needs to upgrade their project and the theme definitions will be created inside your project.
 

Attachments

  • ABMTopSubItem.png
    ABMTopSubItem.png
    12.8 KB · Views: 270
  • welcome.topSubItem10.png
    welcome.topSubItem10.png
    27.6 KB · Views: 288
  • welcome.topItem6.png
    welcome.topItem6.png
    27.2 KB · Views: 292
  • topItemWithSubItems.png
    topItemWithSubItems.png
    6.3 KB · Views: 281

Mashiane

Expert
Licensed User
Longtime User
On exploring the navigation bar, the BuildSideBarTopComponent in ABMShared was also checked. As you might be aware this is to add a component at the top of the sidebar.

The code below is taken from BuildNavBar code, however as I would like my NavBars to be different at times, each page will have this code..

B4X:
Dim sbtopimg As ABMContainer = ABMShared.BuildSideBarTopComponent(page, "sbtopimg", "../images/components.png", "Anele 'Mashy' Mbanga", "ABMaterial Explorer")
page.NavigationBar.Initialize(page, "navBar", ABM.SIDEBAR_MANUAL_HIDEMEDIUMSMALL, "Wamkelekile", True, True, 330, 48, sbtopimg, ABM.COLLAPSE_ACCORDION, "")
page.NavigationBar.SideBarLogoHeight = 49

Looking at the screen definition, one needs to select the logo, indicate the title and sub title and side bar logo height.

ABMNavigationBar.png


NavBarThings.png


Also the definition for the SideBarSubItem has been revamped and with it you can also specify front and behind dividers.

joomla.png
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Each page in ABMaterial can have a gobal based SideBar or can even have individual SideBar menu. Some posts before I spoke about MyMaterial "Side Menu", indicating that with just turning on some page properties, a Side Menu item can be easily created that will be global to the app.

I have just added on the side bar the possibility with ABMShared.BuildSideBarComponent to add a container with an image, a title and sub title as per the DEMO.

To complete this task, when defining one's page, on the NavigationBar tab.

1. Check "On Global SideBar Menu" - this tells MyMaterial.Show that a link for this page you are creating should be added to the SideBar that will be used by the entire app.
2. You can also specify the SideBarItem icon for the page with "Global Side Menu Icon" also here.
3. If the link to the page should appear as a SideBarSubItem, select the "Global Side Bar Item" from the list provided.
4. If you want your page to show the global side bar, check "Show Global Side Bar Menu" and MyMaterial.Show will add the global side menu to this page.

I wanted my side bar items to be based on the image>title>subtitle approach based on BuildSideBarComponent, so I updated MyMaterial to be able to cater for this. I however will be working on dynamic creation of these items based on database records.

By specifying the 4 properties i.e. Build Side Bar Component (on), Component Image, Component Title, Component Sub Title, it was easy to make this possible, with resulting code..

B4X:
page.NavigationBar.AddSideBarComponent("pagebibleinpictures", ABMShared.BuildSideBarComponent(page, "bibleinpictures", "../images/picture.png", "Bible in Pictures", "See the bible in pictures"),"../bibleinpictures/bibleinpictures.html")

bibleinpictures.png


As I have opted this to be part of the global side menu, the "Side Menu" items will be updated for the project, creating a new component as depicted below.

Side Menu.bibleinpictures.png


The Side Menu, will be automatically updated each time you confirm the prompt after selecting "Side Menu" item in the treeview. Existing page links will not be updated and if one needs to change page linked side menu items, one can update that from the Page Designer.

After much ado, I was able to finish my current side bar items based on components to be like this..

sidemenu.png
 

Mashiane

Expert
Licensed User
Longtime User
You have finished creating your app and realise that you need to change all the navigation bars for the app into one particular one.

The Project definition now includes a global ABMNavigation bar that you can change and apply it accross all pages of your app without having to update the navigation bar individually for thise given properties. After saving the project, you are prompted if you want to apply this global setting to the navigation bar. Selecting yes applies the properties based here for all navigation bars.

globalnav.png
 

Mashiane

Expert
Licensed User
Longtime User
What's New: SQLite Database Documentor

Thanks to code found within the forum, MyMaterial.Show is now able to document the SQLite database for using when designing your apps with MyMaterial.Show. This means now we have two database backends that we can link, MySQL and SQLite.

1. As usual, from the Project Definition, select SQLite as the database.
2. Select Server Database prompt to select the SQLite database file to use in your app.
3. In the menu, select Database > Test Connection, when prompted with about Documenting the database, selected Yes.
4. Wait for the database to be documented.

On project compilation, your database will be copied to the File.DirApp of your application.

Watch this space (doing some more tests)
 

Mashiane

Expert
Licensed User
Longtime User
With just a couple of settings, you can now have your ABMImageSlider loaded during runtime from a database table with external images sitting on a folder on your server.

B4X:
'Refresh the contents of the ABMImageSlider during runtime.
Private Sub RefreshOnLoad_imgsld49()
    'Get access to the component in the page.
    Dim imgsld49 As ABMImageSlider = page.Component("imgsld49")
    'Define list details to load to the imageslider
    Dim results As List
    Dim resCnt As Int
    Dim resTot As Int
    Dim resMap As Map
    'The parent folder for the images
    Dim folderPath As String = "../images/"
    'The default extension for each image file
    Dim extension As String = ".jpg"
    Dim imgFile As StringBuilder
    Dim img As String
    'variable to hold the image field
    Dim imgField As String = ""
    'variable to hold the TitleField
    Dim titleField As String = ""
    'variable to hold the SubTitleField
    Dim subTitleField As String = ""
    'Add a spinner to the page
    page.Pause
    'Get connection from current pool if MySQL/MSSQL or SQLite
    Dim jSQL As SQL = ABMShared.SQLGet
    'Get the records as a list of maps from the db
    results = ABMShared.SQLExecuteMaps(jSQL,"select * from pictures order by key", Null)
    'Close the connection to the database
    ABMShared.SQLClose(jSQL)
    'Loop throught each record read and process it
    resTot = results.size - 1
    For resCnt = 0 To resTot
        'Get the record map
        resMap = results.get(resCnt)
        imgField = resMap.getdefault("tag","")
        titleField = resMap.getdefault("text","")
        'Build the image path
        imgFile.Initialize
        imgFile.Append(folderPath)
        imgFile.Append(imgField)
        img = imgFile.ToString
        img = ABMShared.FixImage(img,extension)
        imgsld49.AddSlideImage(img,titleField,subTitleField,ABM.IMAGESLIDER_RIGHT)
    Next
    page.Resume
End Sub

The code above runs a query to select records from a table. These are then loaded from the ../images/ folder of the server and added to an ABMImageSlider. The database that has been used for this example is SQLite.

ABMImageSlider.png


When defining the SliderImage properties, I indicated that the source is a table called Pictures. Each image will have a .jpg extension. We indicate the image field name, the title field and sub title fields if any and the slide type. When running, this will produce an ImageSlider like below.

ImageSlider.png


Im just trying to figure out how to fit the images to the ImageSlider and perhaps hide the indicators.
 

Mashiane

Expert
Licensed User
Longtime User
I also tried the same with the ABMFlexWall, for it to be loaded from images that are referenced from a database table.

B4X:
Private Sub RefreshOnLoad_flex51()
    'Get access to the component in the page.
    'Get the flexwall component to process
    Dim flex51 As ABMFlexWall
    flex51 = page.Component("flex51")
    'Define list details to load to the flexwall
    Dim results As List
    Dim resCnt As Int
    Dim resTot As Int
    Dim resMap As Map
    Dim photoCnt As Int = 0
    Dim photoID As String
    'The parent folder for the images
    Dim folderPath As String = "images"
    'The default extension for each image file
    Dim extension As String = ".jpg"
    Dim simg As String
    Dim strPhoto As String
    'variable to hold the image field
    Dim imgField As String = ""
    'variable to hold the TitleField
    Dim titleField As String = ""
    Dim fStructure As String = "www" & "/" & ABMShared.AppName & "/"
    If folderPath.Length > 0 Then
        fStructure = fStructure & folderPath & "/"
    End If
    'we want a format that will meet ../images
    Dim pStructure As String = fStructure
    pStructure = pStructure.Replace("www/" & ABMShared.AppName, "..")
    fStructure = File.Combine(File.DirApp, fStructure)
    Dim imgSize As String
    'The image width and size if images are sized to be the same size
    Dim imgWidth As String = "350"
    Dim imgHeight As String = "350"
    'Add a spinner to the page
    page.Pause
    'Get connection from current pool if MySQL/MSSQL or SQLite
    Dim jSQL As SQL = ABMShared.SQLGet
    'Get the records as a list of maps from the db
    results = ABMShared.SQLExecuteMaps(jSQL,"select * from pictures order by key", Null)
    'Close the connection to the database
    ABMShared.SQLClose(jSQL)
    'Loop throught each record read and process it
    resTot = results.size - 1
    For resCnt = 0 To resTot
        'Get the record map
        resMap = results.get(resCnt)
        imgField = resMap.getdefault("tag","")
        titleField = resMap.getdefault("text","")
        'Build the image path
        simg = ABMShared.FixImage(imgField,extension)
        'We will get image sizes from the images themselves, hold the photo actual path
        photoCnt = photoCnt + 1
        photoID = "photo" & photoCnt
        strPhoto = pStructure & simg
        'Get the image dimensions
        imgSize = ABM.Util.GetImageDimensions(fStructure,simg)
        If imgSize <> "" Then
            imgWidth = ABMShared.MvField(imgSize,1,"x")
            imgHeight = ABMShared.MvField(imgSize,2,"x")
        End If
        'Add ABMImage component in the FlexWall
        Dim img As ABMImage
        img.Initialize(page, photoID, strPhoto, 1)
        img.IsResponsive = True
        img.Caption = titleField
        img.IsCircular = False
        img.IsClickable = False
        img.IsMaterialBoxed = True
        flex51.AddArrayImage(img,imgWidth,imgHeight,"flex51Images")
    Next
    page.Resume
End Sub

This code is also based from options chosen when designing the ABMFlexWall.

bibleinpictures.flex51.png


These are:
1. Source from Table
2. Folder Path
3. Table Name
4. Select Query
5. Image Field and
6. Title Field

FlexWall.png
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
The database being read for the above examples is SQLite.

1. First establish the link to the SQLite database from the project definition. This database will be copied to File.DirApp of your project on compilation.

ProjectDatabase.png


2. Goto Database > Test Connection > Do you want to document the database now? Choose Yes.
3. The database structure is updated inside MyMaterial.Show. Here is the treeview of this example..

SQLiteLink.png


4. In AppStart, establish the connection to the SQLite database.

B4X:
 ABMShared.InitializeSQLite(File.DirApp, "bibleshow.db", True)

The ABMShared method is

B4X:
Public Sub InitializeSQLite(Dir As String, fileName As String, createIfNeeded As Boolean) 'ignore
    SQLite.InitializeSQLite(Dir, fileName, createIfNeeded)
    DatabaseType = 0
End Sub

From the above FlexWall and ImageSlider, we were able to select the table and the respective fields from these links and process records.

I have not tested this in a live environment yet though. You will also have to reference..

B4X:
#AdditionalJar: sqlite-jdbc-3.7.2
 

Mashiane

Expert
Licensed User
Longtime User
Thanks for @Harris example here, I was able to create a chip grid just the way I wanted.

I defined my grid with...

B4X:
' create the page grid
    page.AddRows(2, True, "").AddCells12(1, "")
    page.AddRows(10, True, "").AddCellsOS(4, 0, 0, 0, 3, 3, 3, "")
    page.AddRows(1, True, "").AddCells12(1, "")
    page.AddRows(10, True, "").AddCellsOS(4, 0, 0, 0, 3, 3, 3, "")

  • We will have 2 rows with 1 cell spanning 12 columns
  • Then 10 rows with 4 columns each spanning 3 columns
  • Another row with 1 cell spanning 12 columns and
  • Another set of 10 rows each with 4 cells each spanning 3 columns

Then, the chips are loaded from the SQLite database table..

B4X:
Private Sub RefreshOnLoad_chpOldTestament()
    'Define list details to load to the chips
    Dim results As List
    Dim resCnt As Int
    Dim resTot As Int
    Dim resMap As Map
    Dim irow As Int = 3
    Dim icell As Int = 1
    'variable to hold the idfield
    Dim idField As String = "BookID"
    'variable to hold the textfield
    Dim textField As String = "BookName"
    'Add a spinner to the page
    page.Pause
    'Get connection from current pool if MySQL/MSSQL or SQLite
    Dim jSQL As SQL = ABMShared.SQLGet
    'Get the records as a list of maps from the db
    results = ABMShared.SQLExecuteMaps(jSQL,"select * from books where BookID <= 39 order by BookID", Null)
    'Close the connection to the database
    ABMShared.SQLClose(jSQL)
    'Loop throught each record read and process it
    resTot = results.size - 1
    For resCnt = 0 To resTot
        'Get the record map
        resMap = results.get(resCnt)
        idField = resMap.getdefault("bookid","")
        textField = resMap.getdefault("bookname","")
        Dim chpOldTestament As ABMChip
        textField = textField.Replace(" ", "{NBSP}")
        chpOldTestament.Initialize(page, idField, textField, False, "bloodred")
        chpOldTestament.Image = "../images/openbook80.png"
        chpOldTestament.Tag = idField
        page.Cell(irow,icell).AddArrayComponent(chpOldTestament, "chpOldTestament")
        icell = icell + 1
        If icell = 5 Then
            irow = irow + 1
            icell = 1
        End If
    Next
    page.Resume
End Sub

This method called directly from ConnectPage. This results in...

ot.png


This is based on this chip definition for the page. Only 1 chip component is defined with the designer.

chip1.png


chip2.png
 

Mashiane

Expert
Licensed User
Longtime User
When a chip is clicked, the details of it based on the BookID and BookName as saved to localstorage.

B4X:
Public Sub chpOldTestament_Clicked(Target As String)
    Dim chip As ABMChip = page.Component(Target)
    'Read the chip tag property
    Dim Tag As String = chip.Tag
    'Convert the tag to a map
    Dim chipMap As Map = ABMShared.Json2Map(Tag)
    'Read the id and text fields
    Dim idField As String = chipMap.GetDefault("bookid", "")
    Dim textField As String = chipMap.GetDefault("bookname", "")
    'Save to LocalStorage
    ABMShared.LocalStorageSave(page, "BookID", idField)
    ABMShared.LocalStorageSave(page, "BookName", textField)
    ABMShared.NavigateToPage(ws, ABMPageId, "../chapters/chapters.html")
End Sub

These are also the helper functions in ABMShared for this

B4X:
' convert a json string to a map
Public Sub Json2Map(jsonText As String) As Map
    Dim json As JSONParser
    Dim Map1 As Map
    Map1.Initialize
    If Len(jsonText) > 0 Then
        json.Initialize(jsonText)
        Map1 = json.NextObject
    End If
    Return Map1
End Sub
'convert a map to a json string
Public Sub Map2Json(m As Map) As String
    Dim gen As JSONGenerator
    Dim outJSON As String
    gen.Initialize(m)
    outJSON = gen.ToString
    Return outJSON
End Sub

And the RefreshOnLoad methods were updated to save each record map.

B4X:
'Create new ABMChips during runtime.
Private Sub RefreshOnLoad_chpOldTestament()
    'Define list details to load to the chips
    Dim results As List
    Dim resCnt As Int
    Dim lsKey As String
    Dim resTot As Int
    Dim resMap As Map
    Dim resJSON As String
    Dim irow As Int = 3
    Dim icell As Int = 1
    'variable to hold the idfield
    Dim idField As String
    'variable to hold the textfield
    Dim textField As String
    'Read arguments from LocalStorage (if any)
    'Add a spinner to the page
    page.Pause
    'Get connection from current pool if MySQL/MSSQL or SQLite
    Dim jSQL As SQL = ABMShared.SQLGet
    'Get the records as a list of maps from the db
    results = ABMShared.SQLExecuteMaps(jSQL,"select * from books where BookID <= 39 order by BookID", Null)
    'Close the connection to the database
    ABMShared.SQLClose(jSQL)
    'Loop throught each record read and process it
    resTot = results.size - 1
    For resCnt = 0 To resTot
        'Get the record map
        resMap = results.get(resCnt)
        'convert map to json
        resJSON = ABMShared.Map2Json(resMap)
        idField = resMap.getdefault("bookid","")
        textField = resMap.getdefault("bookname","")
        'Save record to LocalStorage
        lsKey = "Books" & idField
        ABMShared.LocalStorageSave(page, lsKey, textField)
        Dim chpOldTestament As ABMChip
        textField = textField.Replace(" ", "{NBSP}")
        chpOldTestament.Initialize(page, idField, textField, False, "bloodred")
        chpOldTestament.Image = "../images/openbook80.png"
        chpOldTestament.Tag = resJSON
        page.Cell(irow,icell).AddArrayComponent(chpOldTestament, "chpOldTestament")
        icell = icell + 1
        If icell = 5 Then
            irow = irow + 1
            icell = 1
        End If
    Next
    page.Resume
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
As the previous example talks about the Books, a way to get the Chapters belonging to each book was required.

1. We need a way to read the BookID and Book name and display the BookName in the Navigation Bar Title.
2. We need a way to create Chips for each chapter that exists for the selected Book.

The maximum number of the most chapters in the Bible is 150, so I created a grid with 6 cells spanning over 2 columns each.

B4X:
' create the page grid
    page.AddRows(1, True, "").AddCells12(1, "")
    page.AddRows(25, True, "").AddCellsOS(6, 0, 0, 0, 2, 2, 2, "")
    page.BuildGrid 'IMPORTANT once you loaded the complete grid AND before you start adding components

Then on ConnectPage, I read the BookName from LocalStorage and then update the page title.. I used a stringbuilder as there might be more LS items to concat to make a header. This is obvious in the Verses page

B4X:
Dim sbTitle As StringBuilder
    sbTitle.Initialize
    Dim BookName As String
    BookName = ABMShared.LocalStorageRead(page, "BookName")
    sbTitle.Append(BookName)
    sbTitle.Append(" ")
    page.NavigationBar.Title = sbTitle.ToString.Trim
    'add components for the page
    RefreshOnLoad_chapters

When each chapter chip is selected, save the Book and Chapter to local storage as this will be used in the verses page to display the scriptures.

B4X:
Public Sub chapters_Clicked(Target As String)
    Dim chip As ABMChip = page.Component(Target)
    'Read the chip tag property
    Dim Tag As String = chip.Tag
    'Convert the tag to a map
    Dim chipMap As Map = ABMShared.Json2Map(Tag)
    'Read the id and text fields
    Dim idField As String = chipMap.GetDefault("chapter", "")
    Dim textField As String = chipMap.GetDefault("chapter", "")
    'Save to LocalStorage
    ABMShared.LocalStorageSave(page, "Chapter", idField)
    ABMShared.LocalStorageSave(page, "Chapter", textField)
    ABMShared.NavigateToPage(ws, ABMPageId, "../verses/verses.html")
End Sub

And the refresh code...

B4X:
Private Sub RefreshOnLoad_chapters()
    'Define list details to load to the chips
    Dim results As List
    Dim resCnt As Int
    Dim lsKey As String
    Dim resTot As Int
    Dim resMap As Map
    Dim resJSON As String
    Dim irow As Int = 2
    Dim icell As Int = 1
    'variable to hold the idfield
    Dim idField As String
    'variable to hold the textfield
    Dim textField As String
    'Read arguments from LocalStorage (if any)
    Dim BookID As String = ABMShared.LocalStorageRead(page, "BookID")
    'Add a spinner to the page
    page.Pause
    'Get connection from current pool if MySQL/MSSQL or SQLite
    Dim jSQL As SQL = ABMShared.SQLGet
    'Get the records as a list of maps from the db
    results = ABMShared.SQLExecuteMaps(jSQL,"select * from chapters where Book = ? order by Chapter", Array As String(BookID))
    'Close the connection to the database
    ABMShared.SQLClose(jSQL)
    'Loop throught each record read and process it
    resTot = results.size - 1
    For resCnt = 0 To resTot
        'Get the record map
        resMap = results.get(resCnt)
        'convert map to json
        resJSON = ABMShared.Map2Json(resMap)
        idField = resMap.getdefault("chapter","")
        textField = resMap.getdefault("chapter","")
        'Save record to LocalStorage
        lsKey = "Chapters" & idField
        ABMShared.LocalStorageSave(page, lsKey, textField)
        Dim chapters As ABMChip
        textField = textField.Replace(" ", "{NBSP}")
        chapters.Initialize(page, idField, textField, False, "bloodred")
        chapters.Image = "../images/openbook80.png"
        chapters.Tag = resJSON
        page.Cell(irow,icell).AddArrayComponent(chapters, "chapters")
        icell = icell + 1
        If icell = 7 Then
            irow = irow + 1
            icell = 1
        End If
    Next
    page.Resume
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
Demonstration: How to update ABMLabel content from SQLite records

For the verses screen, On ConnectPage, I add a label, read the BookName, Chapter from the saved LS records and update the havigator title.

B4X:
Dim sbTitle As StringBuilder
    sbTitle.Initialize
    Dim BookName As String
    BookName = ABMShared.LocalStorageRead(page, "BookName")
    sbTitle.Append(BookName)
    sbTitle.Append(" ")
    Dim Chapter As String
    Chapter = ABMShared.LocalStorageRead(page, "Chapter")
    sbTitle.Append(Chapter)
    sbTitle.Append(" ")
    page.NavigationBar.Title = sbTitle.ToString.Trim
    'add components for the page
    Dim lblverse As ABMLabel
    lblverse.Initialize(page, "lblverse", "", ABM.SIZE_PARAGRAPH, False, "")
    lblverse.IconAlign = ABM.ICONALIGN_LEFT
    lblverse.IconSize = ABM.ICONSIZE_SMALL
    page.Cell(2,1).AddComponent(lblverse)
    RefreshOnLoad_lblverse

My label refresh method is...

B4X:
Private Sub RefreshOnLoad_lblverse()
    'Define list details to load to the content
    Dim results As List
    Dim resCnt As Int
    Dim lsKey As String
    Dim resTot As Int
    Dim resMap As Map
    Dim sbLine As StringBuilder
    Dim strValue As String
    'Read arguments from LocalStorage (if any)
    Dim BookID As String = ABMShared.LocalStorageRead(page, "BookID")
    Dim Chapter As String = ABMShared.LocalStorageRead(page, "Chapter")
    'Add a spinner to the page
    page.Pause
    'Get connection from current pool if MySQL/MSSQL or SQLite
    Dim jSQL As SQL = ABMShared.SQLGet
    'Get the records as a list of maps from the db
    results = ABMShared.SQLExecuteMaps(jSQL,"select verse, scripture from Bible where Book = ? and Chapter = ? order by verse", Array As String(BookID,Chapter))
    'Close the connection to the database
    ABMShared.SQLClose(jSQL)
    'Initialize the content holder
    sbLine.Initialize
    'Loop throught each record read and process it
    resTot = results.size - 1
    For resCnt = 0 To resTot
        'Get the record map
        resMap = results.get(resCnt)
        'Build each line
        Dim eachLine As StringBuilder
        eachLine.Initialize
        For Each strField As String In resMap.Keys
            strValue = resMap.getdefault(strField, "")
            eachLine.Append(strValue)
            eachLine.Append(" ")
        Next
        Dim strOutPut As String = eachLine.ToString.Trim
        'RunMethods referenced pasted in MyMethods of the page for eachLine
        strOutPut = ColorScripture(strOutPut)
        strOutPut = ColorScripture1(strOutPut)
        strOutPut = ItalicScripture(strOutPut)
        strOutPut = BoldScripture(strOutPut)
        strOutPut = ItalicScripture1(strOutPut)
        sbLine.Append(strOutPut)
        sbLine.Append("{BR}")
    Next
    'Get the label and update it
    Dim lblverse As ABMLabel = page.Component("lblverse")
    lblverse.Text = sbLine.ToString.Trim
    lblverse.Refresh
    page.Resume
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
Good day, wishing you all the best for 2017 and beyond...

Download Latest Update

Some minor and few adjustments to MyMaterial.Show.

Supports ABMaterial 2.20

2017-01-23

1. Fixed: TabIndex - this is used to order the placement of your controls in your pages. This has been fixed to be aligned with the position of the page.

2. Components: The tabindex, componentid is now based on the page that it is being added to and not a global counter like before.

3. Generate a ReadMe and RunMe.bat files after compilation to run the app. This opens up your default internet browser and the RunMe.bat waits for you to press enter to run the jar file.

4. You can create a SQLite database from within the file and manage partially the structure of the database e.g. create tables, fields and delete fields and tables. This you can later link to your pages. You can also view the records in a table from the app itself too. This will be helpful for query generation.

5. Added Templates: Welcome Page, Login, Sign In, Sign Up page. You need to link these to your database only now. I had thought I will do this a lot.

6. Color coded the buttons for the template pages.

7. Fixed some minor bugs for stability.

8. Remember to "Upgrade" your project once again.

ReadMe.txt example

Double click RunMe.bat, inside there press enter and wait until ready
Back in your Internet Browser, press F5 to refresh (due to the heartbeat of version 2.20, pressing F5 might not be necessary)

RunMe.bat example

pause
start "" http://localhost:51045/drpw
java -jar drpw.jar

This is something wonderful I have done with MyMaterial.Show, not a single code write, everything automated directly inside MyMaterial.Show. I discussed it here in terms of how it was done.

Ta!
 

clarionero

Active Member
Licensed User
Longtime User
Wooww, What a lot of work done!!! Great index of values and tools for ABMaterial :)

I have a issue with Database tree tables display. MyMaterial show the tables and fields of the datatable. If i click a field then it show me the field definition. If i click a Table node then MyMaterial dies with a Java exception.

dbutils._executememorytable (java line: 869)
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PRAGMA table_info ('bloqueo_legal')' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1962)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:353)
at anywheresoftware.b4j.objects.SQL.ExecQuery2(SQL.java:290)
at b4j.ABMaterialShow.dbutils._executememorytable(dbutils.java:869)
at b4j.ABMaterialShow.jmash._loadtable2view(jmash.java:2747)
at b4j.ABMaterialShow.main._t

Thank you for your great work.


Rubén
 
Top