Link to home
Start Free TrialLog in
Avatar of FrankTech
FrankTech

asked on

Use JS to Insert at Cursor in Textarea

This javascript should do either of two things in Internet Explorer 6:
   1) Insert that info before a selection of text, and also insert the word at the end  (This part is working OK); or
   2) Insert today's date and a word, at the cursor position in the textarea  (this gives an error).

For example,

   1) selecting a range of text and then clicking the button will insert like this:
   [01-30-08 Hello] selected text [/Hello]

or

   2) clicking to make a cursor point, and then clicking the button should insert " [01-30-08 Hello] " at the cursor.  Or

     #1 (the range selection / wrap-around insert) is working fine in IE6, but # 2 (the plain insertion-at-cursor) does not work. I get an invalid-argument error.
    What needs to be adjusted to make #2 (insertion at cursor) work?

    (By the way, this is _not_ a duplicate of http:Q_23108350.html .  That question was about #2).
<html>
<head>
<title>Insert Text at Cursor in Textarea</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 
<script type="text/javascript"> 
function insert(el,ins) { 
 
var rightnow= new Date();
var themonth= rightnow.getMonth();
 themonth+=1;
var theday= rightnow.getDate();
 var year= rightnow.getYear();
var theyear = (year+"").substring(2,4);
var today= themonth+"-"+theday+"-"+theyear;
 
    if (document.selection){ 
	
var range = document.selection.createRange(); 
var stored_range = range.duplicate(); 
stored_range.moveToElementText(el); 
stored_range.setEndPoint( 'EndToEnd', range ); 
el.selectionStart = stored_range.text.length - range.text.length; 
el.selectionEnd = el.selectionStart + range.text.length;
	el.value = el.value.substring(0,el.selectionStart) + "[" + today +" "+ ins +"] "+ el.value.substring(el.selectionStart,el.selectionEnd) + "[/" + ins + "]" + el.value.substring(el.selectionEnd,el.value.length) ; 
    } 
    else if (document.selection && document.selection.createRange) { 
        el.focus(); 
        var range = document.selection.createRange(); 
        range.text = "[" + today +" "+ ins +"] "+ range.text; 
    } 
}
</script>
</head>
<body>
<form> 
<input type="button" value="hello" onclick="insert(this.form.ta,'hello')"> 
<input type="button" value="my friend" onclick="insert(this.form.ta,'my friend')"> 
<br /> 
<textarea rows="8" cols="60" name="ta">This is sample text. Click anywhere in here then choose one of the buttons above to see the date and text inserted. 
</textarea> 
</form>  
 
</body>
</html>

Open in new window

Avatar of contactkarthi
contactkarthi
Flag of United States of America image

cut the selected text append at the front and back and paste it again :)
Avatar of FrankTech
FrankTech

ASKER

That's a very useful web site, but what I'm looking for is how to make the following code work in my existing script, to insert the date at the cursor:

    else if (document.selection && document.selection.createRange) {
        el.focus();
        var range = document.selection.createRange();
        range.text = "[" + today +" "+ ins +"] "+ range.text;
    }

That code used to work fine (see my previous question). But when the expert fixed the other part, this part stopped working.  I'm just trying to get both parts working.

Before the script was revised in my previous question (to correct a different problem), the cursor-insertion code worked.  I just want to get it working again.
if you want to insert at cursor position this page will help you

http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130
Yes, I've seen that page, and I appreciate your pointing it out.  However, what I need is some trouble-shooting of my existing script.
    The insert-at-cursor part used to work (but the select-range part did not work in IE6).
   Then an expert fixed the selected-range issue so it would work in IE6.
    But that fix caused the other part to break.  Now the part that was working before, is not working now.  It is this code:

      else if (document.selection && document.selection.createRange) {
        el.focus();
        var range = document.selection.createRange();
        range.text = "[" + today +" "+ ins +"] "+ range.text;
    }


It gives an error:  "invalid argument".


