Hovik Han
Hovik Han

Reputation: 64

When calling jQuery plugin function, the first time call successfully, but run again, call failed

I am developing a webpage and using a third party jQuery plugins called star-rank. when I first call the function rating to draw stars, it works.

In my scenario, I need to call it in the onclick method of a paging plug-in. When the user clicks on a different page number, the comment area is redrawn. Oddly, however, when the page first loads, the method to draw the star ratings is called successfully.

enter image description here

But when you click on the page number, the page reports an error, saying "Uncaught TypeError: $(...).rating is not a function "; But I'm sure that in both the initial and click phases, it's calling the code in onPageClick. I looked at the console and found that the first time I initialized it, there was a rating method in prototype in $('.star-show'), but when I call onPageClick, and check the object $('.star-show'),there is no rating method in the prototype. enter image description here enter image description here photo 2 enter image description here

third-party plugins: https://github.com/kartik-v/bootstrap-star-rating https://github.com/josecebe/twbs-pagination

My page has loaded the required js and css files, as shown below: enter image description here

<!-- Main Style Sheet -->
<link rel="stylesheet" href="../../static/css/bootstrap3/bootstrap.css">
<link rel="stylesheet" href="../../static/css/like.css">
<link rel="stylesheet" href="../../static/css/star-rating/star-rating.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="../../static/js/pagination/jquery.twbsPagination.js"></script>
<script src="../../static/js/star-rating/star-rating.js"></script>
<script src="../../static/js/bootstrap3/bootstrap.js"></script>

<script>
var currentPage = 1;
var totalPage = 5;
var visiblePageNum = 2;
var totalComments = {...}


$('#pagination').twbsPagination({
    totalPages: totalPage,
    visiblePages: visiblePageNum,
    onPageClick: function (event, page) {
        currentPage = page;
        $("#comment-list").empty();
        drawCommentCards(totalComments);
    }
});


function drawCommentCards(datas) {
    console.log("function drawCommentCards: currentpage: " + currentPage);
    console.log("function drawCommentCards: Data: ");
    console.log(datas);

    for (var i = (currentPage - 1) * NumPerPage; i < currentPage * NumPerPage; i++) {

        if (i < datas.length) {
            $("#comment-list").append(drawSingleCommentCard(datas[i], i));
        }
    }

    // here the code has problem saying not a function
    $(document).on('ready', function(){
        // here the code has problem saying not a function
        $(".star-show").rating({displayOnly: true});
    });

}

function drawSingleCommentCard(data, index){
        var html = '';
        if(typeof(data) != 'undefined'){
            html = html + '<div class="comment" number="'+ index +'">'+
               '<li class="media">' +
                    '<div class="media-left">' +
                        '<a href="#">' +
                            '<img class="media-object img-circle" style="height: 70px; width: 70px" src="'+ data.author_avatar +'" alt="photo">' +
                        '</a>' +
                    '</div>' +

                    '<div class="media-body">' +
                        '<h4 class="media-heading inline">'+ data.author_name +'</h4><span>  </span>' +

                        '<div class="caption inline" ><span class="label label-success">'+ data.user_rating +' Stars</span></div>' +
                        '<input value="'+ data.user_rating +'" type="number" class="rating-loading star-show" min=0 max=5 step=0.1 data-size="xs">' +

                        '<p class="inline">'+ data.user_review +'</p><span>   </span>';

            if (data.userId == currentUserId){
                html = html +
                        '<a commentid= "'+ data.commentId +'" class="inline" href="javascript:void(0)" onclick="removeByCommentId(this)">' +
                            '<div class="caption inline" ><span class="label label-danger">Remove</span></div>' +
                        '</a>';
            }

            html = html +
                        '<p>' +
                            '<div class="ds-comment-footer">' +
                                '<span class="ds-time" title="'+ data.time +'">'+ data.time +'</span>&nbsp;'+
                            '</div>'+
                        '</p>' +
                    '</div>' +
                '</li>' +
                '<hr/></div>';
        }

        return html;
    }

</script >

Upvotes: 3

Views: 1535

Answers (2)

ElasticCode
ElasticCode

Reputation: 7867

Try to run your code inside $( document ).ready() block and make sure that you have an element with .star-show class on the next page.

Check below working sample

var currentPage = 1;
var totalPage = 4;
var visiblePageNum = 2;
var NumPerPage = 1;
var currentUserId = 2;
var totalComments = [{
    author_avatar: "https://www.gravatar.com/avatar/8990b8e611d60bd869d1c4f06ab6351e?s=328&d=identicon&r=PG&f=1",
    author_name: "author name 1",
    user_rating: 1,
    user_review: "",
    commentId: 2,
    userId: 1,
    time: ""
  }, {
    author_avatar: "https://www.gravatar.com/avatar/8990b8e611d60bd869d1c4f06ab6351f?s=328&d=identicon&r=PG&f=1",
    author_name: "author name 2",
    user_rating: 2,
    user_review: "",
    commentId: 2,
    userId: 2,
    time: ""
  }, {
    author_avatar: "https://www.gravatar.com/avatar/8990b8e611d60bd869d1c4f06ab6351g?s=328&d=identicon&r=PG&f=1",
    author_name: "author name 3",
    user_rating: 3,
    user_review: "",
    commentId: 2,
    userId: 3,
    time: ""
  },
  {
    author_avatar: "https://www.gravatar.com/avatar/8990b8e611d60bd869d1c4f06ab6351h?s=328&d=identicon&r=PG&f=1",
    author_name: "author name 4",
    user_rating: 4,
    user_review: "",
    commentId: 2,
    userId: 4,
    time: ""
  }
]

$(document).on('ready', function() {
  $('#pagination').twbsPagination({
    totalPages: totalPage,
    visiblePages: visiblePageNum,
    onPageClick: function(event, page) {
      debugger;
      currentPage = page;
      $("#comment-list").empty();
      drawCommentCards(totalComments);
    }
  });
});


function drawCommentCards(datas) {
  //console.log("function drawCommentCards: currentpage: " + currentPage);
  //console.log("function drawCommentCards: Data: ");
  //console.log(datas);

  for (var i = (currentPage - 1) * NumPerPage; i < currentPage * NumPerPage; i++) {

    if (i < datas.length) {
      $("#comment-list").append(drawSingleCommentCard(datas[i], i));
    }
  }

  $(".star-show").rating({
    displayOnly: true
  });
}

function drawSingleCommentCard(data, index) {
  var html = '';
  if (typeof(data) != 'undefined') {
    html = html + '<div class="comment" number="' + index + '">' +
      '<li class="media">' +
      '<div class="media-left">' +
      '<a href="#">' +
      '<img class="media-object img-circle" style="height: 70px; width: 70px" src="' + data.author_avatar + '" alt="photo">' +
      '</a>' +
      '</div>' +

      '<div class="media-body">' +
      '<h4 class="media-heading inline">' + data.author_name + '</h4><span>  </span>' +

      '<div class="caption inline" ><span class="label label-success">' + data.user_rating + ' Stars</span></div>' +
      '<input value="' + data.user_rating + '" type="number" class="rating-loading star-show" min=0 max=5 step=0.1 data-size="xs">' +

      '<p class="inline">' + data.user_review + '</p><span>   </span>';

    if (data.userId == currentUserId) {
      html = html +
        '<a commentid= "' + data.commentId + '" class="inline" href="javascript:void(0)" onclick="removeByCommentId(this)">' +
        '<div class="caption inline" ><span class="label label-danger">Remove</span></div>' +
        '</a>';
    }

    html = html +
      '<p>' +
      '<div class="ds-comment-footer">' +
      '<span class="ds-time" title="' + data.time + '">' + data.time + '</span>&nbsp;' +
      '</div>' +
      '</p>' +
      '</div>' +
      '</li>' +
      '<hr/></div>';
  }

  return html;
}
<!-- Main Style Sheet -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-star-rating/4.0.3/css/star-rating.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twbs-pagination/1.4.1/jquery.twbsPagination.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-star-rating/4.0.3/js/star-rating.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>

<div class="container">
  <div id="comment-list"></div>
  <nav aria-label="Page navigation">
    <ul class="pagination" id="pagination"></ul>
  </nav>
</div>

Upvotes: 1

CREM
CREM

Reputation: 1991

Order your code as follows:

   var currentPage = 1;
    var totalPage = 5;
    var visiblePageNum = 2;
    var totalComments = {...}

   function drawCommentCards(datas) {
        console.log("function drawCommentCards: currentpage: " + currentPage);
        console.log("function drawCommentCards: Data: ");
        console.log(datas);

        for (var i = (currentPage - 1) * NumPerPage; i < currentPage * NumPerPage; i++) {

            if (i < datas.length) {
                $("#comment-list").append(drawSingleCommentCard(datas[i], i));
            }
        }


    }

    function drawSingleCommentCard(data, index){
        var html = '';
        if(typeof(data) != 'undefined'){
            html = html + '<div class="comment" number="'+ index +'">'+
               '<li class="media">' +
                    '<div class="media-left">' +
                        '<a href="#">' +
                            '<img class="media-object img-circle" style="height: 70px; width: 70px" src="'+ data.author_avatar +'" alt="photo">' +
                        '</a>' +
                    '</div>' +

                    '<div class="media-body">' +
                        '<h4 class="media-heading inline">'+ data.author_name +'</h4><span>  </span>' +

                        '<div class="caption inline" ><span class="label label-success">'+ data.user_rating +' Stars</span></div>' +
                        '<input value="'+ data.user_rating +'" type="number" class="rating-loading star-show" min=0 max=5 step=0.1 data-size="xs">' +

                        '<p class="inline">'+ data.user_review +'</p><span>   </span>';

            if (data.userId == currentUserId){
                html = html +
                        '<a commentid= "'+ data.commentId +'" class="inline" href="javascript:void(0)" onclick="removeByCommentId(this)">' +
                            '<div class="caption inline" ><span class="label label-danger">Remove</span></div>' +
                        '</a>';
            }

            html = html +
                        '<p>' +
                            '<div class="ds-comment-footer">' +
                                '<span class="ds-time" title="'+ data.time +'">'+ data.time +'</span>&nbsp;'+
                            '</div>'+
                        '</p>' +
                    '</div>' +
                '</li>' +
                '<hr/></div>';
        }

        return html;
    }

   $( document ).ready(function() {


    $('#pagination').twbsPagination({
    totalPages: totalPage,
    visiblePages: visiblePageNum,
    onPageClick: function (event, page) {
        currentPage = page;
        $("#comment-list").empty();
        drawCommentCards(totalComments);
        }
    });



    $(".star-show").rating({displayOnly: true});

});

</script >

I see no logic to call document.ready inside a function created by you. Function declarations are automatically hoisted on the top of your code

Upvotes: 0

Related Questions