3

I'm having problems adding an event to a dynamically created element in Javascript. This is the code:

var monto=document.createElement('input');
monto.type='text';
monto.name='monto'+cantpagos;
monto.id='monto'+cantpagos;
if(monto.addEventListener) monto.addEventListener("blur", sumpagos, false);
else if(monto.attachEvent) monto.attachEvent("onblur", sumpagos);
document.getElementById('pagos').appendChild(monto);

However it's not working, once I remove the focus the function is not called. What am I doing wrong? Thanks beforehand.

EDIT: This is more relevant code:

function sumpagos()
{
   var total=0;
   for(var i=1;i<=cantpagos;i++)
   {
      total+=document.getElementById('monto'+i).value;
   }
   document.getElementById('total').innerHTML="$"+total;
}

function addpago()
{
var i = 0;
var cuota=document.createElement('select');
cuota.name="cuota"+cantpagos;
cuota.id="cuota"+cantpagos;
for(i=1;i<=3;i++)
{
   cuota.options[i-1]=new Option("Cuota "+i, i);
}
document.getElementById('pagos').appendChild(cuota);
var monto=document.createElement('input');
monto.type='text';
monto.name='monto'+cantpagos;
monto.id='monto'+cantpagos;
if(monto.addEventListener) monto.addEventListener("blur", sumpagos, false);
else if(monto.attachEvent) monto.attachEvent("onblur", sumpagos);
document.getElementById('pagos').appendChild(monto);
document.getElementById('pagos').innerHTML+="<br />";
cantpagos++;
}

<td id="total">
$0
</td>

