Best practices for web apps

I’m preparing to do my first web app and just looking for some guidance on “best practices”. Unfortunately for those who respond, I’ll probably have lots of questions and will continue to update this thread with those questions as time goes on.

Initial question is simply, should all controls be placed on a container and then the container added to the webpage in order to achieve the best results when opening the webpage on various monitors with different resolutions and, more importantly, should the enduser decide to resize the web browser page?

Additional question. Is there a general rule regarding what should be made a property/method of the session versus the webpages of the application?

Since Xojo Web doesn’t really have any sort of grid or flexbox model, I ended up coding a responsive design by hand.

I’m using controls on a single Webpage : no Containers.

Basically, I have code in the WebPage.Resized event which arranges controls based on the size of the WebPage, like this:

event WebPage1.Resized

dim w as integer = self.width
dim h as integer = self.height


dim x,y as integer 

if w < 500 and h > w then
  ' --------------------------------------------------------------------------------
  ' small, Tall screen, such as iPhone 6,7, or 8 which is 375x667
  ' --------------------------------------------------------------------------------
  
  ' set up reasonable left margin and width
  var x1 as integer = 4
  var w1 as integer = w - 8
  
  
  
  ' hide the description header
  lHeader.Visible = false
  
  ' question needs to wrap at screen size
  y = logoBackground.Bottom + 8
  
  lQuestion.width = w1
  lQuestion.Height = 120
  
  lQuestion.top = y
  lQuestion.left = x1
  
  y = lQuestion.Bottom + 4
  
  if showTextArea then
    ' ta goes below it
    ta.Width = w1
    ta.Height = 280
    ta.top = y
    ta.left = x1
    y = ta.Bottom + 4
   
  elseif showgraph then
    wc.Width = w1
    wc.Height = 280
    
    wc.top = y
    wc.left = x1
    
    y = wc.Bottom + 4
    
  else
    
    ' rg goes below it
    rg.Width = w1
    rg.height = 280
    
    rg.top = y
    rg.Left = x1
    
    y = rg.Bottom + 4
  end if
  
 
  ' buttons below that
  pbPrevious.top = y
  pbCheck.top = y
  pbNext.top = y
  
  ' status fields are below buttons
  y = pbNext.Bottom + 4
  
  lTimeLimit.left = pbPrevious.left
  lTimeLimit.top = y
  
  lStatus.left = pbNext.Right - lStatus.Width
  lStatus.top = y
  
  if showTextArea then
    lCharCount.top = y
    lCharCount.left = x1
  end if
  
  y = lStatus.Bottom + 8
  
  
elseif h < 500 and w > h then
  
  ' --------------------------------------------------------------------------------
  ' small, Wide screen, such as iPhone 6,7, or 8 which is 667x375
  ' --------------------------------------------------------------------------------
  
  ' set up reasonable left margin and width
  var x1 as integer = 8
  var w1 as integer = w - 16
  
  
  ' hide the description header
  lHeader.Visible = false
  
  ' question needs to wrap at screen size
  y = logoBackground.Bottom + 4
  
  lQuestion.width = w1
  lQuestion.Height = 76
  
  lQuestion.top = y
  lQuestion.left = x1
  
  y = lQuestion.Bottom
  
  
  if showTextArea then
    ' ta goes below it
    ta.Width = w1
    ta.Height = 146
    ta.top = y
    ta.left = x1
    y = ta.Bottom + 4
    
    ' above/right of ta
    lCharCount.top = ta.top - 32
    lCharCount.left = ta.right - lCharCount.Width - 8
    
    
  elseif showGraph then
    
    wc.Width = w1
    wc.Height = 146
    wc.left = x1
    wc.top = y
    y = wc.Bottom + 4
    
    
  else 
    
    ' rg goes below it
    rg.Width = w1
    rg.height = 152
    
    rg.Left = x1
    rg.top = y
    
    y = rg.Bottom
  end if
  
  
  ' buttons below that
  y = y + 4 // add some padding
  
  pbPrevious.top = y
  pbCheck.top = y
  pbNext.top = y
  
  ' ### Special: status fields go to the Right of buttons!
  y = y 
  lTimeLimit.top = y - 12
  lTimeLimit.left = pbNext.right + 16
  lStatus.top = y + 8
  lStatus.left = lTimeLimit.left
  
  
else
  ' --------------------------------------------------------------------------------
  ' otherwise, assume it's a Tablet or computer with a big-enough screen
  ' --------------------------------------------------------------------------------
  
  ' show the description header
  y = logoBackground.Bottom + 8
  lHeader.top = y
  lHeader.Visible = true
  y = lHeader.Bottom + 8
  
  ' set up reasonable left margin and width
  var x1 as integer = 16
  var w1 as integer = Min(600, w-32)
  
  lQuestion.top = y
  lQuestion.left = x1
  lQuestion.width = w1
  lQuestion.Height = 110
  
  y = lQuestion.Bottom + 8
  
  if showTextArea then
    ' ta goes below it
    ta.Width = w1
    ta.Height = 280
    ta.top = y
    ta.left = x1
    y = ta.Bottom + 4
    
  elseif showGraph then
    wc.Width = w1
    wc.Height = 180
    wc.top = y
    wc.left = x1
    y = wc.Bottom + 4
    
    
  else 
    
    ' rg goes below it
    rg.Left = x1
    rg.Width = w1
    rg.height = 180
    rg.top = y
    
    y = rg.Bottom + 8
  end if

This was not easy but it allows perfect customization, and in the end, the effort was worth it.

The answer for what you should do definitely depends on your specific UI design.

Depends on your design, but for my web app, I have the concept of a User, and each Session has one User instance as a property. When the User goes into WebPage to do something, information needed (for example, to graph some data, allow editing of a field, etc.) are all properties of the WebPage. Any data that needs to persist gets saved in the User object (which has a way to write to disk).

(Edit to add: in case it’s not clear, a WebPage is conceptually part of a Session, so one WebPage is never associated with more than one Session)

I did have to decide how to deal with one User trying to access the system at the same time; I decided to disallow this (if a User opens a new browser Tab, the prior session is terminated).

Hope that helps?

container controls could be useful if you need this same element on multiple pages.

this anchor/locking concept is generelly ok.

instead of programming in events its better to have a class object of your business logic.

i forgot where to place it in xojo but this scaling is useful because at pc the buttons used by mouse and the ui generally could be smaller.

<meta name="viewport" content="width=device-width, initial-scale=1">