Tabulator Javascript Datagrid Integration


Latest code (v0.3), uploaded 14th July 2019 @ 00:04
https://anvil.works/build#clone:GSDA2VMKIZNPWYMF=B52JHTEN4OUGIDZWVODELWGW

(fixed bug in row click)

What is it?
In the spirit of doing everything except what I’m supposed to be doing, I have a very basic implementation of the Tabulator JS data table (http://www.tabulator.info) working as a component.

It’s a work in progress, and I’d welcome any help (particularly on better JS techniques).

How to use it.
Clone the app (make sure it’s the latest one). Look at the Example form and read the Tabulator API notes. You should be able to call any of its API functions following the items and columns examples, but over time I will make it more user friendly and as Anvillic as possible.

It sends click events along with row information back to Anvil for processing there.

It should go without saying that it’s not production ready :slight_smile:

How does it work?
(most people won’t care about this bit).
The Tabulator library is included in Native Libraries, and I have added a class definition which creates an instance in its constructor. The component is a custom html form with some javascript that :

  • generates a random uid
  • renames the DIV defined on the form to be unique (required for anvil.call). This is required to allow for multiple tables
  • adds a new instance of Tabulator into our “namespace” with the uid as the index
  • signals back to anvil to register the uid for future API calls from anvil to the component.

The Examples form shows two tables on the same form both being filled independently (one with 5k rows and lighting fast on pagination).

What’s it for?
Purely for my own entertainment :slight_smile:

5 Likes

Hi,

Thanks for this great sample integration with Tabulator.

I’m trying to do a couple things differently and not having great success. Primarily, my grid is not driven by table data but a custom object with arrays of dicts from which I need to dynamically build the columns and items. Another twist is that I’m trying to pre-pivot the data so the table layout will result in a columnar orientation for the detail rows.

What I am trying to do is pass json from a server module for both the columns and items back to a form with a Tabulator component and display the completed grid when the Form is displayed.

I’m passing json objects to setup() and the columns managed to get configured and displayed, but I’m not having luck with the items.

I suspect my issues are related to the datatype of the dynamically created column and items parms.

Another would be the issue of when/where is the best place to trigger the pre-population of the table. I’ve tried to find more information in the Tabulator documentation but haven’t had luck so far.

Thanks in advance for any suggestions, clues, etc. to get me on the right track.

Cheers!

Glad you like it.

However, this is an older version of the library. I’m a bit short on time today, but as soon as I can I’ll update all references to the new version as it works a little better.

In the mean time, if you could you post an example of your data object and your intended result I’ll see if I can help.

Great! I’ll work on trimming it down to a concise example.

Many thanks!

Hi,

I took another approach and extended your original Example with a second form (Example2) and separate Tabulator component (Tabulator_preload):

https://anvil.works/build#clone:G6FEUVSXZ6JXWOR6=BJT7MZMVNBAP6HNV22T6N373

Once I clarified the order that the components were being created I was able to sort it out.

Thanks!

1 Like

Looks like a great example of integrating a JavaScript component.

I am however not able to follow how the MyTable class is instantiated in this codebase.

Can anyone provide more context?

I’m a little snowed under at the moment, but I will “remind” myself how it works when I get a second and get back to you.

Hi @david.wylie, I was able to figure it out.

It was hidden in the custom html code of the component where the HTML DIV was created along with the necessary JavaScript to create the table.

Thanks
SS

@david.wylie I had a project where I wanted to reuse a datagrid component that had more features out of the box than the anvil datagrid.
I liked what you did with Tabulator so I had a go at taking it on.
It was nice that the table has header sorting by default and is super fast to load.
Adding rows also is simple and doesn’t require a complete redrawing of the element…

Here’s what i’ve come up with.

The example Clone Link and dependency:
https://anvil.works/build#clone:JVL5ORAAPZ6SVWDU=JA27THWRHTGHH7XK4U36PRN4


Hopefully the native datagrid element will get some enhanced features and this dependency will become useless…


5 Likes

(your example has this error : “ExternalError: ReferenceError: Tabulator is not defined”)

Yeah, sorry I meant to update that - took a phone call between posting and realising my mistake!

I am getting another error when I run in the IDE -

AttributeError: 'Tabulator' object has no attribute '_columns'
at app/Tabulator/Tabulator/__init__.py, line 146 column 8
  called from property.py, line 20 column 8
  called from Form1, line 10

I’m looking into it but thought you should know.

thanks - edited so hopefully fixed that.

Looks good!

Just to say I had to do the following to make it work (for anyone else cloning it) -

  1. re-add the dependency (and use Development unless you publish the dependency app)
  2. you need to delete and re-add the Tabulator custom component to the form in the demo app.
  3. BUT BEFORE YOU DO (2) - click the placeholder for the “missing” tabulator control and copy the binding data.
  4. Re-establish the event links - click the tabulator component then click each of the events in the properties and the links to the methods will be established.

You’ll see what i mean when you do it. These are all slight side effects of cloning apps and dependency apps, but once done it all works fine.

Good work!

2 Likes

I think you should break this away into your own Show N Tell thread.
You’ve definitely taken this to the next level, making it far more integrated than I ever did.

You’re suffering from one small issue that I also came across, and that’s if you load the data too quickly after creating the grid none of the formatting (for example “fitColumns”) kicks in.

In your example you don’t see it because you wait for the “refresh data” button to be clicked before loading the data. I do see it because mine gets loaded on the show_form event.

The way I got around it in my early version was I fired an event (table_created) from the JS and caught it in the Anvil form. I then initialised my data from there.

Just a thought.

ta - that was what I was hoping the redraw function would do… I guess it deosn’t… replaced it with a replace_data function on the tabulator show event.

Seems to render properly my end now…

Hmm, not for me.
I’m doing this in my show event :

  def form_show(self, **event_args):
    if not self.visible:
      self.update()
      self.visible = True

If I move the update/visible code to a timer’s tick event and set the timer for about 1 second, everything is fine, but attempting to do anything in the show event (or setting the timer for too short a time) causes the table to be incorrectly formatted.

The visible thing is to stop the (in my view erroneous) visual effect of having a subform set to full_width_row jump from not full width to full width after the data is loaded (there’s a year or more old bug report on that elsewhere).

Hey guys, the tabulator seems like a good component for the library. :smile:

6 Likes