Search code examples
ajaxbrython

How to use ajax in Brython


I am writing a web application using Flask and would like to use browser.ajax functionality in Brython but couldn't find a workable example. It would be very nice if someone demonstrates a short example how to use ajax in Brython. More specifically, how to pass data entered by a user into a textfield to a textarea by clicking submit button. Any help is highly appreciated!


(I am writing this several weeks after I posted the question above). I followed this tutorial on how to implement ajax in Flask (http://runnable.com/UiPhLHanceFYAAAP/how-to-perform-ajax-in-flask-for-python) and tried to replace jquery.ajax by Brython. Unfortunately, I still cannot get it work. Here is my code:

Flask's portion:

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

@app.route('/_add_numbers')
def add_numbers():
    a = request.args.get('a', 0, type=int)
    b = request.args.get('b', 0, type=int)
    return jsonify(result=a + b)

Brython/HTML:

 <body onload="brython()">
 <script type="text/python">
 from browser import document as doc
 from browser import ajax

def on_complete(req):
    if req.status==200 or req.status==0:
        doc["txt_area"].html = req.text
    else:
        doc["txt_area"].html = "error "+req.text

def get(url):        
    req = ajax.ajax()
    a = doc['A'].value        
    b = doc['B'].value
    req.bind('complete',on_complete)
    req.open('GET',url,True)
    req.set_header('content-type','application/x-www-form-urlencoded')
    req.send({"a": a, "b":b})      

doc['calculate'].bind('click',lambda ev:get('/_add_numbers'))

</script>

<div class="container">
  <div class="header">
    <h3 class="text-muted">How To Manage JSON Requests</h3>
  </div>
  <hr/>
  <div>
  <p>
<input type="text" id="A" size="5" name="a"> +
<input type="text" id ="B" size="5" name="b"> =
<textarea type="number" class="form-control" id="txt_area" cols="10" rows = '10'></textarea>
<p><a href="javascript:void();" id="calculate">calculate server side</a>

  </div>
 </div>
 </body>
</html>

What I get is "result":0. It looks like brython does not send data to the Flask's view function but I don't know how to fix that. So, it would be great if some one could point out what exactly I am doing wrong.


Solution

  • In your example, the Ajax request is sent with the method GET. In this case, the argument of send() is ignored : the data must be sent in the query string appended to the url

    The Brython code should be :

    def get(url):        
        req = ajax.ajax()
        a = doc['A'].value        
        b = doc['B'].value
        req.bind('complete',on_complete)
        # pass the arguments in the query string
        req.open('GET',url+"?a=%s&b=%s" %(a, b),True)
        req.set_header('content-type','application/x-www-form-urlencoded')
        req.send()
    

    If you want to use the POST method, then you can keep the Brython code as is, but the Flask code should be modified : you must specify that the function handles a POST request, and you get the arguments with the attribute "form" instead of "args" :

    @app.route('/_add_numbers_post', methods=['POST'])
    def add_numbers_post():
        a = request.form.get('a', 0, type=int)
        b = request.form.get('b', 0, type=int)
        return jsonify(result = a+b)