0

I want to remove the whole table when a delete button in the table's last row is clicked, but nothing works. Should I use a loop or if statement? If so, then where? Or what anonymous function should be declared and then checked if there is any row in the table?

Here's what I have so far:

$(".delete").on("click", function() {
    $(this).parent().parent().fadeOut(500, function(){
    $(this).remove()});
});

This is for a cart in a web store. Users delete some goods from cart, and when it's empty, I'd like it to show "Your cart is empty" without an empty table.

Full code:

$(".delete").on("click", function() {
    $(this).parent().parent().fadeOut(500, function(){
 $(this).remove()});
    
 });
body {
    width: 100%;
    max-width: 1080px;
}
h1 {
    margin-left: 75px;
    margin-top: 60px;
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 30px;
    color: rgba(73, 73, 73, 255);
    text-align: left; 
    font-weight: normal;
}

input {
    width: 63px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    border-bottom: 1px solid gray;
    border-right: 1px solid gray;
}

input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button {
    opacity: 1;
}


th {
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 16px;
    color: rgba(144, 144, 144, 255);
    text-align: left;
    padding: 0px 30px 13px 20px;
    font-weight: normal;
    outline: none;
}

table {
    border-collapse: collapse;
    width: 100%;
}

td {
    padding: 20px;
    vertical-align: top;
    padding-top: 40px;
}

tbody {
    border: 1.5px solid gray;
}

tfoot {
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 20px;
    color: rgba(51, 51, 51, 255);
    text-align: right;
}

tfoot>tr {
    border: none;
}
    
tr {
    border-bottom: 0.5px solid gray;
}

p {
    margin: 10px 0;
}

.delete {
    border: none;
    outline: inherit;
    background: inherit;
    padding-left: 0;
    color: rgba(50, 96, 181, 255);
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 16px;
}

.delete:hover {
    font-weight: bolder;
}

.price-amount {
    width: 89%;
    height: 36%;
    margin: 17px auto;
    padding-bottom: 56px;
    overflow: auto;
}

.extra {
    border-collapse: separate;
    border-spacing: 0px;
}


.extra tr:first-child td {
    border-bottom: 0.5px solid gray;
}

.image {
    width: 130px;
}

.name {
    font-family: 'OpenSans-Bold', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 18px;
    color: rgba(50, 96, 181, 255);
    text-align: left;
    font-weight: bold;
}

.manufactura {
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 18px;
    color: rgba(51, 51, 51, 255);
    text-align: left;
}

.kat {
    font-family: OpenSans, AdobeInvisFont, MyriadPro-Regular;
    font-size: 18px;
    color: rgba(144, 144, 144, 255);
    text-align: left;    
}

.add {
    background: yellow;
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 16px;
    color: rgba(51, 51, 51, 255);
    text-align: center;
    border-radius: 5px;
}

.price {
    font-family: 'OpenSans-Bold', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 18px;
    color: rgba(148, 34, 34, 255);
    text-align: left;
    font-weight: 600;
}

@media(max-width: 640px) {
    .name, .manufactura, .kat {
        font-size: 14px;
    }
    
    .extra {
        border-collapse: collapse;
    }
    
    h1 {
        margin-left: 20px;
        font-size: 20px;
    }
    
    td {
        padding: 10px;
        border-right: 1px solid gray;
        border-left: 1px solid gray;
    }
    
    td:first-of-type, th:first-of-type {
          display: none;
    }
    
    tfoot>tr {
        background: green;
        color: white;
        border-bottom: 1px solid gray;
    }
    
}
<html>
<head>
    <meta charset="utf-8">
 <title></title>
    <link rel="stylesheet" href="style.css">
    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
</head>
<body>
    <h1 id="cartTitle">Спиcок покупок</h1>
<div class="price-amount">
    <table id="cart">
       <thead>
        <th></th>
        <th></th>
        <th id="price">Цена</th>
        <th id="amount">Количество</th>
       </thead>        
            <tbody>
            <tr>
                <td class="image"><img src="hair_clipper.jpg" alt=""></td>
                <td><span class="name">Машинка для стрижки детских волос<br>
                Ramill Baby Hair Clipper BHC330</span><br>
                <p><span class="manufactura">Производитель X</span><br>
                <span class="kat">Категория 1 > Категория 1.2 > Категория 1.3</span>
                </p>
                <button class="delete">Удалить</button>
                </td>
                <td class="price">2499 руб.</td>
                <td><input type="number" value="5"></td>
            </tr>
            <tr>
                <td class="image"><img src="baby_skyler.jpg" alt=""></td>
                <td><span class="name">Автокресло<br>
                Happy Baby Skyler</span>
                <p><span class="manufactura">Производитель Y</span><br>
                <span class="kat">Категория 2 > Категория 2.2 > Категория 2.3.5</span>
                </p>
                <button class="delete">Удалить</button>
                </td>
                <td class="price">18450 руб.</td>
                <td><input type="number" value="1"></td>
            </tr>
            </tbody>
            <tfoot>
                <tr>
                <td></td>
                <td colspan="3">Итого: 100500 руб.</td>
                </tr>
            </tfoot>
        </table>
    </div>
    <h1>Список товаров</h1>
    <div class="price-amount">
        <table class="extra">
       <thead>
        <th></th>
        <th></th>
        <th>Цена</th>
        <th>Количество</th>
       </thead>        
            <tbody>
            <tr>
                <td class="image"><img src="chico.jpg" alt=""></td>
                <td><span class="name">Погремушка-прорезыватель "жираф"<br>
                Chicco</span><br>
                <p><span class="manufactura">Производитель A</span><br>
                <span class="kat">Категория 3 > Категория 3.3 > Категория 3.2.1</span>
                </p>
                <button class="add">В корзину</button>
                </td>
                <td class="price">250 руб.</td>
                <td><input type="number" value="1"></td>
            </tr>
            <tr>
                <td class="image"><img src="smart_cam.jpg" alt=""></td>
                <td><span class="name">Wi-Fi видеоняня<br>
                Samsung SmartCam SNH-V6410PNW</span><br>
                <p><span class="manufactura">Производитель B</span><br>
                <span class="kat">Категория 2 > Категория 2.2 > Категория 2.3.5</span>
                </p>
                <button class="add">В корзину</button>
                </td>
                <td class="price">13999 руб.</td>
                <td><input type="number" value="1"></td>
            </tr>
            </tbody>
        </table>
    </div>
<script rel="tex/javascript" src="cart.js"></script>
</body>
</html>
cjl750
  • 4,380
  • 3
  • 15
  • 27
Daniyal Lukmanov
  • 1,149
  • 10
  • 21

1 Answers1

0

The JS you had going in your CodePen wasn't quite right, but one of the reasons it wasn't doing anything at all is because you had included the full HTML markup in the HTML edit pane. You are only supposed to add the code that goes between the <body></body> tags. You can add jQuery in the pen's settings.

Once we get the clicks actually registering by fixing that issue, we can worry about the code.

You can use .closest() to traverse up the tree from the delete button and find the nearest tr and nearest table to figure out what should be deleted.

From there, here is what we do:

  1. When clicking delete, find the nearest row, and fade it out
  2. Check the number of rows in the table
  3. Using a setTimeout function, delete either the nearest row or the entire table after the fade animation has completed, depending on if there is more than one row left in the table or not.

 

$(".delete").on("click", function() {
  var thisRow = $(this).closest('tr');
  var thisTable = $(this).closest('table');
  var numRows = $(thisTable).find('tbody tr').length;

  $(thisRow).fadeOut(500);

  setTimeout(function(){
    if(numRows === 1) {
      $(thisTable).remove();
    } else {
      $(thisRow).remove();
    }
    //insert 'Your cart is empty' message here
  }, 510);

});

$(".delete").on("click", function() {
  var thisRow = $(this).closest('tr');
  var thisTable = $(this).closest('table');
  var numRows = $(thisTable).find('tbody tr').length;

  $(thisRow).fadeOut(500);
  setTimeout(function(){
    $(thisRow).remove();
  }, 510);
  
  if(numRows === 1) {
    setTimeout(function(){
      $(thisTable).remove();
    }, 510);
    
    //insert 'Your cart is empty' message here
  }
  
});
body {
    width: 100%;
    max-width: 1080px;
}
h1 {
    margin-left: 75px;
    margin-top: 60px;
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 30px;
    color: rgba(73, 73, 73, 255);
    text-align: left; 
    font-weight: normal;
}

input {
    width: 63px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    border-bottom: 1px solid gray;
    border-right: 1px solid gray;
}

input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button {
    opacity: 1;
}


th {
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 16px;
    color: rgba(144, 144, 144, 255);
    text-align: left;
    padding: 0px 30px 13px 20px;
    font-weight: normal;
    outline: none;
}

table {
    border-collapse: collapse;
    width: 100%;
}

td {
    padding: 20px;
    vertical-align: top;
    padding-top: 40px;
}

tbody {
    border: 1.5px solid gray;
}

tfoot {
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 20px;
    color: rgba(51, 51, 51, 255);
    text-align: right;
}

tfoot>tr {
    border: none;
}
    
tr {
    border-bottom: 0.5px solid gray;
}

p {
    margin: 10px 0;
}

.delete {
    border: none;
    outline: inherit;
    background: inherit;
    padding-left: 0;
    color: rgba(50, 96, 181, 255);
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 16px;
}

.delete:hover {
    font-weight: bolder;
}

.price-amount {
    width: 89%;
    height: 36%;
    margin: 17px auto;
    padding-bottom: 56px;
    overflow: auto;
}

.extra {
    border-collapse: separate;
    border-spacing: 0px;
}


.extra tr:first-child td {
    border-bottom: 0.5px solid gray;
}

.image {
    width: 130px;
}

.name {
    font-family: 'OpenSans-Bold', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 18px;
    color: rgba(50, 96, 181, 255);
    text-align: left;
    font-weight: bold;
}

.manufactura {
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 18px;
    color: rgba(51, 51, 51, 255);
    text-align: left;
}

.kat {
    font-family: OpenSans, AdobeInvisFont, MyriadPro-Regular;
    font-size: 18px;
    color: rgba(144, 144, 144, 255);
    text-align: left;    
}

.add {
    background: yellow;
    font-family: 'OpenSans', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 16px;
    color: rgba(51, 51, 51, 255);
    text-align: center;
    border-radius: 5px;
}

.price {
    font-family: 'OpenSans-Bold', 'AdobeInvisFont', 'MyriadPro-Regular', sans-serif;
    font-size: 18px;
    color: rgba(148, 34, 34, 255);
    text-align: left;
    font-weight: 600;
}

