Reputation: 820
I am working on a star rating system for when you visit any restaurant, all the `Attributes' I have to show on UI are dynamic for which I am getting data in JSON format
Here I have five attributes each of them having up to 5 star rating option
My 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
}
];
What I am trying to achieve is this:
What I have done
@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>
at the end of the form there will be a submit button which will send action to server to save the feedback, as I am lacking in approach I think, like how it will work and how should I do it.
I have edited my snippet where I have two attributes Quality of food
, Cleanliness
but when I click on Cleanliness
stars the above star gets colored filled, I know that is because of common css, but that is my issue All the attributes are dynamic, please check my JSON data I have uploaded Image of what I am trying to do.
This is dynamic code which is creating stars and labels dynamically
$(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>
In the second snippet I have added the dynamic code which is not taking css correctly.
Issue: once if I had marked the stars and want to unmarked them from 4 to 2 it is not happening. Please check snippet 1 where I have static code using HTML, I want that type of functionality.
Upvotes: 3
Views: 9158
Reputation: 971
Check code snipet below I have made some corrections, added submit button to get result
$(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>
Upvotes: 1
Reputation: 33933
If i had marked the stars and want to unmarked them from 4 to 2 it is not happening...
You yellowish the stars using the following CSS rule:
input.star:checked~label.star:before {
That applies on all label.star
following a checked checkbox.
Now to un-yellowish... You simply have to uncheck the sibling inputs... I used .siblings(selector)
to match them... And an .each()
loop to change the checked
property to false.
$(this).siblings("input").each(function() {
$(this).prop("checked", false);
});
Here is a snippet:
$(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>
Upvotes: 0
Reputation: 11975
Your second example not work because the inputs in each form-group
not have the same name
. Give them the same name
will solve your problem.
Your stars is float: right
so you need to append the stars in descending order to make them work as expected, else the first star on the left will have value 5
.
And I also simplify your code to use element property instead of setAttribute()
method:
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>
Upvotes: 1
Reputation: 552
This is how you can create a dynamic star rating.
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>
Upvotes: 1