nmenego
nmenego

Reputation: 856

jQuery bind change event to all children in several DIV's except selected

I have a listener for 3 DIV's containing several form elements:

<div id="div-a">
  <input type="text" id="txt-a"/>
  <!-- more elements here -->
  ...
</div>
<div id="div-b">
  <input type="text" id="txt-b"/>
  <input type="text" id="txt-c"/>
  <!-- more elements here -->
  ...
</div>
<div id="div-c">
  <input type="text" id="txt-d"/>
  <input type="text" id="txt-e"/>
  <input type="text" id="txt-f"/>
  <!-- more elements here -->
  ...
</div>

I bound the change event for the 3 DIV's as follows:

$("#div-a, #div-b, #div-c").change(function(){
  // do something, except if the change happened to txt-b and txt-c
})

The above listens to change from all of their respective child elements. It works fine, but there is one thing more missing from the equation. The txt-b and txt-c change events is out of my business. So I must not include them in the action being performed by the change event listener. Also, each of the elements under the 3 DIV's already have their own listeners for change so adding the listeners to each of the element's change events is a last option.

I need to listen to changes from the child elements of the three DIV's with some exceptions. I need to execute a function when the child elements of the three DIV's change except for 5 input-types.

So far I did the following which did not work:

  1. I tried separating the three DIV's and added the :not() selector

    $("#div-b :not(#txt-b)").change(function(){ //... });

  2. Using .not()

I would like to know the best possible way to approach this problem. I'd be happy to add more information if you need so. Thank you.

Upvotes: 1

Views: 10649

Answers (3)

Robin Maben
Robin Maben

Reputation: 23094

You can do this with one handler..

<div id="controls-wrapper">
   <!--Wrap all your controls and div's here   -->
</div>

Then..

$('#controls-wrapper').delegate('input', 'change', function(e){
  if($(this).parent().is('#div-a')){
     //this input was in #div-a, do something
  }

 // and so on, as your case might need
});

Note: You can also use .on() in place of .delegate()

Upvotes: 0

afrin216
afrin216

Reputation: 2335

You can just use $(this) variable to your advantage.

Assuming that events are generated by input tag, you just need to check

if(!$(this).parent().attr('id')=='div-b')

if only txt-b and txt-c will be inside div-b.

otherwise you can just go with

if($(this).attr('id')!='div-b') && !$(this).attr('id')!='div-b'))

not selector is not recommended but still if you want to go with :not selector itself try $("div").children("input :not(#txt-b)").change(function(){ //... }); approach with children alone rather than parent clubbing parent and child elements

Upvotes: 0

Esailija
Esailija

Reputation: 140238

You can try checking the target's id for those and then ignore them:

$("#div-a, #div-b, #div-c").change(function(e) {
    var target = e.target;
    if (target.id === "txt-b" || target.id === "txt-c") {
        return;
    }
    //Is not a txt-b or a txt-c
})

http://jsfiddle.net/HGXDT/4/

Upvotes: 3

Related Questions