autocomplete with multiple values and automatic replace - javascript

I'm using autocomplete with multiple remote values.
Every search gives me only one word (words in input text are separated by space)
I removed return false; from focus function and now when I focus on autocomplete results it automaticly change the input text and when i return focus to input text it show the original text i wrote.
This is behaviour that i want, but the problem is when I search second word.
Then when the autocomplete search i focused it overwrites the first word in input text.
I want the first word stay the same and only second (3, 4 ..) word changes. And when I return to input text I get the original text I wrote before I focus the search result.
My code:
$(function() {
function split( val ) {
return val.split( / \s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
source: function( request, response ) {
$.getJSON( "http://test.dev/search.php", {
term: extractLast( request.term ),
complete: request.term,
}, response );
},
search: function() {
// custom minLength
var term = extractLast( this.value );
if ( term.length < 2 ) {
return false;
}
},
focus: function(event, ui) {
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( " " );
return false;
}
});
});

Related

Need to do multiple search at a time with starting character which is search in autocomplete

I am use https://jqueryui.com/autocomplete/#multiple for autocomplete functionality in my site. Its work fine, Now I want to search record with first character that added to text box only.
Here is my code:
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css"><input type="text" id="multi"><script>$(document).ready(function() {var avail = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
];
$("#single").autocomplete({
source:avail
});
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#multi" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
avail, extractLast( request.term ) ) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});});</script>
As per comments:
To make the typeahead.js multipel search demo searching "starting from first character", change matching code line from this:
~item.toLowerCase().indexOf(tquery.toLowerCase())
to this:
item.toLowerCase().indexOf(tquery.toLowerCase()) == 0
Demo fiddle: http://jsfiddle.net/BwDmM/1100/
Additional note: more explanation about how the original matching code works (tilda bitwise operator) can be found here: http://www.joezimjs.com/javascript/great-mystery-of-the-tilde/

Lazy initialization of jquery UI autocomplete

I'd like to lazy initialize the source options of a jQueryUI autocomplete. I'm aware of the possibility to pass a function to the source option, but I want to delay the initialization until the user really starts using the autocomplete.
I tried waiting for the search event and then set the source option, but this has no effect.
var availableTags = [
"ActionScript",
"AppleScript",
"Scheme"
];
$("#searchFirstTransactionStateInfo_searchPartnerId").autocomplete({
source : [],
minLength: 0,
search: function( event, ui ) {
$(event.target).source = availableTags;
}
});
How can I delay setting the source option until the user starts using the UI element?
Note: I used a fixed array for simplicity. Finally I want to call an AJAX function.
Well, if you use a function as the source parameter, and let that function perform a get request (ajax ofcourse), it will actually only start making requests when you've typed something. As an example, open up your network tab and start typing in this UI example:
http://jqueryui.com/autocomplete/#multiple-remote
$(function() {
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#birds" )
.autocomplete({
source: function( request, response ) {
$.getJSON( "search.php", {
term: extractLast( request.term )
}, response );
},
search: function() {
// custom minLength
var term = extractLast( this.value );
if ( term.length < 2 ) {
return false;
}
},
focus: function() {
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
});

jquery autocomplete special char trigger

i have the following problem:
i must make a special autocomplete with jquery triggered by char "#"
the problem is that if i begin the textbox with # it works but if i enter # after i write some chars it doesn't work.
how it must work:
-i write some text an i want to add someone from "utilizatoriJson",
-to add someone from "utilizatoriJson" i must press the # key and an autocomplete dropdown must apear,
-after i select someone from dropdown or i type a full label from dropdown it must put space and let me continue my message
how can i do this ?
code that i wrote :
var utilizatoriJson = <%=utilizatoriJson%>;
$( '#textarea_mesaj_colaborare').autocomplete({
source: utilizatoriJson
}) .autocomplete( "instance" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
}
$( '#textarea_mesaj_colaborare').autocomplete("disable");
$('#textarea_mesaj_colaborare').keyup(function(){
if ($('#textarea_mesaj_colaborare').val()[$('#textarea_mesaj_colaborare').val().length-1]==='#'){
var inceput = $('#textarea_mesaj_colaborare').val().length;
$( '#textarea_mesaj_colaborare').autocomplete("enable");
}
});
As already mentioned, you would require multiple words approach here.
The link to original source has already been provided above. So, I would like show what I understood from your doubt.
But first let me know if you want to have autocompletion like after '#' all label that start with 'a' should give results that only start with 'a' and not those which contain 'a'.
Since I suppose this would be of much better use, I have code for that part.
Working Demo: http://jsfiddle.net/AJmJt/2/
$(function() {
//Since you told that labels start with '#'
var utilizatoriJson = [
{'label': "#ActionScript",'id':'1'},
{'label': "#Java",'id':'2'},
{'label': "#C++",'id':'3'},
{'label': "#Javascript",'id':'4'},
{'label': "#Python",'id':'5'},
{'label': "#BASIC",'id':'6'},
{'label': "#ColdFusion",'id':'7'},
{'label': "#Haskell",'id':'8'},
{'label': "#Lisp",'id':'9'},
{'label': "#Scala",'id':'10'}
];
function split( val ) {
return val.split( / \s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 1,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
var lastword = extractLast(request.term);
// Regexp for filtering those labels that start with '#'
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( lastword ), "i" );
// Get all labels
var labels = utilizatoriJson.map( function( item ) { return item.label; });
var results = $.grep( labels, function( item ) {
return matcher.test( item );
});
response( $.ui.autocomplete.filter( results, lastword ) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( " " );
return false;
}
});
});
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags" size="50">
</div>
If you don't want something like I said, then there is no need for RegExp matching, but there you need to see if word starts with '#' or not.
Code for this behavior working: http://jsfiddle.net/rPfY8/1/
$(function() {
var utilizatoriJson = [
{'label': "#ActionScript",'id':'1'},
{'label': "#Java",'id':'2'},
{'label': "#C++",'id':'3'},
{'label': "#Javascript",'id':'4'},
{'label': "#Python",'id':'5'},
{'label': "#BASIC",'id':'6'},
{'label': "#ColdFusion",'id':'7'},
{'label': "#Haskell",'id':'8'},
{'label': "#Lisp",'id':'9'},
{'label': "#Scala",'id':'10'}
];
function split( val ) {
return val.split( / \s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 1,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
var lastword = extractLast(request.term);
if(lastword[0] != '#')
return false;
// Get all labels
var labels = utilizatoriJson.map(function(item){return item.label;});
response( $.ui.autocomplete.filter(
labels, lastword ) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( " " );
return false;
}
});
});
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags" size="50">
</div>
You don't want to disable/re-enable the autocomplete as that prevents the control from doing anything. You can do this the way you propose, but there's another approach. Take a look at the example here: http://jqueryui.com/autocomplete/#multiple
This should do what you're looking for, you can update the filter to only do a "starts with" search
Here's a JSFIDDLE example of what I mean: http://jsfiddle.net/UhL5d/
And the corresponding Javascript:
$(function () {
var availableTags = [
{value: 1, label: "#ActionScript" },
{value: 2, label: "#AppleScript" },
{value: 3, label: "#Asp" },
{value: 4, label: "#BASIC" },
{value: 5, label: "#C" } ];
function split(val) {
return val.split(/\s/);
}
function extractLast(term) {
return split(term).pop();
}
$("#textarea_mesaj_colaborare").autocomplete({
source: function (request, response) {
// delegate back to autocomplete, but extract the last term
response($.ui.autocomplete.filter(
availableTags, extractLast(request.term)));
},
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.label);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join(" ");
return false;
}
});
});

