jquerydrop-down-menushow-hide

Using JQuery to show multi-ID content based on user SELECT input


I'm building a character wiki for my book series and trying to hide spoilers. The readers are shown a dropdown box asking them which is the last book they've completed. When they select this, the divs with the spoilers should appear.

I have a really basic function that will hide or show a div based on the input (Js Fiddle here), and it works fine.

The problem is that someone who's read book 6 should be able to see the divs for books 1-5, as well, and I'm not sure how to accomplish that.

Any advice? I'm also not entirely convinced this is the best way to hide/show content scattered throughout a page, so if anyone has a better idea, consider me all ears!

$(document).ready(function() {
  $('.spoiler').hide();
  $('#book-1').show();
  $('#spoilerSelect').change(function() {
    $('.spoiler').hide();
    $('#' + $(this).val()).show();
  })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<select id="spoilerSelect">
  <option value="book-1">Book One</option>
  <option value="book-2">Book Two</option>
  <option value="book-3">Book Three</option>
  <option value="book-3-5">Book Three.Five</option>
  <option value="book-4">Book 4</option>
  <option value="book-4-5">Book Four.Five</option>
  <option value="book-5">Book 5</option>
  <option value="book-6">Book 6</option>
</select>

<div id="book-1" class="spoiler">
  Book One
</div>

<div id="book-2" class="spoiler">
  Book Two
</div>

<div id="book-3-5" class="spoiler">
  Book Three.Five
</div>

<div id="book-5" class="spoiler">
  Book 5
</div>


Solution

  • Here is a working code showing the spoilers until the last book in the choice

    This will adhere to the select and the order of the select

    $(function() {
      const $spoiler = $('.spoiler').hide();
      const spoilers = $('#spoilerSelect option').map(function() {
        return +this.value.split('-').pop(); // get the int of the option value
      }).get() // get the list
      $('#book-1').show();
      $('#spoilerSelect').on("change", function() {
        $spoiler.hide();
        const idx = this.selectedIndex;
        const last = spoilers[idx]; // get last book 
        $spoiler.each(function() {
          const divIdx = +this.id.split("-").pop(); // get the int of the div
          $(this).toggle(divIdx <= last)
        })
      })
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <select id="spoilerSelect">
      <option value="book-1">Book One</option>
      <option value="book-2">Book Two</option>
      <option value="book-3">Book Three</option>
      <option value="book-3.5">Book Three.Five</option>
      <option value="book-4">Book 4</option>
      <option value="book-4.5">Book Four.Five</option>
      <option value="book-5">Book 5</option>
      <option value="book-6">Book 6</option>
    </select>
    
    <div id="book-1" class="spoiler">
      Book One
    </div>
    
    <div id="book-2" class="spoiler">
      Book Two
    </div>
    <div id="book-3" class="spoiler">
      Book Three
    </div>
    <div id="book-3.5" class="spoiler">
      Book Three.Five
    </div>
    <div id="book-4" class="spoiler">
      Book Four
    </div>
    <div id="book-4.5" class="spoiler">
      Book Four.Five
    </div>
    
    <div id="book-5" class="spoiler">
      Book Five
    </div>
    
    
    <div id="book-6" class="spoiler">
      Book 6
    </div>

    Here is a prevAll version - it needs $.escapeSelector because of the full stop and an addBack to select the basis for the prevAll

    $(function() {
      const $spoiler = $('.spoiler').hide();
      $('#book-1').show();
      $('#spoilerSelect').on("change", function() {
        $spoiler.hide();
        $(`#${$.escapeSelector(this.value)}`)
          .prevAll() // previous siblings
          .addBack() // and itself
          .show()
      })
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <select id="spoilerSelect">
      <option value="book-1">Book One</option>
      <option value="book-2">Book Two</option>
      <option value="book-3">Book Three</option>
      <option value="book-3.5">Book Three.Five</option>
      <option value="book-4">Book 4</option>
      <option value="book-4.5">Book Four.Five</option>
      <option value="book-5">Book 5</option>
      <option value="book-6">Book 6</option>
    </select>
    
    <div id="book-1" class="spoiler">
      Book One
    </div>
    
    <div id="book-2" class="spoiler">
      Book Two
    </div>
    <div id="book-3" class="spoiler">
      Book Three
    </div>
    <div id="book-3.5" class="spoiler">
      Book Three.Five
    </div>
    <div id="book-4" class="spoiler">
      Book Four
    </div>
    <div id="book-4.5" class="spoiler">
      Book Four.Five
    </div>
    
    <div id="book-5" class="spoiler">
      Book Five
    </div>
    
    
    <div id="book-6" class="spoiler">
      Book 6
    </div>