javascripthtmlcssrating

Implement Star Rating for every element inside a html table, which is generated by User Inputs


I am trying to build a Website, which is able to dynamically store arbitrary events from user inputs on the website in a html table. Every event stored can be rated by a star rating system which i already implemented with html, js & css.

The problem is, my current system only allows to rate one of the elements. If I have two elements in my list and I try to rate the second one, it changes the value of the first element and doesn't allow me to change the value of the second one.

How can i fix this?

Here is my Code (Some Alerts/Comments are in German but just dont mind these really)

And please not i don't want to use a database or anything like this yet. I am just playing around in this case!

$(document).ready(function () {
    function addData() {
        var eventname = $("#eventname").val();
        var eventdate = $("#eventdate").val();
        var eventloc = $("#eventloc").val();
        var eventauthor = $("#eventauthor").val();
        var eventdesc = $("#eventdesc").val();

        if (eventname.trim() === '' || eventdate.trim() === '' || eventloc.trim() === '' || eventauthor.trim() === '' || eventdesc.trim() === '') {
            alert("Bitte f�llen Sie alle Felder aus");
            return;
        }

        if (!isValidDate(eventdate)) {
            alert("Datum muss folgendem Format entsprechen: dd.mm.yyyy ein");
            return;
        }

        // Validierung und Hinzuf�gen zur Tabelle

        $(".table tbody tr").last().after(
            '<tr>' +
            '<td><input type="checkbox" id="select-row"></td>' +
            '<td>' + eventname + '</td>' +
            '<td>' + eventdate + '</td>' +
            '<td>' + eventloc + '</td>' +
            '<td>' + eventdesc + '</td>' +
            '<td>' + eventauthor + '</td>' +
            '<td><button class="btn btn-link like-button">Gefällt mir</button></td>' +
            '<td><div class="rate"><input type="radio" id="star5" name="rate" value="5" /><label for="star5" title="text">5 stars</label><input type="radio" id="star4" name="rate" value="4" /><label for="star4" title="text">4 stars</label><input type="radio" id="star3" name="rate" value="3" /><label for="star3" title="text">3 stars</label><input type="radio" id="star2" name="rate" value="2" /><label for="star2" title="text">2 stars</label><input type="radio" id="star1" name="rate" value="1" /><label for="star1" title="text">1 star</label></div></td>'
            + '</tr>'
        );

        function isValidDate(dateString) {
            var regex = /^\d{2}\.\d{2}\.\d{4}$/;
            return regex.test(dateString);
        }

    }

    // Eventlistener f�r den Button
    $('#addData').click(addData);

    $('.table').on('click', '.like-button', function () {
        $(this).toggleClass('liked');
        if ($(this).hasClass('liked')) {
            $(this).text('Gefällt mir nichtmehr');
            $(this).closest('tr').addClass('liked-event');
        } else {
            $(this).text('Gefällt mir');
            $(this).closest('tr').removeClass('liked-event');
        }
    });
});
*{
    margin: 0;
    padding: 0;
}
.rate {
    float: left;
    height: 46px;
    padding: 0 10px;
}
.rate:not(:checked) > input {
    position:absolute;
    top:-9999px;
}
.rate:not(:checked) > label {
    float:right;
    width:1em;
    overflow:hidden;
    white-space:nowrap;
    cursor:pointer;
    font-size:30px;
    color:#ccc;
}
.rate:not(:checked) > label:before {
    content: '★ ';
}
.rate > input:checked ~ label {
    color: #ffc700;    
}
.rate:not(:checked) > label:hover,
.rate:not(:checked) > label:hover ~ label {
    color: #deb217;  
}
.rate > input:checked + label:hover,
.rate > input:checked + label:hover ~ label,
.rate > input:checked ~ label:hover,
.rate > input:checked ~ label:hover ~ label,
.rate > label:hover ~ input:checked ~ label {
    color: #c59b08;
}
<!DOCTYPE html>

<head>
    <meta charset="utf-8" />
    <title>Eventüberblick</title>
    <link href="style.css" rel="stylesheet" type="text/css">

    <!-- Bootstrap 4 CDN -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <script src="Script1.js"></script>

    <!-- Fontawesome CDN Link -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" />
</head>

<header>
    <a href="index.html">Überblick</a>
    <a href="CreateEvent.html">Event erstellen</a>
</header>

