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

FrankTechAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

contactkarthiCommented:
cut the selected text append at the front and back and paste it again :)
0
FrankTechAuthor Commented:
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.
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

contactkarthiCommented:
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
0
FrankTechAuthor Commented:
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

0
FrankTechAuthor Commented:
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?
0
HonorGodSoftware EngineerCommented:
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

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

    if ( document.selection && document.selection.type == 'Text' ) {
0
HonorGodSoftware EngineerCommented:
You do know that this is an IE only function, right?
0
FrankTechAuthor Commented:
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?
0
FrankTechAuthor Commented:
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.
0
HonorGodSoftware EngineerCommented:
ok.  it's going to take a bit of thought/work...
0
FrankTechAuthor Commented:
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?
0
FrankTechAuthor Commented:
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

0
HonorGodSoftware EngineerCommented:
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

0
FrankTechAuthor Commented:
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.
0
HonorGodSoftware EngineerCommented:
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?
0
FrankTechAuthor Commented:
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
0
HonorGodSoftware EngineerCommented:
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:

http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_23123667.html#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

0
FrankTechAuthor Commented:
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.
0
HonorGodSoftware EngineerCommented:
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

0
FrankTechAuthor Commented:
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]
0
HonorGodSoftware EngineerCommented:
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 ;
       }
    }
0
FrankTechAuthor Commented:
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.
0
HonorGodSoftware EngineerCommented:
I think (believe) that I found my problem.  Please forgive me for making this mistake.
Please try this function:
  //------------------------------------------------------------------
  // 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 + '] ';
 
    if ( document.selection && document.selection.type == 'Text' ) {
      alert( '#1' );
      //--------------------------------------------------------------
      // 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;
      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 );
      alert( 'Start: ' + el.selectionStart + '\n End: ' + el.selectionEnd + '\nText: "' + during + "'" );
      //--------------------------------------------------------------
      // Rewrite element value 
      //--------------------------------------------------------------
      el.value = before + openTag + during + closeTag + after ;
    } else if ( document.selection && document.selection.createRange ) {
      alert( '#2' );
      el.focus();
      var range = document.selection.createRange();
      range.text = openTag + range.text;
    } else {
      before   = el.value.substring( 0, el.selectionStart );
      during   = el.value.substring( el.selectionStart, el.selectionEnd );
      after    = el.value.substring( el.selectionEnd, el.value.length );
      if ( during != '' ) {
       el.value = before + openTag + during + closeTag + after ;
      } else {
       el.value = before + openTag + after ;
      }
    }
  }

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
HonorGodSoftware EngineerCommented:
oops, I left in:

alert( '#1' );

and

alert( '#2' );
0
FrankTechAuthor Commented:
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!
   
0
HonorGodSoftware EngineerCommented:
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.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.