0

I'm trying to learn JS and jQuery and I'm using a project to do this. I've been scratching my head for the last 4 hours trying to figure out how to do something and I'm completely stuck.

Basically I want to update a div's content based on clicks from other div's using HTML data- attributes on the ".blue". I have price and description fields. I have managed to collect the data from the first div no matter where I click but then can't get this updated correctly based on the DIV I click in.

I've tried multiple combinations of $(this) keyword to try and make this work but couldn't figure it out. I've searched these forums and found somewhat a solution but couldn't get it, I think my mind is just too overwhelmed with this.

Here's the one I looked at: Update content in div, on click of another div

I'm sure this must be super simple but I can't get my head around it today.

Here's my code:

var upload = $('.blue').data('target1');
var download = $('.blue').data('target2');
var price = $(this).data('price');

$(document).ready(function() {
  $('.blue').on('click', function() {
      $(upload).removeClass('hide');
      $(download).removeClass('hide');
  });
  $('#price').text(price);
});
div {
  margin:0;
  padding:0;
}
.blue {
  background-color: #ddddEE;
  border: 1px solid black;
}
.blue:hover {
  cursor: pointer;
  background-color: #aaaaEE;
}
.red {
  background-color: #EEdddd;
  border: 1px solid black;
}
.bold {
  font-weight: 600;
  text-align: center;
}
.hide {
  display:none;
}
#price {
  font-size: 22px;
  color: blue;
  font-weight: 400;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-xs-3">
  <div class="col-xs-12 blue" data-target1="#target1" data-target2="#target2">
  <span>$</span><span data-price="300" id="1">300</span><br>
  <p id="desc1" class="hide">Description 1</p>
    <span>text here</span><br>
    <span>text here</span><br>
    <span>text here</span>
  </div>
</div>
<div class="col-xs-3">
  <div class="col-xs-12 blue" data-target1="#target3" data-target2="#target4">
  <span>$</span><span data-price="600" id="2">600</span><br>
   <p id="desc2" class="hide">Description 2</p>
    <span>text here</span><br>
    <span>text here</span><br>
    <span>text here</span>
  </div>
</div><div class="col-xs-3">
  <div class="col-xs-12 blue" data-target1="#target5" data-target2="#target6">
  <span>$</span><span class="prices" data-price="1200" id="3">1200</span><br>
     <p id="desc3" class="hide">Description 3</p>
    <span>text here</span><br>
    <span>text here</span><br>
    <span>text here</span>
  </div>
</div>
<div class="col-xs-3">
  <div class="col-xs-12 red">
    <span class="bold">Summary</span><br>
    <div id="target1" class="hide"><span>TARGET 1</span></div>
    <div id="target2" class="hide"><span>TARGET 2</span></div>.
    <div id="target3" class="hide"><span>TARGET 3</span></div>
    <div id="target4" class="hide"><span>TARGET 4</span></div>
    <div id="target5" class="hide"><span>TARGET 5</span></div>
    <div id="target6" class="hide"><span>TARGET 6</span></div>
    <span id="price" class=""></span>
  </div>
</div>

Here is my fiddle: https://jsfiddle.net/rodcunha/qav9sn6n/42/

Thank you in advance for any help for this newbie.

Community
  • 1
  • 1
rodcunha
  • 387
  • 1
  • 16

4 Answers4

0

Replace you code by:

  $(document).ready(function() {
      $('.blue').on('click', function(e) {
        $($(e.currentTarget).data('target1')).removeClass('hide');
        $($(e.currentTarget).data('target2')).removeClass('hide');
        $('#price').text($(e.target).parent().find('.price').data('price'));
      });
  }); 
Brent Boden
  • 569
  • 2
  • 10
0

Add a price class for every span data-price.

<span>$</span><span class="price" data-price="300" id="1">300</span><br>

HTML:

<div class="col-xs-3">
    <div class="col-xs-12 blue" data-target1="#target1" data-target2="#target2">
      <span>$</span><span class="price" data-price="300" id="1">300</span><br>
      <p id="desc1" class="hide">Description 1</p>
      <span>text here</span><br>
    </div>
</div>

<div class="col-xs-3">
    <div class="col-xs-12 blue" data-target1="#target3" data-target2="#target4">
       <span>$</span><span class="price" data-price="600" id="2">600</span><br>
       <p id="desc2" class="hide">Description 2</p>
       <span>text here</span><br>
    </div>
</div>

<div class="col-xs-3">
    <div class="col-xs-12 blue" data-target1="#target5" data-target2="#target6">
      <span>$</span><span class="prices price" data-price="1200" id="3">1200</span><br>
      <p id="desc3" class="hide">Description 3</p>
      <span>text here</span><br>
    </div>
</div>

<div class="col-xs-3">
  <div class="col-xs-12 red">
    <span class="bold">Summary</span><br> 

    <!-- add 'summary' class for all div -->
    <div id="target1" class="hide summary"><span>TARGET 1</span></div>
    <div id="target2" class="hide summary"><span>TARGET 2</span></div>
    <div id="target3" class="hide summary"><span>TARGET 3</span></div>
    <div id="target4" class="hide summary"><span>TARGET 4</span></div>
    <div id="target5" class="hide summary"><span>TARGET 5</span></div>
    <div id="target6" class="hide summary"><span>TARGET 6</span></div>
    <span id="price" class=""></span>
  </div>
