Search code examples
javascriptknockout.jsknockout-mapping-pluginknockout-validation

Star rating binding using knockout js


i am trying to bind the star rating using knockout js and ajax, the star rating is bind if i assign the value manually lik data=3 or data=4,but the data which i am getting from ajax its not getting bind,but i am getting the value from the ajax result and passing it to viewmodel its not working below is my code need help.

 //HTML//

 <div id="divstarRating">
 <span data-bind="readonlyStarRating:starpoints"></span></a>
 </div>

     ///Custom Binding
ko.bindingHandlers.readonlyStarRating =
 {
  init: function (element, valueAccessor) {

   $(element).addClass("readonlyStarRating");
   for (var i = 0; i < 5; i++)
   $("<span>").appendTo(element);
             $("span", element).each(function (index) {
             var observable = valueAccessor();
             $(this).hover(
                 function () { $(this).prevAll().add(this).addClass("hoverChosen") },
                 function () { $(this).prevAll().add(this).removeClass("hoverChosen") }
             )
         });
     },
     update: function (element, valueAccessor) {
         var observable = valueAccessor();
         $("span", element).each(function (index) {
         $(this).toggleClass("chosen", index < observable());
         });
     }
 }
//viewModel

 function starRating(data) {
if (data != 0) {
    this.starpoints = ko.observable(data);
}
else {
    this.starpoints = ko.observable(1);
}
 }
 ko.applyBindings(new starRating(), document.getElementById('divstarRating'))

 //ajax///

$.ajax({
    type: "POST",
    dataType: "json",
    data: xxxx,
    url: xxxx+ 'api/xx/xxxxxx',
    success: function (data) {
      //I am getting the value and passing to viewModel
        return new starRating(data); 
    }
});

   //CSS//
.readonlyStarRating span { width:24px; height:24px; background-image:      url(../star.png); display:inline-block; cursor: pointer; background-position: -24px 0; }
.readonlyStarRating span.chosen { background-position: 0 0; }

Solution

  • You have actually two instance of starRating. In order to reflect the value in your html you should store the instance of new startRating before passing to ko.applyBindings. Then use that instance on your ajax request instead of return new startRating(data).

    Or you can use ko.dataFor to get the instance of your viewModel.

    It looks like this

    ...
       //in your ajax request    
       success: function (data) {
           var vm = ko.dataFor(document.getElementById('divstarRating'));
           vm.starpoints(data);
       }
    ...