<input type="button" name="maspago" value="Añadir un Pago" onclick="addpago();" />
<input type="button" name="memospago" value="Eliminar un Pago" onclick="deletepago();" />
<div id="pagos"></div>
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
Carlos
  • 33
  • 5
  • [Works for me](http://jsfiddle.net/alexdickson/tm2Gg/). – alex Feb 25 '11 at 00:24
  • 1
    You've excluded relevant javascript and HTML. There's nothing visibly wrong with the code you posted. – user113716 Feb 25 '11 at 00:26
  • patrick, I'm gonna post the affected boxes and functions. – Carlos Feb 25 '11 at 00:28
  • @Carlos Is the function `sampagos` defined? What does `typeof sampagos` give you? – alex Feb 25 '11 at 00:31
  • 3
    Does your browser report an error? <-- this question should be a mandatory prompt on SO whenever a new user tries to post a question `:)` – Šime Vidas Feb 25 '11 at 00:32
  • @alex: function @Sime: Not at all. No errors, it just somehow doesn't work. – Carlos Feb 25 '11 at 00:34
  • @Carlos Could you post the generated HTML source code instead? This PHP stuff is not very useful. (View source in the browser) – Šime Vidas Feb 25 '11 at 00:34
  • @Sime Edited, check the js code. – Carlos Feb 25 '11 at 00:39
  • @Carlos Are the input boxes added to the page when you call addpago()? what happens when you call sumpagos() manually? – Šime Vidas Feb 25 '11 at 00:55
  • @Carlos: What happens if you remove the line `document.getElementById('pagos').innerHTML+="
    ";`? Does that fix it for you?
    – sarcastyx Feb 25 '11 at 01:07
  • @Sime: Yes they are added correctly. How can I call the function manually? @sarcastyx I'll try but I don't think so. – Carlos Feb 25 '11 at 01:15
  • @Carlos Just run `sumpagos()` in the console. If you don't know how to run JavaScript in the console, the instructions are here: http://webmasters.stackexchange.com/questions/8525/how-to-open-the-javascript-console-in-different-browsers – Šime Vidas Feb 25 '11 at 01:23
  • Nevermind, I got an error from calling the function. Actually sumpagos is throwing that document.getElementById("monto" + i) is null. – Carlos Feb 25 '11 at 01:24
  • How about Firefox 3? I tried ctrl+shift+k and it's not working. – Carlos Feb 25 '11 at 01:25
  • @Carlos Yes, I was suspecting that.. – Šime Vidas Feb 25 '11 at 01:26
  • Okay, I fixed the function and it's working properly. However I still can't call it when I make the box lose the focus. – Carlos Feb 25 '11 at 01:30

1 Answers1

0

Here, this should make it work:

function sumpagos() {
    var total = 0,
        monto;

    for(var i=1; i <= cantpagos; i++) {
        monto = document.getElementById('monto' + i);
        if ( monto != null ) {
            total += +monto.value;
        }
    }    
    document.getElementById('total').innerHTML = '$' + total;
}

Try this:

var monto = document.createElement('input');
monto.type = 'text';
monto.name = monto.id = 'monto' + cantpagos;
monto.onblur = sumpagos;
document.getElementById('pagos').appendChild(monto);

Update:

I believe this line of code is the cause of your issue:

document.getElementById('pagos').innerHTML+="<br />";

Demo without that line: http://jsfiddle.net/A7aPA/
Demo with that line: http://jsfiddle.net/A7aPA/1/

As you can see, the first demo works, the second one doesn't.

Remove that line and it should work...

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • @Carlos Strange, if works fine in this demo: http://jsfiddle.net/A7aPA/ I don't understand this. It either has to work, or an error must be thrown. There is no third option here. Are you sure that no error is thrown? – Šime Vidas Feb 25 '11 at 01:41
  • Sure that no error is thrown, I'm checking the error console. Whenever I add an alert to the function, it's not displayed, so I can say for sure there must be some kind of problem when the function is attached to the input element and not in the function itself. – Carlos Feb 25 '11 at 01:46
  • @Carlos You have to make sure that inside the `addpago` function the identifier name `sumpagos` refers to the correct function. Try `console.log(sumpagos)` from within the `addpago` function. Is the correct function logged? – Šime Vidas Feb 25 '11 at 01:56
  • @Carlos Do you have Firebug in Firefox? do you have Chrome installed? – Šime Vidas Feb 25 '11 at 02:01
  • I do have Firebug but not Chrome. – Carlos Feb 25 '11 at 02:02
  • @Carlos In Firebug, there is a Console tab. When you open it, you should see the result of `console.log(sumpagos);`. – Šime Vidas Feb 25 '11 at 02:05
  • The result logged is sumpagos() with a link which leads me to the function. – Carlos Feb 25 '11 at 02:07
  • By the way, the code generated when the child is appended is . Doesn't it lack the onBlur element? – Carlos Feb 25 '11 at 02:09
  • @Carlos I've run out of ideas. If you could put the page online, I would be able to find the cause of the problem. – Šime Vidas Feb 25 '11 at 02:11
  • @Carlos Try `console.dir(monto);` instead. That will log the entire object. Then you can open it up and check if the `onblur` property is set correctly. – Šime Vidas Feb 25 '11 at 02:13
  • Sure. By the way, if I add the onBlur element manually, it works properly. Here's the page: http://www.codesin.cl/delacosta/IngresoPagos_Costa.php ("Elegir Curso", then any button, then any "Elegir Concepto", then "Añadir un pago" for adding the input elements. That button calls the function dynamically) – Carlos Feb 25 '11 at 02:13
  • @Carlos I'm baffled. Inside the addpago function the monto element has an onblur property, but once we append the element to the page using appendChild, the onblur property is emptied. I really would like to know why this happens... – Šime Vidas Feb 25 '11 at 02:37
  • @Carlos I've figured it out `:)` – Šime Vidas Feb 25 '11 at 02:43
  • That's extremely weird, but thank you, that will be of a huge help. I'll do a bit of research, but any help is welcome. – Carlos Feb 25 '11 at 02:43
  • That's awesome, thank you! Then, what can I do to add the br element? – Carlos Feb 25 '11 at 02:48
  • @Carlos This should do it: `document.getElementById('pagos').appendChild( document.createElement('br') );` – Šime Vidas Feb 25 '11 at 02:50
  • How do I remove these br elements then? Can I just use the removeChild function? – Carlos Feb 25 '11 at 02:53
  • @Carlos If you want more information on the cause of your issue, the full report is [here](http://stackoverflow.com/questions/5113105/manipulating-innerhtml-removes-the-event-handler-of-a-child-element) `:)` – Šime Vidas Feb 25 '11 at 03:08
  • Oh wow, you always learn something new. I'll make sure to not make that mistake again. Thank you! – Carlos Feb 25 '11 at 03:13
  • @Carlos Yea, this was a valuable lesson for both of us `:)` – Šime Vidas Feb 25 '11 at 03:18