使用HTML单选按钮和javascript进行评级


Ratings using HTML radio buttons and javascript

我试图改变Magento评论扩展的默认行为,这样它将允许不投票,但只有当有评论附加。我已经做了足够的研究,知道在哪里修改代码,我已经添加了一个"取消评级"功能,但它并没有像预期的那样工作,我似乎不知道如何检查评级是否存在。

这里是定义无线电的HTML部分。

<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>

这里是验证和重置发生的JavaScript部分

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);
        }
    );

我无法让控制台一致地报告值,尽管在这里阅读有关在firefox与firebug和Chrome中使用delete window['console'];方法的问题。但是,我的。onclick函数似乎将所有收音机都更改为未检查,包括应该检查的收音机。就我所知,我没有在验证部分选择无线电,我尝试使用。val()和。value属性,但这段代码是我最近的尝试。

所有我想要的是单选,点击保持检查与所有其他未选中,并确定是否有任何被选中(包括取消)或如果文本区域'review_field'包含任何验证。

我的最终答案如下。它比我的第一个解决方案更优雅,但我希望这对将来的人有所帮助。

根据你想做什么

所有其他未选中,并通过确定是否有选中(包括取消)或文本区域'review_field'是否包含任何内容来验证

这个函数可能有帮助:

function isValidForm() {
   var numRadios = $('#ratings-right input:radio:checked').length,
       reviewContents = $('#review_field').val(),
       isValid = numRadios == 1 || reviewContents != '';
   return isValid;
}

首先,我的Javascript日志问题解决了这个问题的答案:Javascript控制台日志在Magento

jQuery(document).ready(function(){
   window.console = jQuery('<iframe>').hide().appendTo('body')[0].contentWindow.console;
});

这显然只适用于使用jQuery。

我的问题的其余部分通过bbird代码的一个变体的实现来解决:

var rated = 0;
var ratingValue = $('#ratings-right input:radio:checked');
var reviewArea = $('#review_field');
var reviewContents = "";
for (i=0; i<reviewArea.length; i++) {
    reviewContents += reviewArea[i].value;
    }
for (i=0; i<ratingValue.length; i++) {
    if (ratingValue[i].value.length == 1 )
    rated = 1;
    }
console.log("%s", rated);
console.log("%s", reviewContents);
var isValid = rated > 0 || reviewContents != '';
console.log("%s", isValid);
return isValid;

对于单选按钮本身,在Magento的数据库中,我添加了一个零星值,optionId为99999。该评级首先显示在评级选项中,为此,我在控制器中检查小于9999的值。这确保了零星级评分不会被计算到聚合中。

这也允许所有单选按钮具有相同的类和名称,因此不再需要通过编程取消选中任何内容。单选按钮的默认行为是只允许在具有相同名称的组中选中一个单选按钮。

现在是单选按钮的实现:

<div <?php if ($_option->getValue() == "0" ) echo "class='"rating-cancel'""; else echo "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" />

这样,第一个选项(值为0)可以用css样式化为某种形式的取消按钮,其余的将是星号。