1

I have a text with an input field. I want the field to start as blank, and when clicked upon, set the input's text to its correct value (saved in the "name" field, for instance).

If I do it this way, it works fine:

Buy  <input type="text" name="eggs" onclick="this.value=this.name;"> tomorrow.

However, if I try to clean the DOM and move the function to a separate javascript file, it stops working:

HTML:

Buy <input type="text" name="eggs" onclick="showname(this);"> tomorrow.

JS:

function showname(el) {
     el.value = el.name;
}

function showname(el){
    el.value = el.name;
}
.closeform{
    width: 70px;
}

.closeform input {
    width: 70px;
}

.closeform button {
    width: 70px;
}
Buy
<span class="closeform">
    <input type="text" name="eggs" onclick="showname(this);"> 
 </span> 
    tomorrow.

I'm very new to Javascript - what am I missing here?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Venomouse
  • 311
  • 2
  • 12
  • snippet works fine in FF. What browser/version are you using? What does it's error-console say? – GitaarLAB Apr 29 '15 at 22:55
  • 2 files in same folder: *index.html* (contents: ` Demo Buy tomorrow. `) and *myscript.js* (contents: `function showname(el) { el.value = el.name; }`) works perfectly. You probably didn't post all relevant code. – GitaarLAB Apr 29 '15 at 23:15
  • 1
    @GitaarLAB Thanks! I tried it with Fiddle - maybe the problem is in Fiddle interface. – Venomouse Apr 30 '15 at 05:51

2 Answers2

1

Everything in JavaScript has a scope. Where you are defining your function, it is not visible to the input so the input doesn't know that function even exists. You can use window to make the function visible to it:

<input type="text" name="eggs" onclick="window.showname(this);"/> 

window.showname = function (el)

Fiddle

I don't recommend global functions though. So then what else?


You can use the onclick function in JavaScript. To find elements in JavaScript, you use selectors. I'm using getElementById() this will get an element by it's id. A list of selectors are here
<input id="my_input" type="text" name="eggs"/>

Then in JavaScript:

document.getElementById('my_input').onclick = function () {
    //Use this to refer to the element
    this.value = this.name;
};

Fiddle


When doing this. Make sure all your code is wrapped in a window.onload. This will make sure the code is run at the right time:

window.onload = function () {
    //Your code
};

JSFiddle automatically puts your code in this.

Downgoat
  • 13,771
  • 5
  • 46
  • 69
1

You say in your question:

However, if I try to clean the DOM and move the function to a separate javascript file, it stops working

Let's say you have 2 actual files in the same folder:

  • myscript.js contents:

    function showname(el) { el.value = el.name; }
    
  • index.html contents:

    <!DOCTYPE html>
    <html><head><title>Demo</title>
      <script src="myscript.js"></script>
    </head><body>
      Buy <input type="text" name="eggs" onclick="showname(this);"> tomorrow.
    </body></html>
    

    OR

    <!DOCTYPE html>
    <html><head><title>Demo</title>
    </head><body>
      Buy <input type="text" name="eggs" onclick="showname(this);"> tomorrow.
      <script src="myscript.js"></script>
    </body></html>
    

That should work perfectly...


However, in the comments you say:

I tried it with Fiddle - maybe the problem is in Fiddle interface.

That is where your problem was....

There is no separate javascript-file in jsfiddle.
The three code-blocks (html, js, css) get merged into one file.
Right-click the result-window in jsfiddle and look at the generated file.
Then notice the options (top right corner) from jsfiddle: by default the code is wrapped in an onload-method (suiting to the library you selected or window.onload if you are not using a library).

You can however place the script in the head or body, thereby not wrapping your code inside a function's scope (which then closes over the containing identifiers).
See http://jsfiddle.net/wf55a5qb/ for a working example.

The reason your example stack-snippet worked here on StackOverflow is that it's snippet-editor does not wrap the javascript codeblock in a (onload-like) function (when it combines the three code-blocks).

Having said and explained this, I do encourage you to set your events (Using obj.addEventListener/obj.attachEvent or the direct elm.onevent) from the/a script once the elements (that your script manipulates, place script as last element of the html-body) or page (using window.onload/etc) has loaded.

I posted this to clear up what actually went wrong so you don't make false models in your head about how javascript works (like "an external script runs in it's own scope" which no-one claimed but might be an assumption you might make) whilst still learning it!

Community
  • 1
  • 1
GitaarLAB
  • 14,536
  • 11
  • 60
  • 80