Snippets

Create an account or login to be able to add, comment and rate snippets.

Navigation

AJAX vote - 5 stars

In the template where the object that users can vote on (here, a snippet) is displayed, add:

  <?php echo use_helper('Javascript') ?>
  <?php $id = $snippet->getId() ?>
  <?php if($sf_user->canVoteFor($snippet)): ?>
    <span id="vote_for_<?php echo $id ?>" style="white-space:nowrap;">
      rate this snippet: <?php for($i = 1 ; $i <= 5 ; $i++): ?><div class="rate <?php if($i <= $snippet->getAverageVote()): ?>rated<?php endif; ?>" 
      id="vote_<?php echo $id ?>_<?php echo $i ?>"><?php echo link_to_remote(image_tag('spacer.gif', 'width=10 height=10'), array(
        'url'         => 'snippet/voteForSnippet?id='.$id.'&vote='.$i,
        'update'      => 'vote_for_'.$id,
        'loading'     => visual_effect('appear', 'indicator'),
        'complete'    => visual_effect('fade', 'indicator').visual_effect('highlight', 'vote_for_'.$id),
      ), array(
        'onMouseOver' => 'highlight_stars('.$id.', '.$i.', true);',
        'onMouseOut'  => 'highlight_stars('.$id.', '.$i.', false);',  
      )) ?></div><?php endfor; ?>
      <span id="indicator" style="display:none"> <?php echo image_tag('indicator.gif') ?></span>
    </span>
  <?php else: ?>
    <?php include_partial('voted', array('id' => $id, 'vote' => $snippet->getAverageVote())) ?>
  <?php endif; ?>

Of course, you have to define the rules about who can vote on what in the -&gt;canVoteFor() method of the User object (in apps/myapp/lib/myUser.php). The template uses a _voted.php partial:

<?php for($i = 1 ; $i <= 5 ; $i++): ?><div class="rate <?php if($i <= $vote): ?>rated<?php endif; ?>" id="vote_<?php echo $id ?>_<?php echo $i ?>"><img src="/images/spacer.gif" width="10" height="10" /></div><?php endfor; ?>

DO NOT add extra spaces to the long lines, or the stars get separated by blank spaces.

The mechanism that changes the aspect of stars relies on classes, so add the following styling to a CSS used in your template:

.rate {
display:inline;
width:10px;
height:10px;
margin:0;
padding:0;
background-image:url(/images/vote_star.gif);
background-position: left 10px;
}
.rated
{
background-position: left 0px;
}
.ratehover {
background-position: left 20px;
}

The vote_star.gif file is a 10x30px image containing three versions of the star: voted, hovered, not voted.

vote_star

The snippet/voteForSnippet action does something like:

  public function executeVoteForSnippet()
  {
    $this->id   = $this->getRequestParameter('id');
    $snippet = SnippetPeer::retrieveByPk($this->id);
    if(!$snippet)
    {
      return sfView::NONE;
    }
 
    $vote = new Vote();
    $vote->setUserId($this->getUser()->getUserId());
    $vote->setSnippetId($snippet->getId());
    $vote->setVote($this->getRequestParameter('vote'));
    $vote->save();
 
    $this->vote = $vote->getSnippet()->getAverageVote();
  }
by Francois Zaninotto on 2006-05-20, tagged ajax  vote 

Comments on this snippet

gravatar icon
#1 Colin Williams on 2006-05-31 at 07:05

Just to make things easier for someone trying to replicate this, the schema for this table should look something like this, going along with the snippets theme:

<table name="votes" phpName="Vote"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="user_id" type="integer" /> <foreign-key foreignTable="users"> <reference local="user_id" foreign="id" /> </foreign-key> <column name="snippet_id" type="integer" /> <foreign-key foreignTable="snippets"> <reference local="snippet_id" foreign="id" /> </foreign-key> <column name="vote" type="integer" /> <column name="created_at" type="timestamp" /> </table>

And nice job with this... I'm in the process of adapting it for myself. :-)

gravatar icon
#2 tobias stanzel on 2006-06-13 at 05:27

if some one looking for the "function highlight_stars(id, note, do_highlight) { for (var i = 1 ; i <= note ; i++) { if(do_highlight) Element.addClassName($('vote_' + id + '' + i), 'ratehover'); else Element.removeClassName($('vote' + id + '_' + i), 'ratehover'); } }"

gravatar icon
#3 Francois Zaninotto on 2006-06-20 at 12:11

Or, with syntax highlighting:

function highlight_stars(id, note, do_highlight)
{
  for (var i = 1 ; i <= note ; i++)
  {
    if(do_highlight)
      Element.addClassName($('vote_'+id+'_'+i), 'ratehover');
    else
      Element.removeClassName($('vote_'+id+'_'+i), 'ratehover');
  }
}
gravatar icon
#4 excessive demon on 2007-10-09 at 04:42

u;re comment system is messy

gravatar icon
#5 Celso Andrade on 2007-10-11 at 09:13

nice snippet... thx

gravatar icon
#6 tentamen tentamen on 2008-05-03 at 05:43

thanks

You need to create an account or log in to post a comment or rate this snippet.