We help IT Professionals succeed at work.

Extract the matched substring that  surrounds the cursor position in a text field

nuno
nuno asked
on
791 Views
Last Modified: 2012-06-10
Hi!!

I want a JS function that returns the substring that is between commas, or between the last comma and the end of the string, or between the beggining of the string and the first comma,  depending on the cursor position. I want this to work on an input type text field.

For example:
Imagine that you write in an input type text  this: "aaaa,bbb,    cccc, dddd,eee_".
**** Note: The '_' char marks the cursor position. ******
In this case, I want the function to return "eee".
If you move the cursor back to the first or second 'd'  ("aaaa,bbb,    cccc, d_ddd,eee") I want it to return "dddd".
If you have the curson on the first a's ("a_aaa,bbb,    cccc, d_ddd,eee") I want it to return "aaaa".

I think you get the idea. I want this to work on both *Mozilla* and *IE* (latest versions are enough).

Thank you in advance.

PS: I want to give 1000 points for the correct anwer.. So we can arrange some way to do it.
Comment
Watch Question

Saqib KhanSenior Developer

Commented:
Just wondering is it Really possible to Retieve the Cursor Location within the Textbox without Selecting the Text.............
this works in IE but i do not know about moz

it was adapted from a script i found on http://www.faqts.com
i thinks it still has a bug if you user highlights a piece of the textbox but im trying to work it out

************  WARNING THE CODE YOU ARE ABOUT TO VIEW IS RATHER UGLY ******************

<HTML>
     <HEAD>
     <SCRIPT>
var textEl

 function storeCaret (x) {
      textEl = x
      if (textEl.createTextRange)
         textEl.caretPos = document.selection.createRange().duplicate();
 }

 function insertAtCaret (text) {
      var caretPos = (textEl.caretPos) ? textEl.caretPos : textEl.length;
   
   //whatever is higlight or wherever the cursor is, replace with a bar |
      caretPos.text = text;

   //store the current value of the text
      theValue = textEl.value

  //split the value into left of the bar and right of the bar
      toTheLeft=theValue.split('|') != -1 ? theValue.split('|') : theValue

  //split the text to the right of the bar by a comma
      toTheRight = toTheLeft[1].split(',')

  //save the info to the left of the bar and to the next comma
      combined = toTheLeft[0] + toTheRight[0]

  //split this by comma
      vals = combined.split(',')

  //get rid of the bar in the input field
      textEl.value = textEl.value.replace('|','')

  //alert the last value in the array
      alert(vals[vals.length-1])
 }
     </SCRIPT>
     </HEAD>
     <BODY onload="document.aForm.aText.focus()">
     <FORM NAME="aForm">
     
     <BR>
     <INPUT TYPE="text" NAME="aText" SIZE="80" VALUE="aaaa,bbb,    cccc, dddd,eee"
             ONFOCUS="storeCaret(this);"
               ONSELECT="storeCaret(this);"
               ONCLICK="storeCaret(this);"
               ONKEYUP="storeCaret(this);"
>
     <BR>
     <INPUT TYPE="button" VALUE="Find My Cursor"
            ONCLICK="insertAtCaret('|');"
     >
     </FORM>
     </BODY>
     </HTML>

Author

Commented:
bustarooms,

 Unfortunally it doesn't work with mozilla!
I also saw the example you based on in faqts.com...

adilkhan,

In IE it is possible.
In mozilla I don't know. I only know that if it's possible in mozilla, probably mozilla version must be greater than v1.3.

That's why I'm offering 500 points, and will give 500 more if possible by some way.
ahosangFinance Systems Developer

Commented:
Possible in Mozilla with onkeyup:
<html>
<head>
<title>Moz Caret Positions</title>
<script>
function update(field) {// MOZ ONLY - integrate or branch with IE version
  if(typeof field.setSelectionRange!="undefined") {
    var val=field.value;
    var oldStart=field.selectionStart;
    var oldEnd=field.selectionEnd;
    var start=val.substring(0, oldStart).lastIndexOf(",");
    start=(start>-1)?start+1:0;
    var end=val.substr(oldEnd).indexOf(",");
    end=(end>-1)?end+oldEnd:val.length;
    field.form.result.value=val.substring(start, end);
    //field.form.result.value=typeof field.selectionStart;
  } else {
    field.form.result.value="Not Possible";
  }
}

