I am trying to change the default behavior of a Magento Reviews extension such that it will allow a no-vote but only if there is a review attached. I have done enough research to know where to change the code, and I have added a "Cancel Rating" function, but it isn't working exactly as expected, and I can't seem to figure out how to check if a rating is present.
Here is the HTML part where the radios are defined.
<div class="right" id="ratings-right">
<?php $countRatings = count($this->getRatings()); ?>
<?php foreach ($this->getRatings() as $_rating): ?>
<?php if ( $countRatings > 1 ): ?>
<div class="rating-code" id="ratings-code[<?php echo $_rating->getRatingCode(); ?>]"</div>
<?php endif; ?>
<ul>
<?php $sizeOptions = sizeof($_rating->getOptions()); $index=0; ?>
<li class="value">
<div class="rating-cancel"></div>
<input type="radio" value="0" name="cancel[<?php echo $_rating->getId() ?>]" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>C<?php echo $_rating->getId() ?>" class="radio" /></li>
<?php foreach ($_rating->getOptions() as $_option): $index++;?>
<li class="value">
<div class="separate-rating-star"></div>
<input type="radio" <?php if ( $sizeOptions == $index ) :?><?php endif; ?>name="ratings[<?php echo $_rating->getId() ?>]" id="<?php echo $this->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $_option->getValue() ?>" value="<?php echo $_option->getId() ?>" class="radio" />
</li>
<?php endforeach; ?>
</ul>
<?php endforeach; ?>
<input type="hidden" name="validate_rating" class="validate-rating" value="" />
</div>
And here is the JavaScript portion where validation and resetting occur
Validation.addAllThese(
[
['validate-rating', '<?php echo $this->__('Please select a rating above OR write your Review below') ?>', function(v) {
var ratingContainer = document.getElementById('ratings-right');
var ratings = ratingContainer.getElementsByClassName('rating-code');
var values;
var star;
var error = 1;
window.console&&console.log("START");
for (r=0;r < ratings.length; r++ ) {
values = ratings.getElementsByClassName('value');
stars = values.getElementsByTagName('radio');
for (s=0; s < stars.length; s++ ) {
console.log("Checking star %d.", s);
if (stars[s].checked == true) {
error = 0;
window.console&&console.log("Radio %d is checked.\n", s);
}
}
var review = $('review_field').length;
window.console&&console.log("Review size %d.", review);
if ( review > 5 ) {
error = 0;
window.console&&console.log("Review size (%d) greater than 5.", review);
}
if( error != 0 ) {
window.console&&console.log("Failed.\n");
return false;
} else {
window.console&&console.log("Passed.\n");
error = 1;
}
}
return true;
}]
]
);
$(".overall-raiting ul li").click(
function(){
var tthis = this;
var done = 0;
var $li = $(tthis).parent().children('li');
$li.removeClass('active');
$li.each(function(){
if( done < 1 ) $(this).addClass('active');
if ( tthis == this ) done++;
if( done != 1 ) $(this).prop('checked', false);
})
if ( done > 0 ) return false;
$(this).find('input.radio').attr('checked',true);
}
);
I can't get the console to consistently report values despite reading questions here about using the delete window['console'];
method in firefox with firebug and Chrome. But it appears that my .onclick function is changing all radios to unchecked, including the one that should be checked. And as near as I can tell I am not selecting the radios in the validation portion, I've tried using the .val() and .value properties, but this code is my most recent attempt.
All I want is the radio that is clicked to stay checked with all others unchecked and to validate by determining if any is checked (including the cancel) OR if the textarea 'review_field' contains anything.
My final answer is provided below. It is more elegant than my first solution, but I hope this helps someone in the future.