Welcome Guest, Not a member yet? Register   Sign In
Flash Ajax effect seen in Rails
#1

[eluser]ccachor[/eluser]
Has anyone recreated or used the javascript effect seen in rails that flashes information to the user such as "Record Saved"..then disappears? It's a great UI effect and I was hoping some of you have created this or something similar. I believe the effect is from a bigger name javascript framework like Scriptaculous.
#2

[eluser]Nick Husher[/eluser]
Yeah, they do use Scriptaculous. The effect isn't too hard, I could write a tutorial on how to do it with the Yahoo User Interface Library and CodeIgniter, if you like.
#3

[eluser]ejangi[/eluser]
I think it's called "Yellow fade" if you need something to search for. Most of those JavaScript framework's should be able to handle it pretty easily (YUI, Scriptaculous, MooTools, etc...).
#4

[eluser]Derek Allard[/eluser]
I did an example of integrating scriptaculous with CodeIgniter at http://video.derekallard.com although I didn't use the highlight function. Its super easy. Off-hand I think its
Code:
new Effect.highlight('some_id');
#5

[eluser]CI Lee[/eluser]
Hey Nick,

I think a tutorial on that would benefit many on this site. There seem to be many questions that could easily be answered by a clear tutorial on YUI and some ajax effects.

-Lee
#6

[eluser]ccachor[/eluser]
Yea that would be great for the wiki/forums! Derek, I'll take a look at that demo and try to put something together Smile
#7

[eluser]Nick Husher[/eluser]
Well, I wrote the code for this yesterday evening and this morning. It's very 37signals-esque. Now I just need to take what I have and walk backward through the steps to write the text to go along with it. I'll post a demo when I have a spare minute at work. Smile
#8

[eluser]Nick Husher[/eluser]
Here's the finished product:

CodeIgniter+AJAX comment system

It looks a little strange in IE6. Untested in IE7. IE6 also doesn't correctly ajaxify the delete operation. Otherwise behaves magnificently in Firefox, Opera, and Safari.

A quick rundown
The page's controller is wired up to a database that stores basic information to display comments. A user can only make one comment, so any duplicate names return an error using CodeIgniter's validation library. You can click the [-] links to delete a post. You can turn AJAX on and off with the AJAX checkbox, to simulate a situation where the user has javascript turned off, or has asynchronous requests somehow disabled. The page behaves as a typical 'flat' form, adding the new content and refreshing the page.

The AJAX system works by intercepting the button press on the Add Comment button and instead submitting the POST data asynchronously to the controller function named ajax_request. Ajax_request takes one parameter, which is the action to take, either an add_comment or delete_comment. CodeIgniter performs the requested action, then returns a JSON object containing relevant return data. In the case of a successful add_comment action, it will return the HTML for displaying the new comment. In the case of a failed add_comment action, it will return the HTML for displaying CI's validation error messages. They are then inserted into the DOM Tree in the appropriate places.

There's a limitation with this approach, however: If there are multiple people posting comments and deleting them at the same time, the HTML visualization will not accurately represent the database state. The solution to this would be to return a complete updated comment list on every asynchronous query. I decided that this problem would appear rarely and wouldn't be inconvenient enough to really warrant the extra transfer of data, especially because I don't have a lot of bandwidth or high-capacity hosting. Still, it's something to keep in mind where client-server replication is important.
#9

[eluser]Nick Husher[/eluser]
I have some downtime at work waiting for a new build, so I'll start this now. I'm going to write it from a general-purpose background, so that it's appropriate for adding to the wiki.

Rails-style AJAX effect in CodeIgniter: From the ground up.

The following is a tutorial on how to create a comment form that updates asynchronously and then returns that updated information through that asynchronous link, and then applying the updated state on the page in a clear way through javascript animation. By the end of this tutorial, the reader should have a basic knowledge of unobtrusive javascript techniques, as well as some skills in Yahoo's javascript libraries (YUI) for event listening, animation, and asynchronous connections. I've divided this increasingly-massive tutorial into three sections.

Part 1 covers the basics of the non-ajaxy codeigniter application. It's pretty straightforward, and is probably only handy as a reference for the second two parts.
Part 2 applies unobtrusive AJAX creation and deletion to the application created in Part 1.
Part 3 inserts animations to draw attention to the changes to the page structure.

For a sneak peek of the final application, check out the demo installation.

1. Creating the basic application

Before we do any cool effects, we need to create a basic working application. Our final app will be a simple comment form or shoutbox application. A user can write a comment with a title, their name, and some content. For the purposes of making the application a little more interesting, we're going to restrict the comment form to one comment per username. It's trivally easy to post multiple times on the form by changing the comment author field, but it's possible to link the username field with another database table of users.

For the purposes of this tutorial, I've autoincluded the database library and the form and url helpers. I'll also be making extensive use of the validation library. I set up my codeigniter config to operate in my favorite operating environment and set up my database to access the database I intend to use for storage. I set up my database with a fields id, comment_author, comment_date, comment_text, comment_title. See the appendix for the SQL table create script for the table I'll be using.

