1

In the code snippet below, you can press the yellow button and make it green (alternatively, press the green button and make it yellow). However, if you click them again, they don't return to the previous state again even though I have that covered in my script as well. I discovered a similar problem in my project (of course, it's not just about the color). It appears, jQuery scripts "remember" the HTML they "saw" the first time the page was loaded and never consider any changes to the code a user may make. If the page is refreshed, my scripts work the other way too

enter image description here

enter image description here

$(document).ready(function () {
    $('td a.btn-outline-warning').on('click', async function () {
        let username = $(this).closest('tr').children().eq(0).text();
        console.log(`username in disable event handler: ${username}`);
// ...

$(document).ready(function () {
    $('td a.btn-outline-success').on('click', async function () {
        let username = $(this).closest('tr').children().eq(0).text();
        console.log(`username in enable event handler: ${username}`);
// ...

Why does this happen and how do I fix it?

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
              integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
        <title>Admin Page</title>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <table class="table table-hover text-center">
                      <thead>
                            <tr>
                                <th scope="col">Name</th>
                                <th scope="col">Last name</th>
                                <th scope="col">Department</th>
                                <th scope="col">Buttons</th>
                            </tr>
                      </thead>
                      <tbody>
                            <tr>
                                <td>John</td>
                                <td>Doe</td>
                                <td>IT</td>
                                <td class="btn-group btn-group-sm">
                                    <a class="btn btn-outline-warning" href="#">Yellow button</a>
                                </td>
                            </tr>
                            <tr>
                                <td>Jane</td>
                                <td>Doe</td>
                                <td>HR</td>
                                <td class="btn-group btn-group-sm">
                                    <a class="btn btn-outline-success" href="#">Green button</a>
                                </td>
                            </tr>
                     </tbody>
              </table>
          </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
    <script>
$(document).ready(function () {
$('td a.btn-outline-warning').on('click', async function () {

    $(this).removeClass('btn-outline-warning')
        .addClass('btn-outline-success')
        .text('Green button');
});
});

$(document).ready(function () {
$('td a.btn-outline-success').on('click', async function () {
    $(this).removeClass('btn-outline-success')
        .addClass('btn-outline-warning')
        .text('Yellow button');
});
});
    </script>
    </body>
    </html>
Phil
  • 157,677
  • 23
  • 242
  • 245
  • You only query for the elements by class once when the page is loaded. Changing the element's class after that won't make it included in the previously found collection. Your best bet is to use event delegation (see the duplicate) – Phil Apr 12 '23 at 01:59
  • FYI your example code is excellent. Wish all questions were this thorough – Phil Apr 12 '23 at 01:59
  • 1
    Here's an event delegation example ~ https://jsfiddle.net/sbft4ckm/ – Phil Apr 12 '23 at 02:11
  • @Phil why did you remove the second code snippet? I'm sure folks that struggle with the same issue would appreciate it – Sergey Zolotarev Apr 12 '23 at 02:38
  • Solutions don't belong in questions. The duplicate link at the top is enough – Phil Apr 12 '23 at 02:39
  • An alternative solution is to not assign events to classes that change - ie: instead of `$('td a.btn-outline-warning')` use `$('td a.btn-outline-toggle')` then check the state within the event handler. Here's a simple example: https://jsfiddle.net/Ljqnxa98/ this could be simplified eg using toggleClass and even have the text set via css. – freedomn-m Apr 12 '23 at 05:48

0 Answers0