</script>
</head>

<body>
<form>
<input name="txt" onkeyup="update(this)"><br><br>
<input name="result" value="">
</form>
<br>
</body>
</html>
ahosangFinance Systems Developer

Commented:
Any feedback nuno?

Author

Commented:
Sorry for the delay...

ahosang,

   Your solution seems to work in mozilla, but it has a problem. A '|' is left in the input text, after each comma, when you cursor left or right and pass a comma. If you go from the end of the input to the begginning, I'll have something like this in the text input:
"aaa|,eeee|,iiii,iiii|,ooooo|,uuu". Anyway, this seems like a rendering problem, but if you have any other solution or how to fix this I'd appreciate it.

As I said, I'm willing to give you 1000 points for this, but I want the complete solution,  so it works on both IE and Mozilla.

Thanks
ahosangFinance Systems Developer

Commented:
Three things:
1) What version of Mozilla/OS, and are you using onkeyup?
2) If the situation continues(but otherwise the script works perfectly), then it's a rendering problem which I don't get, and so can't fix.
3) Regarding the IE branch - I can't use IE's textranges much because I have a Mac, but I may have a little time at work on a Windows OS. Otherwise did you get anywhere with Bustarooms code??
 If so, then I could merge them. It's not the points that motivate me any more but interesting questions(such as this). I can't really stay late at work just to solve the IE part for you, but if Bustarooms works then we're OK. All we have to do is combine the scripts so they work on both.
Remember points can always be split among experts.

Author

Commented:

Here are the responses:

1) Mozilla 1.4 / Linux. I just copy&paste your example.
3) bustarooms code works on IE

TIA,

 Nuno
ahosangFinance Systems Developer

Commented:
1) I don't have Linux and so can't really fix. I'll try some guesses later
Sorry, but I forgot to say - with regarding the combination, Bustarooms is calling function that does this onclick of a button. Do you want this to run onkeyup like I did or what?

Author

Commented:
I'd like on keyup...
Thanks again for all your help.

Nuno
ahosangFinance Systems Developer

Commented:
Using my form setup, but altering the textfield to:
<input name="txt" ONFOCUS="storeCaret(this)" ONSELECT="storeCaret(this)" ONCLICK="storeCaret(this)"           ONKEYUP="storeCaret(this);update(this)">

<script>
 function storeCaret (x) {
    if (!document.all) {return}
     textEl = x
     if (textEl.createTextRange)
        textEl.caretPos = document.selection.createRange().duplicate();
}

 function insertAtCaret (field) {
  if (document.all) {// IE VERSION
     var caretPos = (textEl.caretPos) ? textEl.caretPos : textEl.length;
 
   //whatever is higlight or wherever the cursor is, replace with a bar |
     caretPos.text = "|";

  //store the current value of the text
     theValue = textEl.value

 //split the value into left of the bar and right of the bar
     toTheLeft=theValue.split('|') != -1 ? theValue.split('|') : theValue

 //split the text to the right of the bar by a comma
     toTheRight = toTheLeft[1].split(',')

 //save the info to the left of the bar and to the next comma
     combined = toTheLeft[0] + toTheRight[0]

 //split this by comma
     vals = combined.split(',')

 //get rid of the bar in the input field
     textEl.value = textEl.value.replace('|','')

  //set new value
     field.form.result.value=vals[vals.length-1];
  } else if(typeof field.setSelectionRange!="undefined") {// MOZILLA VERSION
   var val=field.value;
   var oldStart=field.selectionStart;
   var oldEnd=field.selectionEnd;
   var start=val.substring(0, oldStart).lastIndexOf(",");
   start=(start>-1)?start+1:0;
   var end=val.substr(oldEnd).indexOf(",");
   end=(end>-1)?end+oldEnd:val.length;
   field.form.result.value=val.substring(start, end);
 } else {
   field.form.result.value="Not Possible";
 }
}
</script>

