Задать вопрос
@inkkei

Почему не работает рейтинг Yii2?

Мне нужно сделать звездный рейтинг на сайте для оценки книги. Т.к. я новичок в yii2, я нашел решение в интернете. Оно состоит в использование этого виджета: demos.krajee.com/widget-details/star-rating

Сам виджет со звездочками выводится, однако при клике ничего не происходит. Помогите пожалуйста в какую сторону двигаться и как найти решение.

Я создал модель :
spoiler
class Raits extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
        return 'raits';
    }

    public function rules()
    {
        return [
            [['book_id', 'user_id', 'rateNum'], 'safe'],
            [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']],
            [['book_id'], 'exist', 'skipOnError' => true, 'targetClass' => Book::className(), 'targetAttribute' => ['book_id' => 'id']],
        ];
    }

    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'book_id' => 'Book ID',
            'user_id' => 'User ID',
            'rateNum' => 'Rate Num',
        ];
    }


    public function behaviors()
    {
        return [
            'blameable' => [
                'class' => BlameableBehavior::className(),//устанавливаем id юзера
                'createdByAttribute' => 'user_d',
                'updatedByAttribute' => null,
            ],
        ];
    }


    
    public function getUser()
    {
        return $this->hasOne(User::className(), ['id' => 'user_id']);
    }

    
    public function getBook()
    {
        return $this->hasOne(Book::className(), ['id' => 'book_id']);
    }
}


Мой action, выводящий конкретную книга:
spoiler
public function actionOne($id)
    {
        $book = Book::findOne(['id' => $id]);
        if (Yii::$app->request->isPost && Yii::$app->request->isAjax && Yii::$app->request->post('rait')){

            $rait = Yii::$app->request->post('rait');//оценка пользователя
            $res = [];
            if(!Yii::$app->user->isGuest){
                //есть ли запись о голосовании на материале у данного пользователя
                $userRaits = Raits::find()
                    ->andWhere(['book_id' => $id])
                    ->count();

                //если пользователь уже голосовал выводим сообщение и далее не выполняем
                if($userRaits){
                    $res['message'] = 'Этот голос не учитывается. Вы уже проголосовали ранее...';
                    return json_encode($res, JSON_NUMERIC_CHECK);
                }

                //Если новый голос пользователя, записываем в бд
                $newRait = new Raits();
                $newRait->book_id = $id;
                $newRait->rateNum = $rait;
                $newRait->save();

                /**
                 * Вычисляем общий рейтинг с учетом изменений
                 */
                //выбираем все голоса по данной записи
                $allRaits = Raits::find()->where(['book_id' => $id])
                    ->select('rateNum');

                $allUsers = $allRaits->count();//сумма всех учетных записей пользователей к дан. материалу (1а запись - 1 пользователь)
                $sumVotes = $allRaits->sum('rateNum');//сумма всех оценок пользователей к дан. материалу

                $totalRating = round($sumVotes / $allUsers, 2);// округляем до сотых

                //записываем вычесленный рейтинг в таблицу книги в поле rating
                $inst = Book::findOne($id);
                $inst->rating = $totalRating;
                $inst->ratingVotes = $allUsers;
                $inst->save();

                //возвращаем новый рейтинг в вид
                $res['rating'] = $inst->rating;//передаем вычесленный рейтинг по материалу
                $res['ratingVotes'] = $inst->ratingVotes;//передаем сумму всех голосов по материалу

                return json_encode($res, JSON_NUMERIC_CHECK);
            }

        }

        $countComments = Comments::countComments($id);

        return $this->render('one', ['book' => $book, 'countComments' => $countComments]);

    }


И, файл вида:
spoiler
<?php //echo $institution->rating;

echo StarRating::widget([
    'name' => 'rating_1',
    'model' => $book,
    'attribute' => 'rating',
    //'value' => 3,
    'pluginOptions' => [
         //'displayOnly' => true,//звезды только для показа, но не активны
        'theme' => 'krajee-svg',
        'stars' => 5,
        'step' => 1,
        'min' => 0,
        'max' => 5,
        'showClear' => false,// (знак "кирпич")
        'showCaption' => true,//без подписи количества выбранных
        'size' => 's',//mili
        'defaultCaption' => 'оценка {rating}',
        'starCaptions' => [
            0 => 'Extremely Poor',
            1 => 'оценка 1',
            2 => 'оценка 2',
            3 => 'оценка 3',
            4 => 'оценка 4',
            5 => 'оценка 5',

        ],
    ],
    'pluginEvents' => [
        //когда кликаем на звезды всплывает это событие, которое и обробатываем
        'rating.change' => "function(event, value, caption) {
            $.ajax({
                type: 'POST',
                url: '".Url::to("book/one")."',//адрес контроллера и экшена. Так как вид вызван из того же экшена, что и обработка этого запроса, тооставляем пустым или пишем - controller/action
                data: {'rait': value},// value - число выбранных звезд
                cache: false,
                success: function(data) {
                    var data = jQuery.parseJSON(data);//конвертируем json обьект, что передаем из php  в обьект jquery
                    var inputRating = $('#book-rating');

                        if (typeof data.message !== 'undefined') {
                            console.log(data.message);
                            inputRating.rating('reset');//очищает рейтинг до значения в бд

                            $('#myModal-geo .modal-body strong').text(data.message);//забиваем сообщение в модальное окно
                            $('#myModal-geo').modal();//вызываем виджет модального окна

                        }else{

                            $('#numRait').text(data.rating);//обновляем цыфры рейтинга в тегах на странице
                            $('#numVotes').text(data.ratingVotes);//обновляем цыфры кол-ва голосов в тегах на странице
                            inputRating.rating('refresh', {disabled: true, showClear: false, showCaption: true});//добавляет рейтинг и блокирует повторное нажатие
                        }

                    }
                });



            }",

    ],
]);
?>
  • Вопрос задан
  • 129 просмотров
Подписаться 1 Простой 5 комментариев
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы