B4J Question [ABMaterial] How to get a scrollable textbox?

MbedAndroid

Active Member
Licensed User
Longtime User
Looking in the possibilities of ABMaterial i couldnt find a scrollable label or whatever of textbox

ABMaterial has the possibility to save the logfile.
In a special page "Logs" i like to read those logs, but as these will be long to very long a small textbox with scroll is needed.

May be i missed it, but is this textbox with scroll not included in ABM?
 

alwaysbusy

Expert
Licensed User
Longtime User
ABMaterial follows the Google Guidelines as close as possible, and (as it is 'mobile first') a textbox does not have scrollbars. It has many disadvantages (difficult for touch screen for example, it is not printable, etc). For your purpose it could even be bad as it is also one of the 'slow' html components.

But you can easily create a custom component like this. Note this is written for demonstration and would need some tuning (e.g. I use the .template css class to get the component, so you can only use one such a component per page).

Terminal.png


B4X:
' Class module
Sub Class_Globals
   'Dim ABM As ABMaterial
   Dim ABMComp As ABMCustomComponent   
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(InternalPage As ABMPage, ID As String)   
   Dim CSS As String = $".terminal {
     border: 1px solid grey;
     height: 400px;
     overflow: auto;
     margin: 0;
       padding: 5px;
       list-style: none;
       background: #141414;
       color: #45D40C;
       font: 0.8em 'Andale Mono', Consolas, 'Courier New';
       line-height: 1.6em;
   }"$
   
   ABMComp.Initialize("ABMComp", Me, InternalPage, ID, CSS)
   ' the automatic events will be raised on the page e.g. if the id = "mycomp" then the event will be mycomp_Click(params as Map)
   ' future: we'll see if some other mechanisme is needed for non automatic events
   
End Sub

' runs when an object is created for the first time. Expects a valid html string
' will get surrounded by a div automatically
' in the html file:
'<div ID="mycomp" class="">
'  <h1 ID="testh1">This Is a test</h1>
'</div>
Sub ABMComp_Build(InternalPage As ABMPage, internalID As String) As String       
   Return $"<div id="${internalID}" class="terminal"></div><script>var terminal;</script>"$
End Sub

' Is useful to run some initalisation script.
Sub ABMComp_FirstRun(InternalPage As ABMPage, internalID As String)
   Dim script As String = $"terminal = $('.terminal')[0];"$
   
   InternalPage.ws.Eval(script, Array As Object(ABMComp.ID))
   ' flush not needed, it's done in the refresh method in the lib
End Sub

' runs when a refresh is called
Sub ABMComp_Refresh(InternalPage As ABMPage, internalID As String)
   'Dim script As String = $""$
   'InternalPage.ws.Eval(script, Null)
End Sub

' do the stuff needed when the object is removed
Sub ABMComp_CleanUp(InternalPage As ABMPage, internalID As String)
   
End Sub

public Sub AddToLog(InternalPage As ABMPage, logText As String)
   Dim script As String = $"terminal.appendChild(document.createTextNode("${logText}"));
  terminal.appendChild(document.createElement('br'));
     terminal.scrollTop = terminal.scrollHeight - terminal.clientHeight;"$
   
   InternalPage.ws.Eval(script, Array As Object(ABMComp.ID))
   InternalPage.ws.Flush   
End Sub

public Sub AddToLogLimited(InternalPage As ABMPage, logText As String, MaxLines As Int)
   Dim script As String = $"while (terminal.children.length >= ${MaxLines}) {
  terminal.removeChild(terminal.firstChild);
  terminal.removeChild(terminal.firstChild);
  }
     terminal.appendChild(document.createTextNode("${logText}"));
  terminal.appendChild(document.createElement('br'));"
     terminal.scrollTop = terminal.scrollHeight - terminal.clientHeight;"$
       
   InternalPage.ws.Eval(script, Array As Object(ABMComp.ID))
   InternalPage.ws.Flush   
End Sub

public Sub Clear(InternalPage As ABMPage)
   Dim script As String = $"while (terminal.firstChild) {
  terminal.removeChild(terminal.firstChild);
  }"$
   
   InternalPage.ws.Eval(script, Array As Object(ABMComp.ID))
   InternalPage.ws.Flush
End Sub

Usage:
B4X:
' in page Class_Globals
Dim terminal As CompLogger
Dim terminalTimer As Timer
Dim counter As Int

' in connectpage
...
terminal.Initialize(page, "Terminal")
page.Cell(2,1).AddComponent(terminal.ABMComp)   
     
' refresh the page
page.Refresh
   
' Tell the browser we finished loading
page.FinishedLoading
' restoring the navigation bar position
page.RestoreNavigationBarPosition   
   
terminalTimer.Initialize("terminalTimer", 1000)
terminalTimer.Enabled = True

' the timer for demo
Sub terminalTimer_Tick
   counter = counter + 1
   terminal.AddToLog(page, "[" & DateTime.Date(DateTime.Now) & " " & DateTime.time(DateTime.now) & "] Terminal log line " & counter)
End Sub
 
Upvote 0
Top