Wordy Jquery toggle

I am using this Jquery toggle script, which selects particular buttons to show/hide particular tables of information on the same page. This shows only 2 buttons; there are as many as 20 or so on the page. This code works fine:

      <script>
$(document).ready(function(){
    $("#btnbag1a").click(function(){
        $("#bag1a").toggle();
    });
    $("#btnbag1b").click(function(){
        $("#bag1b").toggle();
    });
});
</script>

I expect to keep repeating the same code again and again until all buttons are accounted for. Is this the best way to do this kind of repetitive code?

For clarity, the page has the tables set to hidden in the style tags:

.hidden {display:none;}

In the body, the tables have the ‘hidden’ class and their unique id that’s referenced in the code:

<table id="bag1a" class="hidden">

Right after the table I have its toggle button, which has been styled according to materializecss and given the id for the code:

<a id="btnbag1a" class="light-blue btn" href="#">Show/Hide Parts</a>

(Explanation of “bag1” in the code: “Bag 1” describes the content inside a model kit’s Bag 1, and the button btnbag1x will show-hide a table listing of clickable contents of Bag 1. It is kept initially hidden to limit scrolling.)

You can bind an event listener to all buttons which have an ID starting with btnbag, and strip the btn part to toggle the corresponding element like

$('[id^="btnbag"]').click(function() {
  var id = this.id.replace(/^btn/, '')
  $('#' + id).toggle()
})

although it would be safer to add a dedicated class to those buttons, like say

$('.toggle-btn').click(function() {
  var id = this.id.replace(/^btn/, '')
  $('#' + id).toggle()
})

Performance-wise this is still not ideal though as it means a lot of redundant DOM queries – each time you click the button, the corresponding element has to be searched anew. So you might map the element references to the button IDs beforehand, like

var toggleMap = {}

$('.toggle-btn')
  .each(function() {
    var id = this.id.replace(/^btn/, '')
    toggleMap[this.id] = $('#' + id)
  })
  .click(function() {
    toggleMap[this.id].toggle()
  })

I will keep it simple and write out all the occurences, then. Thanks!

Well if you prefer maintaining a c&p job over 4 LOC… ^^ anyway to answer your other question, try

$('#btnbag1a').click(function(event) {
  event.preventDefault()
  $('#bag1a').toggle()
})

On another note, you might actually link to the elements in questions, like

<a id="btnbag1a" class="light-blue btn" href="#bag1a">Show/Hide Parts</a>

The JS might thus become

$('#btnbag1a').click(function(event) {
  event.preventDefault()
  $('#' + this.href).toggle()
})

… and with the following CSS…

#bag1a:target {
  display: block;
}

… it will still get you to (and show) the corresponding element if JS is disabled. (This one was for @felgall…)

1 Like

Good old fellgall - what a great guy!

And thanks for your help!

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.