JqueryUI autocomplete returns wrong item on focus

I used JqueryUI on this project im working on.
When I focus on the next item in the list with the down arrow key, jqueryui returns the previous selected item
Here's a perfect working sample is here on jsFiddle
Here's the Jquery code
$( "#itemname" ).autocomplete({
source: function( request, response ) {
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( request.term ), "i" );
response( $.grep( tags, function( item ){
return matcher.test( item );
}) );
},
//focus: function(event) { alert( event.type ); }
focus : function(event, ui) {
//alert( $(this).val() );
var item_name_this = $(this).val();
$('#properties_item_name').html(item_name_this);
}
});
focus: function (event, ui) {
var item_name_this = ui.item.value;
$('#properties_item_name').html(item_name_this);
}
Demo --> http://jsfiddle.net/VCd4J/16/

Javascript Autocomplete email's domain using jQuery UI

I need help, I am stuck with trying to make the following case scenario work:
You have email input field, you type: foo#y - it should pop up autocomplete box, offering yahoo.com (for example).
If you take this suggestion, the end value should become: foo#yahoo.com
I have wrote this code (modified off another jquery UI sample):
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 3,
source: function( request, response ) {
var mail_regex = /^([\w.]+)#([\w.]+)$/;
var match = mail_regex.exec(request.term);
if (match)
var matcher = new RegExp( "^" + match[2], "i" );
response( $.grep( availableTags, function( item ){
return matcher.test( item );
}) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
Full working interactive sample:
http://jsfiddle.net/rRF2s/3/
However, it REPLACES the foo# with just yahoo.com - I can not for the life of me figure out how to override this behaviour...
Any Javascript/jQuery masters - help please! how to accomplish this goal?
I tried doing: return match[1]+matcher.test( item ), but that does not work.
The select function is assigning the resultant value with this.value =. However it is replacing the input value completely rather than appending it with the drop down value.
Without a great deal of testing the following, simplified function seems to work as required:
select: function( event, ui ) {
this.value = this.value.substring(0, this.value.indexOf('#') + 1) + ui.item.value;
return false;
}
This is taking the first part of the already entered value, for example foo# for the input foo#ya and then adding on the value of the selected item from the drop down.
You may want to trigger the dropdown when someone enters the # symbol (seems more intuitive to me) and if so, this function may also need modifying to correctly extract the user entered value.
Here is the complete code:
$(function() {
var availableTags = [
"Yahoo.com",
"Gmail.com"
];
function extractLast( val ) {
if (val.indexOf("#")!=-1){
var tmp=val.split("#");
console.log(tmp[tmp.length-1]);
return tmp[tmp.length-1];
}
console.log("returning empty");
return "";
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 1,
source: function( request, response ) {
var mail = extractLast(request.term);
if(mail.length<1){return;}
var matcher = new RegExp( "^" + mail, "i" );
response( $.grep( availableTags, function( item ){
return matcher.test( item );
}));
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = this.value.split(", ");
// remove the current input
var ml=terms[terms.length-1].split("#")[0];
terms.pop();
// add the selected item
terms.push( ml+"#"+ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
});

Categories