To begin, we're going to create a controller named comments, and give it a function index. The index function is the only function the user is going to directly interact with.
Code:
function index($id = 0) {
    if($id == 0) {
        $this->load->library('validation');

        /*
        We want to check to see if the username is unique to prevent the database
        throwing an error for multiple duplicate usernames. I'm going to omit the
        username_check function for the purposes of brevity, it'll be in the
        attached source later on.
        */
        $rules['comment_author'] = 'trim|required|callback__username_check';
        $rules['comment_text'] = 'trim|required';
        $rules['comment_title'] = 'trim|required';

        $fields['comment_title'] = "Comment Title";
        $fields['comment_author'] = "Comment Author";
        $fields['comment_text'] = "Comment Text";

        $this->validation->set_rules($rules);
        $this->validation->set_fields($fields);

        if($this->validation->run()) {
            $this->db->insert('comments',$_POST);
        }

        $this->db->orderby('comment_date DESC');
        $data['comments'] = $this->db->get('comments', 10);

        $this->load->view('comments-view',$data);            
    } else {
        /*
        I included the ability to display specific comments. Really, this
        isn't necessary for the purposes of the demo, but it does make the
        project a little more complete. Really, it's included to test the
        'single-comment-view' view, which is important for the AJAX part
        of the application.

        Note the lack of error checking if the ID isn't found. Oops.
        */
        $query = $this->db->getwhere('comments', array('id' => $id));
        
        $data['comment'] = $query->first_row('array');
        
        $this->load->view('single-comment-view', $data);
    }
}

I think this code is pretty straightforward. If the post data passes validation, a new comment record is inserted into the comments table. If not, display the relevant error. [Author's note-- if anything here is unclear, let me know, and I'll do some revision.]

Second, we need a function that will delete a comment given its ID:
Code:
function delete_comment($id) {
    $query = $this->db->delete('comments', array('id' => $id));    
    redirect('comments');
}
Also pretty striaghtforward.


Continued...
#10

[eluser]Nick Husher[/eluser]
Rails-style AJAX effect in CodeIgniter: From the ground up.

1. Creating the basic application (cont'd)

We also need to create some view files. I'm going to strip out the CSS gunk for now because it clogs the message of the code. It's also long enough to completely fill up my character limit. Don't worry, it'll be in the linked code. Here's the code for the view file named comments-view.php:
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
&lt;head&gt;
    &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
    &lt;base href="&lt;?=base_url() ?&gt;" /&gt;
    
    &lt;title&gt;CodeIgniter Ajax Demo - Comments&lt;/title&gt;    
&lt;/head&gt;
&lt;body&gt;
    <div id="wrapper">
        &lt;?=form_open('comments', array('id' => 'add_comment_form')); ?&gt;
            <fieldset>
                <label class="one-line">
                    <span class="label">Comment Title:</span>
                    <span class="field">
                        &lt;input type="text" name="comment_title"
                            value="&lt;?=$this-&gt;validation->comment_title ?&gt;" />
                    </span>
                </label>
                <label class="one-line">
                    <span class="label">Comment Author:</span>
                    <span class="field">
                        &lt;input type="text" name="comment_author"
                            value="&lt;?=$this-&gt;validation->comment_author ?&gt;" />
                    </span>
                </label>
                <label class="two-line">
                    <span class="label">Comment Text:</span>
                    <span class="field">
                        &lt;textarea name="comment_text" rows="25" cols="80"&gt;&lt;?=$this->validation->comment_text ?&gt;&lt;/textarea&gt;
                    </span>
                </label>
                <span class="form-button">&lt;input type="submit" id="add-comment-button" value="Add Comment"&gt;</span>
                <div>&lt;input type="checkbox" id="use-ajax-toggle" checked="checked" /&gt; Use AJAX </div>
            </fieldset>
            
            <div &lt;?=($this->validation->error_string == '') ? 'class="no-errors"' : 'class="errors"' ?&gt; >
                <h4>Errors:</h4>
                <div id="errors">
                    &lt;?=$this->validation->error_string; ?&gt;
                </div>
            </div>
        &lt;/form&gt;
        
        <div id="comments-list">
            &lt;?php foreach($comments->result_array() as $comment): ?&gt;
                &lt;?=$this->load->view('single-comment', array('comment'=>$comment), true) ?&gt;
            &lt;?php endforeach; ?&gt;
        </div>
    </div>
&lt;/body&gt;
&lt;/html&gt;

There are a few bits of this file that are worth commenting on. First is the way I've structured the forms. This is mostly personal preference; I really like placing form elements within label tags, and separating label text from field element with spans. This retains a semantic structure while providing a lot of flexibility for styling the elements. Second, I've 'outsourced' printing the individual comments to another view file. I've found that this is generally good practice, especially if I'm using the same or similar list structures on multiple pages. In this case, we'll be using this external view file (single-comment.php' in our ajax stuff later:

Code:
<div class="comment">
    <h4 class="title">&lt;?=$comment['comment_title'] ?&gt;</h4>
    <p class="comment-info">
        Posted by &lt;?=$comment['comment_author'] ?&gt; at &lt;?=$comment['comment_date'] ?&gt;
    </p>
    <p class="body">&lt;?=$comment['comment_text'] ?&gt;</p>
    <a class="delete" href="&lt;?=site_url('comments/delete_comment/'.$comment['id']) ?&gt;" title="delete comment">[-]</a>
</div>

At this point, you should have a very basic working shoutbox/comment form. It doesn't do anything cool, but it's a base to build off of for AJAX development that will come in Part 2. Below are the script-free files. If you have any questions from Part 1, let me know and I'll update to accomadate.

Script-free Comment Box
AJAX-free Demo




Theme © iAndrew 2016 - Forum software by © MyBB