1 of 2
1
jQuery function to handle Rating Submittal
Posted: 02 June 2008 03:32 PM   [ Ignore ]
Newbie
Rank
Total Posts:  3
Joined  2008-06-02

I’ve been able to get the Ratings module/extension installed and working, but showing the drop down options and a submit button isn’t very appealing.

I’d really like to use the CSS Star Rating Redux for the star ratings on a site, but that is only part of the puzzle.  Does anyone have the javascript (using jQuery) that can handle the rating form submittal?

Or if there is another method that works better I’d love to hear it. 

If someone could provide some help/insight I would greatly appreciate it!

Cheers!

Profile
 
 
Posted: 03 June 2008 07:39 AM   [ Ignore ]   [ # 1 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  3356
Joined  2006-10-18

Adam,

Here’s a link to AJAX submittal of Stars:

http://www.solspace.com/forums/viewthread/606/

 Signature 
Profile
 
 
Posted: 16 June 2008 05:20 PM   [ Ignore ]   [ # 2 ]
Jr. Member
RankRank
Total Posts:  32
Joined  2007-03-17

I thought I would throw my hat in on this one.... A method I have been using is not that simple but it seems to do everything that i need it too.

Firstly it requires that your template allows php and your user has javascript enabled. Basically the idea is that the code checks to see if a registered member has voted before or if a non-registered visitor has voted before using cookies.

So here’s the template code.

{exp:weblog:entries
weblog
="gallery"
disable="categories|category_fields|member_data|pagination|trackbacks"
rdf='off'
}

{
!-- Set some defaults for the rating. --}
<?php $overallCount
= 0; $overallSum = 0; $overallAvg = 0; ?>

{
!-- Nothing will be rendered if there has been no ratings so our default values will stick --}
{exp
:rating:stats
entry_id
="{entry_id}"
precision = "2"
}

{
!-- If the profile has been rated update the default values --}
<?php
$overallCount
= {overall_count};
$overallSum = {overall_sum};
$overallAvg = {overall_avg};
?>
{
/exp:rating:stats}

<p id="stats-for-{entry_id}" class="stats">
Average Rating: <strong class="overall_avg"><?php print($overallAvg); ?></strong>/<span class="max_rating">5</span>
(<
span class="overall_sum"><?php print($overallSum); ?></span> of a possible <span class="max_overall_sum"><?php print($overallCount * 5); ?></span> stars)
based on <span class="overall_count"><?php print($overallCount); ?></span> votes.
</
p>

{!-- Render the form --}
{exp
:rating:form
entry_id
="{entry_id}"
form_name="Hot or Not"
class="profile-rating"
form_id="profile-rating-{entry_id}"
allow_duplicates="no"
return="{permalink="gallery/rate"}{url_title}"
anonymous="no"
require_membership="no"
}

{
!-- If the user has rated this before we can just render the finished stars in a UL. Not semantically correct but who really cares. --}
<div id="submission-status-for-{entry_id}">You have already rated this hairstyle. <a href='{permalink="hot-or-not/rate"}{url_title}'>Show me another!</a></div>

{!-- This tests for the rating module duplicate for logged in members --}
{if duplicate}
<ul class="star-rating">
  <
li class="current-rating" style="width:<?php print($overallSum / ($overallCount * 5) * 100 ); ?>%" > Currently <?php print($overallAvg); ?>/5 Stars.</li>
</
ul>
{!-- This may still be a duplicate so we need to check our cookies --}
{if
:else}
<fieldset>
<
input type="hidden" name="name" value="{screen_name}" />
<
input type="hidden" name="email" value="{email}" />
<
div class="star-rating" id="rating-{entry_id}">
  <
label for="review" class="avg">Rate this profile:</label>
  <
select name="rating" id="review">
  <
option value="1">1</option>
  <
option value="2">2</option>
  <
option value="3">3</option>
  <
option value="4">4</option>
  <
option value="5">5</option>
  </
select>
</
div>
</
fieldset>
<
input type="submit" name="submit" value="Submit" />
{/if}

{
/exp:rating:form}

<p class="photo"><a href='{permalink="hot-or-not/rate"}{url_title}'><img src="path/to/image" /></a></p>

{/exp:weblog:entries}

 Signature 

Newism - Newcastle Web Design & Development

LG Better Meta now w/ Sitemap Meta & XML Generator | LG Polls | LG .htaccess Generator | LG TinyMCE | LG Twitter


More EE Extensions & Modules 20+

Profile
 
 
Posted: 16 June 2008 05:21 PM   [ Ignore ]   [ # 3 ]
Jr. Member
RankRank
Total Posts:  32
Joined  2007-03-17

The jquery:

(function( $ ) {
  
$.fn.Rater = function(settings) {

settings
= $.extend({
   ratingContSelector
:    "div.star-rating",
   
ratingContPrefix:    "rating-",
   
ratingStatsContPrefix:   "stats-for-"
}, settings);

// return each of the submitted forms
return this.each(function(){
   
   
var theForm =    this,      // the form
  
theRatingConts =  $(settings.ratingContSelector, theForm), // the containers holding the select rating elements
  
ratedForms = $.cookie("exp_rating-" + $(theForm).attr("name")),  // the existing cookie
  
rated =    $(theForm).is(".rated") ? true : false   // everything is unrated by default

   
console.log("Cookie: " + ratedForms);

   
// if there is a cookie
   
if(ratedForms && !rated){
  
// match the current form.id and the users rating to the cookie string
  
matchRegExp = new RegExp("(("+theForm.id+"):([1-5]))");
  
rated = matchRegExp.exec(ratedForms);
   
}

   
// log the form status
   
console.log("Form ID: " + theForm.id +" has "+ ((rated)?"been rated":"NOT been rated"));

   $(
settings.ratingContSelector, theForm).each(function(){

  
var theRatingCont =   $(this),    // The container that holds the select and the rating stats
    
theRater =   $("select", theRatingCont).get(0), // The rating select box
    
theRaterOpts = $("option", theRater),    // The rating options
    
    
theRaterEntryId =   this.id.replace(settings.ratingContPrefix, ""),
    
    
theStats =   $("#" + settings.ratingStatsContPrefix + theRaterEntryId),
    
overallCountEl =  $(".overall_count", theStats),   // The number of ratings
    
overallAvgEl = $(".overall_avg", theStats),   // The average rating
    
overallSumEl = $(".overall_sum", theStats),   // The sum of all the ratings
    
maxOverallSumEl =   $(".max_overall_sum", theStats), // The maximum sum of all the ratings
   
    
overallCount = parseFloat(overallCountEl.html()), // The number of ratings
    
overallAvg = parseFloat(overallAvgEl.html()), // The average rating
    
overallSum = parseFloat(overallSumEl.html()), // The sum of all the ratings
    
maxRating =  theRaterOpts.length,    // The maximum rating
    
maxOverallSum =   maxRating * overallCount;    // The maximum sum of all the ratings

  
console.log(theRatingCont);
  
console.log("Rating Entry: " + theRaterEntryId);
  
console.log("Searching For Sats Container... " + settings.ratingStatsContPrefix + theRaterEntryId);
  
console.log("Stats: ");
  
console.log(theStats);

  
// create a new UL star rating container
  
var starRater = $("<ul></ul>")
    .
insertBefore(theRater)
    .
hide()
    .
addClass(this.className)
    .
fadeIn("slow")
    .
mouseover(function(){
   
$("a.active", this).removeClass("active");
    
});

  
// create and append the current rating list item
  
if(overallCount != 0){
    
var currentRating = $("<li class='current-rating' style='width:" + (overallSum / maxOverallSum) * 100 + "%;'> Currently " + overallAvg + "/" + maxRating + " Stars.</li>");
  
}
  
else
  
{
    
var currentRating = $("<li class='current-rating' style='width:0%;'>Unrated!</li>");
  
}
  starRater
.append(currentRating);

  if(!
rated){
    
// create and append the rating anchors
    
theRaterOpts.each(function(i){
   starRater
.append("<li class='star-" + ( i + 1 ) + "'><a href='#' title='Give it a " + this.value + " Star Rating'>" + this.value + "</a></li>");
    
});
  
} else {
    
$("#submission-status-for-" + theRaterEntryId).show();
  
}

  
$("a", starRater).click(function(){
    
// set the anchor to active
    
$(this).addClass("active").blur();
    
// Get the clicked elements rating
    
var rating = parseFloat($(this).html());
    
// update the select element with the new value
    
theRater.selectedIndex = rating - 1;
    
    
// Get the latest cookie
    
var ratedForms = $.cookie("exp_rating-" + $(theForm).attr("name")); // the existing cookie

    // if there is not a cookie
    
if(!ratedForms){
   ratedForms
= "|";
    
}

    
// Add the new form id and the rating to the front of the cookie
    // |theForm.id:rating|theForm.id:rating|
    
$.cookie("exp_rating-" + $(theForm).attr("name"), ratedForms + theForm.id + ":" + rating + "|", {path: "/", expires: 365});
    
    
// remove the mouseover event on the UL
    
$(starRater).unbind("mouseover");

    
// remove all the star links that are not active
    
$("li a:not(.active)", starRater).parent().remove();

    
// Update Stats for this rating
    
overallCount++;
    
overallSum += rating;
    
maxOverallSum = overallCount * maxRating;
  
    
overallCountEl.html(overallCount);
    
overallSumEl.html(overallSum);
    
maxOverallSumEl.html(maxOverallSum);
    
overallAvgEl.html( ((overallSum / maxOverallSum ) * maxRating).toFixed(2) );

    
currentRating.css({ "width": (overallSum / maxOverallSum ) * 100 + "%" });

    $(
'input[type=submit]', theForm).click();

    return
false;
  
});
   
});

   
// add classes to the form
   
$(theForm).addClass("has-rateables" +
  
// auto-submit or button-submit
  
((settings.autoSubmit)?" auto-submit":" button-submit") +
  
// submitted or not-submitted
  
((rated)?" submitted":" not-submitted")
   );
});
  
}
}
)(jQuery);

 Signature 

Newism - Newcastle Web Design & Development

LG Better Meta now w/ Sitemap Meta & XML Generator | LG Polls | LG .htaccess Generator | LG TinyMCE | LG Twitter


More EE Extensions & Modules 20+

Profile
 
 
Posted: 16 June 2008 05:24 PM   [ Ignore ]   [ # 4 ]
Jr. Member
RankRank
Total Posts:  32
Joined  2007-03-17

Of course you will need to call the plugin with something like:

$("form.profile-rating").Rater();

And you will probably need some css as well:

form.profile-rating fieldset{border: none; margin: 0; padding: 0;}
form
.profile-rating legend,
form.profile-rating select,
form.profile-rating input[type=submit],
form.profile-rating label{display: none;}

ul
.star-rating{
  background
:url(../images/nsm_rating_stars.png) 0 -16px;
  
height:16px;
  list-
style-type:none;
  
margin:5px auto 7px auto;
  
overflow:hidden;
  
padding:0;
  
position:relative;
  
width:80px;
}
.not-submitted ul.star-rating{margin-bottom: 9px;}

ul
.star-rating li{
  left
:0;
  
margin:0;
  
padding:0;
  
position:absolute;
  
top:0;
}

ul
.star-rating a,
ul.star-rating li{
  background
:url(../images/nsm_rating_stars.png);
  
display:block;
  
text-indent:-999em;
  
width:100%;
}
ul
.star-rating a{background-position:left top;}
ul
.star-rating a:hover,
ul.star-rating a.active{background-position:0 -32px;}
ul
.star-rating .current-rating{background-position: 0 -48px; text-indent:-999em; z-index:1; }
ul
.star-rating li.star-1{ width:20%; z-index:6; }
ul
.star-rating li.star-2{ width:40%; z-index:5; }
ul
.star-rating li.star-3{ width:60%; z-index:4; }
ul
.star-rating li.star-4{ width:80%; z-index:3; }
ul
.star-rating li.star-5{ width:100%; z-index:2; }

So like I said its fairly complicated but it does the job once you understand it all.

I would love to see some kind of cookie / IP checking for duplicates in the next version of the Rating module.

 Signature 

Newism - Newcastle Web Design & Development

LG Better Meta now w/ Sitemap Meta & XML Generator | LG Polls | LG .htaccess Generator | LG TinyMCE | LG Twitter


More EE Extensions & Modules 20+

Profile
 
 
Posted: 24 June 2008 09:01 PM   [ Ignore ]   [ # 5 ]
Sr. Member
RankRankRankRank
Total Posts:  153
Joined  2007-02-19

I think I’ll give that a try Leevi. So it basically just creates the usual 5 star rating system where all the user has to do is click on a star to rate an entry?

Profile
 
 
Posted: 24 June 2008 09:05 PM   [ Ignore ]   [ # 6 ]
Jr. Member
RankRank
Total Posts:  32
Joined  2007-03-17

yep… basically thats it.. but it also uses jquery to update the element on the fly as soon as the form is submitted… obviously making the update seem instant to the user.

 Signature 

Newism - Newcastle Web Design & Development

LG Better Meta now w/ Sitemap Meta & XML Generator | LG Polls | LG .htaccess Generator | LG TinyMCE | LG Twitter


More EE Extensions & Modules 20+

Profile
 
 
Posted: 24 June 2008 09:13 PM   [ Ignore ]   [ # 7 ]
Sr. Member
RankRankRankRank
Total Posts:  153
Joined  2007-02-19

Nice! Thanks!

Profile
 
 
Posted: 17 July 2008 06:08 PM   [ Ignore ]   [ # 8 ]
Sr. Member
RankRankRankRank
Total Posts:  153
Joined  2007-02-19

Hey Leevi,

I haven’t had the chance to try this yet, but had another question. I know you said it checks to see if the user has voted before based on a cookie. Do you think this approach is better than checking an for an IP address? I’m not familiar enough with these two methods of checking for duplicate votes, but I would assume a cookie would be the lesser of the two ways since a user would just have to clear cookies and then vote again?

Profile
 
 
Posted: 18 July 2008 03:24 PM   [ Ignore ]   [ # 9 ]
Newbie
Rank
Total Posts:  4
Joined  2005-05-05

I’m not Leevi wink , but I can share our experiences with IP vs. cookie based limiting of votings and else: Both techniques have different advantages and disadvantages and it depends on your needs what is best suited for you and your users. IP based limitation is strictly server based: each and every computer in an intranet that uses a router to access the web might be logged out so, because they all share the same external IP address, while dial-in users often can simple change the associated IP address by disconnecting and then reconnecting to their ISP. Cookies are client based - checking for a cookie blocks one particular browser/user/pc combo, so changing the browser, logging in as another user or deleting the the cookie allows to overwrite the blocking. So, none of the techniques is failproof - best would be to only allow registered and logged-in members to rate entries - then, the vote would be tied to the user account. But of course, that is not always desirable.

Markus

Profile
 
 
Posted: 18 July 2008 07:22 PM   [ Ignore ]   [ # 10 ]
Sr. Member
RankRankRankRank
Total Posts:  153
Joined  2007-02-19

Thanks for the information Markus. Like you said, look like either way you go about it, it’s not fool proof, so it really isn’t is a huge decision. wink

Profile
 
 
Posted: 08 August 2008 06:49 AM   [ Ignore ]   [ # 11 ]
Jr. Member
RankRank
Total Posts:  33
Joined  2008-04-14

In Leevi’s example where do I put this code.

$("form.profile-rating").Rater();

I’m not very php savvy and I’m not sure where or how to “call the plugin” using this code.

Thanks for any help.