<body>
    <h1 class="headline" style="text-align: center;">Neues Event</h1>


    <div class="container">

        <div class="form-div">
            <div class="row">
                <div class="col-md-3">
                    <input type = "text" class="form-control" id="eventname" placeholder="Eventname">
                </div>
                <div class="col-md-3">
                    <input type = "datetime" class="form-control" id="eventdate" placeholder="Eventdatum">
                </div>
                <div class="col-md-3">
                    <input type = "text" class="form-control" id="eventloc" placeholder="Eventort">
                </div>
                <div class="col-md-3">
                    <input type = "text" class="form-control" id="eventauthor" placeholder="Eventautor">
                </div>
                <div class="col-md-3">
                    <input type = "text" class="form-control" id="eventdesc" placeholder="Eventbeschreibung">
                </div>
                <div class="col-md-3" style="text-align: right;">
                    <button class="btn btn-primary" id="addData">Hinzufügen</button>
                </div>
            </div>
        </div>

        <h2 class="headline" style="text-align: center;">Eventliste</h2>
        <div class="container">
            <table class="table">
                <thead>
                    <tr>
                        <th>All<input type="checkbox" id="select-all"></th>
                        <th>Eventname</th>
                        <th>Eventdatum</th>
                        <th>Eventort</th>
                        <th>Eventbeschreibung</th>
                        <th>Eventautor</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                    
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

   <script></script> 

</body>


