tags:

views:

3175

answers:

5

For my small wiki application, I mostly need to have the textarea used to edit the contents to use soft (or virtual) wrapping. However, in some cases, not wrapping the content would be preferable. I thought I would do this by simply having a button to turn off wrapping. Here is the simplified code:

  <form name="wikiedit" action="[[script_name]]" method="post">
    <textarea name="content" rows="25" cols="90" wrap="virtual">[[content]]</textarea>
    <input type="button" onclick="document.wikiedit.content.wrap='off';" value="No Wrap"> &nbsp;
    <input type="submit" value="Save">
  </form>

It works with IE, but not with Firefox or Opera. How should I do this?

A: 

According to the HTML 4.01 spec, wrap isn't a valid attribute for <textarea>s which would explain why it's so difficult and strange. It looks as though Firefox actually does use the wrap attribute, but it won't let you change it.

I do have a solution though! It's pretty awful, but here it is. Completely replace the textarea with a new one.

// this is the onclick handler for your button
document.getElementById("nowrapButton").onclick = function() {
  var oldOne = this.form.content;  // the old textarea
  var newOne = document.createElement('textarea'); // the new textarea
  var attrs = ['name', 'rows', 'cols']; // these are the attributes to keep
  for (var i = 0; i < attrs.length; ++i) {
    // copy the attributes to the new one
    newOne.setAttribute(attrs[i], oldOne.getAttribute(attrs[i]));
  }

  // toggle the wrapping on and off
  if (oldOne.getAttribute('wrap') != 'off') {
    newOne.setAttribute('wrap', 'off');
  }

  // copy the text over
  newOne.value = oldOne.value;

  // add the new one
  oldOne.parentNode.insertBefore(newOne, oldOne);
  // get rid of the old one
  oldOne.parentNode.removeChild(oldOne);
  return false;
};

Here's a working version of this you can play with: http://jsbin.com/ugepa

As usual, this'd be much nicer in jQuery. :)

nickf
+2  A: 

See bug 41464: https://bugzilla.mozilla.org/show_bug.cgi?id=41464

Nasty workaround for now is to replace the textarea with a clone of itself:

function setWrap(area, wrap) {
    if (area.wrap) {
        area.wrap= wrap;
    } else { // wrap attribute not supported - try Mozilla workaround
        area.setAttribute('wrap', wrap);
        var newarea= area.cloneNode(true);
        newarea.value= area.value;
        area.parentNode.replaceChild(newarea, area);
    }
}

Unrelated: try to avoid accessing elements straight out of the document object, it is unreliable on some browsers and causes name clash problems. ‘document.forms.wikiedit’ is better, and moving to ‘id’ on the form instead of ‘name’ and then using ‘document.getElementById('wikiedit')’ better still.

form.elements.content is also more reliable than form.content for similar reasons... or, indeed, you could give the textarea an ID and go straight to the textarea with getElementById without having to bother look at the form.

bobince
What is 'textarea.wrap' supposed to be?
a typo - thanks, fixed
bobince
That's not nasty at all. It works great. Thx.
orokusaki
A: 

Here is a primer on textarea wrap, including a CSS solution:

http://www.web-wise-wizard.com/html-tutorials/html-form-forms-textarea-wrap.html

The CSS solution they cite is:

white-space: pre; overflow: auto;

Which would be:

<script type="text/javascript">
function setNoWrap(textarea) {
    textarea.style.whiteSpace = 'pre';
    textarea.style.overflow = 'auto';
}
</script>
<form name="wikiedit" action="[[script_name]]" method="post">
 <textarea name="content" rows="25" cols="90" wrap="virtual">[[content]]</textarea>
 <input type="button" onclick="setNoWrap(this);" value="No Wrap">  
 <input type="submit" value="Save">
</form>
Jared Farrish
A: 

Although, this is a old post, but as I getting help from this, I also what to show a easier method I found just now. And I think it's more correct.

To replace the .cloneNode(), I think the best method is:

child.setAttribute( 'wrap', wrap ); parent.removeChild( child ); parent.appendChild( child );

using this way, you can not only save the attributes of itself, but also the attributes you added, for example, a script handle or something else.

A: 

Try this jQuery extension: Textarea Wrap Changer .