Mayank
Mayank

Reputation: 954

addEventListener calling function twice with in immediate function pattern

I am getting issue with calling immediate function with addEventListener, which is calling it twice. tried to change from bubbling to capturing but not working. here is my code

some description: I am trying to add text box where it clicked.

var mod = (function(){

    var sEventType = 'click',
        labelObj = document.getElementsByTagName('label');

            return {

                    createTextBox : function(targetId,inputVal){

                        alert('hi');
                        var elemInput = document.createElement('input');
                    },

                    addEvents : function(){

                        for (var i = 0; i < labelObj.length; i++) {
                            if (window.addEventListener) //Firefox, Chrome, Safari, IE 10
                            labelObj[i].addEventListener(sEventType,function(){ mod.createTextBox(this,this.innerHTML);}, false);
                            else if (window.attachEvent) //IE < 9
                            labelObj[i].attachEvent(sEventType, function(){ mod.createTextBox(this,this.innerHTML);});
                        }
                    }
          }
  }());

  //Intialise Event
  mod.addEvents();

Check out addEventListener which is calling createTextBox ,alert inside popup twice.

Here is HTML part

<body>

<div id='tableMain'>

  <div id='exlTopHd'>
    <div id='loginData'>
      <div id='yourName'><label id='mNam'>type your name here</label></div>
      <div id='yourEmail'><label>your email address</label></div>
    </div>
    <div id='exlCtr'>
        <div id='exlTitle'><label>add title<lable></div>
        <div id='addRow'>+row</div>
        <div id='addColomn'>+colomn</div>
        <div id='saveExl'>saving...</div>
    </div>  
  </div>

  <div id='exlTb'></div>

</div>  

Upvotes: 2

Views: 1101

Answers (1)

Teemu
Teemu

Reputation: 23416

Probably you've nested an input within label like this:

<label>Check 1: <input type="checkbox" /></label>

Clicking on a label triggers also a click on input, when using nested elements. To avoid this you can use for attribute:

<label for="check1">Check 1: </label><input id="check1" type="checkbox" />

A live demo at jsFiddle.


EDIT

Looks like you edited your question at the same time I wrote my answer. Anyway, what's written above, stands, even if the inputs would be added dynamically. Please check this fiddle, and let me know, if that's what you need. The snippet creates inputs dynamically, and inserts them after label.

Here's the modified code snippet:

var mod = (function () {
    var sEventType = 'click',
        labelObj = document.getElementsByTagName('label');
    return {
        createTextBox: function (e) {
            var target = e.target || e.srcElement,
                parent = target.parentElement,
                elemInput = document.createElement('input');
                inpId = parent.id + 'Inp';
            elemInput.value = target.innerHTML;
            elemInput.id = inpId;
            target.setAttribute('for', inpId);
            parent.insertBefore(elemInput, target.nextSibling);
        },
        addEvents: function () {
            for (var i = 0; i < labelObj.length; i++) {
                if (window.addEventListener) //Firefox, Chrome, Safari, IE 10
                labelObj[i].addEventListener(sEventType, function (e) {
                    mod.createTextBox(e);
                }, false);
                else if (window.attachEvent) //IE < 9
                labelObj[i].attachEvent('on' + sEventType, function (e) {
                    mod.createTextBox(e);
                });
            }
        }
    }
}());

Upvotes: 2

Related Questions