Плагин jquery не передает данные php обработчику через ajax запрос

337
21 февраля 2018, 09:53

Итак, имеем 5 файлов:

  1. 'main.php' (розмещение /page/main.php, отвечает за главную страницу сайта)
  2. 'randfilm.php' (розмещение /page/randfilm.php, отвечает за видачу информации о фильме на ajax запрос)
  3. 'footer.php' (розмещение /page/footer.php, отвечает за подключение всех java-скриптов и функций)
  4. 'jquery.rating-2.0.js' (розмещение /resourcse/js/jquery.rating-2.0.js, отвечает за визуальную обработку действий с формой рейтинга, и видачей числового значения результатов голосования)
  5. 'rating.php' (розмещение /rating.php, отвечает за обработку результата голосования виданую плагином, и внесения данных в БД)

Теперь собственно и сама проблема: Данные о фильме передаються на главную страницу посредством Ajax запроса к файлу 'randfilm.php', и выводятся посредством 'echo' в блоке 'rand-film'

Файл главной страницы

<php
  echo '
    <div class="catMenuRand">
      <form method="POST" id="find-rand" onsubmit="changeRand()" action="javascript:void(null);">
         <select size="1" name="randcat">
                        ...здесь перечень категорий...
         </select>
         <div class="catYear">
                        ...здесь инпуты вибора года...
         </div>
         <input type="submit" name="search" value="Знайти фільм">
       </form>
    </div><br>
        ';
    echo '<div id="rand-film" class="rand-film"> </div>';
?>

Файл 'randfilm.php'

    $Row = mysqli_fetch_assoc(mysqli_query($CONNECT, "SELECT * FROM `films` WHERE  `active` = 1 AND (`date` >= $_POST[rangeFor] AND `date` <= $_POST[rangeTo]) ORDER BY RAND() LIMIT 1"));
if ($Row) { 
    echo '
      <span class="rand-film-title"><a href="/material/film/id/'.$Row['id'].'">'.$Row['name'].'</a></span>
            <div class="rand-film-poster">
                <img src="/resource/poster/'.$Row['dir'].'/'.$Row['id'].'.jpeg">';
                if ($Row['original_name']) echo '<span style="color: #d8d8d8">Авторська назва: </span>'.$Row['original_name'].'<br>';
                echo '
                <span style="color: #d8d8d8">Жанр: </span>'.$category.'<br>
                <span style="color: #d8d8d8">Рік: </span>'.$Row['date'].'<br>
                <span style="color: #d8d8d8">Країна: </span>'.$Row['country'].'<br>
                <span style="color: #d8d8d8">Тривалість: </span>'.$Row['lenght'].' хв.<br>
                <span style="color: #d8d8d8">Режисер: </span>'.$Row['director'].'<br>
                <span style="color: #d8d8d8">В ролях: </span>'.$role.'<br>
                <div id="rating">
                    <input type="hidden" name="val" value="'.$Row['total_value'].'">
                    <input type="hidden" name="votes" value="'.$Row['total_votes'].'">
                    <input type="hidden" name="id" value="'.$Row['vote_id'].'">
                </div>
            </div>
            <span class="rand-film-description">'.$Row['description'].'</span>
    ';
}

Файл 'footer.php'

    <script type="text/javascript" src="/resource/js/jquery.rating-2.0.js"></script>
<script>
  function showRand() {
    $.ajax({
      url: "/page/randfilm.php",
      cache: false,
      success: function(html){
        $("#rand-film").html(html);
        $('#rating').rating({
          fx: 'half',
              image: '/resource/img/stars.png',
              loader: '/resource/img/ajax-loader.gif',
              minimal: 1,
          url: '/rating.php'
        });
      }
    });          
  }
  function changeRand() {
    var msg = $('#find-rand').serialize();
    $.ajax({
      type: 'POST',
      url: "/page/randfilm.php",
      data: msg,
      success: function(html) {
        $('#rand-film').html(html);
        $('#rating').rating({
          fx: 'half',
              image: '/resource/img/stars.png',
              loader: '/resource/img/ajax-loader.gif',
              minimal: 1,
          url: '/rating.php'
        });
      }
    });
  }
  $(document).ready(function(){
    showRand();
  });
</script>

Теперь объясняю почему 2 ajax-запроса к одному файлу:

  1. Первий вызов делаем при загрузке главной страници, и выводим любой случайний фильм.
  2. Второй вызов делаем когда пользователь фильтрует фильми по категории, и передаем дание из форми методом POST обработчику запроса

Также в обеих запросах присутствуем скрипт подключения плагина рейтинга. Сам рейтинг работает следующим образом: вместо блока #rating рисуються звезды, и когда пользователь кликает по какой-то из них - файл 'jquery.rating-2.0.js' обрабатывает действие, висчитывает числовое значение, и Ajax POST-запросом передает значение файлу-обработчику 'rating.php', которий уже вносит данные в БД, и после этого возвращает плагину json-ответ о результате обработки, после чего плагин оставляет нужное колличество звез закрашеными.

