0

EDIT: Thanks, but those answers are not the best way to do it and are difficult to understand by a beginner.

I have this structure:

<div>Title <a href="#" onclick="a1()">+</a>
<div id="b1">...content...</div></div>

..... n times this structure ....

<div>Title <a href="#" onclick="function aN()">+</a>
<div id="bN">...content...</div></div>

When the user clicks the + sign the content should show or disappear.

    function a1(){
            $('#b1').toggle(); 
    }

     .... too many functions .....

    function aN(){
            $('#bN').toggle(); 
    }

How can I rewrite all those functions in one single function to write less code?

Claudiu Creanga
  • 8,031
  • 10
  • 71
  • 110
  • http://stackoverflow.com/questions/190253/jquery-selector-regular-expressions – Donal Aug 28 '14 at 22:05
  • 2
    Whenever you have something like this, the first step you can do is make the thing that's different in each function (in your case the selector), a **parameter** of the function. – Felix Kling Aug 28 '14 at 22:24

10 Answers10

6

You can just make it more descriptive int he markup itself , use a custom attribute data-target (or use the href itself) and store the id of the target.

<div>Title <a data-target="#b1" class="toggler" href="#">+</a>
<div id="b1">...content...</div></div>

..... n times this structure ....

<div>Title <a data-target="#b2" class="toggler" href="#" >+</a>
<div id="bN">...content...</div></div>

and just register a function:-

$(function(){
   $('.toggler').on('click', function(e){
      e.preventDefault();
      $($(this).data('target')).toggle();
   });
});

This way you can put any selector for the target in the attribute, regardless of wherever it appears in your markup (Not just the next element), and move away from the inline click handlers.

PSL
  • 123,204
  • 21
  • 253
  • 243
  • +1 - Nice way not to rely on markup structure and still using a performant selector. – Nope Aug 28 '14 at 23:02
5

You can abstract your code by using a generalized class to hook your javascript to. jsFiddle Example


HTML
<div>
    Title <a href="#" class="toggleNext">+</a>
    <div id="b1">...content...</div>
</div>

jQuery

$('.toggleNext').click(function(e){
    e.preventDefault();
    $(this).next().toggle()
});
Claudiu Creanga
  • 8,031
  • 10
  • 71
  • 110
Brian Dillingham
  • 9,118
  • 3
  • 28
  • 47
2

Have you tried?

<div>Title <a href="#" onclick="a('b1')">+</a>
<div id="b1">...content...</div></div>

..... n times this structure ....

<div>Title <a href="#" onclick="a('bN')">+</a>
<div id="bN">...content...</div></div>

 function a(id){
            $('#' + id).toggle(); 
    }
ntl
  • 1,289
  • 1
  • 10
  • 16
2
<div class="container">Title <a href="#" class="link">+</a>
<div class="content">...content...</div></div>

..... n times this structure ....

<div class="container">Title <a href="#" class="link">+</a>
<div class="content">...content...</div></div>

<script>
    $(".container .link").bind('click', function(event) {
        event.preventDefault();

        $(this).parent().find('.content').toggle();
    });
</script>
mstrthealias
  • 2,781
  • 2
  • 22
  • 18
1

First, using inline event handlers is considered bad form for a variety of reasons.

That said, there are a few ways to do what you like. Personally, I would go for this approach:

<div>Title <a href="#" onclick="toggleThing()" data-thing-to-toggle="b1">+</a>
<div id="b1">...content...</div></div>


function toggleThing() {
  var toggleId = this.getAttribute("data-thing-to-toggle");
  var $target = $(toggleId);
  $target.toggle();
}
Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
1

Add a dummy class to all + anchor. e.g. anc

Then

$('.anc').on('click', function (){
   $(this).next('div').toggle();
}
PSL
  • 123,204
  • 21
  • 253
  • 243
SSA
  • 5,433
  • 4
  • 36
  • 50
1

DEMO

HTML: Using a CSS class

<div>Title <a href="#" class="myanchor">+</a>
<div id="b1">...content...</div></div>

<!--..... n times this structure ....-->

<div>Title <a href="#" class="myanchor">+</a>
<div id="bN">...content...</div></div>

JS

$(function() {
    $('a.myanchor').on('click', a);
    function a(e) {
        e.preventDefault();
        $(this).next('div').toggle();
    }
});
PeterKA
  • 24,158
  • 5
  • 26
  • 48
1

Use jQuery's on method:

HTML:

<div>Title <a href="#" class="toggle">+</a>
<div class="content">...content...</div></div>
<div>Title <a href="#" class="toggle">+</a>
<div class="content">...content...</div></div>
<div>Title <a href="#" class="toggle">+</a>
<div class="content">...content...</div></div>

JavaScript:

$(document).on('click', '.toggle', function(e) {
    $(e.currentTarget).parent().find('.content').toggle();
});

Working jsfiddle: http://jsfiddle.net/uq1mafs3/

dta
  • 654
  • 4
  • 19
0

A simple solution is passing the id of the element:

function a(id) {
    $('#' + id).toggle();
}

Your HTML would look like this:

<div>Title <a href="#" onclick="a('b1');">+</a>
<div id="b1">...content...</div></div>

..... n times this structure ....

<div>Title <a href="#" onclick="a('bN');">+</a>
<div id="bN">...content...</div></div>
0

You should be able to pass the id of the element to be toggled as a function parameter:

<div>Title <a href="#" onclick="toggle('#b1')">+</a>
<div id="b1">...content...</div></div>

..... n times this structure ....

<div>Title <a href="#" onclick="toggle('#bN')">+</a>
<div id="bN">...content...</div></div>    

Then you can implement just one function:

function toggle(id){
        $(id).toggle(); 
}

See JavaScript Function Parameters for more information.

Brix
  • 31
  • 2