views:

108

answers:

4

I've been researching this on and off for a number of months now, but I am incapable of finding clear direction.

My goal is to have a page which has a form on it and a graph on it. The form can be filled out and then sent to the CGI Python script (yeah, I'll move to WSGI or fast_cgi later, I'm starting simple!) I'd like the form to be able to send multiple times, so the user can update the graph, but I don't want the page to reload every time it doe that. I have a form and a graph now, but they're on separate pages and work as a conventional script.

I'd like to avoid ALL frameworks except JQuery (as I love it, don't like dealing with the quirks of different browsers, etc).

A nudge in the right direction(s) is all I'm asking for here, or be as specific as you care to.

(I've found similar guides to doing this in PHP, I believe, but for some reason, they didn't serve my purpose.)

EDIT: The graph is generated using Flot (a JQuery plugin) using points generated from the form input and processed in the Python script. The Python script prints the Javascript which produces the graph in the end. It could all be done in Javascript, but I want the heavier stuff to be handled server-side, hence the Python.

Thanks!

A: 

Update img.src attribute in onsubmit() handler.

  • img.src url points to your Python script that should generate an image in response.
  • onsubmit() for your form could be registered and written using JQuery.
J.F. Sebastian
I don't wish to generate an image in response – I'm generating Javascript and HTML with the Python script.
Isaac Hodes
+2  A: 

If you'll be loading HTML and Javascript that needs to be executed, and your only reason for not wanting to load a new page is to preserve the surrounding elements, you could probably just stick the form in an IFRAME. When the form is POSTed, only the contents of the IFRAME are replaced with the new contents. No AJAX required either. You might find that the answers here give you sufficient direction, or Google for things like "form post to iframe".

Peter Hansen
+4  A: 

I'm assuming that you have two pages at the moment - a page which shows the form, and a page which receives the POST request and displays the graph.

Will a little jQuery you can do exactly what you want.

First add to your form page an empty div with id="results". Next in your graph plotting page put the output you want to show to the user in a div with the same id.

Now attach an onclick handler to the submit button (or to the individual parts of the form if you want it to be more dynamic). This should serialize the form, submit it to the plotting page snatch the contents of the id="results" div and stuff them into the id="results" div on the the form page.

This will appear to the user as the graph appearing on the page whenever they click submit.

Here is a sketch of the jQuery code you will need

$(function(){
    // Submit form
    // Get the returned html, and get the contents of #results and
    // put it into this page into #results
    var submit = function() {
        $.ajax({
            type: "POST",
            data: $("form").serialize(),
            success: function(data, textStatus) {
                $("#results").replaceWith($("#results", $(data)));
            }
        });
    };
    $("form input[type=submit]").click(submit);
    // I think you'll need this as well to make sure the form doesn't submit via the browser
    $("form").submit(function () { return false; });
});

Edit

Just to clarify on the above, if you want the form to redraw the graph whenever the user clicks any of the controls not just when the user clicks submit, add a few more things like this

$("form input[type=text]").keypress(submit);
$("form input[type=checkbox], form select").change(submit)
Nick Craig-Wood
Thank you! I'm going to give this a try, as well as the JQuery free answer below. I'll accept an answer after I implement them, and I guess I'll accept on some basis of votes received/time submitted/clarity of answer? Thanks again!
Isaac Hodes
Best just to accept on the basis of what works for you. Vote up any you find "useful", accept the one that solves your problem.
Peter Hansen
Reasonable – that I'll do. Unfortunately, none quite solve my problem yet. This one, with modification, has me 80% there. My final issue is that when I submit a new set of values from my form, my CGI script fails. I'm unsure of what's happening here, but I have a feeling it has to do with CGI and the way the variables are passed and stored to the script. Is there a way to submit the form values to a new instance of my script each time – and is that wise? Thanks!
Isaac Hodes
"Is there a way to submit the form values to a new instance of my script each time[...]?" I believe this is exactly the way that CGI works - a new process for each request.
Rafał Dowgird
I'm not sure what the issue is then, but it must be with my javascript reloading or something... I'll work it out. Thanks!
Isaac Hodes
+1  A: 

I'd like the form to be able to send multiple times, so the user can update the graph, but I don't want the page to reload every time it doe that.

The general pattern goes like that:

  1. Generate an XMLHttpRequest (in form's onsubmit or it's 'submit' button onclick handler) that goes to your Python script. Optionally disable the submit button.
  2. Server side - generate the graph (assuming raw HTML+JS, as hinted by your comment to another answer)
  3. Client side, XmlHttp response handler. Replace the necessary part of your page with the HTML obtained via the response. Get responseText from the request (it contains whatever your Python script produced) and set innerHtml of a control that displays your graph.

The key points are:

  • using XMLHttpRequest (so that the browser doesn't automatically replace your page with the response).
  • manipulating the page yourself in the response handler. innerHtml is just one of the options here.

Edit: Here is a simple example of creating and using an XMLHttpRequest. JQuery makes it much simpler, the value of this example is getting to know how it works 'under the hood'.

Rafał Dowgird
How do I implement this (I like that it doesn't use JQuery, is why I ask)? I've used an XMLHttpRequest before, but I don't quite get what you mean when you say to "generate an XMLHttpRequest" or "XmlHttp response handler" – could you clarify just a bit, please? Thank yoU!
Isaac Hodes
I'll try - in a short time.
Rafał Dowgird
Great! Thank you – I'll be trying these out shortly.
Isaac Hodes