Grid - WebView JS (Tabulator)

Share your advanced PureBasic knowledge/code with the community.
wombats
Enthusiast
Enthusiast
Posts: 716
Joined: Thu Dec 29, 2011 5:03 pm

Grid - WebView JS (Tabulator)

Post by wombats »

You can use the WebViewGadget to implement really good table/grid libraries like Tabulator. This is just a simple example, but the library offers a lot of options.

Image

HTML:

Code: Select all

<!doctype html>
<html>
  <head>
    <style>
      .grid {
        -webkit-touch-callout: none; /* iOS Safari */
        -webkit-user-select: none; /* Safari */
        -khtml-user-select: none; /* Konqueror HTML */
        -moz-user-select: none; /* Old versions of Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome, Edge, Opera and Firefox */
      }
      div.grid {
        font-family: sans-serif;
        position:fixed;
        padding:0;
        margin:0;
        top:0;
        left:0;
        width: 100%;
        height: 100%;
      }
    </style>
    <link href="https://cdn.jsdelivr.net/npm/tabulator-tables@6.3.1/dist/css/tabulator.min.css" rel="stylesheet">
  </head>
  <body>
    <div class="grid" id="array-grid"></div>
  </body>

  <script src="https://cdn.jsdelivr.net/npm/tabulator-tables@6.3.1/dist/js/tabulator.min.js"></script>

  <script>

    var table;

     var tabledata = [
      {id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
      {id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
      {id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
      {id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
      {id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
     ];

    table = new Tabulator("#array-grid", {
      data:tabledata,

      height:false,

      editTriggerEvent:"dblclick",

      columns:[
      {title:"Name", field:"name", width:150, resizable:true, editor:"input"},
      {title:"Age", field:"age", hozAlign:"left", formatter:"progress"},
      {title:"Favourite Color", field:"col"},
      {title:"Date of Birth", field:"dob", sorter:"date", hozAlign:"center"},
      ],
    });

    table.on("cellEdited", function(cell) {
        let column = cell.getColumn();
        let row = cell.getRow();
        window.OnCellEdited(row.getIndex(), column.getField(), cell.getValue());
    });

  </script>
</html>
PB:

Code: Select all

EnableExplicit

Declare OnCellEdited(params.s)

OpenWindow(0, 100, 100, 640, 480, "Grid", #PB_Window_SystemMenu | #PB_Window_Invisible)

WebViewGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), #PB_WebView_Debug)
SetGadgetText(0, "file://" + GetCurrentDirectory() + "grid.html")

BindWebViewCallback(0, "OnCellEdited", @OnCellEdited())

HideWindow(0, #False)

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Procedure OnCellEdited(params.s)
  Protected json.i, id, column.s, value.s
  json = ParseJSON(#PB_Any, params)
  If IsJSON(json)
    id = GetJSONInteger(GetJSONElement(JSONValue(json), 0))
    column = GetJSONString(GetJSONElement(JSONValue(json), 1))
    value = GetJSONString(GetJSONElement(JSONValue(json), 2))
    Debug "Row " + Str(id) + ", column '" + column + "' edited: " + value
    FreeJSON(json)
  EndIf
EndProcedure
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Grid - WebView JS (Tabulator)

Post by idle »

thanks and good example too.
wombats
Enthusiast
Enthusiast
Posts: 716
Joined: Thu Dec 29, 2011 5:03 pm

Re: Grid - WebView JS (Tabulator)

Post by wombats »

idle wrote: Thu Apr 24, 2025 1:22 am thanks and good example too.
Thanks!

Here's an example of adding a row header so it's a grid rather than a table. Only the HTML/JS is different.

Image

Code: Select all

<!doctype html>
<html>
  <head>
    <style>
      .grid {
        -webkit-touch-callout: none; /* iOS Safari */
        -webkit-user-select: none; /* Safari */
        -khtml-user-select: none; /* Konqueror HTML */
        -moz-user-select: none; /* Old versions of Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome, Edge, Opera and Firefox */
      }
      div.grid {
        font-family: sans-serif;
        position:fixed;
        padding:0;
        margin:0;
        top:0;
        left:0;
        width: 100%;
        height: 100%;
      }
    </style>
    <link href=" https://cdn.jsdelivr.net/npm/tabulator-tables@6.3.1/dist/css/tabulator.min.css " rel="stylesheet">
  </head>
  <body>
    <div class="grid" id="array-grid"></div>
  </body>

  <script src=" https://cdn.jsdelivr.net/npm/tabulator-tables@6.3.1/dist/js/tabulator.min.js "></script>

  <script>

    var table;

     var tabledata = [
      {id:0, 0:"", 1:"", 2:"", 3:""},
      {id:1, 0:"", 1:"", 2:"", 3:""},
      {id:2, 0:"", 1:"", 2:"", 3:""},
      {id:3, 0:"", 1:"", 2:"", 3:""},
      {id:4, 0:"", 1:"", 2:"", 3:""},
     ];

    table = new Tabulator("#array-grid", {
      data:tabledata,

      height:false,

      editTriggerEvent:"dblclick",

      rowHeader:{resizable:false, frozen:true, width:75, hozAlign:"center", editor:false, formatter:function(row) {
          var data = row.getData();
          row.getElement().style.backgroundColor = "#c0c0c0";
          row.getElement().style.fontWeight = "bold";
          return data.id;
        }},

      columns:[
      {title:"0", field:"0", width:100, resizable:true, editor:"input"},
      {title:"1", field:"1", width:100, resizable:true, editor:"input"},
      {title:"2", field:"2", width:100, resizable:true, editor:"input"},
      {title:"3", field:"3", width:100, resizable:true, editor:"input"},
      ],
    });

    table.on("cellEdited", function(cell) {
        let column = cell.getColumn();
        let row = cell.getRow();
        window.OnCellEdited(row.getIndex(), column.getField(), cell.getValue());
    });

  </script>

</html>
User avatar
jacdelad
Addict
Addict
Posts: 1991
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Grid - WebView JS (Tabulator)

Post by jacdelad »

I've used Tabulator a couple of times and it's really great. Integrating it in PureBasic is a good thing. Thanks very much!
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Fred
Administrator
Administrator
Posts: 18150
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Grid - WebView JS (Tabulator)

Post by Fred »

That's cool stuff ! Here is a dialog version to show how it looks when integrated in your app:

Code: Select all

  #Dialog = 0
  #Xml = 0
  
  Runtime Enumeration Gadget
    #ListView
    #EditorContainer
    #BackupContainer
    #Table
  EndEnumeration
  
  Procedure ShowPanels()
    
    HideGadget(#Table, #True)
    HideGadget(#EditorContainer, #True) 
    HideGadget(#BackupContainer, #True)
    
    Select GetGadgetState(#ListView)
      Case 0
        HideGadget(#Table, #False)
        
      Case 1
        HideGadget(#EditorContainer, #False)
        
      Case 2
        HideGadget(#BackupContainer, #False)
    EndSelect
  EndProcedure
  
  Runtime Procedure OnListViewEvent()
    ShowPanels()
  EndProcedure
  
  XML$ = "<window id='#PB_Any' name='test' text='Preferences' minwidth='auto' minheight='auto' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
         "  <hbox expand='item:2'>" +
         "    <listview id='#ListView' width='100' onEvent='OnListViewEvent()'/>" +
         "    <multibox>" +
         "" +
         "      <webview id='#Table'>" +
         "      </webview>" +
         "" +
         "      <container id='#EditorContainer' invisible='yes'>" +
         "        <frame text='Editor'>" +
         "          <vbox expand='no'>" +
         "            <checkbox text='Set read only mode'/>" +
         "            <checkbox text='Duplicate line automatically'/>" +
         "            <checkbox text='Enable monospace font'/>" +
         "          </vbox>" +
         "        </frame>" +
         "      </container>" +
         "" +
         "      <container  id='#BackupContainer' invisible='yes'>" +
         "      <frame text='Backup'>" +
         "        <vbox expand='no'>" +
         "          <checkbox text='Activate backup'/>" +
         "        </vbox>" +
         "      </frame>" +
         "      </container>" +
         "" +
         "    </multibox>" +
         "  </hbox>" +
         "</window>"
  
  UseDialogWebViewGadget()
  
  Procedure OnCellEdited(params.s)
    Protected json.i, id, column.s, value.s
    json = ParseJSON(#PB_Any, params)
    If IsJSON(json)
      id = GetJSONInteger(GetJSONElement(JSONValue(json), 0))
      column = GetJSONString(GetJSONElement(JSONValue(json), 1))
      value = GetJSONString(GetJSONElement(JSONValue(json), 2))
      Debug "Row " + Str(id) + ", column '" + column + "' edited: " + value
      FreeJSON(json)
    EndIf
  EndProcedure
  
  If ParseXML(#Xml, XML$) And XMLStatus(#Xml) = #PB_XML_Success
    
    If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "test")
      
      AddGadgetItem(#ListView, -1, "Tabulator")
      AddGadgetItem(#ListView, -1, "Editor")
      AddGadgetItem(#ListView, -1, "Backup")
      
      SetGadgetState(#ListView, 0)
      
      ShowPanels()
      
      SetGadgetText(#Table, "file://" + GetCurrentDirectory() + "test.html")

      BindWebViewCallback(#Table, "OnCellEdited", @OnCellEdited())
      
      Repeat
        Event = WaitWindowEvent()
      Until Event = #PB_Event_CloseWindow 
      
    Else  
      Debug "Dialog error: " + DialogError(#Dialog)
    EndIf
  Else
    Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
  EndIf

Mesa
Enthusiast
Enthusiast
Posts: 433
Joined: Fri Feb 24, 2012 10:19 am

Re: Grid - WebView JS (Tabulator)

Post by Mesa »

For information, nothing work on my laptop win10 x64 + pb 6.21b6 x64 c backend.
No grid, just header on the wombat example. Idem in my firefox.
The https://tabulator.info/ works on firefox.

M.
User avatar
skywalk
Addict
Addict
Posts: 4210
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Grid - WebView JS (Tabulator)

Post by skywalk »

I'm also having troubles on Windows11.
I'll try some more and post later.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
wombats
Enthusiast
Enthusiast
Posts: 716
Joined: Thu Dec 29, 2011 5:03 pm

Re: Grid - WebView JS (Tabulator)

Post by wombats »

Thanks, Fred! It looks good in that example.

Hmm, I'm on Windows 11, and I also tested it on macOS. I wonder what the issue could be.

Does it make a difference if the JS and CSS are loaded locally rather than online from the CDN? I load it locally in my project, but I did it from a CDN for this example just to make it easier to test.
Mesa
Enthusiast
Enthusiast
Posts: 433
Joined: Fri Feb 24, 2012 10:19 am

Re: Grid - WebView JS (Tabulator)

Post by Mesa »

It doesn't make any difference if the JS and CSS are loaded locally.

I've updated my drivers without any success too.

M.
User avatar
the.weavster
Addict
Addict
Posts: 1576
Joined: Thu Jul 03, 2003 6:53 pm
Location: England

Re: Grid - WebView JS (Tabulator)

Post by the.weavster »

Mesa wrote: Fri Apr 25, 2025 10:33 am It doesn't make any difference if the JS and CSS are loaded locally.
It can do, you can't load ES6 modules via the file:// protocol so you have to be careful which version of the Tabulator files you use.
User avatar
the.weavster
Addict
Addict
Posts: 1576
Joined: Thu Jul 03, 2003 6:53 pm
Location: England

Re: Grid - WebView JS (Tabulator)

Post by the.weavster »

A related tip:

Tabulator wants the record data in this format:

Code: Select all

[
      {id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
      {id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
      {id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
      {id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
      {id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
];
If you're retrieving your data from SQLite3 you can get the result of your Select statement already formatted that way:

Code: Select all

select json_group_array(json_object( 
'id', id, 
'name', name, 
'age', age, 
'col': col, 
'dob', dob 
 )) from users order by id
Post Reply