如何使用JSON数据进行动态星级评分

时间:2019-08-19 10:21:03

标签: javascript jquery html css

我正在使用星级评分系统,当您访问任何餐厅时,我要在UI上显示的所有“属性”都是动态的,因此我要以JSON格式获取数据

在这里,我有五个属性,每个属性都具有5星评级选项

我的数据:

    [
          {
            "ATTRIBUTEID": "FOODQUALITY",
            "ATTRIBUTENAME": "Quality Of Food",
            "POSITION": 1
          },
          {
            "ATTRIBUTEID": "CLEANLINESS",
            "ATTRIBUTENAME": "Cleanliness",
            "POSITION": 2
          },
          {
            "ATTRIBUTEID": "SERVICE",
            "ATTRIBUTENAME": "Service",
            "POSITION": 3
          },
          {
            "ATTRIBUTEID": "STAFFBEHAVE",
            "ATTRIBUTENAME": "Staf Behavior",
            "POSITION": 4
          },
          {
            "ATTRIBUTEID": "AMBIENCE",
            "ATTRIBUTENAME": "Ambience",
            "POSITION": 5
          }
        ];

我要实现的目标是:

Image

我做了什么

@charset "ISO-8859-1";
div.stars {
  width: 300px;
  display: inline-block;
  margin-left: -35px;
}

.commonLable {
  margin-left: 55px;
  font-family: sans-serif;
  font-weight: bold;
  margin-bottom: 0;
}

input.star {
  display: none;
}

label.star {
  float: right;
  padding: 5px;
  font-size: 40px;
  color: grey;
  transition: all .2s;
  margin-top: -25px;
}

hr {
  margin: 0;
}

input.star:checked~label.star:before {
  content: '\2605';
  color: #ffd309;
  transition: all .25s;
}

input.star-5:checked~label.star:before {
  color: #ffe840;
  text-shadow: 0 0 20px #952;
}

input.star-1:checked~label.star:before {
  color: #f24800;
}

label.star:hover {
  transform: rotate(-15deg) scale(1.3);
  cursor: pointer;
}

