Link to home
Start Free TrialLog in
Avatar of nuno
nuno

asked on

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

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.
Avatar of Saqib Khan
Saqib Khan
Flag of United States of America image

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>
Avatar of nuno
nuno

ASKER

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.
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>
Any feedback nuno?
Avatar of nuno

ASKER

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
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.
Avatar of nuno

ASKER


Here are the responses:

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

TIA,

 Nuno
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?
Avatar of nuno

ASKER

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

Nuno
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
Avatar of nuno

ASKER

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
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.
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!
Avatar of nuno

ASKER

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
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
ASKER CERTIFIED SOLUTION
Avatar of ahosang
ahosang
Flag of United Kingdom of Great Britain and Northern Ireland 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
Avatar of nuno

ASKER

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.