-1

I am currently learning JavaScript, and I got stuck at the following problems: I have tried to dynamically create an input of type text from JavaScript and to set its onChange method, but it is fired only when the page is loaded. In addition, document.onload does not work for creating my input, but window.onload does, although the tutorials I read claim that these two are almost the same thing. The code is the following:

<html>
    <head>
        <script type="text/javascript">
            function f(value) {
                alert(value);
                return true;
            }

            window.onload = function() {
                if (document.getElementById("cloned") == null) {
                     var clonedInput = document.createElement('input');
                     clonedInput.type = 'text';
                     clonedInput.value = "";
                     clonedInput.id = 'cloned';
                     clonedInput.size = 20;
                     clonedInput.onChange = f(clonedInput.value);
                     var lastChild = document.getElementById("parent");
                     document.body.insertBefore(clonedInput, lastChild);
                }
            };
        </script>
    </head>
    <body>
        <input id="toClone" type="text"/>
        <div id="parent"></div>
    </body>
</html>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
user998692
  • 4,970
  • 7
  • 38
  • 58
  • What about creating an input field and setting it to hidden? Then when your event happens, display it. – Eamorr Oct 17 '11 at 07:43

2 Answers2

4

f(clonedInput.value) calls the function immediately and sets its return value (which is true in this case) as event handler.

You want to use an anonymous function:

clonedInput.onchange = function(){ f(this.value); };

Note: While HTML attributes are case-insensitive, JavaScript object properties are not.

Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072
2

You can actually clone the existing input element:

if (document.getElementById("cloned") == null) {
     var clonedInput = document.getElementById("toClone").cloneNode(true);
     clonedInput.id = 'cloned';
     clonedInput.onchange = f;
     var lastChild = document.getElementById("parent");
     document.body.insertBefore(clonedInput, lastChild);
}

Now to read the value change f to this:

function f() {
    var value = this.value;
    alert(value);
    return true;
}

Edit: to make the cloned input reflect the first "live" you'll have to attach couple of events:

if (document.getElementById("cloned") == null) {
     var orgInput = document.getElementById("toClone");
     var clonedInput = orgInput.cloneNode(true);
     clonedInput.id = 'cloned';
     clonedInput.onchange = f;
     orgInput.onkeypress = ReflectValue;
     orgInput.onchange = ReflectValue;
     var lastChild = document.getElementById("parent");
     document.body.insertBefore(clonedInput, lastChild);
}

Then have this function:

function ReflectValue() {
    var cloned = document.getElementById("cloned");
    cloned.value = this.value;
}

Now whenever user type in the first input, it will reflect in the second input, and whenever user focus out it will also reflect any "non-keyboard" changes like pasting text.

Shadow The Vaccinated Wizard
  • 62,584
  • 26
  • 129
  • 194
  • Thank you, it seems to work. Do you have any idea why this stuff works for window.onload, but not for document.onload? – user998692 Oct 17 '11 at 08:29
  • The `document` refers to the top element, parent of all other elements while `window` is more "general", not related directly to the elements - attaching the global events to `window` is the correct way - not sure why, sorry. If it's working, feel free to mark this answer as Accepted by ticking the empty V to the left. :) – Shadow The Vaccinated Wizard Oct 17 '11 at 09:00
  • Thank you, it works, but only if I refresh the page, otherwise, when I change the first field, the second is not updated. – user998692 Oct 17 '11 at 09:06