Search code examples
javascriptjqueryasp.netajaxupdatepanel

ASP Update panel breaks jQuery star rating system


I've added an updatePanel to my ListView. When the page first loads, it displays my rating system fine (here is the krajee-star rating library that I'm using):

enter image description here

However, when the page does a partial-postback, it causes the control to appear like this:

enter image description here

Here is the code snippet:

<asp:UpdatePanel runat="server">
    <ContentTemplate>
        <asp:ListView ID="ListView1" runat="server" ItemType="Country" SelectMethod="ListView1_GetData">
            <ItemTemplate>
             ...
            <input id="starRating" value="<%# Item.AverageRating %>" type="number" class="rating" min="0" max="5" step="0.5" readonly="true" data-size="xs">
             ...
        </ListView>
    </ContentTemplate>
</asp:UpdatePanel>

What are my options? I did have a look at triggers, but I think these only work with ASP controls. Ideally, I would like to keep the updatePanel.

I also tried to use pageLoad() but this also didn't solve the issue (it actually wipes out 'score' for the rating completely):

function pageLoad() {
  $(function () {
    $("div.star-rating").rating('create', { showClear: false, size: "xs", readonly: true });
  });
};

Solution

  • After looking at the outputted HTML, I noticed that on partial-page load the rating-system was not rendering, but instead it was showing the <input ... tag, being the reason why it was displaying it like shown above.

    I decided to look at the correct, star-rating markup, where I was able to understand how the star-system works and was able to configure some javascript code to run:

    function pageLoad(sender, args) {
      if (args.get_isPartialLoad())
      {
        $(function () {
          $('input[type="number"]').each(function () {
            var value = $(this).val();            
            var width = value * 20;
            var elem = "<div class='star-rating rating-xs rating-disabled'><div class='clear-rating' title='Clear'><i class='glyphicon glyphicon-minus-sign'></i></div><div class='rating-container rating-gly-star' data-content=''><div class='rating-stars' data-content='' style='width: " + width +"%;'></div><input id='starRating' value='" + value + "' type='number' class='rating form-control hide' min='0' max='5' step='0.5' readonly='true' data-size='xs'></div><div class='caption'><span class='label label-default'>" + value + " Stars</span></div></div>"
            $(this).replaceWith(elem);
          })
        });
      }
    };
    

    This method will only run on partial load, which is when the problem arises. I loop through all the elements and grab the unrendered input. I then calculate the width, which is the amount of 'star' to show and I then insert the correctly, ready to ouput markup, replacing the old one unrendered one.

    This has solved my issue, not pretty, but it has solved my issue.