Javascript – Python/Flask/HTML – Rendering HTML in a new window instead of the home page

Python/Flask/HTML – Rendering HTML in a new window instead of the home page… here is a solution to the problem.

Python/Flask/HTML – Rendering HTML in a new window instead of the home page

I

have a Python code where I create a web page using Flask. On the homepage, I’m filling out a form, submitting it with a button, and it displays a form based on input.

The problem I’m having is that after clicking the button to submit the form, it renders the form on the same web page. I want to create a new window using JavaScript window.open() or any other method you might suggest to render the table in a new window and leave the homepage unchanged. I tried to look around and didn’t seem to be able to do anything. I’ve read through this question and this question.

Here is my code :

Python code

from flask import Flask, render_template, request,
app = Flask(__name__)

def get_table(user_input):
...
return dict    //returns list of dictionaries, for example... 
               dict = [{'name':'Joe','age':'25'},
                       {'name':'Mike','age':'20'}, 
                       {'name':'Chris','age':'29'}] 

@app.route("/")
def home():
    return render_template('home.html')

@app.route("/table", methods = ['POST'])
def table():
    user_input = request.form['input']
    dict_table = get_table(user_input)     //return list of dictionaries
    return render_template('table.html', dict_table=dict_table)

if __name__ == '__main__':
    app.run(debug=True)

home.html

<! DOCTYPE html>
<html>
<head>
   <title>Homepage</title>
</head>
<body>
        <form action="/table" method="post">
            <select name="input">
               <option value="1">Input</option>
            </select>
           <button type="submit">Click Me!</button>
        </form>
</body>
</html>

table.html

<! DOCTYPE html>
<html>
<head>
   <title>Table</title>
</head>
<body>
        <table id="table">
        {% if dict_table %}
        <tr>
            {% for key in dict_table[0] %}
                <th>{{ key }}</th>
            {% endfor %}
        </tr>
        {% endif %}

{% for dict in dict_table %}
        <tr>
            {% for value in dict.values() %}
                <td>{{ value }}</td>
            {% endfor %}
        </tr>
        {% endfor %}
    </table>
</body>
</html>

Can anyone clearly explain how to click the form submission button on the home page, stay on the home .html, and have the table in table.html open in a new window (maybe using window.open() from JavaScript or something)?

I would appreciate it if someone could walk me through the steps on how to do this with the code I provided and specifically tell me where to call the function and things like that. I’m new to Flask/HTML/JS and I’m just trying to learn for personal use, but I’m frustrated with reading links and documentation that show how to display URLs like google.com in a new tab, which isn’t what I want. Thanks!

Solution

Step 1: Check out this link that explains how to use Jquery and Ajax with FLASK

The key concept here is AJAX (asynchronous JavaScript and XML). In short, it is an architecture that sends a request to the server in the background (called an asynchronous request) and then modifies the content of the page currently displayed by the Web browser based on the results received from the server, avoiding as and the server no longer transmitting the full page.

Step 2: Resolve your issue

  • First we write the route:

    from flask import Flask, render_template, request,
    app = Flask(__name__)
    
    user_input = None
    
    def get_table(user_input):
        ...
        return dict    # returns list of dictionaries, for example... 
                       # dict = [{'name':'Joe','age':'25'},
                       #         {'name':'Mike','age':'20'}, 
                       #         {'name':'Chris','age':'29'}] 
    
    @app.route('/')
    def home():
        return render_template('home.html')
    
    @app.route('/_ajax_user_input')
    def ajax_user_input():
        global user_input
        user_input = request.args.get('user_input', 0, type=int)
        return "ok"
    
    @app.route("/table")
    def table():
        x = user_input
        dict_table = get_table(x)     # return list of dictionaries
        return render_template('table.html', dict_table=dict_table)
    
  • After we attack the template:

  • home.html:

         <select id="input" name="input">
             <option value="1">Input</option>
         </select>
         <button type="button" class="test"> Click Me! </button>
    
    <script>
             $(document).ready(function(){
                 $('.test').bind('click', function() {
                     $.getJSON($SCRIPT_ROOT + '/_ajax_user_input',{
                         user_input: $('#input').val(),
                     },function() {
                         window.open('http://127.0.0.1:5000/table', '_blank');
                     });
                     return false;
                 });
             });
         </script>
    
  • table.html:

         <table id="table">
             {% if dict_table %}
                 <tr>
                     {% for key in dict_table[0] %}
                         <th>{{ key }}</th>
                     {% endfor %}
                 </tr>
             {% endif %}
    
    {% for dict in dict_table %}
                 <tr>
                     {% for value in dict.values() %}
                         <td>{{ value }}</td>
                     {% endfor %}
                 </tr>
             {% endfor %}
         </table>
    

Basically like this :

  • When I hit my button, I call the Javascript script:

       $('.test').bind('click', function() {
    
  • This sends an ajax request to FLASK, including executing the ajax_user_input() function:

       $.getJSON($SCRIPT_ROOT + '/_ajax_user_input',
    
  • I send a data (the value selected by the user in the select tag) to this function, and this data is stored in the variable user_input:

       user_input: $('#input').val(),
    
  • On the Flask side, I take the data and store it in a global variable that I also named user_input:

       global user_input
       user_input = request.args.get('user_input', 0, type=int)
    
  • Then call a JavaScript method in my script that allows me to < a href="https://stackoverflow.com/questions/19851782/how-to-open-a-url-in-a-new-tab-using-javascript-or-jquery" rel=" in a new tab Noreferrer noopener nofollow" >more details here) opens a URL:

       window.open('http://127.0.0.1:5000/table', '_blank');
    
  • ‘table’ routing, storing the data previously stored in my global variable (user_input) in variable x, then calling the function get_table() (by passing variable x in the argument) to return the dictionary list, and finally returning the page table.html, It contains a list of dictionaries in the parameter:

       x = user_input
       dict_table = get_table(x)
       return render_template('table.html', dict_table=dict_table)
    

I

hope this will help you, although I believe there are plenty of other ways to do this, perhaps more effectively.

Related Problems and Solutions