Autofill Textarea

J

jim

Hi,

I have a form that accepts free text from users in a single textarea
field. I would like for a select list of words (15 or so) to
autopopulate as the user types. For example, instead of typing
"customer" the user could type "cu" and the form finish it for him/
her.

I know how to set autocomplete for a single text field, but don't know
if it's possible to have a field autocomplete partway through (e.g. if
the first word here is "customer" then we're set, but if the sentence
is "gave a coupon to customer X" then autocomplete wouldn't work).

Is this possible? If so, can anyone point me toward a script?

Thanks.


jim
 
D

Daz

Hi,

I have a form that accepts free text from users in a single textarea
field. I would like for a select list of words (15 or so) to
autopopulate as the user types. For example, instead of typing
"customer" the user could type "cu" and the form finish it for him/
her.

I know how to set autocomplete for a single text field, but don't know
if it's possible to have a field autocomplete partway through (e.g. if
the first word here is "customer" then we're set, but if the sentence
is "gave a coupon to customer X" then autocomplete wouldn't work).

Is this possible? If so, can anyone point me toward a script?

Thanks.

jim


Hi Jim.

Yes it's possible, but I believe it's far from simple, as you would
need to create a class to handle it, and create custom methods for
your textarea. I was trying to acheive the same thing a few months
ago, and unfortunately, despite my efforts, I was unable to find a
script to do what I needed.

I think it would benefit you to take a look at Google Mail, and the
way it does it's spell checking, and also www.google.com/webhp?complete=1
which is Google Suggest. It uses a text input field instead of a
textarea, but you might be able to get some inspiration from it.

Good luck.

Daz.
 
E

Elegie

jim wrote:

Hi Jim,
I have a form that accepts free text from users in a single textarea
field. I would like for a select list of words (15 or so) to
autopopulate as the user types. For example, instead of typing
"customer" the user could type "cu" and the form finish it for him/
her.

The following script should work decently on IE5+ and Firefox 2.0, and
is close to working in Opera 9 (I have encountered a problem with
setSelectionRange, which unfortunately does not seem to work when the
length is zero).

The script uses DOM Ranges extensively, which are, if I remember
correctly, not well-supported across user agents. As a result, I am
afraid this script will not work outside a very limited set of browsers
(though it should not harm navigators deprived from DOM Ranges
functionalities).


Regards,
Elegie.

---

<form action="#">
<textarea
rows="5"
cols="50"
onkeypress="return autocomplete(this, event)"
onkeyup="return autocomplete(this, event)"
onclick="return autocomplete(this, event)"
</textarea>
</form>

<script type="text/javascript">
var autocomplete=(function(){

// here, define the start chars and their word
var values={ // min 2 chars
"cu" : "customer",
"he" : "hello",
"wo" : "world"
};

// do not edit the code below

(function(){
var v;
for (var k in values) {
v=values[k];
for(var ii=k.length+1; ii<v.length; ii++) {
values[v.substr(0,ii)]=v;
}
}
})();

var finishAndComplete=0;

var getCaretPos=function(el) {
var rng, ii=-1;
if(typeof el.selectionStart=="number") {
ii=el.selectionStart;
} else if (document.selection && el.createTextRange){
rng=document.selection.createRange();
rng.collapse(true);
rng.moveStart("character", -el.value.length);
ii=rng.text.length;
}
return ii;
}

var highlight=function(el, start, length) {
var rng;
// set the selection
if(el.setSelectionRange) {
el.setSelectionRange(start, start+length);
} else if(el.createTextRange){
rng=el.createTextRange();
rng.moveStart("character", start);
rng.collapse(true);
rng.moveEnd("character", length);
rng.select();
}
}

return function (el, evt) {
var ii=getCaretPos(el), txt, complete;

//1) check if there's some opportunity to autocomplete
if(ii!=-1) {
// validate that there's some word boundary *after*
if(ii==el.value.length ||
/^.\b.$/.test(el.value.substring(ii-1,ii+1))
){
// validate that the started word matches
txt=/\b(.(\B.)+)$/.exec(el.value.substr(0, ii));
if(txt) {
complete=values[txt[1].toLowerCase()];
if(complete) complete=complete.substring(txt[1].length);
}
}
}

// 2) manage the entry
if(finishAndComplete && evt.keyCode==13) {
// validate the entry with [RETURN]
if(evt.type=="keyup") {
highlight(el, ii+finishAndComplete, 0); // fails in Opera :'(
finishAndComplete=0;
}
return false;
} else {
// propose the entry
if(complete) {
// only autocomplete if the user is not deleting
if(evt.keyCode &&
evt.keyCode!=8 &&
evt.keyCode!=46
){
el.value=el.value.substr(0,ii)+
complete+
el.value.substring(ii);
highlight(el, ii, finishAndComplete=complete.length);
} else {
// selection deleted
finishAndComplete=0;
}
} else {
finishAndComplete=0;
}
}
}
})();
</script>
 