Файл 'jquery.rating-2.0.js'

    ;(function($){

    $.rating = function(e, o){
        this.options = $.extend({
            fx: 'half',
            image: '/resource/img/stars.png',
            stars: 10,
            minimal: 0,
            titles: ['голос','голоси','голосів'],
            readOnly: false,
            url: '/rating.php',
            type: 'post',
            loader: '/resource/img/ajax-loader.gif',            
            click: function(){},
            callback: function(){}
        }, o || {});
        this.el = $(e);
        this.left = 0;
        this.width = 0;
        this.height = 0;
        this._data = {};
        var self = this;
        this.el.find(':hidden').each(function(){
            var $this = $(this);
            self._data[$this.attr('name')] = $this.val();
        });
        this._data.val = parseFloat(this._data.val) || 0;
        this._data.votes = parseFloat(this._data.votes) || '';

        if(this._data.val > this.options.stars) this._data.val = this.options.stars;
        if(this._data.val < 0) this._data.val = 0;
        this.old = this._data.val;
        this.vote_wrap = $('<div class="vote-wrap"></div>');
        this.vote_block = $('<div class="vote-block"></div>');
        this.vote_hover = $('<div class="vote-hover"></div>');
        this.vote_stars = $('<div class="vote-stars"></div>');
        this.vote_active = $('<div class="vote-active"></div>');
        this.vote_result = $('<div class="vote-result"></div>');
        this.vote_success = $('<div class="vote-success"></div>');
        this.loader = $('<img src="'+this.options.loader+'" alt="load...">');
        this.el.html(this.loader);
        //Загружаем изображение звезд и высчитываем ширину и высоту одной звезды
        var img = new Image();
        img.src = this.options.image;
        img.onload = function() {
            self.width = this.width; //Ширина одной звезды
            self.height = this.height/3; //Высота одной звезды
            self.init();
        };
    };

    var $r = $.rating;
    $r.fn = $r.prototype = {
        rating: '2.0'
    };
    $r.fn.extend = $r.extend = $.extend;
    $r.fn.extend({
        init: function(){
            this.render();
            if(this.options.readOnly) return;
            var self = this, left = 0, width = 0;
            this.vote_hover.bind('mousemove mouseover',function(e){
                if(self.options.readOnly) return;
                var $this = $(this),
                    score = 0;
                left = e.clientX>0 ? e.clientX: e.pageX;
                width = left - $this.offset().left - 2;
                var max = self.width*self.options.stars,
                    min = self.options.minimal*self.width;
                if(width > max) width = max;
                if(width < min) width = min;   
                score = Math.round( width/self.width * 10 ) / 10; //округляем до 1 знака после запятой
                if(self.options.fx == 'half'){
                    width = Math.ceil(width/self.width*2)*self.width/2;          
                }
                else if(self.options.fx != 'float'){                    
                    width = Math.ceil(width/self.width) * self.width;  
                }
                score = Math.round( width/self.width * 10 ) / 10; 
                self.vote_active.css({
                    'width':width,
                    'background-position':'left center'
                });
                self.vote_success.html('Ваша оцінка: '+score);
             })
             .bind('mouseout',function(){
                if(self.options.readOnly) return; 
                self.reset();
                self.vote_success.empty();
             }).
             bind('click.rating',function(){
                 if(self.options.readOnly) return;
                 var score = Math.round( width/self.width * 10 ) / 10; 
                 if(score > self.options.stars) score = self.options.stars;
                 if(score < 0) score = 0;
                 self.old = self._data.val;
                 self._data.val = (self._data.val*self._data.votes +score)/(self._data.votes + 1);
                 self._data.val = Math.round( self._data.val * 100 ) / 100;
                 self._data.score = score;
                 self.vote_success.html('Ваша оцінка: '+score);
                 if(self.options.url != ''){
                     self.send();
                 }
                 self.options.readOnly = true;        
                 self.options.click.apply(this,[score]);
             });
        },
        set: function(){
            this.vote_active.css({
                'width':this._data.val*this.width,
                'background-position':'left bottom'
            });
        },
        reset: function(){
            this.vote_active.css({
                'width':this.old*this.width,
                'background-position':'left bottom'
            });
        },
        setvoters: function(){
            this.vote_result.html(this.declOfNum(this._data.votes));  
        },
        render: function(){
            this.el.html(this.vote_wrap.append(
                this.vote_hover.css({
                    padding:'0 4px',
                    height:this.height,
                    width:this.width*this.options.stars
                }),
                this.vote_result.text(this.declOfNum(this._data.votes)),
                this.vote_success
            ));

            this.vote_block.append(
                this.vote_stars.css({
                    height:this.height,
                    width:this.width*this.options.stars,
                    background:"url('"+this.options.image+"') left top"
                }),
                this.vote_active.css({
                    height:this.height,
                    width:this._data.val*this.width,
                    background:"url('"+this.options.image+"') left bottom"
                })
            ).appendTo(this.vote_hover);
        },
        send: function(score){
            var self = this;
            this.vote_result.html(this.loader);
            this._data.votes++;
            $.ajax({
                url: self.options.url,
                type: self.options.type,
                data: this._data,
                dataType: 'json',
                success: function(data){
                    if(data.status == 'OK') {
                      self.set();
                    }  
                    else{
                        self._data.votes--;
                        self.reset();
                    }      
                    self.setvoters();
                    if(data.msg)self.vote_success.html(data.msg);
                    if(typeof self.options.callback == 'function'){
                        self.options.callback.apply(self,[data]);
                    }
                }
            });
        },
        declOfNum: function(number){  
            if(number <= 0) return '';
            number = Math.abs(Math.floor(number));
            cases = [2, 0, 1, 1, 1, 2];  
            return number+' '+ this.options.titles[ (number%100>4 && number%100<20)? 2 : cases[(number%10<5)?number%10:5] ];  
        }  
    });

    $.fn.rating = function(o){
        if (typeof o == 'string') {
            var instance = $(this).data('rating'), args = Array.prototype.slice.call(arguments, 1);
            return instance[o].apply(instance, args);
        } else {
            return this.each(function() {
                var instance = $(this).data('rating');
                if (instance) {
                    if (o) {
                        $.extend(instance.options, o);
                    }
                    instance.init();
                } else {
                    $(this).data('rating', new $r(this, o));
                }
            });
        }
    }; 
})(jQuery);