Before the script was ever revised, that part of the code worked.   This is how the original script was (and the cursor-insertion worked):
<html>
<head>
<title>Insert Text at Cursor in Textarea</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript"> 
function insert(el,ins) { 
 
var rightnow= new Date();
var themonth= rightnow.getMonth();
 themonth+=1;
var theday= rightnow.getDate();
 var year= rightnow.getYear();
var theyear = (year+"").substring(2,4);
var today= themonth+"-"+theday+"-"+theyear;
 
    if (el.setSelectionRange){ 
        el.value = el.value.substring(0,el.selectionStart) + "[" + today +" "+ ins +"] "+ el.value.substring(el.selectionStart,el.selectionEnd) + el.value.substring(el.selectionEnd,el.value.length) + "[/" + ins + "]"; 
    } 
    else if (document.selection && document.selection.createRange) { 
        el.focus(); 
        var range = document.selection.createRange(); 
        range.text = "[" + today +" "+ ins +"] "+ range.text; 
    } 
} 
</script> 
</head>
<body>
<form> 
<input type="button" value="hello" onclick="insert(this.form.ta,'hello')"> 
<input type="button" value="my friend" onclick="insert(this.form.ta,'my friend')"> 
<br /> 
<textarea rows="8" cols="60" name="ta">This is sample text. Click anywhere in here then choose one of the buttons above to see the date and text inserted. 
</textarea> 
</form>  
 
</body>
</html>
 

Open in new window

So the question is, why won't that part work now, after the other issue (insertion around a selected range) was fixed for IE?   Why the "invalid argument" error?
I haven't checked to see if anyone else has updated in quite awhile... let's see... :-)
<html>
<head>
<title>Insert Text at Cursor in Textarea</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 
<script type='text/javascript'>
  //------------------------------------------------------------------
  // Name: D2()
  // Role: Simple test to guarantee value has at least two digits
  //------------------------------------------------------------------
  function D2( val ) {
    return ( val < 10 ) ? '0' + val : '' + val;
  }
 
  //------------------------------------------------------------------
  // Name: insert()
  // Role: Insert the specified text to the user selected location
  //------------------------------------------------------------------
  function insert( el, ins ) {
    var now   = new Date();
    var mon   = D2( now.getMonth() + 1 );
    var day   = D2( now.getDate() );
    var year  = D2( now.getYear() % 100 );
    var today = mon + '-' + day + '-' + year;
 
    if ( document.selection &&
         document.selection.type == 'Text' && ( 'cursorAt' in el ) ) {
      var range = document.selection.createRange();
      var stored_range = range.duplicate();
      stored_range.moveToElementText( el );
      stored_range.setEndPoint( 'EndToEnd', range );
      el.selectionStart = stored_range.text.length - range.text.length;
      el.selectionEnd   = el.selectionStart + range.text.length;
      el.value = el.value.substring( 0, el.selectionStart ) + '[' +
         today + ' ' + ins + '] ' +
         el.value.substring( el.selectionStart, el.selectionEnd ) +
         '[/' + ins + ']' +
         el.value.substring( el.selectionEnd,el.value.length ) ;
    } else if ( document.selection && document.selection.createRange ) {
      el.focus();
      var range = document.selection.createRange();
      range.text = '[' + today + ' ' + ins + '] ' + range.text;
    }
  }
</script>
</head>
<body>
<form>
<input type='button' value='hello' onclick='insert(this.form.ta,"hello")'>
<input type="button" value="my friend" onclick="insert(this.form.ta,'my friend')">
<br />
<textarea rows='6' cols='30' name='ta'>
This is sample text.  Click
anywhere in here then choose
one of the buttons above to
see the date and text
inserted.
</textarea>
</form>
 
</body>
</html>

Open in new window

Sorry, I removed something, change lines 26 & 27 to:

    if ( document.selection && document.selection.type == 'Text' ) {
You do know that this is an IE only function, right?
HonorGod,
    Thanks for the solution; seems to work perfectly now.

    Although this is an IE-only function, it will be used in an IE-only environment for now.
    But if there is a way to make it work on both IE6 and FireFox, etc., it would be nice to have a more cross-browser compatible solution in case it might be used on other browsers sometime.  Would that be possible?
HonorGod,
   I just discovered this will be need for a multi-browser environment, so I would appreciate if you can show me how to make it compatible with both IE and Firefox. Thanks.
ok.  it's going to take a bit of thought/work...
OK. No problem.  I'm pretty sure the original script (not the one in my question, but the one in ID:20781750 ) worked on Firefox.
    Maybe there could be an if-else conditional to run one code if IE, or the other code if not IE?
To be more clear, I believe this code is FireFox compatible, so maybe there's a way to just use a conditional to run it if the browser is FireFox:

 
    if (el.setSelectionRange){ 
el.value = el.value.substring(0,el.selectionStart) + "[" + today +" "+ ins +"] "+ el.value.substring(el.selectionStart,el.selectionEnd) + "[/" + ins + "]" + el.value.substring(el.selectionEnd,el.value.length); 
    } 
    else if (document.selection && document.selection.createRange) { 
        el.focus(); 
        var range = document.selection.createRange(); 
        range.text = "[" + today +" "+ ins +"] "+ range.text; 
    } 
} 

Open in new window

This seems to work for me...
  //------------------------------------------------------------------
  // Name: insert()
  // Role: Insert the specified text to the user selected location
  // Note: Resources
  // - TextRange object
  //   http://www.webreference.com/js/column12/selectionobject.html
  // - TextRange Object Properties and Methods (e.g., setEndPoint)
  //   http://www.webreference.com/js/column12/trmethods.html
  // - Finding selection start and end position in a textarea, in
  //   Internet Explorer (URL should be contiguous)
  //   http://the-stickman.com/web-development/javascript/finding-
  //     -selection-cursor-position-in-a-textarea-in-internet-explorer/
  //------------------------------------------------------------------
  function insert( el, ins ) {
    //----------------------------------------------------------------
    // Generate a datestamp of the form: MM-DD-YY (e.g., 01-30-08)
    //----------------------------------------------------------------
    var now   = new Date();
    var mon   = D2( now.getMonth() + 1 );
    var day   = D2( now.getDate() );
    var year  = D2( now.getYear() % 100 );
    var today = mon + '-' + day + '-' + year;
 
    //----------------------------------------------------------------
    // Before we can do anything, we need to verify that the things
    // that we are trying to do are supported by this browser (i.e.,
    // IE). [pun intended]
    //----------------------------------------------------------------
    var openTag  = '[' + today + ' ' + ins + '] ';
    var closeTag = '[/' + ins + '] ';
    var before   = el.value.substring( 0, el.selectionStart );
    var during   = el.value.substring( el.selectionStart, el.selectionEnd );
    var after    = el.value.substring( el.selectionEnd, el.value.length );
 
    if ( document.selection && document.selection.type == 'Text' ) {
      //--------------------------------------------------------------
      // First, create a TextRange object
      //--------------------------------------------------------------
      var range = document.selection.createRange();
      //--------------------------------------------------------------
      // Duplicate the (parent) TextRange object
      //--------------------------------------------------------------
      var stored_range = range.duplicate();
      //--------------------------------------------------------------
      // Identify the document element with which this duplicate is to
      // be associated...
      //--------------------------------------------------------------
      stored_range.moveToElementText( el );
      //--------------------------------------------------------------
      // setEndPoint (see Resources, above)
      //--------------------------------------------------------------
      stored_range.setEndPoint( 'EndToEnd', range );
      //--------------------------------------------------------------
      // Determine selection starting and ending positions
      //--------------------------------------------------------------
      el.selectionStart = stored_range.text.length - range.text.length;
      el.selectionEnd   = el.selectionStart + range.text.length;
      //--------------------------------------------------------------
      // Rewrite element value 
      //--------------------------------------------------------------
      el.value = before + openTag + during + closeTag + after ;
    } else if ( document.selection && document.selection.createRange ) {
      el.focus();
      var range = document.selection.createRange();
      range.text = openTag + range.text;
    } else {
      el.value = before + openTag + during + closeTag + after ;
    }
  }

Open in new window

Thanks, HonorGod,
    I am getting an "object expected" error in IE6.  The function is not working for me in FF, either, although no error message is raised. I'm not sure what's wrong.
sorry...  It worked for me...  I wonder why?!?

Do you have a line number for the "object expected" error in IE?

And what version of FireFox?
It's FireFox 2.0.0.11 .  
    I'm going to attach a file in case you want to test the exact page that I'm testing in IE. It says error at line 24.
   Right now my form tag is just <form>, but later I will give it an actual name.  I don't know if something is conflicting with the html form code that calls the function, or maybe I copied something into the wrong location?
textinsert.htm.txt
Please do me a favor, and change line 5 from:

<script>

to

<script type='text/javascript'>

and see if the error exists.

Line 24 (in the file you sent) is:

var mon   = D2( now.getMonth() + 1 );

Right?

You didn't copy the D2 function ..

See above:

