Web2.0 Very Simple Responsive Flex Layout

Creating a responsive layouts that work great on mobile is now possible with Web2.0. Here’s a simple example:

Use the Flex layout type for a WebContainer.
In the open event you can do something like this:

LayoutType = LayoutTypes.Flex
for i as integer = 0 to 5
  dim cc as new CCTextfield //ContainerControl with a textfield in it
  cc.EmbedWithin(self, self.Width, cc.Height)
  cc.AddResponsiveLayout(12,6,4,3,2) //Optional if you want to specify columns
next

AddResponsiveLayout is a custom method I built so you can specify the columns for XS,Small,Medium,Large, and XL screens based on a 12 column system. Use this if you want your controls to stretch to fill up the space evenly.

Here’s the helper method you can add to any Module:

Public Sub AddResponsiveLayout(extends control as WebUIControl, ColXS as integer = -1, ColSm as integer = -1, ColMd as integer = -1, ColLg as integer = -1, ColXl as integer = -1)
  dim classesToAdd() as string
  //-1 = inherit
  if ColSm = -1 then ColSm = ColXS
  if ColMd = -1 then ColMd = ColSm
  if ColLg = -1 then ColLg = ColMd
  if ColXl = -1 then ColXl = ColLg
  //0 = hidden https://getbootstrap.com/docs/4.0/utilities/display/
  if colxs = 0 or colsm = 0 or colmd = 0 or collg = 0 or colxl = 0 then //If Any Hidden
    if ColXs = 0 then classesToAdd.Append("d-none") else classesToAdd.Append("d-block")
    if ColSm = 0 then classesToAdd.Append("d-sm-none") else classesToAdd.Append("d-sm-block")
    if ColMd = 0 then classesToAdd.Append("d-md-none") else classesToAdd.Append("d-md-block")
    if ColLg = 0 then classesToAdd.Append("d-lg-none") else classesToAdd.Append("d-lg-block")
    if ColXl = 0 then classesToAdd.Append("d-xl-none") else classesToAdd.Append("d-xl-block")
  end
  //1-12 https://getbootstrap.com/docs/4.0/layout/grid/
  if ColXs > 0 then classesToAdd.Append("col-"+ColXs.ToString)
  if ColSm > 0 then classesToAdd.Append("col-sm-"+ColSm.ToString)
  if ColMd > 0 then classesToAdd.Append("col-md-"+ColMd.ToString)
  if ColLg > 0 then classesToAdd.Append("col-lg-"+ColLg.ToString)
  if ColXl > 0 then classesToAdd.Append("col-xl-"+ColXl.ToString)
  
  //ADD CLASSES
  for each classToAdd as string in classesToAdd
    dim js as string = "document.getElementById('"+control.ControlId+"').classList.add('"+classToAdd+"');"
    control.ExecuteJavaScript(js)
  next
End Sub
12 Likes

Here’s a very simple sample project showing this in action:

There’s a known issue with TabIndex not working across containers:
<https://xojo.com/issue/61609>
To fix the tab order I’ve had to disable the Xojo custom tab engine:
ExecuteJavascript("XojoWeb.TabEngine.currentTabEngine = function(x){};")

7 Likes

Thanks Nash for the sample.

Can you please explain about this “(12,6,4,3,2)”?

The parameters correspond to the 5 screen size breakpoints in order: XS, Small, Medium, Large, and XL
(Think from small phone to large desktop)

Bootstrap is based on a 12 column system with these different screen sizes.
The value is the number of Columns i.e. the WIDTH you want that control to take up for that screen size:
12 = 100%
6 = 50%
4 = 1/3
3 = 1/2
2 = 1/6

You can then organize your controls so they layout appropriately for each screen size by making sure your controls add up to 12 for each row at the desired size.

The input also takes in -1 which means to inherit from the control below it. For example,
AddResponsiveLayout(12,-1,-1,-1,-1) means all screen sizes use 12 and by convention you can remove the extra parameters to simply be AddResponsiveLayout(12)

The input also takes in 0 which means to hide the control for the corresponding screen size.

3 Likes

Tested on my phone and the page doesn’t fit. Changed the webpage Minimum Width to 300 and now it fits. Also if using the desktop browser and making the width smaller I get a scrollbar at the bottom (if I don’t change the min width). Just FYI.

Thanks. I updated the project to reduce the Minimum width!

1 Like

I updated the project to include a simple Response WebListBox, just change the app’s launch page.

Or all you need is a WebListBox with 1-column and no headerand then put this in the open event:

var s as string = "<raw><div class=''><div class='row'><div class='colcol-12 col-sm-6 col-md-6 col-lg-4 col-xl-3'>Apple</div><div class='colcol-12 col-sm-6 col-md-6 col-lg-4 col-xl-3'>0</div><div class='colcol-12 col-sm-6 col-md-6 col-lg-4 col-xl-3'>Type: Awesome</div><div class='colcol-12 col-sm-6 col-md-6 col-lg-4 col-xl-3'>Status: Open</div><div class='colcol-12 col-sm-6 col-md-6 col-lg-4 col-xl-3'>Created: Sep 4, 2020 at 3:41:33 PM</div><div class='colcol-12 col-sm-6 col-md-6 col-lg-4 col-xl-3'>Modified: Oct 4, 2020 at 3:41:33 PM</div></div></div></raw>"
for i as integer = 0 to 100
  me.AddRow(s)
next
2 Likes

Instead of using this hack, please use the property that we made for users wishing to turn off the Xojo tab engine:

Session.AllowTabOrderWrap = False

This needs to be set before the first page is shown, preferably in the Session.Opening event.

@Greg_O_Lone

Yeah except I’ve tried this and it doesn’t actually work. Also would be nice if this was WebView specific. My guess is it doesn’t work for dynamically embedded container controls?

<https://xojo.com/issue/61714>