Textpattern Forms with Some AJAX Love

Zem Contact has been an integral plugin for many TXP users for ages. Now, I've attempted to add some speed and a little Shazam! with our Javascript friend, AJAX.

First Things

  1. Upload the ever resilient and equally small and simple Jquery for your JavaScript library. I’ve uploaded mine into my main directory thus mydomain.com/js/jquery.js.
  2. Upload the Jquery.form plugin. This plugin utilizes the Jquery library and contains the necessary Javascript to make your forms submit using AJAX. I’ve uploaded my plugin to be a sibling file next to my Jquery file thus: http://squaredeye.com/js/jquery.form.js.
  3. You should already have the Zem_Contact_Reborn & Zem_Contact_Lang plugins loaded in your Textpattern install.

Now that you the table set, lets start getting the food out shall we

The Textpattern Form

In this case, I’ll simply be using just slightly more than the simplest available contact form. It actually doesn’t matter what form you use from the ZCR plugin. I’ve placed this XHTML into a Textpattern form (presentations/forms) by the name of basic_contact_form

  1. <txp:zem_contact to="squaredeye+site@gmail.com" thanks_form="contact_thanks" >
  2. <ul class="contact">
  3. <li><txp:zem_contact_text name="name" label="Name" required="1" break="" /><br /></li>
  4. <li><txp:zem_contact_email name="email" label="Email" required="1" break="" /><br /></li>
  5. <li><txp:zem_contact_textarea name="cont_message" label="Message" break="" /><br /></li>
  6. </ul>
  7. <txp:zem_contact_submit label="Send" />
  8. </txp:zem_contact>
  9. download /code/tuts/form_basic_contact.txt

The Textpattern Pages

You’ll be creating two pages. One page will be an include and will essentially be what the AJAX pulls into your next page, which will be whatever page you are displaying the ZCR Contact form on, I’ll call this the “Section Page”.

First, the AJAX page

  1. <txp:output_form form="basic_contact" />
  2. download /code/tuts/page_ajax.txt

Next, the Section Page

  1. <txp:output_form form="basic_dtd_head" />
  2. <body>
  3. <div id="header">
  4. <txp:output_form form="basic_nav" />
  5. </div>
  7. <div id="content" class="wrap">
  8. <div class="sub">
  9. <div class="sub-sect">
  10. <h3>Request a Proposal</h3>
  11. <p>Are you interested in working with Squared Eye Design? This is the place to start. Fill out the basic form below. As soon as I give it a read through, I'll be in touch.</p>
  12. </div>
  13. </div><!--sub-->
  14. <div class="main-list">
  15. <txp:output_form form="basic_contact" />
  16. </div>
  17. </div><!--content-wrap-->
  19. <txp:output_form form="basic_footer" />
  21. </body>
  22. </html>
  23. download /code/tuts/page_contact.txt

As you view the page above, keep in mind, that this is the html I use for this site, but the one piece of code you need to make sure to include in your page is the <txp:output_form form="basic_contact" /> tag.

Behavior One: The Javascript

Authored By: Patrick Woods
Now we can get into the fun part. The Javascript below is will fetch the response that the form is looking for from the server and return it to the ZCR form’s location without refreshing the page.

The setup is pretty simple, on line 35 we start our $(document).ready() function which will run on document load. We then grab all the forms with a class of zemContactForm and loop through of them [line 36] using $('form.zemContactForm').each() and apply the ajaxForm() function to each one.

The essential functionality of the jQuery form plugin is setup by calling ajaxForm() and passing it an options object which let’s you specify what url to post to and what do after a successful ajax response. The success callback does not pass a reference to the form object that was actually submitted to the success function.

This is a problem because our setup applies the functionality to all the ZCR forms on a page. We probably don’t want the same DOM element to be updated for every form so we need to somehow pass the form to the options object. Ideally we want a method that allows us to specify the options object for any form we pass to it. This will allow us to call it later outside of our document preparation section.

