Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 8 of 8
  1. #1
    New Coder
    Join Date
    Nov 2015
    Location
    Germany
    Posts
    35
    Thanks
    20
    Thanked 0 Times in 0 Posts

    I need help to make a click function work for the current header i click on not all

    Greetings everybody!
    There is this assignment I have been doing for some hours now and it torments me. I Know I have to use this to complete my code and make it work for each h2 specificallynot all of them at the same time but I really do not know how to go about it. i have tried putting this nearly everywhere but it does not work. Please help me

    This is the assignment.
    This task illustrates the sliding effects that can be produced with jQuery. Create a div with the class my-item that contains two other divs, the first with the class item-header and the second with the class item-body. The item-header div contains an <h2> tag with some text (e.g. Click Me). The item-body div also contains some text, but the div is initially hidden. If the user clicks on the <h2> headline, the div item-body should slide down and its contents become visible. After another click on the headline, the div should slide up and its contents become invisible

    Extend your code from the previous task in such a way that a deep copy of the first div with the class my-item can be appended to the body of the document by clicking on a button. Be sure to modify your event handler from the previous task so that it also works for the new elements.

    this is what I did

    Code:
    <!DOCTYPE HTML>
    	<html>
    		<head>
    		<title></title>
    		<script src="library/jquery.js"></script>
    		<script>
    		
    			$(document).ready(function() {
    
                $('#copy').click(function(){
                $('.my-item:last').clone().appendTo('body');
    
                });
    
                $('.item-body').hide();
                $(document).on('click','h2', function() {
    
                if  ($('.item-body').is(':visible')) {
    					$('.item-body').slideUp();
    				}
    				else {
    
    					$('.item-body').slideDown();
    					
    				}
              
    
                                 
    
    		    });
               
    
    			
    
    
    			
    
    
    
    
    			});
    
    
    		</script>
    		</head>
    			<body>
    			<div class = 'my-item'>
    				<div class = 'item-header'>
                    	<h2>Jesus is the only Hope</h2>
    				</div><!--closing tag for for div item-header-->
    
    				<div class = 'item-body'>
                    	<h2>I believe in Him</h2>
                    		<p>je leve les yeux vers les monts que jaime dou peut me venir ici le secours. Le secours me vient de lEternel meme</p>
    				</div><!--closing tag for the div item-body-->
    
    		   </div><!-- This is the closing tag of div my_item-->
    		   <button id ='copy'>copy</button>
    			</body>
    	</html>

  2. #2
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    3,476
    Thanks
    57
    Thanked 633 Times in 628 Posts
    without doing your homework for you, you should look at the relation that the 'item-body' div has to the H2 that is clicked on, then use jQuery's traversing methods to target that div in particular: https://api.jquery.com/category/traversing/

  3. Users who have thanked xelawho for this post:

    mimireine (12-22-2015)

  4. #3
    New Coder
    Join Date
    Nov 2015
    Location
    Germany
    Posts
    35
    Thanks
    20
    Thanked 0 Times in 0 Posts
    thank you very much for the tipp xelawo I am going to study the problem from a different angle now and read on the traversing methods to know which one to use.

  5. #4
    New Coder
    Join Date
    Nov 2015
    Location
    Germany
    Posts
    35
    Thanks
    20
    Thanked 0 Times in 0 Posts
    Please I need help. I still have troubles with this exercise. It only works if the div that is supposed to be initially hidden is visible. Please could you tell me why?
    This is what I did with the helpful hints you gave me last time
    Code:
    <!DOCTYPE HTML>
    	<html>
    		<head>
    		<title>event 3</title>
    		<script src="library/jquery.js"></script>
    		<script>
    		/*3.Extend your code from the previous task in such a way that a deep copy of the first div with the class my-item can be appended to the body of the document by clicking on a button. Be sure to modify your event handler from the previous task so that it also works for the new elements.*/
    
    		$(document).ready(function() {
    
            	$('#copy').click(function(){
    
                $('.my-item:last').clone().appendTo('body');
    
                });
            
    
              		/*$('.item-body').hide();*/ 
    It is only when I disable this that the code works
    $(document).on( 'click','h2', function() { if($(this).parent().next().children().is(':visible')){ $(this).parent().next().children().slideUp(); } else{ $(this).parent().next().children().slideDown(); } /*$(this).parent().next().children().clone().appendTo('body').css({"color": "red", "border": "2px solid red"});// i first select the parent of my element then i select the next parent and its children (the paragraph inside item-body)*/ }) }); </script> </head> <body> <div class = 'my-item'> <div class = 'item-header'> <h2>Jesus is the only Hope</h2> </div><!--closing tag for for div item-header--> <div class = 'item-body'> <p>je leve les yeux vers les monts que jaime dou peut me venir ici le secours. Le secours me vient de lEternel meme</p> </div><!--closing tag for the div item-body--> </div><!-- This is the closing tag of div my_item--> <button id ='copy'>copy</button> </body> </html>

  6. #5
    Regular Coder
    Join Date
    Sep 2013
    Location
    Houston
    Posts
    119
    Thanks
    5
    Thanked 21 Times in 21 Posts
    Hey. You are really close, but this is a prime example as to why
    Code:
    .parent().next().children()
    style chaining is extremely brittle.

    I understand for the context of the homework you are just learning a few concepts, but I would avoid this style of programming if at all possible. The reason is if you are depending this heavily on dom node layout, and another developer comes along and changes the html structure your entire 'accordion' would stop working.

    If you will notice most large accordian style libraries require you to use certain classnames in order for them to initial properly. While they look through 'children' as well they at least do so with selectors using the required classnames. This at least allows you to adjust the dom node layout and still select the proper divs to expand or contract.

    Also libraries such as react tend to use unique 'key' identifiers to relate to their children this way you can be 100% sure you get the proper element.
    Ok I'll jump off the soap box. Now for your personal problem.

    Look at what you hide.
    Code:
    ('.item-body').hide();
    Then look at what you select
    Code:
    $(this).parent().next().children().slideUp();
    so lets break this down.
    this => H2 => parent => '.my-item' div => next => '.item-body' div => children() => p tag ...
    what good is showing or hiding the p tag going to do when you already hid its parent element?

    You can either remove the children() call altogether from all three chains OR you can change your initial hide call to hide the p tag instead of the containing div.

    Cheers

    PS: I cant stress this enough please format your code consistently before posting or working with other devlopers you will drive them nuts. Make sure your indentation no matter if 2 spaces, 4 or 5, or tabs (/cry) that you keep that same style consistent through BOTH html and your javascript.
    Last edited by Lesshardtofind; 01-04-2016 at 09:55 PM.
    if(poster === Lesshardtofind){
    output = !certified;
    }

  7. Users who have thanked Lesshardtofind for this post:

    mimireine (01-05-2016)

  8. #6
    New Coder
    Join Date
    Nov 2015
    Location
    Germany
    Posts
    35
    Thanks
    20
    Thanked 0 Times in 0 Posts
    thank you very much for your help. I do not understand what you mean at the beginning. When you talk about method chaining. Could you please break it further? Do you mean that I should use the names of the targetted elements instead?

  9. #7
    Regular Coder
    Join Date
    Sep 2013
    Location
    Houston
    Posts
    119
    Thanks
    5
    Thanked 21 Times in 21 Posts
    I do not understand what you mean at the beginning. When you talk about method chaining. Could you please break it further?
    Its going to be hard to explain what exactly that means without being to verbose, but I will take a shot at it.

    Firstly a method is basically a function that exists on the context of an object or class. An example would be:
    PHP Code:
    var myObject = {
      
    value10,
      
    add: function(toAdd){
        
    this.value += toAdd;
      }
    }

    myObject.add(10); /* myObject.value is now 20 */ 
    Anytime you call a .functionName on an object you are using a method.

    A method chain is a paradigm made popular by functional programming languages and libraries such as jQuery. This paradigm is accomplished by returning the object that has those methods. The above example could use method chaining, by returning the object itself. Here is an example:

    PHP Code:
    var myObject = {
      
    value10,
      
    add: function(toAdd){
        
    this.value += toAdd;
        return 
    this/* this line is key to allowing chaining */
      
    }
    }

    myObject.add(10).add(1).add(9); /* myObject.value is now 30 */ 
    As you can see the chaining paradigm is super useful and accomplishes very difficult tasks in one line of code.

    The problem I mention is not with chaining but with fragile chains. Yours is heavily dependent on dom layout.
    PHP Code:
    <div class="accordion-container">
      <
    div class="accordion-target">
        <
    p>Some random text to click<p>
        <
    div>
          <
    p>More random text to be shown</p>
        </
    div>
      </
    div>
    </
    div
    So you could apply your type of situation on the above code by using non selected dom traversal such as $(this).next().slideDown().

    The problem is if some other elements are added it breaks the chain.

    PHP Code:
    <div class="accordion-container">
      <
    div class="accordion-target">
        <
    p>Some random text to click<p>
        <
    p>Added text that breaks your chain</p>
        <
    div class="expand-me">
          <
    p>More random text to be shown</p>
        </
    div>
      </
    div>
    </
    div
    Now the above chain would fail because it would show hide the P tag instead of the div. You can get around this by using classes such as $(this).next('.expand-me'). Now it would always get the next expand-me div no matter what other elements were added to the dom.

    A common question I ask myself when I think I've finished coding is. When will this fail, or How do I break this now? This causes you to find the weakpoints in the code and learn to avoid them in the future.

    Do you mean that I should use the names of the targetted elements instead?
    In essence yes. You either use classnames or Ids to target depending on the situation, or you write a function that "initiates" on a target div.

    Ultimately its up to you. Coding is a form of self-expression and not to be controlled. Just start making the habit of refactoring code as this allows you to go through something that works and improve it. Therefor you learn from yourself and start the next project a little bit ahead of your last project.

    Hope this helps
    if(poster === Lesshardtofind){
    output = !certified;
    }

  10. Users who have thanked Lesshardtofind for this post:

    mimireine (01-06-2016)

  11. #8
    New Coder
    Join Date
    Nov 2015
    Location
    Germany
    Posts
    35
    Thanks
    20
    Thanked 0 Times in 0 Posts
    thank you so much for your help. I need some time to digest it.


 

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •