How can I make jQuery Autocomplete replaces only certain word - not full string?
I am using bassistance.de jQuery Autocomplete function.
Have text like "hello to you @john" I made, Autocomplete run only when character @ is in word. But when I click on the needed item, it replaces me full text. How can I do so - to replace only "@john"? Or maybe there is another Autocomplete plugin for jQuery, which has such ability?
$('#input_line').autocomplete('data.php', {
extraParams: {input: function() {
return GetTextareaWord("开发者_如何学Pythoninput_line");
}
}
});
As noted on the link you posted for the autocomplete plugin
This plugin is deprecated and not developed anymore. Its successor is part of jQuery UI.
I would recommend checking out jQueryUI autocomplete. With that plugin, you can bind a custom event handler to the select event (fired when an item in the list is selected):
$( ".selector" ).autocomplete({
select: function(event, ui) { ... }
});
Cancel the default event (which is replacing the entire value of the field), and use your own logic to update the field appropriately (in this case, it may be just inserting the value into the text field where the user's cursor is at that point in time).
Seems doable, especially if you've figured out how to only show the autocomplete menu when you want it.
I've been working on something very similar to autocomplete tags. I have some basic code working but I'm a bit ashamed to publish here because it is borderline crap. It needs a lot of cleaning and refactoring which I will get to within the next couple of days. Nevertheless it does what you need in a way similar to what @Andrew suggests.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>jQuery UI Example Page</title>
<link type="text/css" href="../css/smoothness/jquery-ui-1.8.7.custom.css" rel="stylesheet" />
<script type="text/javascript" src="../js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="../js/jquery-ui-1.8.7.custom.min.js"></script>
<script type="text/javascript">
$(function() {
var availableTags = [
"ActionScript", "AppleScript", "Asp", "BASIC", "C",
"C++", "Clojure", "COBOL", "ColdFusion", "Erlang",
"Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp",
"Perl", "PHP", "Python", "Ruby", "Scala", "Scheme"
];
function getCaretPosition(e) {
var p = -1;
if (document.selection) {
e.focus();
var s = document.selection.createRange();
s.moveStart('character', -e.value.length);
p = s.text.length;
} else if (e.selectionStart || e.selectionStart == '0') {
p = e.selectionStart;
}
return p;
}
function getPreviousCaretPosition(e) {
var s = e.value;
var i = getCaretPosition(e) - 1;
while (i >= 0 && s[i] != ' ') { i = i - 1; }
return i;
}
function getTerm(s, p) {
var i = p - 1;
while (i >= 0 && s[i] != ' ') { i = i - 1; }
return s.substring(i + 1, p);
}
$( "#tags" )
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 2,
source: function(request, response) {
var t = getTerm(this.element[0].value, getCaretPosition(this.element[0]));
if (t[0] != '#') {
return false;
}
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
availableTags, t.substring(1, t.length) ) );
return true;
},
focus: function() {
return false;
},
search: function(event, ui) {
return true;
},
select: function(event, ui) {
var current = getCaretPosition(this);
var previous = getPreviousCaretPosition(this);
this.value = this.value.substring(0, previous) +
' #' + ui.item.value + ' ' + this.value.substring(current);
return false;
}
});
});
</script>
</head>
<body>
<div id="container">
<div id="content">
<div id="main">
<div class="item">
<div class="title">
<h2>hash-tag-autocomplete</h2>
</div>
</div>
<div class="item">
<form class="simpleform">
<p><textarea id="tags" rows="5" style="width:100%"></textarea><p>
<p><input type="submit"/><p>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
I will get to this functionality within the next couple of days and will package it as jQuery plugin. I will try to publish a new version of this code as a new answer.
UPDATE
Tried to get something cleaner. You can use your preferred way of getting and setting carets instead of the functions I got.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>jQuery UI Example Page</title>
<link type="text/css" href="../css/smoothness/jquery-ui-1.8.7.custom.css" rel="stylesheet" />
<script type="text/javascript" src="../js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="../js/jquery-ui-1.8.7.custom.min.js"></script>
<script type="text/javascript">
$(function() {
var availableTags = [
"ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++",
"Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy",
"Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python",
"Ruby", "Scala", "Scheme"
];
function getCaretPosition(e) {
if (typeof e.selectionStart == 'number') {
return e.selectionStart;
} else if (document.selection) {
var range = document.selection.createRange();
var rangeLength = range.text.length;
range.moveStart('character', -e.value.length);
return range.text.length - rangeLength;
}
};
function setCaretPosition(e, start, end) {
if (e.createTextRange) {
var r = e.createTextRange();
r.moveStart('character', start);
r.moveEnd('character', (end || start));
r.select();
} else if (e.selectionStart) {
e.focus();
e.setSelectionRange(start, (end || start));
}
};
function getWordBeforeCaretPosition(e) {
var s = e.value;
var i = getCaretPosition(e) - 1;
while (i >= 0 && s[i] != ' ') {
i = i - 1;
}
return i + 1;
};
function getWordBeforeCaret(e) {
var p = getWordBeforeCaretPosition(e);
var c = getCaretPosition(e);
return e.value.substring(p, c);
};
function replaceWordBeforeCaret(e, word) {
var p = getWordBeforeCaretPosition(e);
var c = getCaretPosition(e);
e.value = e.value.substring(0, p) + word + e.value.substring(c);
setCaretPosition(e, p + word.length);
};
$( "#tags" )
.bind("keydown", function(event) {
if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function(request, response) {
var w = getWordBeforeCaret(this.element[0]);
if (w[0] != '#') {
this.close();
return false;
}
response($.ui.autocomplete.filter(availableTags, w.substring(1, w.length)));
return true;
},
focus: function() {
return false;
},
search: function(event, ui) {
return true;
},
select: function(event, ui) {
replaceWordBeforeCaret(this, '#' + ui.item.value + ' ');
return false;
}
});
});
</script>
</head>
<body>
<h2>hash-tag-autocomplete</h2>
<form>
<p><textarea id="tags" rows="5" style="width:100%"></textarea><p/
<p><input type="submit"/><p>
</form>
</body>
</html>
I would really appreciate any feedback on this.
精彩评论