label.star:before {
  content: '\2605';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<div class="stars">
  <form action="">

    <div class="form-row">
      <label class="commonLable"> Cleanliness</label>
      <div class="form-group col-lg-12">
        <input class="star star-5" id="star-5" type="radio" name="star" value="5" />
        <label class="star star-5" for="star-5"></label>
        <input class="star star-4" id="star-4" type="radio" name="star" value="4" />
        <label class="star star-4" for="star-4"></label>
        <input class="star star-3" id="star-3" type="radio" name="star" value="3" />
        <label class="star star-3" for="star-3"></label>
        <input class="star star-2" id="star-2" type="radio" name="star" value="2" />
        <label class="star star-2" for="star-2"></label>
        <input class="star star-1" id="star-1" type="radio" name="star" value="1" />
        <label class="star star-1" for="star-1"></label>
      </div>
    </div>
    <div class="form-row">
      <label class="commonLable"> Quality Of Food
</label>
      <div class="form-group col-lg-12">
        <input class="star star-5" id="star-5r" type="radio" name="starr" />
        <label class="star star-5" for="star-5r"></label>
        <input class="star star-4" id="star-4r" type="radio" name="starr" />
        <label class="star star-4" for="star-4r"></label>
        <input class="star star-3" id="star-3r" type="radio" name="starr" />
        <label class="star star-3" for="star-3r"></label>
        <input class="star star-2" id="star-2r" type="radio" name="starr" />
        <label class="star star-2" for="star-2r"></label>
        <input class="star star-1" id="star-1r" type="radio" name="starr" />
        <label class="star star-1" for="star-1r"></label>
      </div>
    </div>
  </form>
</div>
</form>
</div>

在表单的末尾将有一个提交按钮,该按钮会将动作发送到服务器以保存反馈,因为我缺乏这种方法,例如它将如何工作以及应该如何做。

编辑

我已经编辑了我的代码段,其中有两个属性Quality of foodCleanliness,但是当我单击Cleanliness星形时,上面的星形会变色填充,我知道这是因为常见的CSS ,但这是我的问题。所有属性都是动态的,请检查我已上传的JSON数据,了解我要执行的操作。

编辑

这是动态代码,可以动态创建星星和标签

$(document).ready(function() {
  var data = [{
      "ATTRIBUTEID": "FOODQUALITY",
      "ATTRIBUTENAME": "Quality Of Food",
      "POSITION": 1
    },
    {
      "ATTRIBUTEID": "CLEANLINESS",
      "ATTRIBUTENAME": "Cleanliness",
      "POSITION": 2
    },
    {
      "ATTRIBUTEID": "SERVICE",
      "ATTRIBUTENAME": "Service",
      "POSITION": 3
    },
    {
      "ATTRIBUTEID": "STAFFBEHAVE",
      "ATTRIBUTENAME": "Staf Behavior",
      "POSITION": 4
    },
    {
      "ATTRIBUTEID": "AMBIENCE",
      "ATTRIBUTENAME": "Ambience",
      "POSITION": 5
    }
  ];

  for (v = 0; v < data.length; v++) {

    var container = document.getElementById("container");

    var firstDiv = document.createElement('div');
    firstDiv.setAttribute("class", "form-row");

    var secondDiv = document.createElement('div');
    secondDiv.setAttribute("class", "commonLable");
    secondDiv.append(data[v].ATTRIBUTENAME);


    var thirdDiv = document.createElement('div');
    thirdDiv.setAttribute("class", "form-group col-lg-12");

    /// append stars 

    for (i = 1; i < data.length + 1; i++) {
      var incrementedVar = i + 1;
      var stars = document.createElement("input");
      var label = document.createElement("label");
      stars.setAttribute("type", "radio");
      stars.setAttribute("id", '"' + data[v].ATTRIBUTEID + i + '"');
      stars.setAttribute("name", '"' + data[v].ATTRIBUTEID + i + '"');
      stars.setAttribute("class", "star star-5");
      stars.setAttribute("value", i);
      label.setAttribute("class", "star star-5");
      label.setAttribute("for", '"' + data[v].ATTRIBUTEID + i + '"');
      thirdDiv.append(stars, label);

    }

    secondDiv.append(thirdDiv);
    firstDiv.append(secondDiv);
    container.appendChild(firstDiv);
  }
  $('input:radio').change(
    function() {

      alert($(this).val());
    });
});
@charset "ISO-8859-1";
div.stars {
  width: 300px;
  display: inline-block;
  margin-left: -35px;
}

.commonLable {
  margin-left: 55px;
  font-family: sans-serif;
  font-weight: bold;
  margin-bottom: 0;
}

input.star {
  display: none;
}

label.star {
  float: right;
  padding: 5px;
  font-size: 40px;
  color: grey;
  transition: all .2s;
  margin-top: -25px;
}

hr {
  margin: 0;
}

input.star:checked~label.star:before {
  content: '\2605';
  color: #ffd309;
  transition: all .25s;
}

input.star-5:checked~label.star:before {
  color: #ffe840;
  text-shadow: 0 0 20px #952;
}

input.star-1:checked~label.star:before {
  color: #f24800;
}

label.star:hover {
  transform: rotate(-15deg) scale(1.3);
  cursor: pointer;
}

label.star:before {
  content: '\2605';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<div class="stars">
  <form action="" id="container">

  </form>
</div>

在第二个代码段中,我添加了动态代码,该代码无法正确使用css。

问题:一次,如果我已经标记了星星并希望将它们从4标记为2,则不会发生。请检查代码段1,其中我有使用HTML的静态代码,我需要这种功能。

4 个答案:

答案 0 :(得分:1)

这是创建动态星级的方法。

var data = [
  {
    "ATTRIBUTEID": "FOODQUALITY",
    "ATTRIBUTENAME": "Quality Of Food",
    "POSITION": 1
  },
  {
    "ATTRIBUTEID": "CLEANLINESS",
    "Quantity": "Cleanliness",
    "POSITION": 2
  },
  {
    "ATTRIBUTEID": "SERVICE",
    "Quantity": "Service",
    "POSITION": 3
  },
  {
    "ATTRIBUTEID": "STAFFBEHAVE",
    "Quantity": "Staf Behavior",
    "POSITION": 4
  },
  {
    "ATTRIBUTEID": "AMBIENCE",
    "Quantity": "Ambience",
    "POSITION": 5
  }
];

for (v=0;v<data.length - 1;v++){
  var container = document.getElementById("container");

  var firstDiv = document.createElement('div');
  firstDiv.setAttribute("class", "form-row");

  var secondDiv = document.createElement('div');
  secondDiv.setAttribute("class", "commonLable");
  secondDiv.append(data[v].ATTRIBUTEID);


  var thirdDiv = document.createElement('div');
  thirdDiv.setAttribute("class", "form-group col-lg-12");

  /// append stars 

  for (i=0;i<5;i++){
  	var incrementedVar = i+1;
    var stars = document.createElement("input");
    var label = document.createElement("label");
    stars.setAttribute("type", "radio");
    stars.setAttribute("id", '"'+ data[v].ATTRIBUTEID + i +'"');
    stars.setAttribute("name", '"'+ data[v].ATTRIBUTEID + i +'"');
    stars.setAttribute("class", "star star-5");
    label.setAttribute("class", "star star-5");
    label.setAttribute("for", '"'+ data[v].ATTRIBUTEID + i +'"');
    thirdDiv.append(stars, label);

  }

  secondDiv.append(thirdDiv);
  firstDiv.append(secondDiv);
  container.appendChild(firstDiv);
}
div.stars {
  width: 300px;
  display: inline-block;
}

.commonLable {
  margin-left: 55px;
  font-family: sans-serif;
  font-weight: bold;
}

input.star {
  display: none;
} 

label.star {
  float: right;
  padding: 5px;
  font-size: 30px;
  color: grey;
  transition: all .2s;
}

input.star:checked~label.star:before {
  content: '\2605';
  color: #FD4;
  transition: all .25s;
}

input.star-5:checked~label.star:before {
  color: #FE7;
  text-shadow: 0 0 20px #952;
}

input.star-1:checked~label.star:before {
  color: #F62;
}

label.star:hover {
  transform: rotate(-15deg) scale(1.3);
  cursor: pointer;
}

label.star:before {
  content: '\2605';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<div class="stars">
  <form action="" id="container">
   
  </form>
</div>

答案 1 :(得分:1)

第二个示例不起作用,因为每个form-group中的输入都不具有相同的name。给他们同样的name将解决您的问题。

您的星星是float: right,因此您需要按降序附加星星以使其按预期工作,否则左侧的第一颗星星将具有值5

我还简化了您的代码,使其使用元素属性而不是setAttribute()方法:

var data = [
  {
    "ATTRIBUTEID": "FOODQUALITY",
    "ATTRIBUTENAME": "Quality Of Food",
    "POSITION": 1
  },
  {
    "ATTRIBUTEID": "CLEANLINESS",
    "ATTRIBUTENAME": "Cleanliness",
    "POSITION": 2
  },
  {
    "ATTRIBUTEID": "SERVICE",
    "ATTRIBUTENAME": "Service",
    "POSITION": 3
  },
  {
    "ATTRIBUTEID": "STAFFBEHAVE",
    "ATTRIBUTENAME": "Staf Behavior",
    "POSITION": 4
  },
  {
    "ATTRIBUTEID": "AMBIENCE",
    "ATTRIBUTENAME": "Ambience",
    "POSITION": 5
  }
];

for (i = 0; i < data.length; i++){
  var container = document.getElementById("container");

  var row = document.createElement('div');
  row.className = "form-row";

  var commonLabel = document.createElement('label');
  commonLabel.className = "commonLable";
  commonLabel.innerHTML = data[i].ATTRIBUTENAME;


  var form_group = document.createElement('div');
  form_group.className = "form-group col-lg-12";

  for (j = 5;j > 0; j--) {
    var star = document.createElement("input");
    var label = document.createElement("label");
    star.type = "radio";
    star.id = data[i].ATTRIBUTEID + j;
    star.name = data[i].ATTRIBUTEID;
    star.className = "star star-" + j;
    star.value = j;
    label.className = "star star-" + j;
    label.htmlFor = data[i].ATTRIBUTEID + j;
    form_group.append(star, label);
  }

  row.append(commonLabel, form_group);
  container.appendChild(row);
}

$('#submit').click(function(){
  var formData = $('#container').serialize();
  alert(formData);
});
div.stars {
  width: 300px;
  display: inline-block;
}

.commonLable {
  margin-left: 55px;
  font-family: sans-serif;
  font-weight: bold;
}

input.star {
  display: none;
} 

label.star {
  float: right;
  padding: 5px;
  font-size: 30px;
  color: grey;
  transition: all .2s;
}

input.star:checked~label.star:before {
  content: '\2605';
  color: #FD4;
  transition: all .25s;
}

input.star-5:checked~label.star:before {
  color: #FE7;
  text-shadow: 0 0 20px #952;
}

input.star-1:checked~label.star:before {
  color: #F62;
}

label.star:hover {
  transform: rotate(-15deg) scale(1.3);
  cursor: pointer;
}

label.star:before {
  content: '\2605';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<div class="stars">
  <form action="" id="container">
   
  </form>
  <button type="button" id="submit">Submit</button>
</div>

答案 2 :(得分:0)

下面的检查代码片段已进行了一些更正,添加了提交按钮以获取结果

$(document).ready(function() {
  var data = [{
      "ATTRIBUTEID": "FOODQUALITY",
      "ATTRIBUTENAME": "Quality Of Food",
      "POSITION": 1
    },
    {
      "ATTRIBUTEID": "CLEANLINESS",
      "ATTRIBUTENAME": "Cleanliness",
      "POSITION": 2
    },
    {
      "ATTRIBUTEID": "SERVICE",
      "ATTRIBUTENAME": "Service",
      "POSITION": 3
    },
    {
      "ATTRIBUTEID": "STAFFBEHAVE",
      "ATTRIBUTENAME": "Staf Behavior",
      "POSITION": 4
    },
    {
      "ATTRIBUTEID": "AMBIENCE",
      "ATTRIBUTENAME": "Ambience",
      "POSITION": 5
    }
  ];

  for (v = 0; v < data.length; v++) {

    var container = document.getElementById("container");

    var firstDiv = document.createElement('div');
    firstDiv.setAttribute("class", "form-row");

    var secondDiv = document.createElement('div');
    secondDiv.setAttribute("class", "commonLable");
    secondDiv.append(data[v].ATTRIBUTENAME);


    var thirdDiv = document.createElement('div');
    thirdDiv.setAttribute("class", "form-group col-lg-12");

    /// append stars 

    for (i = 1; i < data.length + 1; i++) {
      var incrementedVar = i + 1;
      var stars = document.createElement("input");
      var label = document.createElement("label");
      stars.setAttribute("type", "radio");
      stars.setAttribute("required", "required");
      stars.setAttribute("id", data[v].ATTRIBUTEID + i ); // removed double quotes
      stars.setAttribute("name",  data[v].ATTRIBUTEID );  // removed incremental i, removed double quotes
      stars.setAttribute("class", "star star-5");
      stars.setAttribute("value", i);
      label.setAttribute("class", "star star-5");
      label.setAttribute("for",  data[v].ATTRIBUTEID + i);  // removed double quotes
      thirdDiv.append(stars, label);

    }

    secondDiv.append(thirdDiv);
    firstDiv.append(secondDiv);
    container.appendChild(firstDiv);
    
  }
  var btn = document.createElement("button");
    btn.type = 'submit'; 
    btn.value= 'submit';
    btn.innerHTML = 'Submit'; 
    btn.setAttribute("style", "margin-left:55px;");
    container.append(btn);
  $('input:radio').change(
    function() {
    });
  $('.buttonSubmit').click(function(){
    var formData = $('#container').serialize();
    alert(formData);
  });
});
@charset "ISO-8859-1";
div.stars {
  width: 300px;
  display: inline-block;
  margin-left: -35px;
}

.commonLable {
  margin-left: 55px;
  font-family: sans-serif;
  font-weight: bold;
  margin-bottom: 0;
}

input.star {
  display: none;
}

label.star {
  float: right;
  padding: 5px;
  font-size: 40px;
  color: grey;
  transition: all .2s;
  margin-top: -25px;
}

hr {
  margin: 0;
}

input.star:checked~label.star:before {
  content: '\2605';
  color: #ffd309;
  transition: all .25s;
}

input.star-5:checked~label.star:before {
  color: #ffe840;
  text-shadow: 0 0 20px #952;
}

input.star-1:checked~label.star:before {
  color: #f24800;
}

label.star:hover {
  transform: rotate(-15deg) scale(1.3);
  cursor: pointer;
}

label.star:before {
  content: '\2605';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<div class="stars">
  <form action="" id="container">

  </form>
  
</div>

答案 3 :(得分:0)

  

如果我已经标记了星星并希望将它们从4标记为2,则不会发生...

您可以使用以下CSS规则使星星变黄:

input.star:checked~label.star:before {

这适用于所有label.star 以下已选中的复选框。

现在要取消黄色...您只需取消选中同级输入 ...我使用了.siblings(selector)来匹配它们...还有一个.each()循环将checked属性更改为false。

$(this).siblings("input").each(function() {
  $(this).prop("checked", false);
});

以下是代码段

$(document).ready(function() {
  var data = [{
      "ATTRIBUTEID": "FOODQUALITY",
      "ATTRIBUTENAME": "Quality Of Food",
      "POSITION": 1
    },
    {
      "ATTRIBUTEID": "CLEANLINESS",
      "ATTRIBUTENAME": "Cleanliness",
      "POSITION": 2
    },
    {
      "ATTRIBUTEID": "SERVICE",
      "ATTRIBUTENAME": "Service",
      "POSITION": 3
    },
    {
      "ATTRIBUTEID": "STAFFBEHAVE",
      "ATTRIBUTENAME": "Staf Behavior",
      "POSITION": 4
    },
    {
      "ATTRIBUTEID": "AMBIENCE",
      "ATTRIBUTENAME": "Ambience",
      "POSITION": 5
    }
  ];

  for (v = 0; v < data.length; v++) {

    var container = document.getElementById("container");

    var firstDiv = document.createElement('div');
    firstDiv.setAttribute("class", "form-row");

    var secondDiv = document.createElement('div');
    secondDiv.setAttribute("class", "commonLable");
    secondDiv.append(data[v].ATTRIBUTENAME);


    var thirdDiv = document.createElement('div');
    thirdDiv.setAttribute("class", "form-group col-lg-12");

    /// append stars 

    for (i = 1; i < data.length + 1; i++) {
      var incrementedVar = i + 1;
      var stars = document.createElement("input");
      var label = document.createElement("label");
      stars.setAttribute("type", "radio");
      stars.setAttribute("id", data[v].ATTRIBUTEID + i);
      stars.setAttribute("name", data[v].ATTRIBUTEID + i);
      stars.setAttribute("class", "star star-5");
      stars.setAttribute("value", i);
      label.setAttribute("class", "star star-5");
      label.setAttribute("for", data[v].ATTRIBUTEID + i);
      thirdDiv.append(stars, label);

    }

    secondDiv.append(thirdDiv);
    firstDiv.append(secondDiv);
    container.appendChild(firstDiv);
  }


  $('input:radio').on("change", function() {
console.log($(this).prop("checked"));
    // Uncheck all sibling inputs that are before $(this) (in DOM... But visually on the right).
    $(this).siblings("input").each(function() {
      $(this).prop("checked", false);
    });
  });

});
@charset "ISO-8859-1";
div.stars {
  width: 300px;
  display: inline-block;
  margin-left: -35px;
}

.commonLable {
  margin-left: 55px;
  font-family: sans-serif;
  font-weight: bold;
  margin-bottom: 0;
}

input.star {
  display: none;
}

label.star {
  float: right;
  padding: 5px;
  font-size: 40px;
  color: grey;
  transition: all .2s;
  margin-top: -25px;
}

hr {
  margin: 0;
}

input.star:checked~label.star:before {
  content: '\2605';
  color: #ffd309;
  transition: all .25s;
}

input.star-5:checked~label.star:before {
  color: #ffe840;
  text-shadow: 0 0 20px #952;
}

input.star-1:checked~label.star:before {
  color: #f24800;
}

label.star:hover {
  transform: rotate(-15deg) scale(1.3);
  cursor: pointer;
}

label.star:before {
  content: '\2605';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<div class="stars">
  <form action="" id="container">

  </form>
</div>