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

Mashiane

Expert
Licensed User
Longtime User
Latest [Beta] Developments....

1. Buttons for Components: Save, Delete,Refresh Code, Copy Code moved to the buttom right status bar. The last pdf button is to open the PDF ABMaterial Pocket Reference posted earlier.



2. Almost all code generators are done (these are not linked to any datasources) and those using labels and textboxes for the initial version revamped. Page & NavBar to be visited again.

3. Functionality to compare previous and current ABMaterial Library XML files and draw dashboards. This was discussed above.

4. Methods - added methods for each component, one can select each method and select 'active', this will add that method call on the rendering of the controls source code. One can also add some code 2 execute.



5. Events - added events for each component, one can select each event and select 'active', this will add the event call for that component's rendering. One can also add some code 2 execute on the event.


6. Create tab now shows code to create the component, methods and events that will run using an Accordion.


7. A makeshift class builder for custom html components - work in progress..




8. Updated Themes definitions for Pen & Paper alignment with ABMaterial

9. Pen & Paper title bar shows ABMaterial compilation library compatible, currently 3.75.



10. Removed reduntant code and merged most repetive code with extremely minor changes - followed the Advay project approach of storing component details, e.g. simple methods to rule them all.



11. Added ABMVideo for video components and removed others and also removed the Timeline control
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Latest Developments...

The structure of the designers has been enhanced. The first screen [1] will be the default properties, the second [2] will be the 'Theme' design applicable to that component. I had thought without having to necessary move around Pen & Paper, the theme should be moved to the component so that I know what I'm dealing with in each component.

If the component has rows/cells e.g. page, container and modal sheet, then the row/cell & component definition is also available. This includes a 'Field Selector' should I want to create a CRUD related container, modal sheet / page. I had thought well, I know how the grid works so I know how my designs should be like. So in my ABMComponents tab, let me define all the controls I need placed on the container, including their RC locations, the padding and margins and then let Pen & Paper figure out the grid. In the images attached, the container will have 5 rows defined by 01..05, this was picked up from the row locations when each of the components was added to the container, this also works the same with the Cells. By default, all cells are added using OSMP, but you can change that after all the components have been created. You can chop and change your padding, offset, sizes and margins as you please with that.


 

Attachments

  • 02ABMContainerTheme.png
    15.2 KB · Views: 323

Mashiane

Expert
Licensed User
Longtime User
A Text Builder

I don't see myself remembering how to apply formatting every time i have to apply it to a text for any of the controls. So added is a Text Builder and later a Style builder will be added. This will make it easier for me going forward and still being tested..

So I add each 'element' of the text I want to build applying the respective format to each part. Here the content is two words, one without formatting and the other with including a link... The Preview sections gives the output...

 

Mashiane

