Search code examples
cssknockout-3.0rating-system

Knockoutjs star rating css


I am trying to use Knockout to implement this css star rating which works well http://jsfiddle.net/madannes/r3s1jx4y/:

<span class="user-rating">
        <input type="radio" name="rating" value="5" /><span class="star"></span>
        <input type="radio" name="rating" value="4" /><span class="star"></span>
        <input type="radio" name="rating" value="3" /><span class="star"></span>
        <input type="radio" name="rating" value="2" /><span class="star"></span>
        <input type="radio" name="rating" value="1" /><span class="star"></span>
    </span>

I modified it as follows:

<div data-bind="foreach: Fields">
            <!--ko if: $parent.HiddenElements().indexOf(Name()) == -1 -->
            <!--ko if: Type() == "Stars"-->
            <div data-bind="foreach: Options">
                <span class="user-rating">
                    <input type="radio" name="rating" data-bind="value:  $data.name,checked: $parent.Default" /><span class="star"></span>
                </span>
            </div>
            <hr />
            <!--/ko-->
            <br />
            <!--/ko-->
        </div>

The array (which I get from MVC Controller using Ajax):

var jsonData  = 
[ {Default: "", Name: "Do you like working here?",Title: "Test Stars",Type: "Stars",
Options:  [
 {name: '1'},{name: '2'},{name: '3'},{name: '4'},{name: '5'}]}];

The viewmodel:

function FormField(data) {
            var self = this;
            self.Name = ko.observable(data.Name);
            self.Type = ko.observable(data.Type);
            self.Options = ko.observableArray(data.Type !== 'text' ? data.Options : []);
            self.Default = ko.observable(data.Default);
            if (self.Type() === 'Stars') {
                this.Default.subscribe(function (newValue) {
                    alert(newValue);
                });
            }
        }
        function ViewModel(data) {
            var self = this;
            self.Fields = ko.observableArray(ko.utils.arrayMap(data, function (item) {
                return new FormField(item);
            }));
            self.HiddenElements = ko.observableArray([]);
            self.Default = ko.observable();
        }
        ko.applyBindings(new ViewModel(jsonData));

It works, except only the star selected is checked for example the third, while in the html/css stars 1,2, and 3 are checked? I checked the value of each star and they were correct 5,4,3,2, and 1.


Solution

  • I see you are outputting some different html than in the example of the JSfiddle. There´s some magic going on under the hood of the html5 elements in the fiddle you are linking to. Make your html to be just as in the fiddle and add in the styles as well. I'm guessing that the usage of <fieldset class="rating"> is not random