AJAX advice

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

AJAX advice

Post by Luke »

I've never been an AJAX guru. I've added a few AJAX features to a few of my apps but I've never written an "ajax app". What is the usual process to take a regular form, submit it via AJAX, accept the response, and update the page with the results? For instance, I'm creating a page that allows you to post little snippets, which it will accept and then insert into "todays entries" below.

Right now, I override the form's submit event, submit data to an ajax action, accept the result, build the entry html, and insert into the HTML node into the DOM below "todays entries". I see two issues with this:

1) The HTML is generated by javascript instead of by the view script I use in PHP, and therefor violates DRY
2) If it's the first entry, there is no "today's entries" to insert it below, so it fudges up.

So, how can I fix this? How do I use PHP to render the entry instead of javascript?

My Javascript:

Code: Select all

$(function(){
 
    // bind to the form's submit event 
    $('#entryform').submit(function() { 
        // show loading on button
        $('#entryform li.buttons input').val('Submitting...');
        // inside event callbacks 'this' is the DOM element so we first 
        // wrap it in a jQuery object and then invoke ajaxSubmit 
        content = $(this).find('#entry').val();
        $.post('<?= $this->url('entry_ajax') ?>', { entry: content }, afterSubmit, "json");
        return false;
    });
 
});
function afterSubmit(data, textStatus) {
    if (textStatus == 'success') {
        if (data.success == true) {
            entry = $("<div class='entry'></div>");
            entry.html(data.entry.entry);
            when = $("<span class='when'></div>");
            when.html("just now");
            entry.append(when);
            entry.hide();
            $("#entrylist h3.Today").after(entry);
            $("#entryform textarea").attr('value', '');
            entry.fadeIn('normal', function() {
                $('#entryform li.buttons input').val('Submit');
            });
        } else {
            alert(data.responseText);
        }
    } else {
        alert('Sorry, we\'re having issues at the moment. Try again when we don\'t suck.');
    }
}
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: AJAX advice

Post by Eran »

This is how I usually approach the two problems you mentioned:
1. AJAX request sends back a rendered view partial.
Mainly for this purpose I started using view partials extensively in my apps. You render the partial according to the parameters sent in by the ajax request and send it back to the script to be added to the document.

Suppose I have list of items, each contained in a DIV element. I have a partial that specifies how one item is rendered, for example:

Code: Select all

//item.phtml
<div class="item">
   <h1><?php echo $this -> title; ?></h1>
   <p><?php echo $this -> content; ?></p>
</div>
This partial is used in rendering the page:

Code: Select all

//$data is an array of item properties arrays. Most likely the results of a datbase query
echo $this -> partialLoop('/path/to/item.phtml',$data);
And also in rendering single items from an ajax request that creates a new one:

Code: Select all

public function additemAction() {
    if($this -> getRequest() -> isXmlHttpRequest()) {
        $itemModel = new ItemModel();
        $result = $itemModel -> add($_POST);
        if(is_numeric($result)) {
            echo $this -> partial('/path/to/item.phtml',$_POST);
        }
    }
}
(I've used Zend Framework conventions since I know you are familiar with those).


2. Create a container for the dynamic items, append/prepend inside of it
Wrap the dynamic area where you want to add/remove items with a container (a DIV for example). That container should exist regardless of there are previous entries or not. Then, simply append/prepend inside of it as necessary.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Re: AJAX advice

Post by Kieran Huggins »

Partials are a fine solution - but if you're staring to render a LOT of content, maybe you should also consider a full page load?

In the case where you're submitting a comment, I could definitely see how an ajax call would be appropriate. If you're switching listing categories in a blog though, you should probably go with a full page load.

My rule of thumb is to use the URL of a page as an indicator. Should it be changing? i.e. seeing the results of your posted comment: No. seeing a different category of a blog: Yes.

The grey area becomes prevalent with things like pagination... take for example something like endless pageless demo. In that case, I think it's largely up to the programmer. I would probably go with the view partial if the framework was so inclined and return fully formed xhtml.

In either case, you should always have the non-AJAXy link work before you go sexifying things up.
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Re: AJAX advice

Post by Luke »

Yea it works beautifully now. Thanks guys. It works with or without javascript and I only render the post that was JUST added and then inject it into the DOM. :)
Post Reply