views:

16748

answers:

10

I need to set the text within a DIV element dynamically. What is the best, browser safe approach? I have prototypejs and scriptaculous available.

<div id="panel">
  <div id="field_name">TEXT GOES HERE</div>
</div>

Here's what the function will look like:

function showPanel(fieldName) {
  var fieldNameElement = document.getElementById('field_name');
  //Make replacement here
}
+4  A: 
$('field_name').innerHTML = 'Your text.';

One of the nifty features of Prototype is that $('field_name') does the same thing as document.getElementById('field_name'). Use it! :-)

John Topley's answer using Prototype's update function is another good solution.

ceejayoz
That doesn't look like JavaScript?
Milan Babuškov
It is JavaScript. See http://prototypejs.org/api/utility
ceejayoz
Don't use innerHTML. It's not a w3c recommendation and behaves inconsistently. It's considered bad style.
Tom
Tom, what should be used instead (if you don't use Prototype)?
Milan Babuškov
Milan, the more accepted way is to loop through the childNodes, call removeNode(true) on each, then append new nodes created using document.createElement() or document.createTextNode(). If you need to do that I would recommend writing a function to avoid a lot of typing.
Joel Anair
+3  A: 

Should just be

fieldNameElement.innerHTML = "Ny new text!";
17 of 26
Shouldn't single quotes be used for 'static' text?
Milan Babuškov
In PHP, yes. In JavaScript, I don't believe it matters.
ceejayoz
In Javascript, single and double quotes are interchangeable.
17 of 26
A: 

If you really want us to just continue where you left off, you could do:

if (fieldNameElement)
    fieldNameElement.innerHTML = 'some HTML';
Milan Babuškov
+10  A: 

I would use Prototype's update method which supports plain text, an HTML snippet or any JavaScript object that defines a toString method.

$("field_name").update("New text");
John Topley
A: 
function showPanel(fieldName) {
  var fieldNameElement = document.getElementById(field_name);

  fieldNameElement.removeChild(fieldNameElement.firstChild);
  var newText = document.createTextNode("New Text");
  fieldNameElement.appendChild(newText);
}
HollyStyles
Better to replace the node then to remove it and add a new one as two separate operations.
David Dorward
+1  A: 

The quick answer is to use innerHTML (or prototype's update method which pretty much the same thing). The problem with innerHTML is you need to escape the content being assigned. Depending on your targets you will need to do that with other code OR

in IE:-

document.getElementById("field_name").innerText = newText;

in FF:-

document.getElementById("field_name").textContent = newText;

(Actually of FF have the following present in by code)

HTMLElement.prototype.__defineGetter__("innerText", function () { return this.textContent; })

HTMLElement.prototype.__defineSetter__("innerText", function (inputText) { this.textContent = inputText; })

Now I can just use innerText if you need widest possible browser support then this is not a complete solution but neither is using innerHTML in the raw.

AnthonyWJones
+9  A: 

function showPanel(fieldName) {
  var fieldNameElement = document.getElementById("field_name");
  while(fieldNameElement.childNodes.length >= 1) {
    fieldNameElement.removeChild(fieldNameElement.firstChild);
  }
  fieldNameElement.appendChild(fieldNameElement.ownerDocument.createTextNode(fieldName));
}

The advantages of doing it this way:

  1. It only uses the DOM, so the technique is portable to other languages, and doesn't rely on the non-standard innerHTML
  2. fieldName might contain HTML, which could be an attempted XSS attack. If we know it's just text, we should be creating a text node, instead of having the browse parse it for HTML

If I were going to use a javascript library, I'd use jQuery, and do this:


  $("div#field_name").text(fieldName);

Note that AnthonyWJones in the comment is correct, and "field_name" isn't a particularly descriptive id and fieldName isn't a particularly descriptive variable name that contains the text.

Daniel Papasian
Which other languages could you port this technique to?
John Topley
Any language with a DOM implementation supports this (and most languages have a DOM implementation).
David Dorward
This is good answer, better than mine and is the correct answer. You might consider tidying the example though. 'fieldname' is not a good name for the function's parameter. In fact it might be best to take two one for the element ID and another for the content, i.e.; elemID, content
AnthonyWJones
I borrowed fieldName and the ID from the question itself.
Daniel Papasian
The question probably used field_name to make the example generic. Also the questioner mentions that Prototype is available but not jQuery.
John Topley
A: 

If you're inclined to start using a lot of JavaScript on your site, jQuery makes playing with the DOM extremely simple.

http://docs.jquery.com/Manipulation

Makes it as simple as: $("#field-name").text("Some new text.");

Steve Perks
Prototype has similar utility functions.
ceejayoz
A: 

Here's an easy jQuery way:

var el = $('#yourid .yourclass');

el.html(el.html().replace(/Old Text/ig, "New Text"));

Cosmin
A: 

nodeValue is also a standard DOM property you can use:

function showPanel(fieldName) {
  var fieldNameElement = document.getElementById(field_name);
  if(fieldNameElement.firstChild)
    fieldNameElement.firstChild.nodeValue = "New Text";
}
palswim