J

jim

jim wrote:

Hi Jim,
I have a form that accepts free text from users in a single textarea
field. I would like for a select list of words (15 or so) to
autopopulate as the user types. For example, instead of typing
"customer" the user could type "cu" and the form finish it for him/
her.

The following script should work decently on IE5+ and Firefox 2.0, and
is close to working in Opera 9 (I have encountered a problem with
setSelectionRange, which unfortunately does not seem to work when the
length is zero).

The script uses DOM Ranges extensively, which are, if I remember
correctly, not well-supported across user agents. As a result, I am
afraid this script will not work outside a very limited set of browsers
(though it should not harm navigators deprived from DOM Ranges
functionalities).

Regards,
Elegie.

---

<form action="#">
<textarea
rows="5"
cols="50"
onkeypress="return autocomplete(this, event)"
onkeyup="return autocomplete(this, event)"
onclick="return autocomplete(this, event)"
</textarea>
</form>

<script type="text/javascript">
var autocomplete=(function(){

// here, define the start chars and their word
var values={ // min 2 chars
"cu" : "customer",
"he" : "hello",
"wo" : "world"
};

// do not edit the code below

(function(){
var v;
for (var k in values) {
v=values[k];
for(var ii=k.length+1; ii<v.length; ii++) {
values[v.substr(0,ii)]=v;
}
}
})();

var finishAndComplete=0;

var getCaretPos=function(el) {
var rng, ii=-1;
if(typeof el.selectionStart=="number") {
ii=el.selectionStart;
} else if (document.selection && el.createTextRange){
rng=document.selection.createRange();
rng.collapse(true);
rng.moveStart("character", -el.value.length);
ii=rng.text.length;
}
return ii;
}

var highlight=function(el, start, length) {
var rng;
// set the selection
if(el.setSelectionRange) {
el.setSelectionRange(start, start+length);
} else if(el.createTextRange){
rng=el.createTextRange();
rng.moveStart("character", start);
rng.collapse(true);
rng.moveEnd("character", length);
rng.select();
}
}

return function (el, evt) {
var ii=getCaretPos(el), txt, complete;

//1) check if there's some opportunity to autocomplete
if(ii!=-1) {
// validate that there's some word boundary *after*
if(ii==el.value.length ||
/^.\b.$/.test(el.value.substring(ii-1,ii+1))
){
// validate that the started word matches
txt=/\b(.(\B.)+)$/.exec(el.value.substr(0, ii));
if(txt) {
complete=values[txt[1].toLowerCase()];
if(complete) complete=complete.substring(txt[1].length);
}
}
}

// 2) manage the entry
if(finishAndComplete && evt.keyCode==13) {
// validate the entry with [RETURN]
if(evt.type=="keyup") {
highlight(el, ii+finishAndComplete, 0); // fails in Opera :'(
finishAndComplete=0;
}
return false;
} else {
// propose the entry
if(complete) {
// only autocomplete if the user is not deleting
if(evt.keyCode &&
evt.keyCode!=8 &&
evt.keyCode!=46
){
el.value=el.value.substr(0,ii)+
complete+
el.value.substring(ii);
highlight(el, ii, finishAndComplete=complete.length);
} else {
// selection deleted
finishAndComplete=0;
}
} else {
finishAndComplete=0;
}
}
}})();

</script>

This worked beautifully in Firefox 1.5.0.9. Thanks for the help!
 
D

Daz

jim wrote:

Hi Jim,
I have a form that accepts free text from users in a single textarea
field. I would like for a select list of words (15 or so) to
autopopulate as the user types. For example, instead of typing
"customer" the user could type "cu" and the form finish it for him/
her.

The following script should work decently on IE5+ and Firefox 2.0, and
is close to working in Opera 9 (I have encountered a problem with
setSelectionRange, which unfortunately does not seem to work when the
length is zero).

The script uses DOM Ranges extensively, which are, if I remember
correctly, not well-supported across user agents. As a result, I am
afraid this script will not work outside a very limited set of browsers
(though it should not harm navigators deprived from DOM Ranges
functionalities).

Regards,
Elegie.

---

<form action="#">
<textarea
rows="5"
cols="50"
onkeypress="return autocomplete(this, event)"
onkeyup="return autocomplete(this, event)"
onclick="return autocomplete(this, event)"
</textarea>
</form>

<script type="text/javascript">
var autocomplete=(function(){

// here, define the start chars and their word
var values={ // min 2 chars
"cu" : "customer",
"he" : "hello",
"wo" : "world"
};

// do not edit the code below

(function(){
var v;
for (var k in values) {
v=values[k];
for(var ii=k.length+1; ii<v.length; ii++) {
values[v.substr(0,ii)]=v;
}
}
})();

var finishAndComplete=0;

var getCaretPos=function(el) {
var rng, ii=-1;
if(typeof el.selectionStart=="number") {
ii=el.selectionStart;
} else if (document.selection && el.createTextRange){
rng=document.selection.createRange();
rng.collapse(true);
rng.moveStart("character", -el.value.length);
ii=rng.text.length;
}
return ii;
}

var highlight=function(el, start, length) {
var rng;
// set the selection
if(el.setSelectionRange) {
el.setSelectionRange(start, start+length);
} else if(el.createTextRange){
rng=el.createTextRange();
rng.moveStart("character", start);
rng.collapse(true);
rng.moveEnd("character", length);
rng.select();
}
}

return function (el, evt) {
var ii=getCaretPos(el), txt, complete;

//1) check if there's some opportunity to autocomplete
if(ii!=-1) {
// validate that there's some word boundary *after*
if(ii==el.value.length ||
/^.\b.$/.test(el.value.substring(ii-1,ii+1))
){
// validate that the started word matches
txt=/\b(.(\B.)+)$/.exec(el.value.substr(0, ii));
if(txt) {
complete=values[txt[1].toLowerCase()];
if(complete) complete=complete.substring(txt[1].length);
}
}
}

// 2) manage the entry
if(finishAndComplete && evt.keyCode==13) {
// validate the entry with [RETURN]
if(evt.type=="keyup") {
highlight(el, ii+finishAndComplete, 0); // fails in Opera :'(
finishAndComplete=0;
}
return false;
} else {
// propose the entry
if(complete) {
// only autocomplete if the user is not deleting
if(evt.keyCode &&
evt.keyCode!=8 &&
evt.keyCode!=46
){
el.value=el.value.substr(0,ii)+
complete+
el.value.substring(ii);
highlight(el, ii, finishAndComplete=complete.length);
} else {
// selection deleted
finishAndComplete=0;
}
} else {
finishAndComplete=0;
}
}
}})();

</script>


Copied into my snippets collection! Thanks for your help. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top