Assigning data to HTML Form function

What I’m trying to do:
I’m trying to implement simple google gantt form, but stuck with the tranfser of data from server side to client and then to HTML Custom Component.

That is a simple example from: Google docs

I need somehow to pass the data rows to the form. Can you please help me how to do it in anvil? Columns are fixed so I can set it directly in HTML of the Custom Form, but the rows with data have to be passed to it.

<center style="font-style:italic; color:#888; margin: 3em;">
<html>
<head>
  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  <script type="text/javascript">
    google.charts.load('current', {'packages':['gantt']});
    google.charts.setOnLoadCallback(drawChart);

    function drawChart() {

      var data = new google.visualization.DataTable();
      data.addColumn('string', 'Task ID');
      data.addColumn('string', 'Task Name');
      data.addColumn('string', 'Resource');
      data.addColumn('date', 'Start Date');
      data.addColumn('date', 'End Date');
      data.addColumn('number', 'Duration');
      data.addColumn('number', 'Percent Complete');
      data.addColumn('string', 'Dependencies');

      data.addRows([
        ['2014Spring', 'Spring 2014', 'spring',
         new Date(2014, 2, 22), new Date(2014, 5, 20), null, 100, null],
        ['2014Summer', 'Summer 2014', 'summer',
         new Date(2014, 5, 21), new Date(2014, 8, 20), null, 100, null],
        ['2014Autumn', 'Autumn 2014', 'autumn',
         new Date(2014, 8, 21), new Date(2014, 11, 20), null, 100, null],
        ['2014Winter', 'Winter 2014', 'winter',
         new Date(2014, 11, 21), new Date(2015, 2, 21), null, 100, null],
        ['2015Spring', 'Spring 2015', 'spring',
         new Date(2015, 2, 22), new Date(2015, 5, 20), null, 50, null],
        ['2015Summer', 'Summer 2015', 'summer',
         new Date(2015, 5, 21), new Date(2015, 8, 20), null, 0, null],
        ['2015Autumn', 'Autumn 2015', 'autumn',
         new Date(2015, 8, 21), new Date(2015, 11, 20), null, 0, null],
        ['2015Winter', 'Winter 2015', 'winter',
         new Date(2015, 11, 21), new Date(2016, 2, 21), null, 0, null],
        ['Football', 'Football Season', 'sports',
         new Date(2014, 8, 4), new Date(2015, 1, 1), null, 100, null],
        ['Baseball', 'Baseball Season', 'sports',
         new Date(2015, 2, 31), new Date(2015, 9, 20), null, 14, null],
        ['Basketball', 'Basketball Season', 'sports',
         new Date(2014, 9, 28), new Date(2015, 5, 20), null, 86, null],
        ['Hockey', 'Hockey Season', 'sports',
         new Date(2014, 9, 8), new Date(2015, 5, 21), null, 89, null]
      ]);

      var options = {
        height: 400,
        gantt: {
          trackHeight: 30
        }
      };

      var chart = new google.visualization.Gantt(document.getElementById('chart_div'));

      chart.draw(data, options);
    }
  </script>
</head>
<body>
  <div id="chart_div"></div>
</body>
</html>
</center>
<div anvil-slot="default"></div>

Here’s a proof of concept for how you might approach this in anvil

I moved the first script tag to native libraries
Then I moved the second script to python, into its own component, and used anvil.js

Code
from ._anvil_designer import GantChartTemplate
from datetime import date

from anvil.js import get_dom_node
from anvil.js.window import google, window


def to_js_date(d):
    return window.Date(d.isoformat())

def days_to_milli(days):
    return days * 24 * 60 * 60 * 1000

class GantChart(GantChartTemplate):
    def __init__(self, **properties):
        self.init_components(**properties)
        self._shown = False

    def draw_chart(self, *args):
        data = google.visualization.DataTable();
        data.addColumn('string', 'Task ID');
        data.addColumn('string', 'Task Name');
        data.addColumn('date', 'Start Date');
        data.addColumn('date', 'End Date');
        data.addColumn('number', 'Duration');
        data.addColumn('number', 'Percent Complete');
        data.addColumn('string', 'Dependencies');
        data.addRows([
            ['Research', 'Find sources', to_js_date(date(2015, 1, 1)), to_js_date(date(2015, 1, 5)), None,  100,  None],
            ['Write', 'Write paper', None, to_js_date(date(2015, 1, 9)), days_to_milli(3), 25, 'Research,Outline'],
            ['Cite', 'Create bibliography', None, to_js_date(date(2015, 1, 7)), days_to_milli(1), 20, 'Research'],
            ['Complete', 'Hand in paper', None, to_js_date(date(2015, 1, 10)), days_to_milli(1), 0, 'Cite,Write'],
            ['Outline', 'Outline paper', None, to_js_date(date(2015, 1, 6)), days_to_milli(1), 100, 'Research']
        ]);
        options = {"height": 275}

        chart = google.visualization.Gantt(get_dom_node(self))
        chart.draw(data, options)

    def form_show(self, **event_args):
        if self._shown:
            return
        self._shown = True

        google.charts.load('current', {'packages':['gantt']})
        google.charts.setOnLoadCallback(self.draw_chart)


2 Likes

Thanks for the solution. It’s really easy now to implement! :grinning: