0

I'm trying to poll the state of checkboxes (this is done in JS every three seconds). This solution returns "None" (see code below); Both printouts (with 'args' and with 'form') return "None". I'm expecting True/False, depending on the checkbox's boolean state.

index.html:

{% extends "layout.html" %}
{% block content %}
   <div  id="results" class="container">{{data_load|safe}}</div>
   <input id='testName' type='checkbox' value='Yes' name='testName'>
{% endblock %}

and the relevant flask app snippet:

@app.route('/', methods = ['GET', 'POST'])
def index(): 
    return render_template('index.html', data_load=timertry()) 

@app.route('/_timertry', methods = ['GET', 'POST']) 
def timertry():    
    print request.args.get('testName')  
    print request.form.get('testName')
    return "some html going into 'results' div.."

The JavaScript polling function (adapted from here):

$(document).ready(function() {
$.ajaxSetup({cache : false});
setInterval(function() {
    $('#results').load('/_timertry?' + document.location );
}, 3000); // milliseconds!
});

This should be simple enough, but none of the SO solutions I looked into (e.g., using jquery, adapting the flask/ajax example, etc.) worked.

EDIT: following mark's suggestion (including the javascript) and adding print request.values in index.html returns (seen on the console in Aptana):

CombinedMultiDict([ImmutableMultiDict([]), ImmutableMultiDict([])])

Clearly, the request seems empty. The post request is logged (when checkbox is pressed) as:

127.0.0.1 - - [03/Oct/2013 00:11:44] "POST /index HTTP/1.1" 200 -

Any ideas here?

Community
  • 1
  • 1
GG_Python
  • 3,436
  • 5
  • 34
  • 46
  • 1
    Try `request.form.get('testName')`. The `request.args` dict contains the values in the query string, `request.form` has the form POST contents. Also, `request.values` has both combined. – Miguel Grinberg Sep 30 '13 at 14:16
  • Please edit your answer and include the Javacript code that actually "polls" the state of the checkbox, which (I can only assume) does the AJAX request to `/`. Also, you say that it "doesn't work". What do you expect? I'm not sure whether you mean the code in your question returns None, or the code in the other answer returns None. Please edit your question and include these details. – Mark Hildreth Sep 30 '13 at 17:21
  • Edited question for more complete question, hope it clears things up. Note that polling the checkboxes is not the concern, i would actually prefer an immediate response to a user changing the checkbox state (which becomes a question of how to submit a form without a 'submit' button..) – GG_Python Sep 30 '13 at 20:55

2 Answers2

0

Your javascript does the following every three seconds...

$('#results').load('/_timertry?' + document.location);

In other words, you are using the jQuery load() function. The documentation for that function states that this will, in essence, call an HTTP get request to the URL you provide as the parameter (something like /_timertry?http://www.example.org. In other words, a GET request will be called to /timertry?http://www.example.org, which will be handled by Flask's timertry method.

When you have an HTTP form, and you click the "Submit" button, the browser does some magic to push all of the values to the server in the request. When you just do a simple AJAX request, none of that happens for you. Instead, you need to explicitly state what you want to be passed as data to the server (although there are plugins to help you with "post the values of an HTML form using AJAX").

So, because at no point did you do anything in your Javascript to retrieve the value of checkbox to include it into the AJAX request, the AJAX request has no values specifying that the checkbox was checked. You would need to have jQuery check if the box is checked...

var isChecked = $('#testName').is(':checked');
# Now do something with isChecked...

From what I can tell, however, you are sort of misusing HTTP: the load function will make a GET request, and you probably want something to happen as a request of the request. You probably want to make it do a POST request instead (see here and here). Also, you mentioned that you're looking for something to post when a value is changed. Putting this together, you can do something like this...

// Ensure that the function is called when the DOM is ready...
$(function() {
    // Register an event that should be fired when the checkbox value is changed
    $('#testName').change(function() {
        var data = { isChecked : $(this).is(':checked') };
        $.post('/', data);
    });
})

In this case, we have an event that is called when a checkbox is checked, and that event causes us to make a POST request to the server.

Community
  • 1
  • 1
Mark Hildreth
  • 42,023
  • 11
  • 120
  • 109
  • Thanks Mark- we're off to a good start- the console is definitely showing a POST request when the checkbox is pressed (after adding your script), but i'm still getting NONE's on the printouts.. Any ideas? – GG_Python Oct 01 '13 at 00:54
  • Did you print request.values and see what the request is sending you? Have you used the debug console in your browser to see what is being sent? – Mark Hildreth Oct 01 '13 at 14:43
  • Mark, edited question to address your comment above. – GG_Python Oct 03 '13 at 04:20
  • @GG_Python: can you please update the question with all new relevant code. I don't see the debug line you added. – Mark Hildreth Oct 03 '13 at 15:37
0

I'm going to answer this question which was found in the comments of the question

"which becomes a question of how to submit a form without a 'submit' button.."

So it is very possible to submit a value when a user clicks on the button

{% block content %}
   <form id="target" action="YourViewName"> 
       <div  id="results" class="container">{{ data_load|safe }}</div>
       <input id='testName' type='checkbox' value='Yes' name='testName'>
   </form>
{% endblock %}

$( "#results" ).click(function() {
    $( "#target" ).submit();
});

If you want to stay on the same page, however, you're going to need to use an ajax call to pass the data back rather then use a standard submit, however This tutorial covers that topic fairly well. but a basic change to send the data back would look like

$( "#results" ).click(function() {
     var request = $.ajax({
         type: "POST",
         url: "/YourViewName",
         data: {'input_value':$('#testName').val()},
         dataType: "html"
         }).done(function(msg) {
              // I don''t know what you want to do with a return value...
              // or if you even want a return value
  }
});

and the flask would look like

@app.route("/YourViewName")
def example():
    list_name = request.args.get("input_value")
    #if you don't want to change the web page just give a blank return
return ""  
iChux
  • 2,266
  • 22
  • 37
AlexLordThorsen
  • 8,057
  • 5
  • 48
  • 103