Search code examples
javascriptjquerytoggleshow-hide

Hide element when I click on an other element with jQuery


So i want to have a function to toggle some text under my image. Here is the script for the toggle :

$(document).ready(function(){
    $('.mariage').click(function(event){
        event.stopPropagation();
         $(".result_mariage").slideToggle("fast");
    });
    $(".result_mariage").on("click", function (event) {
        event.stopPropagation();
    });
});

$(document).on("click", function () {
    $(".result_mariage").hide();
});

The script is working as intended except when the user click on another link who do an other toggle of information, the toggle stack instead of hidding the last one. If i click anywhere else except another toggle, the information will hide and everything work fine.

( here an image of where i click to trigger the 'bug') In blue are the other link who toggle stuff

JS Fiddle exemple:

https://jsfiddle.net/karg007/z6y54uro/

sorry if my english is not so good , its not my main language.

Hope those explanation was clear enough for you to help me even if i doubt it :/ Plz dont hesitate to ask more information so i can provide you with what u need to help me.

So to make it short, how do i do to hide my previous toggle when i click my new one?


Solution

  • Edited Answer

    So the big issue you're running into OP is that you're not trying to understand the code. A big issue with many new programmers (and unfortunately just as many who have been coding forever) is that they are what I call Copy-Coders. Copying tutorials and answers on stackoverflow may allow you to create your site, complete a few consulting jobs, or even support your whole career but it's not the same as actually knowing how to program.

    Doing tutorials and asking questions on SO is perfectly fine (and is in fact how I learned 90% of what I know) but you have to do it with the intent to learn from what you find and not just to complete what you're working on. My advice to you is to really re-read my original answer (I've left it untouched below) and understand how what I showed could be used to accomplish what you want. With that said, I finish what I start so let's get on with the solution:

    I've copied your JSFIDDLE into a Github snippet so you and future users can see the result in the answer. The first thing I immediately noticed is that my code from the original answer was copied into your existing JS. While this is fine and you correctly changed "text" to "_result", you missed a few things:

    • My code takes the ID of the clicked element and uses that to look up the id of what should be unhidden. While you correctly changed the lookup code to fit with the ids on your text, you didn't add any ids to the images being clicked on so my code couldn't do anything.
    • You also didn't remove the 4 functions that you were originally using to implement this feature so it made it look like my code was doing something and working incorrectly, when in fact my code was doing nothing and your code was still doing what it did before (although I definitely see what bug you were talking about before).
    • Related to my copy-coder rant above, notice how you and I both approached the problem differently and what you can learn from that.
      • Whereas you wanted to attach a listener function to each item by looking up it's class (which completely unrelated but you aren't using classes correctly and "mariage", etc... fit better as ids which you can still style like classes) I chose to attach a listener to all elements of a single class and then look them up by id.
      • Your solution requires you to write new JS code for each item you add, and runs the risk of spelling mistakes or forgetting to change something each time you code those functions.
      • My solution allows you to add as many elements to the HTML as you want and there's no need to change the JS. As long as your images have an id and the text has an id equal to "image id" + "_result" the functionality happens automatically.

    I've tried to modify your code as little as possible and only had to delete the 4 functions and add IDs ("mariage" and "amour") to the images in order to get your fiddle to work.

    The four functions I removed from your fiddle:

      // My toggle code for mariage_result ->text #1
      $(document).ready(function() {
        $('.mariage').click(function(event) {
          event.stopPropagation();
          $("#mariage_result").slideToggle("fast");
        });
        $("#mariage_result").on("click", function(event) {
          event.stopPropagation();
        });
      });
    
      $(document).on("click", function() {
        $("#result_mariage").hide();
      });
    
      // My toggle code for amour_result ->text #2
      $(document).ready(function() {
        $('.amour').click(function(event) {
          event.stopPropagation();
          $("#amour_result").slideToggle("fast");
        });
        $("#amour_result").on("click", function(event) {
          event.stopPropagation();
        });
      });
    
      $(document).on("click", function() {
        $("#amour_result").hide();
      });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    The final code:

    // Test code to untoggle the previous element toggled
    let lastClicked = null;
    
    $(".hover_selection").click(function() {
      if (lastClicked) {
        lastClicked.hide();
      }
    
      let me = $("#" + this.id + "_result");
      me.show();
      lastClicked = me;
    });
    
    // slick slider option
    $(document).ready(function() {
      $('.slider_index').slick({
        infinite: true,
        arrows: true,
        centerMode: true,
        slidesToShow: 1,
        variableWidth: true
      });
    });
    .tarif {
      width: 750px;
      text-align: left;
      margin: auto;
      margin-bottom: 30px;
      margin-top: 50px;
    }
    
    .result {
      display: none;
    }
    
    #mariage_result,
    #amour_result,
    #certificat_cadeau_result,
    #maternite_result,
    #portrait_result,
    #commercial_result {
      width: 780px;
      height: auto;
      margin: auto;
    }
    
    
    /* -----------CSS SLIDER BELOW THIS POINT-----*/
    
    
    /* Arrows */
    
    .slick-prev,
    .slick-next {
      font-size: 0;
      line-height: 0;
      position: absolute;
      bottom: 10px;
      display: block;
      width: 150px;
      height: 50px;
      cursor: pointer;
      color: transparent;
      border: none;
      outline: none;
      background: transparent;
    }
    
    .slick-prev:hover,
    .slick-prev:focus,
    .slick-next:hover,
    .slick-next:focus {
      color: transparent;
      outline: none;
      background: transparent;
    }
    
    .slick-prev:hover:before,
    .slick-prev:focus:before,
    .slick-next:hover:before,
    .slick-next:focus:before {
      opacity: 1;
    }
    
    .slick-prev:before,
    .slick-next:before {
      font-size: 20px;
      line-height: 1;
      opacity: .75;
      color: white;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    .slick-prev {
      left: 25%;
      z-index: 9999;
    }
    
    [dir='rtl'] .slick-prev {
      right: 25px;
      left: auto;
    }
    
    .slick-prev:before {
      content: url('https://i.ibb.co/m9zR5YD/avant.png');
    }
    
    [dir='rtl'] .slick-prev:before {
      content: url('https://i.ibb.co/xGrj9kQ/apres.png');
    }
    
    .slick-next {
      right: 25%;
      z-index: 9999;
    }
    
    [dir='rtl'] .slick-next {
      right: auto;
      left: -25px;
    }
    
    .slick-next:before {
      content: url('https://i.ibb.co/xGrj9kQ/apres.png');
    }
    
    [dir='rtl'] .slick-next:before {
      content: url('https://i.ibb.co/m9zR5YD/avant.png');
    }
    
    .slider_index {
      width: 100%;
      margin: auto;
    }
    
    .slider_index img {
      width: 100px;
      margin: auto;
      padding: 0px 20px 0px 20px;
    }
    
    .slick-slider {
      position: relative;
      display: block;
      box-sizing: border-box;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      -webkit-touch-callout: none;
      -khtml-user-select: none;
      -ms-touch-action: pan-y;
      touch-action: pan-y;
      -webkit-tap-highlight-color: transparent;
    }
    
    .slick-list {
      position: relative;
      display: block;
      overflow: hidden;
      margin: 0;
      padding: 0;
    }
    
    .slick-list:focus {
      outline: none;
    }
    
    .slick-list.dragging {
      cursor: pointer;
      cursor: hand;
    }
    
    .slick-slider .slick-track,
    .slick-slider .slick-list {
      -webkit-transform: translate3d(0, 0, 0);
      -moz-transform: translate3d(0, 0, 0);
      -ms-transform: translate3d(0, 0, 0);
      -o-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0);
    }
    
    .slick-track {
      position: relative;
      top: 0;
      left: 0;
      display: block;
      margin-left: auto;
      margin-right: auto;
    }
    
    .slick-track:before,
    .slick-track:after {
      display: table;
      content: '';
    }
    
    .slick-track:after {
      clear: both;
    }
    
    .slick-loading .slick-track {
      visibility: hidden;
    }
    
    .slick-slide {
      display: none;
      float: left;
      min-height: 1px;
    }
    
    [dir='rtl'] .slick-slide {
      float: right;
    }
    
    .slick-slide img {
      display: block;
    }
    
    .slick-slide.slick-loading img {
      display: none;
    }
    
    .slick-slide.dragging img {
      pointer-events: none;
    }
    
    .slick-initialized .slick-slide {
      display: block;
    }
    
    .slick-loading .slick-slide {
      visibility: hidden;
    }
    
    .slick-vertical .slick-slide {
      display: block;
      height: auto;
      border: 1px solid transparent;
    }
    
    .slick-arrow.slick-hidden {
      display: none;
    }
    
    
    /* Dots */
    
    .slick-dotted.slick-slider {
      margin-bottom: 30px;
    }
    
    .slick-dots {
      position: absolute;
      bottom: -40px;
      display: block;
      width: 100%;
      padding: 0;
      margin: 0;
      list-style: none;
      text-align: center;
    }
    
    .slick-dots li {
      position: relative;
      display: inline-block;
      width: 20px;
      height: 20px;
      margin: 0 5px;
      padding: 0;
      cursor: pointer;
    }
    
    .slick-dots li button {
      font-size: 0;
      line-height: 0;
      display: block;
      width: 20px;
      height: 20px;
      padding: 5px;
      cursor: pointer;
      color: transparent;
      border: 0;
      outline: none;
      background: transparent;
    }
    
    .slick-dots li button:hover,
    .slick-dots li button:focus {
      outline: none;
    }
    
    .slick-dots li button:hover:before,
    .slick-dots li button:focus:before {
      opacity: 1;
    }
    
    .slick-dots li button:before {
      font-family: 'slick';
      font-size: 30px;
      line-height: 20px;
      position: absolute;
      top: 0;
      left: 0;
      width: 20px;
      height: 20px;
      content: '•';
      text-align: center;
      opacity: .25;
      color: black;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    .slick-dots li.slick-active button:before {
      opacity: .75;
      color: black;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.js"></script>
    
    <div class="titre_de_page">
      <p id="ancre">- Choisissez votre projet-photo -<br/>
    
      </p>
    </div>
    
    <div class="slider_index">
    
      <div>
        <img class="hover_selection mariage" id="mariage" src="https://via.placeholder.com/300" />
        <div class="caption_text">Mariage</div>
      </div>
      <div>
        <img class="hover_selection amour" id="amour" src="https://via.placeholder.com/300" />
        <div class="caption_text">Amour</div>
      </div>
      <div>
        <img class="hover_selection maternite" src="https://via.placeholder.com/300" />
        <div class="caption_text">Bedon + Bébé</div>
      </div>
      <div>
        <img class="hover_selection portrait" src="https://via.placeholder.com/300" />
        <div class="caption_text">Portrait</div>
      </div>
      <div>
        <img class="hover_selection commercial" src="https://via.placeholder.com/300" />
        <div class="caption_text">Commercial / Éditorial</div>
      </div>
      <div>
        <img class="hover_selection certificat_cadeau" src="https://via.placeholder.com/300" />
        <div class="caption_text">Certificat-cadeau</div>
      </div>
    </div>
    <br/>
    
    
    <div class="result" id="mariage_result">
    
      <p class="all_texte tarif">
        My text to toggle number 1
        <br/><br/>
    
      </p>
    
    </div>
    
    <div class="result" id="amour_result">
    
      <p class="all_texte tarif">
    
        Toggle text number 2
    
      </p>
    
    </div>

    Original Answer

    As far as I understand your question, you simply need a variable to keep track of the previously clicked on item. As for what I've done in the demo beloww, I think it's close enough to what you want to do given we don't have a sample to work with. I imagine the only part where you may differ greatly from my example is in how you look up me as I don't know the exact structure of your DOM or what your exact naming scheme is.

    let lastClicked = null;
    
    $(".clickable").click(function() {
      if (lastClicked) {
        lastClicked.hide();
      }
      
      let me = $("#" + this.id + "text");
      me.show();
      lastClicked = me;
    });
    #root {
      width: 300px;
      height: 300px;
      background-color: black;
    }
    
    .text {
      display: none;
    }
    
    #one {
      width: 50px;
      height: 50px;
      background-color: red;
    }
    
    #two {
      width: 50px;
      height: 50px;
      background-color: green;
    }
    
    #three {
      width: 50px;
      height: 50px;
      background-color: blue;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div id="root">
      <div class="clickable" id="one">
        <p class="text" id="onetext"> 1 </p> 
      </div>
      <div class="clickable" id="two">
        <p class="text" id="twotext"> 2 </p>
      </div>
      <div class="clickable" id="three">
        <p class="text" id="threetext"> 3 </p>
      </div>
    </div>