</div>

To get the current clicked div use currentTarget instead of target because currentTarget always return .blue contains div as event listner is set on '.blue' but target results can be different depending on your click position into .blue class div.

jQuery:

$(document).ready(function() {
      $('.blue').on('click', function(e) {
          var upload = $(e.currentTarget).data('target1');
          var download = $(e.currentTarget).data('target2');
          var price = $(e.target).parent().find('.price').data('price');

         // add a new class 'summary' for all 'summary id div'.
         //   loop over all '.summary' class and add 'hide' class   

         $('.summary').each(function(index, item) {
           // console.log(item);
           $(item).removeClass('hide').addClass('hide');
         }); 

          $(upload).removeClass('hide');
          $(download).removeClass('hide');
          $('#price').text(price);

      });

  }); 


jsfiddle link: https://jsfiddle.net/sajibcse68/qav9sn6n/49/

Sajib Khan
  • 22,878
  • 9
  • 63
  • 73
  • That's a great reply thank you. Only thing is that it doesn't replace the target description text, it just appends. I want to replace it but I have here something to work on and I will crack my head on it for a while to try and figure it out. Appreciate your reply Sajib. – rodcunha Feb 21 '17 at 20:24
  • Thank you so much for your time to reply to my question Sajib. I really appreciate it. – rodcunha Feb 21 '17 at 20:36
  • Welcome. Now summary is replaced with target description text. Edited my answer. Check also jsfiddle. – Sajib Khan Feb 22 '17 at 03:21
0

I'm not sure is this the behaviour you want, can you check it?

https://jsfiddle.net/rodcunha/qav9sn6n/42/

$(document).ready(function() {  

      $('.blue').click(function() {          
          var x = $(this).attr('data-target1');      
          $(x).removeClass('hide');
      });
      $('#price').text(price);
 }); 

if You want to add or remove class hide clicking again on the div you can change the removeClass to toggleClass.

Luiz Rossi
  • 772
  • 5
  • 19
  • Luiz, thank you so much for your time ans explanation. With the help of other users I was able to figure it out. – rodcunha Feb 21 '17 at 20:37
0

To understand the cause of your problem, and how to solve it, you have to be careful in the present case of when the various instructions you've written are evaluated, and also how some of the jQuery instructions you use work.

First thing to note: the first three lines of your Javascript code are evaluated just after they have been read. So after they are evaluated, the state of your variables is as follows :

upload = '#target1'
download = '#target2'
price = undefined

Since these are the values used in the rest of the code, in all cases, you can see why it always shows what you expect for the first <div> only. To understand why, let's analyze the first line :

var upload =
    $('.blue')       [1]
    .data('target1') [2]
  • [1] returns the jQuery collection containing the DOM <div> elements that have the blue class. So far, so good?
  • [2] returns the value associated with the data-target1 attribute of the first element of the jQuery collection (see documentation for the .data method)

What you probably want is for upload, download and price to contain the values of the data-* attributes corresponding to the <div> the user clicks on. You cannot know in advance which element the user will click on, so it does not make sense to read the values before the user clicks on anything. So you should read the values when the event is processed.

According to jQuery's documentation for the event handlers, this is the element the event is currently associated with. So your <div> element.

Now that you know that, you probably realized what you should do to correct your code. By moving your existing code around and making the smallest changes possible, you end up with the following working code.

$(document).ready(function() {
    $('.blue').on('click', function() {
        var upload = $(this).data('target1');
        $(upload).removeClass('hide');
        var download = $(this).data('target2');
        $(download).removeClass('hide');

        var price = $(this).find('[data-price]').data('price');
        $('#price').text(price);
    });
});
KevinLH
  • 328
  • 3
  • 10
  • I have no words to thank you for your explanation. That was very informative and very generous from you. I really appreciate the time and effort you have put to explain this concept to me. I am still in the early days of learning and I have a lot to get around and I'm struggling with reading books so I've decided to take on personal projects and challenge myself as a way to learn. – rodcunha Feb 21 '17 at 20:33
  • I was looking for it to replace the text in the description but after seeing and understanding your code it was quick to figure out how to do that. Thank you again. here's what I wanted to do: `$(document).ready(function() { $('.blue').on('click', function() { $('.red div').addClass('hide') var upload = $(this).data('target1'); $(upload).removeClass('hide'); var download = $(this).data('target2'); $(download).removeClass('hide'); var price = $(this).find('[data-price]').data('price'); $('#price').text(price); }); });` – rodcunha Feb 21 '17 at 20:35
  • Glad to have been of help. Reading books and tutorials is a good way to have a basic understanding of the developer's tools and its underlying concepts (it is not something to be skipped), but nothing beats tinkering around, making mistakes and discussing them with others for what your learned to stick with you. ;-) – KevinLH Feb 22 '17 at 09:23
  • If your current issue has been solved, do not forget to accept one of the answers (the one you found most helpful, that is the most susceptible to help other people who have the same problem in the future and find this Q&A). Happy learning! – KevinLH Feb 22 '17 at 09:26
  • Really appreciate your help. Solution chosen and once again thank you so much. Let me know if you're ever in Dublin, more than glad to buy you a coffee. :) – rodcunha Feb 22 '17 at 11:18