Solution

  • You have two issues in your javascript code.

    1. Each event had a series of checkboxes with the same id attribute across multiple events.
    2. Each event had a series of checkboxes with the same name attribute across multiple events.

    This means that each row had a checkbox with a name attribute called "star1", "star2", ... The browser doesn't know in which event (group of checkboxes) you clicked.

    I added the event name to the ID and the name attribute of each row and it works, because now the browser can make a distinction between each group of checkboxes per event.

    In your string, an input is changed to:

    <input type="radio" id="'+eventname+'5" name="'+eventname+'rate" value="5" />
    

    And now looks like this:

            $(".table tbody tr").last().after(
                '<tr>' +
                '<td><input type="checkbox" id="select-row"></td>' +
                '<td>' + eventname + '</td>' +
                '<td>' + eventdate + '</td>' +
                '<td>' + eventloc + '</td>' +
                '<td>' + eventdesc + '</td>' +
                '<td>' + eventauthor + '</td>' +
                '<td><button class="btn btn-link like-button">Gefällt mir</button></td>' +
                '<td><div class="rate"><input type="radio" id="'+eventname+'5" name="'+eventname+'rate" value="5" /><label for="'+eventname+'5" title="text">5 stars</label><input type="radio" id="'+eventname+'4" name="'+eventname+'rate" value="4" /><label for="'+eventname+'4" title="text">4 stars</label><input type="radio" id="'+eventname+'3" name="'+eventname+'rate" value="3" /><label for="'+eventname+'3" title="text">3 stars</label><input type="radio" id="'+eventname+'2" name="'+eventname+'rate" value="2" /><label for="'+eventname+'2" title="text">2 stars</label><input type="radio" id="'+eventname+'1" name="'+eventname+'rate" value="1" /><label for="'+eventname+'1" title="text">1 star</label></div></td>'
                + '</tr>'
            );
    

    The rest of your code (CSS, HTML) is fine. Here's the entire working code:

    $(document).ready(function () {
        function addData() {
            var eventname = $("#eventname").val();
            var eventdate = $("#eventdate").val();
            var eventloc = $("#eventloc").val();
            var eventauthor = $("#eventauthor").val();
            var eventdesc = $("#eventdesc").val();
    
            if (eventname.trim() === '' || eventdate.trim() === '' || eventloc.trim() === '' || eventauthor.trim() === '' || eventdesc.trim() === '') {
                alert("Bitte f�llen Sie alle Felder aus");
                return;
            }
    
            if (!isValidDate(eventdate)) {
                alert("Datum muss folgendem Format entsprechen: dd.mm.yyyy ein");
                return;
            }
    
            // Validierung und Hinzuf�gen zur Tabelle
    
            $(".table tbody tr").last().after(
                '<tr>' +
                '<td><input type="checkbox" id="select-row"></td>' +
                '<td>' + eventname + '</td>' +
                '<td>' + eventdate + '</td>' +
                '<td>' + eventloc + '</td>' +
                '<td>' + eventdesc + '</td>' +
                '<td>' + eventauthor + '</td>' +
                '<td><button class="btn btn-link like-button">Gefällt mir</button></td>' +
                '<td><div class="rate"><input type="radio" id="'+eventname+'5" name="'+eventname+'rate" value="5" /><label for="'+eventname+'5" title="text">5 stars</label><input type="radio" id="'+eventname+'4" name="'+eventname+'rate" value="4" /><label for="'+eventname+'4" title="text">4 stars</label><input type="radio" id="'+eventname+'3" name="'+eventname+'rate" value="3" /><label for="'+eventname+'3" title="text">3 stars</label><input type="radio" id="'+eventname+'2" name="'+eventname+'rate" value="2" /><label for="'+eventname+'2" title="text">2 stars</label><input type="radio" id="'+eventname+'1" name="'+eventname+'rate" value="1" /><label for="'+eventname+'1" title="text">1 star</label></div></td>'
                + '</tr>'
            );
    
            function isValidDate(dateString) {
                var regex = /^\d{2}\.\d{2}\.\d{4}$/;
                return regex.test(dateString);
            }
    
        }
    
        // Eventlistener f�r den Button
        $('#addData').click(addData);
    
        $('.table').on('click', '.like-button', function () {
            $(this).toggleClass('liked');
            if ($(this).hasClass('liked')) {
                $(this).text('Gefällt mir nichtmehr');
                $(this).closest('tr').addClass('liked-event');
            } else {
                $(this).text('Gefällt mir');
                $(this).closest('tr').removeClass('liked-event');
            }
        });
    });
    *{
        margin: 0;
        padding: 0;
    }
    .rate {
        float: left;
        height: 46px;
        padding: 0 10px;
    }
    .rate:not(:checked) > input {
        position:absolute;
        top:-9999px;
    }
    .rate:not(:checked) > label {
        float:right;
        width:1em;
        overflow:hidden;
        white-space:nowrap;
        cursor:pointer;
        font-size:30px;
        color:#ccc;
    }
    .rate:not(:checked) > label:before {
        content: '★ ';
    }
    .rate > input:checked ~ label {
        color: #ffc700;    
    }
    .rate:not(:checked) > label:hover,
    .rate:not(:checked) > label:hover ~ label {
        color: #deb217;  
    }
    .rate > input:checked + label:hover,
    .rate > input:checked + label:hover ~ label,
    .rate > input:checked ~ label:hover,
    .rate > input:checked ~ label:hover ~ label,
    .rate > label:hover ~ input:checked ~ label {
        color: #c59b08;
    }
    <!DOCTYPE html>
    
    <head>
        <meta charset="utf-8" />
        <title>Eventüberblick</title>
        <link href="style.css" rel="stylesheet" type="text/css">
    
        <!-- Bootstrap 4 CDN -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
        <script src="Script1.js"></script>
    
        <!-- Fontawesome CDN Link -->
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" />
    </head>
    
    <header>
        <a href="index.html">Überblick</a>
        <a href="CreateEvent.html">Event erstellen</a>
    </header>
    
    <body>
        <h1 class="headline" style="text-align: center;">Neues Event</h1>
    
    
        <div class="container">
    
            <div class="form-div">
                <div class="row">
                    <div class="col-md-3">
                        <input type = "text" class="form-control" id="eventname" placeholder="Eventname">
                    </div>
                    <div class="col-md-3">
                        <input type = "datetime" class="form-control" id="eventdate" placeholder="Eventdatum">
                    </div>
                    <div class="col-md-3">
                        <input type = "text" class="form-control" id="eventloc" placeholder="Eventort">
                    </div>
                    <div class="col-md-3">
                        <input type = "text" class="form-control" id="eventauthor" placeholder="Eventautor">
                    </div>
                    <div class="col-md-3">
                        <input type = "text" class="form-control" id="eventdesc" placeholder="Eventbeschreibung">
                    </div>
                    <div class="col-md-3" style="text-align: right;">
                        <button class="btn btn-primary" id="addData">Hinzufügen</button>
                    </div>
                </div>
            </div>
    
            <h2 class="headline" style="text-align: center;">Eventliste</h2>
            <div class="container">
                <table class="table">
                    <thead>
                        <tr>
                            <th>All<input type="checkbox" id="select-all"></th>
                            <th>Eventname</th>
                            <th>Eventdatum</th>
                            <th>Eventort</th>
                            <th>Eventbeschreibung</th>
                            <th>Eventautor</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                        
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    
       <script></script> 
    
    </body>