-2

So I'm busy creating a mini webshop, and I'm using google's front-end (MDL) template

What I wanted to do in my webshop is, when a user clicks on x product I want to toggle a class,

I'm using closures inside loops to detect clicks on any product.

My only issue is, the class won't toggle. I tried using addClass which does work but its not as convenient because I really want to toggle the class (From selected product to not selected)

Checkout my snippet & you will understand, you will see that I do detect the clicks properly. But toggling the classes doesn't work.

$(document).ready(function() {
 console.log("Document ready");
  for (var i = 1; i < $(".products").length; i++) {
  (function(index){
  $(".products").click(
   function(e){
   console.log("click successfull!");
         console.log(this);
          $(this).css("border", "1px solid #1976D2");
          
          $(this).toggleClass("mdl-shadow--16dp");
      });
  })(i);
 }

 $("#Card").keyup(function(event){
         if(event.keyCode == 84){
         console.log("Class toggled!");
         $(".products").toggleClass("mdl-shadow--2dp mdl-shadow--16dp");
         }
     });
  
  });
.mdl-card__actions{
  display: flex;
  box-sizing:border-box; 
  align-items: center;
}
.page-content .mdl-card {
 display: inline-block;
 margin: 5px 5px 5px 5px; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.2/material.indigo-pink.min.css">
    <script src="https://storage.googleapis.com/code.getmdl.io/1.0.2/material.min.js"></script>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
   <div class="page-content">
       <!-- Your content goes here -->
       <div class="mdl-card mdl-shadow--2dp products">
        <div class="mdl-card__title">
         <h2 class="mdl-card__title-text">Dell XP13 </h2>
        </div>
        <img src="https://goo.gl/gDDH0i" alt="dell xp13">
        <div class="mdl-card__supporting-text"><b>Basisprijs: 1.649,00$<b></div>
        <div class="mdl-card__actions mdl-card--border">
         <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
          Add to cart
         </a>
         <div class="mdl-layout-spacer"></div>
         <i class="material-icons">add_shopping_cart</i>
        </div>
       </div>  
       <div class="mdl-card mdl-shadow--2dp products">
       <div class="mdl-card__title">
        <h2 class="mdl-card__title-text">Chromebook pixel2</h2>
       </div>
       <img src="https://goo.gl/pNie9C.png" alt="chrombook">
       <div class="mdl-card__supporting-text"><b>Basisprijs: 999,99$<b></div>
       <div class="mdl-card__actions mdl-card--border">
        <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
         Add to cart
        </a>
        <div class="mdl-layout-spacer"></div>
         <i class="material-icons">add_shopping_cart</i>
       </div>
      </div>
      <div class="mdl-card mdl-shadow--2dp products">
       <div class="mdl-card__title">
        <h2 class="mdl-card__title-text">Macbook 13'</h2>
       </div>
       <img src="https://goo.gl/qzq0Cr" alt="Macbook">
       <div class="mdl-card__supporting-text"><b>Basisprijs: 1.129,00$<b></div>
       <div class="mdl-card__actioder">
        <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
         Add to cart
        </a>
        <div class="mdl-layout-spacer"></div>
         <i class="material-icons">add_shopping_cart</i>
       </div>
      </div>
     </div>
  </body>

I will show you the effect I'm toggling in a separate link, in this link I'm toggling the effect for all the "divs" But I won't it to be per click.

realappie
  • 4,656
  • 2
  • 29
  • 38

2 Answers2

1

I'm not sure for what you would need a loop here, but in my opionion this could be the reason why it wasn't working. I've set up a snippet without a loop, so now toggleClass() works well, I've also added a .border class to css, it's easier to handle it like this. Further, I've combined both toggleClass() in one line, but it's just an optical thing.

Check out the snippet

$(document).ready(function() {
  console.log("Document ready");
  $(".products").click(function() {
    console.log("click successfull!");
    console.log(this);
    $(this).toggleClass("border").toggleClass("mdl-shadow--16dp");

  });

  $("#Card").keyup(function(event) {
    if (event.keyCode == 84) {
      console.log("class toggled!");
      $(".products").toggleClass("mdl-shadow--2dp mdl-shadow--16dp");
    }
  });
});
.mdl-card__actions {
  display: flex;
  box-sizing: border-box;
  align-items: center;
}
.page-content .mdl-card {
  display: inline-block;
  margin: 5px 5px 5px 5px;
}
.border {
  border: 1px solid #1976D2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://storage.googleapis.com/code.getmdl.io/1.0.2/material.indigo-pink.min.css">
<script src="https://storage.googleapis.com/code.getmdl.io/1.0.2/material.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div class="page-content">
    <!-- Your content goes here -->
    <div class="mdl-card mdl-shadow--2dp products">
      <div class="mdl-card__title">
        <h2 class="mdl-card__title-text">Dell XP13 </h2>
      </div>
      <img src="https://goo.gl/gDDH0i" alt="dell xp13">
      <div class="mdl-card__supporting-text"><b>Basisprijs: 1.649,00$<b></div>
        <div class="mdl-card__actions mdl-card--border">
         <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
          Add to cart
         </a>
         <div class="mdl-layout-spacer"></div>
         <i class="material-icons">add_shopping_cart</i>
        </div>
       </div>  
       <div class="mdl-card mdl-shadow--2dp products">
       <div class="mdl-card__title">
        <h2 class="mdl-card__title-text">Chromebook pixel2</h2>
       </div>
       <img src="https://goo.gl/pNie9C.png" alt="chrombook">
       <div class="mdl-card__supporting-text"><b>Basisprijs: 999,99$<b></div>
       <div class="mdl-card__actions mdl-card--border">
        <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
         Add to cart
        </a>
        <div class="mdl-layout-spacer"></div>
         <i class="material-icons">add_shopping_cart</i>
       </div>
      </div>
      <div class="mdl-card mdl-shadow--2dp products">
       <div class="mdl-card__title">
        <h2 class="mdl-card__title-text">Macbook 13'</h2>
       </div>
       <img src="https://goo.gl/qzq0Cr" alt="Macbook">
       <div class="mdl-card__supporting-text"><b>Basisprijs: 1.129,00$<b></div>
       <div class="mdl-card__actioder">
        <a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
         Add to cart
        </a>
        <div class="mdl-layout-spacer"></div>
         <i class="material-icons">add_shopping_cart</i>
       </div>
      </div>
     </div>
  </body>
Ramiz Wachtler
  • 5,623
  • 2
  • 28
  • 33
  • I looped through them because that's how I achieved something similar in another project where I would take the innerHTML of the clicked element. But I definitely overthink-ed how I should have achieved this, thanks for the editeed snippet, I understand what I could have done it much simpler now. Its just confused me the CSS borders worked but the toggleClass() didn't. – realappie Aug 30 '15 at 22:42
  • 1
    Well, I think you misunderstood the way how `.click(...)` listener works. As I said before, it's not necessary to loop through every button, because as the name already says it's an event **listener**. So it's like always waiting for your interaction to fire the handler function, specially when you've more buttons which have the same class, the listener will be triggered as soon as one of them will be clicked, no matter which one (just one to which class, ID or other attribute the listener is bound) – Ramiz Wachtler Aug 31 '15 at 07:41
  • 1
    Yes, you are absolutely right about thee fact I misunderstood how the the listener worked. Reading this question 5 weeks after asking it makes me feel very oblivious, I understand everything a lot better now, thanks for taking the time explaining & demonstrating me how "this" works. I use it a LOT now. – realappie Oct 10 '15 at 01:19
  • You're welcome! I'm glad to hear that :-) – Ramiz Wachtler Oct 10 '15 at 08:48
0

the problem is only in your loop. If you are using class selector and bind the event then why are you looping it. So instead of using

for (var i = 1; i < $(".products").length; i++) {
    (function(index){
    $(".products").click(
        function(e){
        console.log("click successfull!");
        console.log(this);
         $(this).css("border", "1px solid #1976D2");

         $(this).toggleClass("mdl-shadow--16dp");
        });
    })(i);
}

use the below code

$(".products").click(
    function(e){
    console.log("click successfull!");
    console.log(this);
    $(this).css("border", "1px solid #1976D2");
    $(this).toggleClass("mdl-shadow--16dp");
});

Please let me know you will face any issue.

Eshu
  • 359
  • 1
  • 8
  • I looped through them because that's how I achieved something similar in another project where I would take the innerHTML of the clicked element. But I definitely overthink-ed how this should have done, thanks man! – realappie Aug 30 '15 at 22:39