tired now - any problems I'll try and look tomorrow

Author

Commented:
ahosang,

It doesn't work in IE neither in Mozilla...
Here's the source: http://nuno.uncovering.org/curPosF.html

Did I do anything wrong?

TIA
ahosangFinance Systems Developer

Commented:
ahh very sorry, simple typo.
Change the name of the insertAtCaret function to update!!!

function update (field) {
 if (document.all) {// IE VERSION
    var caretPos = (textEl.caretPos) ? textEl.caretPos : textEl.length;
****** AND SO ON *******

The IE version is buggy - working on it.
ahosangFinance Systems Developer

Commented:
The best so far is:
<html>
<head>
<title>Moz Caret Positions</title>
<script>
function storeCaret (x) {
   if (!document.all) {return}
    textEl = x
    if (textEl.createTextRange)
       caretPos = document.selection.createRange().duplicate();
}

function update (field) {
 if (document.all) {// IE VERSION
    var icaretPos = (caretPos) ? caretPos : textEl.length;

   //whatever is higlight or wherever the cursor is, replace with a bar |
    icaretPos.text = "|";
   
 //store the current value of the text
    theValue = textEl.value;

// get two halves
   var arr=theValue.split("|");

//split the value into left of the bar and right of the bar
    toTheLeft=arr[0].split(",")[arr[0].split(",").length-1];

//split the text to the right of the bar by a comma
    toTheRight = arr[1].split(',')[0];

//save the info to the left of the bar and to the next comma
    combined = toTheLeft + toTheRight;

//split this by comma
   // vals = combined.split(',')

//get rid of the bar in the input field
 textEl.value = textEl.value.replace('|','')

 //set new value
    field.form.result.value=combined;
 } else if(typeof field.setSelectionRange!="undefined") {// MOZILLA VERSION
  var val=field.value;
  var oldStart=field.selectionStart;
  var oldEnd=field.selectionEnd;
  var start=val.substring(0, oldStart).lastIndexOf(",");
  start=(start>-1)?start+1:0;
  var end=val.substr(oldEnd).indexOf(",");
  end=(end>-1)?end+oldEnd:val.length;
  field.form.result.value=val.substring(start, end);
} else {
  field.form.result.value="Not Possible";
}
}
</script>
</head>

<body>
<form>
<input name="txt" ONFOCUS="storeCaret(this)" ONSELECT="storeCaret(this)" ONCLICK="storeCaret(this)" ONKEYUP="storeCaret(this);update(this)">
<br><br>
<input name="result" value="">
</form>
<br>
</body>
</html>

Gotta go now!

Author

Commented:
ahosong,

There's only a problem with the IE version.
If you go back in the text input with the left cursor, the cursor jumps to the last position.

TA
ahosangFinance Systems Developer

Commented:
Yes I said that the IE version is buggy. I'll try again tomorrow, but it may be that IE's typical limitations mean this won't work well in IE
Finance Systems Developer
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

Author

Commented:
I'll accept your last answer.
It looks great on both browsers, so you  deserve the 500 points.
How can I give you the extra 500 points, as I promised?

Anyway, is it easy to ignore the comma if between double quotes? I only find out now that I need that too...
If it's easy, you could prepare the answer, and I put the question with 500 points and tell you to answer it. If not, answer my above question please.

I'll describe a bit more what I want...
I want this to extract the email address on the cursor position, so if you type  aaa@aaa.com, bbb@ccc.com, ccc@ddd.com and go back with your cursor to ccc@ddd.com it outputs ccc@ddd.com. Your version already works that way, but I realized one case that it doesn't work (and it's my fault because I didn't tell it in the beggining). It's in the case you type bbb@bbb.com, "bbbb, aaaa <aaa@aaa.com>", ccc@dddd.com. I think you understand the problem....

my email is:  n u n o @(at)  c o  .(dot)  s a p o  .(dot)  p t
sorry to write the email this way, but I don't want to get caught by spambots.

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions