I am trying to implement Autocomplete in a text area (similar to http://www.pengoworks.com/workshop/jquery/autocomplete.htm).
我正在尝试在文本区域中实现自动完成功能(类似于http://www.pengoworks.com/workshop/jquery/autocomplete.htm)。
What I am trying to do is when a user enters a specific set of characters (say insert:) they will get an AJAX filled div with possible selectable matches.
我想要做的是当用户输入一组特定的字符(比如插入:)时,他们会得到一个带有AJAX填充的div,可能有可选的匹配。
In a regular text box, this is of course simple, but in a text area I need to be able to popup the div in the correct location on the screen based on the cursor.
在常规文本框中,这当然很简单,但在文本区域中,我需要能够根据光标在屏幕上的正确位置弹出div。
Can anyone provide any direction?
有人可以提供任何指示吗?
Thanks, -M
4 个解决方案
#1
#2
1
Implementing an autocomplete in a text area is not that easy. I implemented a jquery plugin that does that, and i had to create a clone of the texarea to guess where the cursor is positioned inside the textarea. Its working, but its not perfect.
在文本区域中实现自动完成并不容易。我实现了一个jquery插件来实现这一点,我必须创建texarea的克隆来猜测光标在textarea中的位置。它的工作,但它并不完美。
You can check it out here: http://www.amirharel.com/2011/03/07/implementing-autocomplete-jquery-plugin-for-textarea/
你可以在这里查看:http://www.amirharel.com/2011/03/07/implementing-autocomplete-jquery-plugin-for-textarea/
I hope it helps.
我希望它有所帮助。
#3
0
an ugly solution:
丑陋的解决方案:
for ie: use document.selection...
for ie:使用document.selection ...
for ff: use a pre behind textarea, paste text before cursor into it, put a marker html element after it (cursorPos), and get the cursor position via that marker element
for ff:使用前置textarea,将光标前的文本粘贴到其中,在其后放置一个标记html元素(cursorPos),并通过该标记元素获取光标位置
Notes: | code is ugly, sorry for that | pre and textarea font must be the same | opacity is utilized for visualization | there is no autocomplete, just a cursor following div here (as you type inside textarea) (modify it based on your need)
备注:|代码很难看,对不起pre和textarea字体必须相同|不透明度用于可视化|没有自动完成功能,只有一个光标跟在div后面(当你在textarea里面输入时)(根据你的需要修改它)
<html>
<style>
pre.studentCodeColor{
position:absolute;
margin:0;
padding:0;
border:1px solid blue;
z-index:2;
}
textarea.studentCode{
position:relative;
margin:0;
padding:0;
border:1px solid silver;
z-index:3;
overflow:visible;
opacity:0.5;
filter:alpha(opacity=50);
}
</style>
hello world<br/>
how are you<br/>
<pre class="studentCodeColor" id="preBehindMyTextarea">
</pre>
<textarea id="myTextarea" class="studentCode" cols="100" rows="30" onkeyup="document.selection?ieTaKeyUp():taKeyUp();">
</textarea>
<div
style="width:100px;height:60px;position:absolute;border:1px solid red;background-color:yellow"
id="autoCompleteSelector">
autocomplete contents
</div>
<script>
var myTextarea = document.getElementById('myTextarea');
var preBehindMyTextarea = document.getElementById('preBehindMyTextarea');
var autoCompleteSelector = document.getElementById('autoCompleteSelector');
function ieTaKeyUp(){
var r = document.selection.createRange();
autoCompleteSelector.style.top = r.offsetTop;
autoCompleteSelector.style.left = r.offsetLeft;
}
function taKeyUp(){
taSelectionStart = myTextarea.selectionStart;
preBehindMyTextarea.innerHTML = myTextarea.value.substr(0,taSelectionStart)+'<span id="cursorPos">';
cp = document.getElementById('cursorPos');
leftTop = findPos(cp);
autoCompleteSelector.style.top = leftTop[1];
autoCompleteSelector.style.left = leftTop[0];
}
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}
return [curleft,curtop];
}
//myTextarea.selectionStart
</script>
</html>
#4
0
function getCursor(nBox){
var cursorPos = 0;
if (document.selection){
nBox.focus();
var tmpRange = document.selection.createRange();
tmpRange.moveStart('character',-nBox.value.length);
cursorPos = tmpRange.text.length;
}
else{
if (nBox.selectionStart || nBox.selectionStart == '0'){
cursorPos = nBox.selectionStart;
}
}
return cursorPos;
}
function detectLine(nBox,lines){
var cursorPos = getCursor(nBox);
var z = 0; //Sum of characters in lines
var lineNumber = 1;
for (var i=1; i<=lines.length; i++){
z = sumLines(i)+i; // +i because cursorPos is taking in account endcharacters of each line.
if (z >= cursorPos){
lineNumber = i;
break;
}
}
return lineNumber;
function sumLines(arrayLevel){
sumLine = 0;
for (var k=0; k<arrayLevel; k++){
sumLine += lines[k].length;
}
return sumLine;
}
}
function detectWord(lineString, area, currentLine, linijeKoda){
function sumWords(arrayLevel){
var sumLine = 0;
for (var k=0; k<arrayLevel; k++){
sumLine += words[k].length;
}
return sumLine;
}
var cursorPos = getCursor(area);
var sumOfPrevChars =0;
for (var i=1; i<currentLine; i++){
sumOfPrevChars += linijeKoda[i].length;
}
var cursorLinePos = cursorPos - sumOfPrevChars;
var words = lineString.split(" ");
var word;
var y = 0;
for(var i=1; i<=words.length; i++){
y = sumWords(i) + i;
if(y >= cursorLinePos){
word = i;
break;
}
}
return word;
}
var area = document.getElementById("area");
var linijeKoda = area.value.split("\n");
var currentLine = detectLine(area,linijeKoda);
var lineString = linijeKoda[currentLine-1];
var activeWord = detectWord(lineString, area, currentLine, linijeKoda);
var words = lineString.split(" ");
if(words.length > 1){
var possibleString = words[activeWord-1];
}
else{
var possibleString = words[0];
}
That would do it ... :)
那会这么做...... :)
#1
4
You can get the caret using document.selection.createRange(), and then examining it to reveal all the information you need (such as position). See those examples for more details.
您可以使用document.selection.createRange()获取插入符号,然后检查它以显示您需要的所有信息(例如位置)。有关详细信息,请参阅这些示例
#2
1
Implementing an autocomplete in a text area is not that easy. I implemented a jquery plugin that does that, and i had to create a clone of the texarea to guess where the cursor is positioned inside the textarea. Its working, but its not perfect.
在文本区域中实现自动完成并不容易。我实现了一个jquery插件来实现这一点,我必须创建texarea的克隆来猜测光标在textarea中的位置。它的工作,但它并不完美。
You can check it out here: http://www.amirharel.com/2011/03/07/implementing-autocomplete-jquery-plugin-for-textarea/
你可以在这里查看:http://www.amirharel.com/2011/03/07/implementing-autocomplete-jquery-plugin-for-textarea/
I hope it helps.
我希望它有所帮助。
#3
0
an ugly solution:
丑陋的解决方案:
for ie: use document.selection...
for ie:使用document.selection ...
for ff: use a pre behind textarea, paste text before cursor into it, put a marker html element after it (cursorPos), and get the cursor position via that marker element
for ff:使用前置textarea,将光标前的文本粘贴到其中,在其后放置一个标记html元素(cursorPos),并通过该标记元素获取光标位置
Notes: | code is ugly, sorry for that | pre and textarea font must be the same | opacity is utilized for visualization | there is no autocomplete, just a cursor following div here (as you type inside textarea) (modify it based on your need)
备注:|代码很难看,对不起pre和textarea字体必须相同|不透明度用于可视化|没有自动完成功能,只有一个光标跟在div后面(当你在textarea里面输入时)(根据你的需要修改它)
<html>
<style>
pre.studentCodeColor{
position:absolute;
margin:0;
padding:0;
border:1px solid blue;
z-index:2;
}
textarea.studentCode{
position:relative;
margin:0;
padding:0;
border:1px solid silver;
z-index:3;
overflow:visible;
opacity:0.5;
filter:alpha(opacity=50);
}
</style>
hello world<br/>
how are you<br/>
<pre class="studentCodeColor" id="preBehindMyTextarea">
</pre>
<textarea id="myTextarea" class="studentCode" cols="100" rows="30" onkeyup="document.selection?ieTaKeyUp():taKeyUp();">
</textarea>
<div
style="width:100px;height:60px;position:absolute;border:1px solid red;background-color:yellow"
id="autoCompleteSelector">
autocomplete contents
</div>
<script>
var myTextarea = document.getElementById('myTextarea');
var preBehindMyTextarea = document.getElementById('preBehindMyTextarea');
var autoCompleteSelector = document.getElementById('autoCompleteSelector');
function ieTaKeyUp(){
var r = document.selection.createRange();
autoCompleteSelector.style.top = r.offsetTop;
autoCompleteSelector.style.left = r.offsetLeft;
}
function taKeyUp(){
taSelectionStart = myTextarea.selectionStart;
preBehindMyTextarea.innerHTML = myTextarea.value.substr(0,taSelectionStart)+'<span id="cursorPos">';
cp = document.getElementById('cursorPos');
leftTop = findPos(cp);
autoCompleteSelector.style.top = leftTop[1];
autoCompleteSelector.style.left = leftTop[0];
}
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}
return [curleft,curtop];
}
//myTextarea.selectionStart
</script>
</html>
#4
0
function getCursor(nBox){
var cursorPos = 0;
if (document.selection){
nBox.focus();
var tmpRange = document.selection.createRange();
tmpRange.moveStart('character',-nBox.value.length);
cursorPos = tmpRange.text.length;
}
else{
if (nBox.selectionStart || nBox.selectionStart == '0'){
cursorPos = nBox.selectionStart;
}
}
return cursorPos;
}
function detectLine(nBox,lines){
var cursorPos = getCursor(nBox);
var z = 0; //Sum of characters in lines
var lineNumber = 1;
for (var i=1; i<=lines.length; i++){
z = sumLines(i)+i; // +i because cursorPos is taking in account endcharacters of each line.
if (z >= cursorPos){
lineNumber = i;
break;
}
}
return lineNumber;
function sumLines(arrayLevel){
sumLine = 0;
for (var k=0; k<arrayLevel; k++){
sumLine += lines[k].length;
}
return sumLine;
}
}
function detectWord(lineString, area, currentLine, linijeKoda){
function sumWords(arrayLevel){
var sumLine = 0;
for (var k=0; k<arrayLevel; k++){
sumLine += words[k].length;
}
return sumLine;
}
var cursorPos = getCursor(area);
var sumOfPrevChars =0;
for (var i=1; i<currentLine; i++){
sumOfPrevChars += linijeKoda[i].length;
}
var cursorLinePos = cursorPos - sumOfPrevChars;
var words = lineString.split(" ");
var word;
var y = 0;
for(var i=1; i<=words.length; i++){
y = sumWords(i) + i;
if(y >= cursorLinePos){
word = i;
break;
}
}
return word;
}
var area = document.getElementById("area");
var linijeKoda = area.value.split("\n");
var currentLine = detectLine(area,linijeKoda);
var lineString = linijeKoda[currentLine-1];
var activeWord = detectWord(lineString, area, currentLine, linijeKoda);
var words = lineString.split(" ");
if(words.length > 1){
var possibleString = words[activeWord-1];
}
else{
var possibleString = words[0];
}
That would do it ... :)
那会这么做...... :)