skip to Main Content

I’ve got a nested div that contains ‘additional information’.

When a person clicks the div, it opens the ‘additional information’ div.

I have used .stopPropagation() to prevent it from closing when the person clicks the text in the ‘additional information’, but if they click the borders or something, the collapse happens and the information goes away.

I found this SO post – which was seemingly close to what I wanted, but I couldn’t figure out how to make it work exactly how I need.

Here is a codepen of what I’m trying to accomplish.

$('#collapsDiv').on('show.bs.collapse', function( event ) {
	event.stopPropagation();
    console.log('Only happen when outter div is opened');
})
$('#collapseDiv').on('hide.bs.collapse', function( event ) {
	event.stopPropagation();
	console.log('Only happen when outter div is collapsed');
})
$('#additionalDiv').on('click', function( event ) {
    event.stopPropagation();
})

$('#collapseDiv').click(function(e) {
     if (e.pageY > $(this).offset().top + $(this).height()) {
          // bottom was clicked
          console.log('bottom clicked!');
          e.stopPropagation();
     } else {
          // up of the div was clicked
          console.log('top clicked');
     }
});
#collapseDiv {
	cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
	<div id="collapseDiv" class="alert alert-warning" data-toggle="collapse" href="#additionalDiv" role="button" aria-expanded="false" aria-controls="additionalDiv">
		This Div shows by default - I used an alert to make it more visually obvious. Only this part should remain clickable. The hidden stuff should not be clickable. A bonus would be having the lower portion not have a pointer!
		<div id="additionalDiv" class="collapse">
			<div class="other-stuff">
				<h2>This stuff should not be clickable</h2>
				<p>There may be paragraphs here a user might want to copy/paste!</p>
				<p>In a perfect world - even the bottom / sides would not trigger the collapse. This would only be collapsed by clicking the original div area.</p>
			</div>
		</div>
	</div>
</div>

This is ‘working’, but it only avoids clicks on the bottom – how would I make it avoid clicks on the sides as well?

side note: it seems there is about a very tiny row on the bottom that causes it to collapse if clicked still.

3

Answers


  1. The padding space makes it clickable.

    You don’t need javascript to achieve this. Just add another div for toggling only.

    #collapseDiv { 
      padding: 0;
    }
    
    .my-toggle {
      cursor: pointer;
      padding: 20px;
    }
    
    #additionalDiv {
      padding: 20px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
    <div class="container">
      <div id="collapseDiv" class="alert alert-warning">
        <div class="my-toggle" data-toggle="collapse" href="#additionalDiv" role="button" aria-expanded="false" aria-controls="additionalDiv">
          This Div shows by default - I used an alert to make it more visually obvious. Only this part should remain clickable. The
          hidden stuff should not be clickable. A bonus would be having the lower portion not have a pointer!
        </div>
        
        <div id="additionalDiv" class="collapse">
          <div class="other-stuff">
            <h2>This stuff should not be clickable</h2>
            <p>There may be paragraphs here a user might want to copy/paste!</p>
            <p>In a perfect world - even the bottom / sides would not trigger the collapse. This would only be collapsed by clicking
              the original div area.</p>
          </div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. I would adjust a couple things – get the additional div outside of the clickable one and put the padding on the sub-containers and styling on the container.

    The problem really is that your container padding is clickable around the collapsable div.

    .container--nopad {
        padding: 0;
    }
    
    #collapseDiv, #additionalDiv {
        padding: 20px;
    }
    
    
    <div class="container container--nopad alert alert-warning">
        <div id="collapseDiv"  data-toggle="collapse" href="#additionalDiv" role="button" aria-expanded="false" aria-controls="additionalDiv">
            This Div shows by default - I used an alert to make it more visually obvious. Only this part should remain clickable. The hidden stuff should not be clickable. A bonus would be having the lower portion not have a pointer!
        </div>
        <div id="additionalDiv" class="collapse">
            <div class="other-stuff">
                <h2>This stuff should not be clickable</h2>
                <p>There may be paragraphs here a user might want to copy/paste!</p>
                <p>In a perfect world - even the bottom / sides would not trigger the collapse. This would only be collapsed by clicking the original div area.</p>
            </div>
        </div>
    </div>
    

    codepen: https://codepen.io/dmgig/pen/EpzGLG

    Login or Signup to reply.
  3. the padding from the container div is what is causing the action. remove the padding and instead add it to both inner elements.

    $('#collapsDiv').on('show.bs.collapse', function( event ) {
    	event.stopPropagation();
        console.log('Only happen when outter div is opened');
    })
    $('#collapseDiv').on('hide.bs.collapse', function( event ) {
    	event.stopPropagation();
    	console.log('Only happen when outter div is collapsed');
    })
    $('#additionalDiv').on('click', function( event ) {
        event.stopPropagation();
    })
    
    $('#collapseDiv').click(function(e) {
         if (e.pageY > $(this).offset().top + $(this).height()) {
              // bottom was clicked
              console.log('bottom clicked!');
              e.stopPropagation();
         } else {
              // up of the div was clicked
              console.log('top clicked');
         }
    });
     #collapseDiv {
    	cursor:pointer;
    	padding-left: 0;
    	padding-right: 0;
    }
    #collapseDiv .triggerDiv, 
    #collapseDiv #additionalDiv {
    	padding-left: 1.25rem;
    	padding-right: 1.25rem;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
    <div class="container">
    	<div id="collapseDiv" class="alert alert-warning" data-toggle="collapse" href="#additionalDiv" role="button" aria-expanded="false" aria-controls="additionalDiv">
    		<div class="triggerDiv">This Div shows by default - I used an alert to make it more visually obvious. Only this part should remain clickable. The hidden stuff should not be clickable. A bonus would be having the lower portion not have a pointer!</div>
    		<div id="additionalDiv" class="collapse">
    			<div class="other-stuff">
    				<h2>This stuff should not be clickable</h2>
    				<p>There may be paragraphs here a user might want to copy/paste!</p>
    				<p>In a perfect world - even the bottom / sides would not trigger the collapse. This would only be collapsed by clicking the original div area.</p>
    			</div>
    		</div>
    	</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search