https://www.experts-exchange.com/questions/23123667/Use-JS-to-Insert-at-Cursor-in-Textarea.html?anchorAnswerId=20783342#a20783342

  //------------------------------------------------------------------
  // Name: D2()
  // Role: Simple test to guarantee value has at least two digits
  //------------------------------------------------------------------
  function D2( val ) {
    return ( val < 10 ) ? '0' + val : '' + val;
  }
 

Open in new window

Ah!  OK. So now the script is running without error codes in both IE and FF.  However, it is not working right.
    In IE, the insert-at-cursor function works properly, (but the other function (highlight text and then click to "wrap" codes around that range) is adding a lot of extra text (looks like it's adding an additional copy of all the text that was highlighted, in addition to the actual text that was selected).

    In FF, it's the opposite.  The plain insert-at-cursor function is acting up: it's inserting both a beginning and an ending "tag"-- but it should only insert one thing (e.g., [01-31-08 Hello] .)   But the other function (to "wrap" beginning and ending tags around selected text) works great in FF.
IE - Test #1:
------------------------------
This is sample text.  Click
anywhere in here then choose
one of the buttons above to
see the date and text
inserted.
------------------------------

Test:
- Click on the "space" after "This"

So the TextArea looks (kind of like):

------------------------------
This| is sample text.  Click
anywhere in here then choose
one of the buttons above to
see the date and text
inserted.
------------------------------

After clicking "hello" button,
the TextArea appears to be:

------------------------------
This[01-31-08 hello]  is
sample text.  Click
anywhere in here then choose
one of the buttons above to
see the date and text
inserted.
------------------------------

Is this correct?  It appears that this means that the code that was executed is the  one if the 2nd if() - i.e., the code shown below.

If this is the wrong action, what should it appear like?
    } else if ( document.selection && document.selection.createRange ) {
      el.focus();
      var range = document.selection.createRange();
      range.text = openTag + range.text;
    }

Open in new window

Yes, that's the right part of the code, and that part is working right in IE -- but not in FF.  

In IE it correctly changes this:
      sample| text
to:
     sample [01-31-08 hello] text

However, in FF it mistakenly changes this:
     sample| text
to:
     sample [01-31-08 hello] [/hello] text

(It's mistakenly adding two tags (a beginning *and* ending) in FF, where it should only put one thing at the cursor).

 -  -  -  -  -  -  -  -  -

The other function (the first "if . . ." in the code) is working fine in FF.  It's correctly changing this:
     selected-->   sample text   <--selected

to:
     [01-31-08 hello] sample text [/hello]

However, IE is not handling that function correctly.
Instead of   [01-31-08 hello] sample text [\hello]  ,
IE is adding or copying/pasting extra text into the area between the tags, like this:

     [01-31-08 hello] sample text sample text sample text [/hello]
Ah, that implies that the code being executed for FireFox is the final else clause.
So, what if we change the from:

    } else {
      el.value = before + openTag + during + closeTag + after ;
    }

To:

    } else {
       if ( during != '' ) {
        el.value = before + openTag + during + closeTag + after ;
       } else {
        el.value = before + openTag + after ;
       }
    }
Yes, FireFox seems to work properly now with that change. Great!

But IE is still acting up with the wrap-around tags.  Here is the original text:
----------------
  This is sample text.
----------------

This is how it should look if we select the whole block of text and click Hello in IE:
----------------
  [01-31-08 hello] This is sample text. [/hello]
----------------

But this is what it is mistakenly doing:
----------------
This is sample text.  
[01-31-08 hello] This is sample text.
[/hello] This is sample text.  
----------------

Looks like it's copying and pasting the select text before the selection and after the selection.
ASKER CERTIFIED SOLUTION
Avatar of HonorGod
HonorGod
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
oops, I left in:

alert( '#1' );

and

alert( '#2' );
No problem, it was actually good to see the alerts working to indicate what part of the code was running.  I took them out, and tested everything in both FF and IE.  It all seems to be working now.
    Once again, your expertise is remarkable, and your willingness to help is greatly appreciated.  Nicely formatted and well-documented code, too. Thanks!
   
You are very welcome.  Thanks for the nice words.  That is part of the reason I like doing this.

Interestingly enough, some people think that my comments are too verbose.  :-)

But that is something that I consider as valuable as working code.

Thanks for the Grade, the Points, and the Compliments.

Good luck & have a great day... whatever you have left of it anyway.