5

I am trying to make a jQuery-compatible composite HTML input.

In this example when either select changes, the alert is invoked twice. Why?

Given a simple container node:

<span id="x"></span>

Here is a fully working demo:

function el (type) {
    return document .createElement (type);
}

function opt (sel, value) {
    let node = el ('option');
    node .value = value;
    node .appendChild (document .createTextNode (value));
    sel .appendChild (node);
}

let x = document .getElementById ('x');
let a = el ('select');
let b = el ('select');

x .appendChild (a);
x .appendChild (b);

opt (a, 'a_1');
opt (a, 'a_2');
opt (b, 'b_1');
opt (b, 'b_2');

$(a) .change (function () {$(x) .trigger ('change');});
$(b) .change (function () {$(x) .trigger ('change');});

$(x) .change (function () {alert ('changed');});
Community
  • 1
  • 1
spraff
  • 32,570
  • 22
  • 121
  • 229

2 Answers2

3

Its because when you are change value in dropdown it change parent evelement drom structure. it means you are changing value of A an B it patent of A and B is X so it change automatically so you have to stop event propagation

you have to remove below code

$(a) .change (function () {$(x) .trigger ('change');});
$(b) .change (function () {$(x) .trigger ('change');});

or you have to use preventDefault();

$(a) .change (function (e) {e.preventDefault(); $(x) .trigger ('change'); return false; });
$(b) .change (function (e) {e.preventDefault(); $(x) .trigger ('change'); return false; });
Haresh Vidja
  • 8,340
  • 3
  • 25
  • 42
0

Does the onchange event propagate?

The jQuery documentation suggests that this event applies only to inputs, selects and textarea, in any case, what is happening is propagation (bubble) to the parent element.

If you stop the propagation, will work:

$(a) .change (function (event) {
    $(x) .trigger ('change');
    console.log('a');
    event.stopPropagation();
});

$(b) .change (function (event) {
    $(x) .trigger ('change');
    console.log('b');
    event.stopPropagation();
});
Community
  • 1
  • 1
Edmundo Santos
  • 8,006
  • 3
  • 28
  • 38