@media(max-width: 640px) {
    .name, .manufactura, .kat {
        font-size: 14px;
    }
    
    .extra {
        border-collapse: collapse;
    }
    
    h1 {
        margin-left: 20px;
        font-size: 20px;
    }
    
    td {
        padding: 10px;
        border-right: 1px solid gray;
        border-left: 1px solid gray;
    }
    
    td:first-of-type, th:first-of-type {
          display: none;
    }
    
    tfoot>tr {
        background: green;
        color: white;
        border-bottom: 1px solid gray;
    }
    
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 id="cartTitle">Спиcок покупок</h1>
<div class="price-amount">
  <table id="cart">
    <thead>
      <th></th>
      <th></th>
      <th id="price">Цена</th>
      <th id="amount">Количество</th>
    </thead>        
    <tbody>
      <tr>
        <td class="image"><img src="hair_clipper.jpg" alt=""></td>
        <td><span class="name">Машинка для стрижки детских волос<br>
          Ramill Baby Hair Clipper BHC330</span><br>
          <p><span class="manufactura">Производитель X</span><br>
            <span class="kat">Категория 1 > Категория 1.2 > Категория 1.3</span>
          </p>
          <button class="delete">Удалить</button>
        </td>
        <td class="price">2499 руб.</td>
        <td><input type="number" value="5"></td>
      </tr>
      <tr>
        <td class="image"><img src="baby_skyler.jpg" alt=""></td>
        <td><span class="name">Автокресло<br>
          Happy Baby Skyler</span>
          <p><span class="manufactura">Производитель Y</span><br>
            <span class="kat">Категория 2 > Категория 2.2 > Категория 2.3.5</span>
          </p>
          <button class="delete">Удалить</button>
        </td>
        <td class="price">18450 руб.</td>
        <td><input type="number" value="1"></td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td></td>
        <td colspan="3">Итого: 100500 руб.</td>
      </tr>
    </tfoot>
  </table>
</div>
<h1>Список товаров</h1>
<div class="price-amount">
  <table class="extra">
    <thead>
      <th></th>
      <th></th>
      <th>Цена</th>
      <th>Количество</th>
    </thead>        
    <tbody>
      <tr>
        <td class="image"><img src="chico.jpg" alt=""></td>
        <td><span class="name">Погремушка-прорезыватель "жираф"<br>
          Chicco</span><br>
          <p><span class="manufactura">Производитель A</span><br>
            <span class="kat">Категория 3 > Категория 3.3 > Категория 3.2.1</span>
          </p>
          <button class="add">В корзину</button>
        </td>
        <td class="price">250 руб.</td>
        <td><input type="number" value="1"></td>
      </tr>
      <tr>
        <td class="image"><img src="smart_cam.jpg" alt=""></td>
        <td><span class="name">Wi-Fi видеоняня<br>
          Samsung SmartCam SNH-V6410PNW</span><br>
          <p><span class="manufactura">Производитель B</span><br>
            <span class="kat">Категория 2 > Категория 2.2 > Категория 2.3.5</span>
          </p>
          <button class="add">В корзину</button>
        </td>
        <td class="price">13999 руб.</td>
        <td><input type="number" value="1"></td>
      </tr>
    </tbody>
  </table>
</div>
cjl750
  • 4,380
  • 3
  • 15
  • 27
  • It works just as i need. Thanks. But unfortunately another task that i can't solve yet: the second table with another goods that can be added to the cart - when click the yellow button (class="add") that item should be added to the cart table and change the button to another with class="delete" and be just as another goods in cart. And that added item should remain on it's previous place too. – Daniyal Lukmanov Aug 23 '17 at 19:22
  • @DaniyalLukmanov That sounds like something to ask in a separate question, but in general you could probably use a similar technique of using `.closest()` to find the nearest `tr` to the add button, then use `.clone()` to make a copy of it. Then add the clone to the cart table with `.append()` or something similar. Once it's added, you can select the add button and change its class with the `.attr()` method and change its text with the `.text()` method. Make sense? – cjl750 Aug 23 '17 at 19:31
  • I tried to use .append() and got not what i wanted. I will try again with using .closest() and .clone() as you mentioned. If nothing happens i should probably ask again. I'm just trying to get a little deeper in JS/JQuery by myself. – Daniyal Lukmanov Aug 23 '17 at 19:36
  • @DaniyalLukmanov Here, I forked your pen to add that functionality. [https://codepen.io/cjl750/pen/VzdEPP](https://codepen.io/cjl750/pen/VzdEPP). Let me know when you get that copied because I will probably delete the pen from my own profile after that. Also, please consider accepting and upvoting this answer. – cjl750 Aug 23 '17 at 19:42
  • Did it. The only issue is that after new items added to the cart they can't be deleted. But i fixed that. Thanks for you answer. You really motivated me to learn it harder. – Daniyal Lukmanov Aug 23 '17 at 19:46
  • @DaniyalLukmanov Yes, notice how in my forked pen I have changed `$('.delete').on('click', function(){...` to `$(document).on('click', '.delete', function(){...`. That will solve that problem. See [this question](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) about that. – cjl750 Aug 23 '17 at 19:48
  • @DaniyalLukmanov No problem! Good luck with the rest of your project. – cjl750 Aug 23 '17 at 19:49