title: pass JavaScript var back to Flask and have ajax reload
body: <p>Preface: I've already looked at similar questions and tried to extrapolate code/concepts to help resolve with no luck.</p>
  <p>-https://stackoverflow.com/questions/43645790/passing-javascript-variable-to-python-flask</p>
  <p>-https://stackoverflow.com/questions/10313001/is-it-possible-to-make-post-request-in-flask</p>
  <p><strong>Please do not just close because it's a &quot;similar&quot; question.</strong></p>
  <p>I'm designing a simple flask app which can be viewed live here:</p>
  <p><a href="https://flaskapp.gullp.repl.co/" rel="nofollow noreferrer">https://flaskapp.gullp.repl.co/</a></p>
  <p><a href="https://i.stack.imgur.com/JDqUx.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JDqUx.png" alt="enter image description here" /></a></p>
  <p>There is a chart using chart.js and underneath resides a Pandas dataframe.</p>
  <p>Goal: When you click a bar on the chart, it filters the dataframe. Concretely, if I click the &quot;Big Home&quot; bar, the dataframe below will only show values where the label = &quot;Big Home&quot;.</p>
  <p>Attempts:</p>
  <p>Trying to use Ajax/jQuery to pass the value back to Python and have it filter the dataframe accordingly.</p>
  <p>I've been able to get the corresponding clicked value (i.e when you click the first bar it will output &quot;big home&quot;) My thought is that i can take this value, pass it back to python, and have it filter the dataframe, and subsequently reload the dataframe using ajax on the site.</p>
  <p>Current attempt = bar is clicked -&gt; corresponding value is saved to javascript var -&gt; the javascript var is loaded into json string -&gt; json string is then loaded back to flask -&gt; flask rerenders dataframe.</p>
  <pre><code>@app.route(&quot;/&quot;, methods=[&quot;GET&quot;, &quot;POST&quot;])
  def home():
      labels = chart_df['label'].tolist()
      values = chart_df['value'].tolist()
      return render_template('index.html', values=values, labels=labels, column_names=df.columns.values, row_data=list(df.values.tolist()), zip=zip)
  
      if request.method == &quot;POST&quot;:
          data = request.get_json()
          return jsonify(status=&quot;success&quot;, score=data)
          
      else:
          return render_template('index.html', score='', values=values, labels=labels, column_names=df.columns.values, row_data=list(df.values.tolist()), zip=zip)
  
  </code></pre>
  <p>the onclick logic i'm using to grab value from graph and pass it to variable:</p>
  <pre><code>             //below allows you to click the chart and get the respective value. you will pass this value to python
                  ,onClick: function(c,i) {
        
                  e = i[0];
                  //console.log(e._index)
                  var x_value = this.data.labels[e._index];
                  var y_value = this.data.datasets[0].data[e._index];
                 // console.log(x_value);
                  //console.log(y_value);
                  console.log('you clicked the graph, now the x value is = ' + x_value)
          
                } 
            }
        });
  
  //below puts the clicked value into a json format so we can pass it back to python/flask to reload the dataframe table that resides below the chart/graph. I'm attempting to pass it via ajax.
  
  //start off with default chart values
        var x_value = '444'
        console.log('when the page loaded we defaulted x-value = ' + x_value + ' now try clicking one of the bars below.')
        var ctx = document.getElementById('myChart').getContext('2d');
  
  
  
      var chart_clicked_data = { 'score' : x_value}
        console.log('this is the json chart clicked data that we want to pass back to flask = ' + JSON.stringify(chart_clicked_data) )
  
  </code></pre>
  <p>the ajax im attempting to implement</p>
  <pre><code>     $.ajax({
      type: &quot;POST&quot;,
      url: &quot;/&quot;,
      contentType: &quot;application/json&quot;,
      data: JSON.stringify(chart_clicked_data),
      dataType: &quot;json&quot;,
      success: function(response) {
          console.log(response);
      },
      error: function(err) {
          console.log(err);
      }
  });
  
  </code></pre>
  <p>Problem:</p>
  <p>I just learned flask, javascript, &amp; jquery this week, so go easy on me, but I'm unable to get the entire process to work.</p>
  <p><a href="https://i.stack.imgur.com/caF6z.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/caF6z.png" alt="enter image description here" /></a></p>
  <p>I'm suspecting that i have no way to trigger the post method? Not sure how to accomplish this.</p>
  <p>My entire code is running here (can be edited here too) -&gt; <a href="https://repl.it/join/rbkobiqi-gullp" rel="nofollow noreferrer">https://repl.it/join/rbkobiqi-gullp</a></p>
  <p>app.py (application factory)</p>
  <pre><code>import os
  import random
  import pandas as pd
  import datetime as dt
  from flask import Flask, render_template, url_for, request, jsonify
  
  
  '''dataframe for table/graph'''
  df = pd.DataFrame({'label': ['Big Home','Big Home', 'Big Home',  'Medium Home', 'Medium Home', 'Small Home'], 
                     'value': [10, 9, 9, 7, 6, 2]})
  
  '''dataframe to display graph'''
  chart_df = df.copy()
  chart_df = chart_df.groupby(&quot;label&quot;).count().reset_index()
  
  
  
  '''Application Factory'''
  app = Flask(  # Create a flask app
      __name__,
      template_folder='templates',  # Name of html file folder
      static_folder='static'  # Name of directory for static files
  )
  
  @app.route(&quot;/&quot;, methods=[&quot;GET&quot;, &quot;POST&quot;])
  def home():
      labels = chart_df['label'].tolist()
      values = chart_df['value'].tolist()
      return render_template('index.html', values=values, labels=labels, column_names=df.columns.values, row_data=list(df.values.tolist()), zip=zip)
  
      if request.method == &quot;POST&quot;:
          data = request.get_json()
          return jsonify(status=&quot;success&quot;, score=data)
          
      else:
          return render_template('index.html', score='', values=values, labels=labels, column_names=df.columns.values, row_data=list(df.values.tolist()), zip=zip)
  
  
  
  @app.route('/tabletest')
  def hello_world():
      return chart_df.to_html(header=&quot;true&quot;, table_id=&quot;table&quot;)
  
  
  if __name__ == &quot;__main__&quot;:  # Makes sure this is the main process
      app.run( # Starts the site
          host='0.0.0.0',  # EStablishes the host, required for repl to detect the site
          port=random.randint(2000, 9000),  # Randomly select the port the machine hosts on.
      debug=True
      )
  </code></pre>
  <p>index.html (under templates)</p>
  <pre><code> &lt;!doctype html&gt;
   &lt;html&gt;
     &lt;head&gt;
        &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js&quot;&gt;&lt;/script&gt;
        &lt;script src=&quot;//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js&quot;&gt;&lt;/script&gt;
     &lt;/head&gt;
    &lt;body&gt;
  
   &lt;center&gt;&lt;canvas id=&quot;myChart&quot; width=&quot;600&quot; height=&quot;200&quot;&gt;&lt;/canvas&gt;
  
      &lt;script&gt;
         var ctx = document.getElementById('myChart').getContext('2d');
         Chart.defaults.global.responsive = false;
  
  
        var myChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: /* {{ labels }}*/ ['Big Home', 'Medium Home', 'Small Home'] ,
                datasets: [{
                    label: 'count per label',
                    data: /*{{ values }} */ [3,2,1]
                }]
            },
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true
                        }
                    }]
                }
                //below allows you to click the chart and get the respective value. you will pass this value to python
                  ,onClick: function(c,i) {
        
                  e = i[0];
                  //console.log(e._index)
                  var x_value = this.data.labels[e._index];
                  var y_value = this.data.datasets[0].data[e._index];
                 // console.log(x_value);
                  //console.log(y_value);
                  console.log('you clicked the graph, now the x value is = ' + x_value)
          
                } 
            }
        });
  
  //below puts the clicked value into a json format so we can pass it back to python/flask to reload the dataframe table that resides below the chart/graph. I'm attempting to pass it via ajax.
  
  //start off with default chart values
        var x_value = '444'
        console.log('when the page loaded we defaulted x-value = ' + x_value + ' now try clicking one of the bars below.')
        var ctx = document.getElementById('myChart').getContext('2d');
  
  
  
      var chart_clicked_data = { 'score' : x_value}
        console.log('this is the json chart clicked data that we want to pass back to flask = ' + JSON.stringify(chart_clicked_data) )
  
        $.ajax({
      type: &quot;POST&quot;,
      url: &quot;/&quot;,
      contentType: &quot;application/json&quot;,
      data: JSON.stringify(chart_clicked_data),
      dataType: &quot;json&quot;,
      success: function(response) {
          console.log(response);
      },
      error: function(err) {
          console.log(err);
      }
  });
  
  
  
  
  
        &lt;/script&gt;
  
  
  &lt;!-- Table Logic Below --&gt;
  
  &lt;br&gt;
  &lt;br&gt;
       &lt;div&gt; Your current score selected is = {{score}} &lt;/div&gt;
  &lt;br&gt;
  &lt;br&gt;
  Trying to make it so when you click &quot;Big Home&quot; for example, the data table will only show values for &quot;big home&quot;
  &lt;br&gt;
  &lt;br&gt;
        &lt;table border='1'&gt;
          &lt;thead&gt;
  
            &lt;tr&gt;
              {% for col in column_names %}
              &lt;th&gt;
              
                {{col}}
               
              &lt;/th&gt;
              {% endfor %}
            &lt;/tr&gt;
  
          &lt;/thead&gt;
          &lt;tbody&gt;
            {% for row in row_data %}
            &lt;tr&gt;
              {% for col, row_ in zip(column_names, row) %}
              &lt;td&gt;{{row_}}&lt;/td&gt;
              {% endfor %}
            &lt;/tr&gt;
            {% endfor %}
  
           
          &lt;/tbody&gt;
    
        &lt;/table&gt;
  
  &lt;/center&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  
  
  </code></pre>