In order to accomplish this we create our own options object which can take the parameters we will need to specify on a case by case basis. I decided to place it inside a more general zcr object in order to properly encapsulate all my ZCR functions in a common namespace in case I decide to move into client side validation functions or something like that. Since these options are only for ajax calls I went ahead and placed it in an ajax object. The result on line 12 is a zcr.ajax.options(form,url) method which takes as parameters the form object it should observe and what url the ajax request should go to and returns an options object which we can pass to ajaxForm(). That is exactly what we do on lines 38 and 39.

Let’s look at the options we are setting. The first option is target: which simply specifies what DOM element should be updated with the ajax response. In this case we set it to the form’s parent using $(form).parent(). The next one is url: this is where the ajax request will be sent to. We provide this when we call zcr.ajax.options() and it should point to whatever section url you set up for your AJAX page above.

Now we get to the success: option. Because we are in essence completely reloading the form every time it is submitted we need to rewire the form again after a successful submit. The problem is that new form is a completely new DOM object so we can’t use the object reference we passed when called zcr.ajax.options(). However because Ruud (the latest ZCR developer) is very clever the new form and the old form share the same id. So on line 18 we fetch the new form with the id we currently have using $('#' + form.attr("id")). This will fetch a form with the same id as the form we passed to zcr.ajajx.options(). We then create an options object for this new form on line 20 using the same url, and finally bind the new form using ajaxForm() on line 22. This will make the new form work just like the original form.

The beforeSubmit: option let’s you specify behavior to happen before the form submission happens so you can indicate to the user that something is happening. In this case it replaces the submit buttons with a small loading image.

  1. <script type="text/javascript">
  2. // <![CDATA[
  3. //Create a zcr object so everything is properly namespaced
  4. var zcr = {
  5. //create an ajax object in zcr just for good measure
  6. ajax: {
  7. // create the options object
  8. options : function(form,url) {
  9. return {
  10. target: form.parent(),
  11. url: url,
  12. success: function(msg) {
  13. // grab the current form id so we can grab the new form object return in the Ajax response
  14. var newForm = $("#" + form.attr("id"));
  15. //Create an options object for the new form
  16. var options = zcr.ajax.options(newForm,url);
  17. //wire up the new form
  18. newForm.ajaxForm(options);
  19. },
  20. beforeSubmit: function() {
  21. form.find('input.zemSubmit').toggle()
  22. form.find('input.zemSubmit').parent().append('<img class="loadingImg" src="http://www.squaredeye.com/css/images/icon_loading.gif" alt="waiting" />');
  23. } // end beforeSubmit
  24. };
  25. } //end options
  26. } //end ajax
  27. };
  31. // prepare the forms when the DOM is ready
  32. $(document).ready(function() {
  33. $('form.zemContactForm').each(function() {
  34. var options = zcr.ajax.options($(this), '/ajax/');
  35. $(this).ajaxForm(options);
  36. }); //end each
  37. }); //end document.ready
  38. // ]]>
  39. </script>
  40. download /code/tuts/form_javascript.txt

Back to: Matthew Smith
You’ll note in the code above, that I’ve found a small loading.gif to let users know that the form is being processed. There are a number of different places to find free and good loading gifs for this purpose. You can always edit them as I did mine, if you are so inclined.

Also note that the comments of articles are not handled by AJAX. This article refers only to the contact forms.

The Credit

Thanks for your help and writing Patrick Woods for schooling me in the art of coding Javascript with Jquery. I’d also like to thank Ruud at the Textpattern forums”:http://forums.textpattern.com for doing further development on Zem Contact Reborn. You’ve turned a great plugin into a jedi plugin.

Have you got something to add? Maybe a question for me? Perhaps you're a fan of brown-nosing? If you've got something to throw my way, feel free to send me an email.

Near Here

Next in Line:

Related by Category

Well, I'll be darned! No related articles were found for this particular entry.