如何实施 css 星评级与淘汰赛

how to implement a css star rating with knockout

有一个我想要实现的星级,它的工作原理是可以点击星星,我遇到的问题是当我显示多组星星时。发生的事情是点击哪一组星星会影响另一组,只是改变点击的数量。如果我没有很好地解释,比如说我有 3 组星星,我会转到第一组并给它 5 星评级,它保持这个值(都很好),但是如果转到下一组星星并赋予它 2 的值,第二组将保持 2 星的值,但是上面的组设置为 none。它就像检查的事件对于每组和重置另一组都不是唯一的。我正在为此使用 bootstrap 和 Knockout js,我试图提供一个唯一的 ID,希望可以解决它,但没有运气。任何人都可以帮忙吗?

下面的代码,我已经跳过了一些创建我的可观察数组的淘汰赛代码,当我为我的每个 feedbackToBeLeft 数组获得一组星星时,我已经开始工作了

<style>
.star-rating {
    font-size: 0;
}

.star-rating__wrap {
    display: inline-block;
    font-size: 16px;
}

    .star-rating__wrap:after {
        content: "";
        display: table;
        clear: both;
    }

.star-rating__ico {
    float: right;
    padding-left: 2px;
    cursor: pointer;
    color: #9933cc;
}

    .star-rating__ico:last-child {
        padding-left: 0;
    }

.star-rating__input {
    display: none;
}

    .star-rating__ico:hover:before,
    .star-rating__ico:hover ~ .star-rating__ico:before,
    .star-rating__input:checked ~ .star-rating__ico:before {
        content: "\f005";
    }

<div data-bind="foreach: feedbackToBeLeft"><table style="background-color:transparent;border:none;">
                                <tr>
                                    <td style="width:100px;">
                                        Rating
                                    </td>
                                    <td>
                                        <div class="star-rating" data-bind="attr: { id: 'star_' + bookingGuid }">
                                            <div class="star-rating__wrap" data-bind="attr: { id: 'wrap_' + bookingGuid }">
                                                <input class="star-rating__input" data-bind="attr: { id: 'star5_' + bookingGuid }" type="radio" name="rating" value="5">
                                                <label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: { for: 'star5_' + bookingGuid }" title="Amazing"></label>
                                                <input class="star-rating__input" data-bind="attr: { id: 'star4_' + bookingGuid }" type="radio" name="rating" value="4">
                                                <label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: { for: 'star4_' + bookingGuid }" title="Good"></label>
                                                <input class="star-rating__input" data-bind="attr: { id: 'star3_' + bookingGuid }" type="radio" name="rating" value="3">
                                                <label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: { for: 'star3_' + bookingGuid }" title="Ok"></label>
                                                <input class="star-rating__input" data-bind="attr: { id: 'star2_' + bookingGuid }" type="radio" name="rating" value="2">
                                                <label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: { for: 'star2_' + bookingGuid }" title="Not good"></label>
                                                <input class="star-rating__input" data-bind="attr: { id: 'star1_' + bookingGuid }" type="radio" name="rating" value="1">
                                                <label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: { for: 'star1_' + bookingGuid }" title="Bad"></label>
                                            </div>
                                        </div>
                                    </td>
                                </tr>
                            </table></div>

这就是我接近你想要做的事情的方式。

var ratings = [{
    name: 'Bad',
    value: 1
  },
  {
    name: 'Not Good',
    value: 2
  },
  {
    name: 'Ok',
    value: 3
  },
  {
    name: 'Good',
    value: 4
  },
  {
    name: 'Amazing',
    value: 5
  },
];

var data = [{
  bookingGuid: '11111111-1111-1111-1111-111111111111',
  bookingName: 'Room 1',
  ratingValue: 4
}, {
  bookingGuid: '22222222-2222-2222-2222-222222222222',
  bookingName: 'Room 2',
  ratingValue: 2
}];

function StarRatingVm(id, title, value) {
  var self = this;
  self.id = id;
  self.value = value;
  self.title = title;
  self.groupName = ko.pureComputed(function() {
    return 'star_' + self.id;
  });
  self.name = ko.pureComputed(function() {
    return 'star' + self.value + '_' + self.id;
  });
}


function Vm() {
  var self = this;

  var mappedData = data.map(function(item) {
    item.availableRatings = createRatings(item.bookingGuid, ratings);
    item.selectedValue = ko.observableArray();
    return item;
  })

  self.feedbackToBeLeft = ko.observableArray(mappedData);



  function createRatings(id, ratings) {
    return ratings.map(function(item) {
      return new StarRatingVm(id, item.name, item.value);
    });
  }

}
var vm = new Vm();
window.vm = vm;
ko.applyBindings(vm);
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: {data: feedbackToBeLeft, as: 'feedback'}">
  <table style="background-color:transparent;border:none;">
    <tr>
      <td style="width:100px;">
        Rating <span data-bind="text: feedback.bookingName"></span>
      </td>
      <td>
        <div class="star-rating" data-bind="attr: { id: 'star_' + bookingGuid }">
          <div class="star-rating__wrap" data-bind="attr: { id: 'wrap_' + bookingGuid }, foreach: { data: availableRatings, as : 'rating'}">
            <input class="star-rating__input" data-bind="checkedValue: rating, checked: feedback.selectedValue, attr: { id: rating.name, name: rating.groupName, title: rating.title } " type="radio">
            <label class="star-rating__ico fa fa-star-o fa-lg" data-bind="attr: { for: rating.name, title: rating.title }"></label>
          </div>
        </div>
      </td>
    </tr>
  </table>
</div>

<br/>

<ul data-bind="foreach: feedbackToBeLeft">
  <li><span data-bind="text: bookingName"></span>  Rating: <span data-bind="text: selectedValue().value"></span> stars</li>
</ul>

<pre data-bind="text: ko.toJSON(vm)"></pre>