Expert
Licensed User
Longtime User
Inside Pen & Paper (let's take a look behind the scenes)

Each ABMComponent is made up of properties, methods, events and perhaps some fields i.e. constants, you find most of these in the ABM.<field>.

Using the XML analysis done, a property bag is created with these properties for each of the components. As an example, selecting the ABMChip from Designers > Components in the tree, the ABMChip_Action event is fired.

B4X:
Sub ABMChip_Action
    ' get the page name
    Dim pgName As String
    pgName = jMash.GetSimple("page")
    ' a page should be selected first before you can add a control
    If jMash.Len(pgName) = 0 Then
        jMash.msgboxError(MainForm,"Page Error", "The page to add the component has not been selected. Please select a page first.")
        Return
    End If
    oldName = ""
    PageName = pgName
    ABMChip_Initialize
    Dim nc As String
    nc = modABMaterial.NextCount(jMash.jSQL,PageName, "id")
    nc = nc + 1
    ComponentID = "chp" & nc
    etvComponent.SetProperty("PageName", PageName)
    etvComponent.SetProperty("ComponentID", ComponentID)
    etvComponent.SetProperty("tabindex", nc)
End Sub

The ABMChip_Initialize methods draws up the property bag using my own custom made property bag. After that method is called, the next component counter for the page is incremented and the pagename, componentid and tabindex updated in the propertybag. The tabindex just stores the order of the components.

B4X:
Sub ABMChip_Initialize
    ' clear the views
    ShowLayout("vPageMaster")
    'load an empty property bag
    splitPage.LoadLayout("vComponent", "ABMChip")
    'determine if this component has a theme, if so add the theme property bag
    ThemeType = ThemeNameFromComponent("ABMChip")
    If ABMComponentHasTheme("ABMChip") = True Then
        splitPage.LoadLayout("vTheme", ThemeType)
        ABMComponentShowTheme(ThemeType)
    End If
    'add the methods property bag
    splitPage.LoadLayout("vComponentMethods", "Methods")
    'add the events property bag
    splitPage.LoadLayout("vComponentEvents", "Events")
    'add the accordion for 'Create', events and methods 
    SourcePreview_Initialize
    'add the additional events a user can type source code for
    splitPage.LoadLayout("vDefaultSC", "Default Events")
    'create the property bag for the methods
    ABMComponentMethods_Initialize("ABMChip")
    ABMComponentEvents_Initialize("ABMChip")
    'store the create tab position in case user refreshes the code
    splitLoc= jMash.TabPageFindPos(splitPage,"Create")
    'create the default property bag
    Dim xl As List
    xl.Initialize
     etvComponent.setloading(True)
    etvComponent.SetParentForm(MainForm,False)
    etvComponent.readonly = jMash.CreateList(",","PageName,ComponentType")
    etvComponent.ImagesFolder = ImagesFolder
    etvComponent.AddTextBoxProperty("Page Name", "", "Page Name", "PageName")
    etvComponent.AddTextBoxProperty("Component Type", "ABMChip", "Component Type", "ComponentType")
    xl = modABMaterial.GetComponentsForPage(PageName,True)
    etvComponent.AddComboBoxProperty("Parent ID", "", "Parent ID", "ActionButton", xl)
    etvComponent.AddComboBoxProperty("Placement", "", "Placement", "Placement", modABMaterial.abmplacement)
    etvComponent.AddTextBoxProperty("Component ID", "", "Component ID", "ComponentID")
    etvComponent.AddTextBoxProperty("Array Name", "", "Array Name", "ArrayName")
    etvComponent.AddTextBoxProperty("Chip ID", "", "Chip ID", "ID")
    etvComponent.AddTextBoxProperty("Text", "", "Text", "Text")
    etvComponent.AddImageFileChooserProperty("Image", "", "Image", "Image")
    etvComponent.AddCheckBoxProperty("Can Be Closed", "0", "Can Be Closed", "CanBeClosed")
    etvComponent.AddTextBoxProperty("Tag", "", "Tag", "Tag")
'    ThemeType = ThemeNameFromComponent("ABMChip")
    etvComponent.AddBiggerTextAreaProperty("intro","","","intro")
    If ThemeType.length > 0 Then
        xl = modABMaterial.GetThemes(ThemeType,True,True)
        If xl.Size >= 2 Then
        etvComponent.AddComboBoxProperty("Theme Name", "", "ThemeName", "ThemeName", xl)
        End If
    End If
    etvComponent.AddComboBoxProperty("Cell Method", "Cell", "Cell Method", "CellMethod", modABMaterial.abmCellMethod)
    etvComponent.AddComboBoxProperty("Visibility", "ABM.VISIBILITY_ALL", "Visibility", "Visibility", modABMaterial.ABMVisibility)
    etvComponent.AddTextBoxProperty("Row ID / #OfRows", "1", "Row ID", "RowID")
    etvComponent.AddTextBoxProperty("Cell ID", "1", "Cell ID", "CellID")
    etvComponent.AddTextBoxProperty("Tab Index", "0", "Tab Index", "TabIndex")
    etvComponent.AddCheckBoxProperty("Active", "1", "Active", "Active")
    etvComponent.addcheckboxproperty("RefreshOnLoad","0","","RefreshOnLoad")
    etvComponent.AddTextBoxProperty("# of Grid Columns", "4", "", "GridColumns")
    etvComponent.addcheckboxproperty("Table Source","0","","TableSource")
    etvComponent.AddComboBoxProperty("TableName", "", "TableName", "TableName", modABMaterial.GetTableNames)
    etvComponent.AddTextAreaProperty("Select Query", "", "Select Query", "SelectQuery")
    etvComponent.AddTextAreaProperty("Arguements (sep by ,)","Null","","Arguements")
    etvComponent.addcheckboxproperty("Arguements from LocalStorage","1","","ArguementsFromLS")
    xl.clear
    etvComponent.AddComboBoxProperty("ID Field", "", "IDField", "IDField", xl)
    etvComponent.AddComboBoxProperty("Text Field", "", "Text Field", "TextField", xl)
    xl = modABMaterial.getallpages(True)
    etvComponent.AddComboBoxProperty("Navigate To", "", "", "NavigateTo", xl)
    etvComponent.SetLoading(False)
End Sub

1. We need the Page to know where to place the component
2. We need the parent id to know where to place the component inside the page (this could be a container / modal sheet)
3. We need the placement to know where to place the component inside the parent (this could be the header, footer etc)
4. The component id is the identifier (unique) for this component for the Initialize methods and also refering to it in the page.

So after the initialize method is executed, we see this on the screen.



Whilst inside Pen&Paper these properties are hard coded, what Advay did was to read each property per component from a database and generate the propertybag. This was due to the dynamic changes in the framework. As Pen&Paper comes a long way, re-writing the code is out of the question. (If it works, why brake it? However I have another plan in terms of maintaining this, though it will mean hard coding (not-enjoyable-at-times)).

So, after defining the properties for the component, the component is saved. A single method for all the controls with a few exceptions has been built, ABMComponent_Save

B4X:
Sub ABMComponent_Save(sComponentType As String)
    Dim props As Map
    Dim propsJSON As String
    Dim title As String
    props.Initialize
    ' get the propertybag
    Needs = ""
    If etvPageNeeds.isinitialized Then Needs = etvPageNeeds.tostring
    props = etvComponent.GetPropertyBag
    PageName = etvComponent.GetProperty("PageName")
    ComponentID = etvComponent.GetProperty("ComponentID")
    TabIndex = etvComponent.GetProperty("TabIndex")
    Active = etvComponent.GetProperty("Active")
    ActionButton = etvComponent.GetProperty("ActionButton")
    RefreshOnLoad = etvComponent.GetProperty("RefreshOnLoad")
    title = etvComponent.GetProperty("title")
    Extras = ""
    Menus = ""
    If letvComponentItems.isinitialized Then Extras = letvComponentItems.tostring
    If letvComponentSubItems.isinitialized Then Menus = letvComponentSubItems.tostring
    Dim IsFieldName As String = etvComponent.GetProperty("IsFieldName")
    If IsFieldName = "1" Then
        props.Put("fieldname", ComponentID)
    End If
    Dim IsComputed As String = props.GetDefault("iscomputed","0")
    If IsComputed = "1" Then
        props.Put("required","0")
        props.Put("donotsave","0")
    End If
    Dim required As String = props.getdefault("required","0")
    If required = "1" Then
        props.Put("enabled","0")
    End If
    'Static = etvComponent.GetProperty("Static")
    propsJSON = jMash.Map2Json(props)
    ComponentKey = PageName & "." & ComponentID
    newName = ComponentKey
    dbAction.Initialize
    dbAction.Put("pagename", PageName)
    dbAction.Put("componentid", ComponentID)
    dbAction.Put("tabindex", TabIndex)
    dbAction.Put("componentkey", ComponentKey)
    dbAction.Put("componentproperties", propsJSON)
    dbAction.Put("componenttype", sComponentType)
    dbAction.Put("active", Active)
    dbAction.Put("needs", Needs)
    'dbAction.Put("static", Static)
    dbAction.Put("ActionButton", ActionButton)
    dbAction.Put("refreshonload", RefreshOnLoad)
    dbAction.Put("extras", Extras)
    dbAction.Put("menus", Menus)
    dbAction.Put("upgrade","1")
    dbAction.put("sourcecode", txtDefaultSC.GetText)
    If txtComputed.IsInitialized Then dbAction.Put("computed", txtComputed.gettext)
    Select Case sComponentType
    Case "ABMNavigationBar"
        DBUtils.RecordUpdateField(jMash.jSQL,"Pages","navbartitle", title, "PageName", PageName)
    End Select
    UpdateTreeWithComponent(dbAction)
End Sub

This gets the Map property bag and after reading some properties that are specific, saves the component to the database project opened. The treeview is updated with the new component and if code preview is turned on, the code for the component displayed. The generated source code is done by a method called ABMChip_Render in this particular case. This is the same method that will run for all chips defined per each of the pages to generate the code for the ABMChip.

B4X:
public Sub ABMChip_Render(pgName As String, comp As Map, bPreview As Boolean, bIsVariables As Boolean) As String
    Dim componentID As String = comp.GetDefault("componentid","")
    If Main.Rendered.IndexOf(pgName & "." & componentID) = -1 Then
        Main.Rendered.Add(pgName & "." & componentID)
    Else
        'already rendered, ignore this time around
        Return ""
    End If
    Dim sb As StringBuilder
    Dim props As Map
    Dim pageName As String
    Dim propsJSON As String
    Dim componentID As String
    Dim ChipImage As String
    Dim ChipText As String
    Dim ChipCanBeClosed As String
    Dim ChipTheme As String
    Dim ChipCellID As String
    Dim ChipRowID As String
    Dim ChipID As String
    Dim ChipArrayName As String
    Dim ActionButton As String
    Dim Tag As String
    Dim Placement As String
    Dim CellMethod As String
    Dim Visibility As String
    Dim RefreshOnLoad As String
    Dim TableSource As String
    sb.Initialize
    propsJSON = comp.Get("componentproperties")
    props = jMash.Json2Map(propsJSON)
    props = jMash.MapRemoveNulls(props)
    componentID = comp.Get("componentid")
    ChipText = props.Getdefault("text","")
    ChipCanBeClosed = props.Getdefault("canbeclosed","0")
    ChipTheme = props.Getdefault("themename","")
    ChipImage = props.Getdefault("image","")
    ChipCellID = props.Getdefault("cellid","1")
    ChipRowID = props.Getdefault("rowid","2")
    ChipID = props.Getdefault("id","")
    ChipArrayName = props.Getdefault("arrayname","")
    ActionButton = comp.Getdefault("actionbutton","")
    Placement = props.Getdefault("placement","")
    CellMethod = props.Getdefault("cellmethod","Cell")
    Visibility = props.Getdefault("visibility","ABM.VISIBILITY_ALL")
    RefreshOnLoad = props.getdefault("refreshonload","0")
    TableSource = props.getdefault("tablesource","0")
    Tag = props.GetDefault("tag","")
 
    If bPreview = False Then
        If (RefreshOnLoad = "1") And (TableSource = "1") Then Return ""
    End If
 
    ' define page to add to
    Select Case pgName
        Case "index"
            pageName = "AppPage"
        Case Else
            pageName = "page"
    End Select
 
    ' build render code
    sb.Append("Dim ").Append(componentID).Append(" As ABMChip").Append(CRLF)
    If bIsVariables = True Then
        sb.Append(ChipText).Append(" = ").Append(ChipText).Append(".Replace(")
        sb.Append(jMash.InQuotes(" ")).Append(", ").Append(jMash.InQuotes("{NBSP}"))
        sb.Append(")").Append(CRLF)
    End If
    sb.Append(componentID).Append(".Initialize")
    sb.Append("(").Append(pageName).Append(", ")
    If ChipArrayName.length > 0 Then
        If bIsVariables = True Then
            sb.Append(ChipID).Append(", ")
        Else
            sb.Append(jMash.InQuotes(ChipID)).Append(", ")
        End If
    Else
        If bIsVariables = True Then
            sb.Append(componentID).Append(", ")
        Else
            sb.Append(jMash.InQuotes(componentID)).Append(", ")
        End If
    End If
    If bIsVariables = True Then
        sb.Append(ChipText).Append(", ")
    Else
        sb.Append(jMash.InQuotes(ChipText)).Append(", ")
    End If
    If ChipCanBeClosed = "1" Then
        sb.Append("True, ")
    Else
        sb.Append("False, ")
    End If
    sb.Append(jMash.InQuotes(ChipTheme)).Append(")").Append(CRLF)
sb.Append(componentID).Append($".Tag = "${componentID}""$).append(CRLF)
    If jMash.Len(ChipImage) > 0 Then
        sb.Append(componentID).Append(".Image = ").Append(jMash.InQuotes(ChipImage)).Append(CRLF)
    End If
If jMash.Len(Visibility) > 0 And Visibility <> "ABM.VISIBILITY_ALL" Then
        sb.Append(componentID).Append(".Visibility = ").Append(jMash.InQuotes(Visibility)).Append(CRLF)
    End If
    If jMash.Len(Tag) > 0 Then
        sb.Append(componentID).Append(".Tag = ")
        If bIsVariables = True Then
            sb.Append(Tag).Append(CRLF)
        Else
            sb.Append(jMash.InQuotes(Tag)).Append(CRLF)
        End If
    End If
    If jMash.Len(ActionButton) > 0 Then
        sb.Append(ActionButton).Append(Placement).Append(".").append(CellMethod).Append("(").Append(ChipRowID)
    Else
        sb.Append(pageName).Append(Placement).Append(".").Append(CellMethod).Append("(").Append(ChipRowID)
    End If
    sb.Append(",").Append(ChipCellID).Append(").")
    If jMash.Len(ChipArrayName) > 0 Then
        sb.Append("AddArrayComponent(").Append(componentID).Append(", ")
        sb.Append(jMash.InQuotes(ChipArrayName)).Append(")").Append(CRLF)
    Else
        sb.Append("AddComponent(").Append(componentID).Append(")").Append(CRLF)
    End If
    Return sb.tostring
End Sub

So for each of the controls that Pen&Paper can now generate in helping build ABMaterial WebApps, that's the maintainance behind the scenes..
 

Mashiane

Expert
Licensed User
Longtime User
Did you know?

Once you have created a page, a component, a theme using Pen&Paper, you can export these as JSON format and another Pen&Paper user can Import them into their project? This means that more than one person can work on the same project and develop different sections of it and then consolidate later.

Each of the items to export should be selected first.

1. For themes - select Themes > Export Theme, to import a JSON theme file, select Import
2. For pages - selected Pages > Export Page, this will export both the page and components into two JSON files, to import select Import page
3. For components - select Components > Export Component, this will export the component, to import select Import Component

You can use a JSON viewer for this self-containing ABMContainer definition. Importing this and clicking 'Create Controls' will create the grid ABMRow(s) for the container and all other components inside the container.

Ta!

PS: There is a Convert.NET app on this page that also does json viewing and other things...
 

Attachments

  • contLogin.txt
    21.5 KB · Views: 350

Mashiane

Expert
Licensed User
Longtime User
Hi y'all

This update addresses everything discussed in this thread between posts #196 - #205.

NB: All projects opened with this version should be Upgraded i.e. File > Upgrade (after you open the project)

For consistency...
  • ABMGridRows has been renamed correctly to ABMRow.
  • NavPills has been renamed to be CTNavPills and
  • JustGage has been renamed to MashJustGage (this is different to the custom JustGage posted here as I added more things to the version posted here)
Doing a project upgrade will also run the renaming of the controls, thus its crucial you upgrade.

Update: Dropbox it here.

PS: This is ABMaterial 3.75 specific, you are welcome to report any breakages, I've tried to test as much as possible.

Now to the next important part, Debugging Pen&Paper and adding Reporting, let me go and learn that first.

Enjoy...

13-11-2017 Fixed a bug with page creation, download link above updated.
 
Last edited:

Molchyn

Member
Licensed User
Longtime User
HI Mashiane,
Just try create new project on the new fresh computer with installed 3.75 ABMaterial
P&P crashed
BR
VK
B4X:
PenNpaper>java -jar pennpaper.jar
Class not found: b4j.Mashy.ETV.editabletv, trying: b4j.Mashy.PenNPaper.editabletv
Class not found: b4j.Mashy.ETV.editabletv, trying: b4j.Mashy.PenNPaper.editabletv
Class not found: b4j.Mashy.ETV.editabletv, trying: b4j.Mashy.PenNPaper.editabletv
Class not found: b4j.ABMaterialShow.editabletv, trying: b4j.Mashy.PenNPaper.editabletv
Class not found: b4j.Mashy.ETV.editabletv, trying: b4j.Mashy.PenNPaper.editabletv
Class not found: b4j.ABMaterialShow.listviewetv, trying: b4j.Mashy.PenNPaper.listviewetv
Class not found: b4j.Mashy.ETV.editabletv, trying: b4j.Mashy.PenNPaper.editabletv
Class not found: b4j.ABMaterialShow.listviewetv, trying: b4j.Mashy.PenNPaper.listviewetv
Class not found: b4j.Mashy.ETV.editabletv, trying: b4j.Mashy.PenNPaper.editabletv
Class not found: b4j.ABMaterialShow.codearea, trying: b4j.Mashy.PenNPaper.codearea
main._project_read (java line: 44904)
java.lang.NullPointerException
        at b4j.Mashy.PenNPaper.main._project_read(main.java:44904)
        at b4j.Mashy.PenNPaper.main._project_open(main.java:44843)
        at b4j.Mashy.PenNPaper.main._getfile(main.java:33552)
        at b4j.Mashy.PenNPaper.main._mnufilenew_action(main.java:42794)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
        at anywheresoftware.b4a.BA$1.run(BA.java:215)
        at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
        at java.lang.Thread.run(Unknown Source)
 

Mashiane

Expert
Licensed User
Longtime User
HI Mashiane,
Just try create new project on the new fresh computer with installed 3.75 ABMaterial
P&P crashed
BR
VK
The only reason I think such would happen is if you did not upgrade your project. Please note that as per post #206, the NB part says that all projects opened with this version should be upgraded. Please try and upgrade your project after you open it, then compile it. If the error happens again, pm me please. Ta!
 

Mashiane

Expert
Licensed User
Longtime User
Hi y'all

I kindly need some volunteers who will help me take this B4J app forward.

1. In most cases new releases of this need to be tested, I need someone(s) who can help me in doing that, I miss some things I have seen.
2. The priority is just running tests and ensuring that stuff works before a release of Pen&Paper
3. This will mean creating basic apps with Pen & Paper and seeing their functionality working, in most cases, just skeletons.
4. If you are willing and will play ball, please pm me and let's talk.

Kind Regards

Mashy
 

Mashiane

Expert
Licensed User
Longtime User
Hi y'all

Pen & Paper 4 is now available, this version supports ABMaterial 4.00. The filename is PenNPaper4.jar. You can Dropbox it here.
This version also uses MashPlugIns Library.

For now, the additional designers are:

  • CTNavPills
  • MashBreadCrumbs
  • MashCameraPlain
  • MashClock
  • MashJustGage
  • MashStats

Enjoy.

PS: The MashPlugIns blog is here. As it takes time to develop these PlugIns, there is a free version of MashPlugs and donator specific library which has additional components for your minimum $1 donation.

Your support is greatly appreciated.
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Pen & Paper 4.03

Dropbox
your free version here. You will also need the MashPlugIns library going forward.

The strides made with B4J and ABMaterial have been immense and I also found out some few bugs with Pen & Paper that I needed to iron out.

As usual, this helps with creating basic ABMaterial WebApps, you will have to do the rest of the customization yourself.

What you can do with ABMaterial?

1. Create a b4j project automatically based on properties you specifiy.
2. Create ABMPages with components depending on what you want to do
3. Create simple CRUD functionality inclusive of the ABMTable.

Here are some startup to tutorials:
1. Create a simple 'Hello World' WebApp
2. Create a simple 'Contacts' form - Part 1

Pen & Paper Forum Search
MashPlugIns Dropbox
 
Last edited:
Cookies are required to use this site. You must accept them to continue using the site. Learn more…