Файл 'rating.php'

<?php 
if ($_POST['score'] and $_POST['vote_id']) {
    $Row = mysqli_fetch_assoc(mysqli_query($CONNECT, "SELECT * FROM `films` WHERE `id` = $_POST[vote_id]"));
    $used_id = explode(", ", $Row['used_id']);
    if ($_SESSION['USER_LOGIN_IN'] == 1) $id = $_SESSION['USER_ID'];
    $used_ips = explode(" | ", $Row['used_ips']);
    $ip = $_SERVER['REMOTE_ADDR'];
    if (array_search($ip, $used_ips) or array_search($id, $used_id)) {
        $data['status'] = 'ERR';
        $data['msg'] = 'Ви вже проголосували.';
    }
    else {
        $new_total_value = ($Row['total_value'] * $Row['total_votes'] + $_POST['score'])/($Row['total_votes'] + 1);
        $new_total_votes = $Row['total_votes'] + 1;
        array_push($used_ips, $ip);
        $used_ips = implode(' | ', $used_ips);
        if ($_SESSION['USER_LOGIN_IN'] == 1) array_push($used_id, $id);
        $used_id = implode(' | ', $used_id);
        mysqli_query($CONNECT, "UPDATE `films` SET `total_value` = $new_total_value, `total_votes` = $new_total_votes, `used_ips` = '$used_ips', `used_id` = '$used_id' WHERE id = $_POST[vote_id]");
        $data['status'] = 'OK';
        $data['msg'] = 'Дякуємо. Ваш голос враховано.';
    }
}
else {
    $data['status'] = 'ERR';
    $data['msg'] = 'Ви не передали дані.';
}
echo json_encode($data);
?>

Так вот, дело в том что данние файлу-бработчику почему-то не передаються (он возвращает ответ "status":ERR; "msg":Ви не передали дані.) когда все построено именно так, !НО если вывод данных о фильме делать не через Ajax запрос к файлу 'randfilm.php', а напрямую из файла главной страницы, то рейтинг работает как надо.

Может кто нибуть помочь разобраться почему так, может быть я както не верно Ajax-запроси составил, или они конфликтуют между собой :((

Answer 1

Доброго времени суток.

Попробуйте использовать вместо id (#rating) class, id должен быть уникальным на странице. Cелектор должен указывать на конкретный элемент, чтобы на один и тот же элемент повторно не инициализировался плагин, поэтому нужно указать контекст или родительский class / id.

Например $('#rand-film .rating').rating(...);

Либо

var $c = $('#rand-film');
$c.html(html);
$('.rating', $c).rating(...);
READ ALSO
остановить скипт php из ajax

остановить скипт php из ajax

реализую progress-bar выполнения скрипта в пхпПо кнопке старт запускаю скрипт пхп аяксом и получаю данные о прогрессе

270
Глючит текстовый input с jQuery маской

Глючит текстовый input с jQuery маской

Сделал на сайте форму быстрого заказа, в которой для поля "телефон" приделал маску с помощью jQueryПроблема вот в чём: с мобильных устройств поле...

249
Как получить значение поля input из другого файла?

Как получить значение поля input из другого файла?

Значение второго input'a подтягивается в файл ajax, не знаю как, в переменную idА вот значение input type="text" name="name" id="textfield2" class="input-xlarge" data-rule-required="true"...

252