This tutorial will guide you through basic form submission, and using AJAX.
Form Submission
The most basic method of submitting a form is to submit a form using the HTTP POST method. Let's create a basic Feedback form that fires an email off to feedback@mysite.com as an example.
Let's assume we have an instance of the HomePage prototype that we're going create our Feedback form on. We need to to do a few things:
- The form is going to have some HTML markup in it, so we'll create a TALE template called feedback_form.tal that the function will use. This will go in the HomePage directory.
- Next, we need a JavaScript function to Display the Form - Let's call this function feedback().
- We also need another JavaScript function to Process the Form - Let's call this one process_feedback(). Both of these functions can go in any .js file in the HomePage directory.
- Finally to remember to set the security to @Anyone for the feedback and process_feedback functions in HomePage's security.properties, since only main is available by default:
feedback = @Anyone process_feedback = @Anyone
First let's take a look at the feedback_form.tal file:
<html xmlns:tal="http://axiomstack.com/tale">
<head>
<title>Feedback Form</title>
</head>
<body>
<form tal:attr="action: this.getURI('process_feedback')" method="post">
<fieldset>
<label for="fullname">Your Full Name:</label> <input type="text" name="fullname" id="fullname" />
</fieldset>
<fieldset>
<label for="email">Your Email:</label> <input type="text" name="email" id="email" />
</fieldset>
<fieldset>
<label for="feedback">Your Feedback:</label><br/>
<textarea name="feedback" id="feedback">Enter Your Feedback Here</textarea>
</fieldset>
<fieldset>
<button type="submit">Submit</button>
</fieldset>
</form>
</body>
</html>
The only thing special to note in this TALE file is that we're dynamically specifying the action of the form element. We always want to dynamically specify any URIs in our application so we never have to worry about mountpoint/rewrite rule/accessname changes.
Next, to display our TALE file, our feedback function will look like this:
function feedback() {
return this.feedback_form();
}
Now we can load our form by opening our browser and navigating to:
http://<Your Server Address>/<This Application's Mountpoint>/<This HomePage Object's Accessname>/feedback
Finally, all we have to do now is define our form processing function:
function process_feedback() {
var fullname = req.data.fullname;
var email = req.data.email;
var feedback = req.data.feedback;
var mail = new Mail();
mail.setTo("feedback@mysite.com", "Feedback");
mail.setFrom(email, fullname);
mail.setSubject("Feedback Submission from " + fullname);
mail.addText(fullname + " submitted the following feedback:\n\n" + feedback);
mail.send();
res.write("Your Feedback was successfully submitted.");
}
And there we have it! After submitting the form, we retrieve the form data, throw it into a Mail Object, send it, and display a success message.
AJAX
Let's do the same thing, using AJAX this time. We'll use the popular jQuery Library for this example.
First, we need to modify our feedback_form.tal from the first example:
<html xmlns:tal="http://axiomstack.com/tale">
<head>
<title>Feedback Form - AJAX Enhanced</title>
<script tal:attr="src: app.getStaticMountpoint('jquery-1.2.3.min.js')" type="text/javascript"></script>
<script tal:text="$" type="text/javascript">
function submit_form() {
var url = '${this.getURI('process_feedback')}';
var data = {};
data.fullname = $('#fullname').value;
data.email = $('#email').value;
data.feedback = $('#feedback').value;
$.post(url,data,callback,'json');
return false;
}
function callback(data, textStatus) {
$('#message').text(data.fullname + ', thank you for submitting your feedback!');
$('form')[0].reset();
}
</script>
</head>
<body>
<div id="message"></div>
<form onsubmit="return submit_form()">
<fieldset>
<label for="fullname">Your Full Name:</label> <input type="text" name="fullname" id="fullname" />
</fieldset>
<fieldset>
<label for="email">Your Email:</label> <input type="text" name="email" id="email" />
</fieldset>
<fieldset>
<label for="feedback">Your Feedback:</label><br/>
<textarea name="feedback" id="feedback">Enter Your Feedback Here</textarea>
</fieldset>
<fieldset>
<button type="submit">Submit</button>
</fieldset>
</form>
</body>
</html>
We made the following modifications:
- Added the script tag to include the jQuery .js file. Note that we're using the app.getStaticMountpoint() function to dynamically determine the URI of the script file in our static content location.
- Added two client-side JavaScript functions in another script tag, the submit_form() function, which makes the AJAX request, and the callback() function, which handles the data returned from the request. Here we're using the tal:text command to refer to server-side JavaScript in order to dynamically specify the URI of our process_feedback() function. Also note that we're using the "json" type option in our jQuery post call.
- Modified the form tag by removing the action and method attributes, and added an onsubmit event that refers to our submit_form() function. (Note: We made this function return false so the form does not actually submit.)
- Added a div where our resulting message will be placed.
Now we need to make a minor modification to our process_feedback() function:
function process_feedback() {
var fullname = req.data.fullname;
var email = req.data.email;
var feedback = req.data.feedback;
var mail = new Mail();
mail.setTo("feedback@mysite.com", "Feedback");
mail.setFrom(email, fullname);
mail.setSubject("Feedback Submission from " + fullname);
mail.addText(fullname + " submitted the following feedback:\n\n" + feedback);
mail.send();
var success_obj = {};
success_obj.fullname = fullname;
res.write(success_obj);
}
Here, rather than writing the message to the response, we're creating a JavaScript Object, and setting the fullname property of it to the fullname that was submitted. When you pass a JavaScript Object into res.write(), it automatically writes the literal notation of the object (JSON). If Bill Gates were to submit the form, the response would appear like this:
({fullname:"Bill Gates"})
Since we specified the "json" type option in our jQuery post call, this response is automatically evaluated into a client-side JavaScript Object and passed into our callback() function. The callback() function simply writes a personalized thank you message using the data returned from the server to our new div and resets the form. And that's all there is to it!
