I try to make an autocomplete input, as I did sometimes in the past.
But today I have to face a issue i can't really understand.
$( "#search_collab_autocomplete" ).autocomplete({
appendTo :$('.form-add-new-user'),
source : function(requete, response){
$.ajax({
url : $('.form-add-new-user').data('url'),
dataType : 'json',
data : {
email : $('#search_collab_autocomplete').val(),
},
success : function(data){
var arr = [];
var i = 0;
var fullObj = data;
$.each(data, function(index, value){
var obj = {
id: index,
email: value,
};
arr[i] = obj;
i++;
});
response(arr, fullObj);
},
select: function( event, ui ) {
console.log("hi");
}
});
},
minLength: 3
}).data( "ui-autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" ).data("item.autocomplete", item)
.append( "<a>"+item.email + "</a>")
.appendTo( ul );
};
I have this code, which is partially workink because i can see list of result juste below my input field.
But when I click on / when I choose a item with keyboard I can't see nothing happening.. not even a simple console.log('hi');....
Am I using wrong select ?
Your "select" is attached to $.ajax. It must be on the same level as "source" and "minLength".
Related
I have a form with duplicate fields including autocomplete input.
The issue is : when i duplicate the fields, the autocomplete doesn't work on the new fields.
I spent time googling my issue and often it's a clone('true') issue, which i don't use already and still have the problem.
Can you help me please ? Thanks a lot !
I made a JSFiddle : https://jsfiddle.net/vqnaedvx/
Try with the letter j or s
HTML :
<div id="projects" class="content">
<button type="button" id="btnAdd" class="btn btn-primary btn-sm">Add Project</button>
<div class="row form-group group">
<input class="project-label">
<input type="hidden" class="project-id">
<button type="button" class="btn btn-danger btnRemove">Remove</button>
</div>
</div>
JS Multifield :
/**
* jQuery Multifield plugin
*
* https://github.com/maxkostinevich/jquery-multifield
*/
;(function ( $, window, document, undefined ) {
// our plugin constructor
var multiField = function( elem, options ){
this.elem = elem;
this.$elem = $(elem);
this.options = options;
// Localization
this.localize_i18n={
"multiField": {
"messages": {
"removeConfirmation": "Are you sure you want to remove this section?"
}
}
};
this.metadata = this.$elem.data( 'mfield-options' );
};
// the plugin prototype
multiField.prototype = {
defaults: {
max: 0,
locale: 'default'
},
init: function() {
var $this = this; //Plugin object
// Introduce defaults that can be extended either
// globally or using an object literal.
this.config = $.extend({}, this.defaults, this.options,
this.metadata);
// Load localization object
if(this.config.locale !== 'default'){
$this.localize_i18n = this.config.locale;
}
// Hide 'Remove' buttons if only one section exists
if(this.getSectionsCount()<2) {
$(this.config.btnRemove, this.$elem).hide();
}
// Add section
this.$elem.on('click',this.config.btnAdd,function(e){
e.preventDefault();
$this.cloneSection();
});
// Remove section
this.$elem.on('click',this.config.btnRemove,function(e){
e.preventDefault();
var currentSection=$(e.target.closest($this.config.section));
$this.removeSection(currentSection);
});
return this;
},
/*
* Add new section
*/
cloneSection : function() {
// Allow to add only allowed max count of sections
if((this.config.max!==0)&&(this.getSectionsCount()+1)>this.config.max){
return false;
}
// Clone last section
var newChild = $(this.config.section, this.$elem).last().clone().attr('style', '').attr('id', '').fadeIn('fast');
// Clear input values
$('input[type=text],input[type=hidden],textarea', newChild).each(function () {
$(this).val('');
});
// Fix radio buttons: update name [i] to [i+1]
newChild.find('input[type="radio"]').each(function(){var name=$(this).attr('name');$(this).attr('name',name.replace(/([0-9]+)/g,1*(name.match(/([0-9]+)/g))+1));});
// Reset radio button selection
$('input[type=radio]',newChild).attr('checked', false);
// Clear images src with reset-image-src class
$('img.reset-image-src', newChild).each(function () {
$(this).attr('src', '');
});
// Append new section
this.$elem.append(newChild);
// Show 'remove' button
$(this.config.btnRemove, this.$elem).show();
},
/*
* Remove existing section
*/
removeSection : function(section){
if (confirm(this.localize_i18n.multiField.messages.removeConfirmation)){
var sectionsCount = this.getSectionsCount();
if(sectionsCount<=2){
$(this.config.btnRemove,this.$elem).hide();
}
section.slideUp('fast', function () {$(this).detach();});
}
},
/*
* Get sections count
*/
getSectionsCount: function(){
return this.$elem.children(this.config.section).length;
}
};
multiField.defaults = multiField.prototype.defaults;
$.fn.multifield = function(options) {
return this.each(function() {
new multiField(this, options).init();
});
};
})( jQuery, window, document );
$('#projects').multifield({
section: '.group',
btnAdd:'#btnAdd',
btnRemove:'.btnRemove'
});
JS Autocomplete :
$( function() {
var projects = [
{
value: "jquery",
label: "jQuery"
},
{
value: "jquery-ui",
label: "jQuery UI"
},
{
value: "sizzlejs",
label: "Sizzle JS"
}
];
$( ".project-label" ).autocomplete({
minLength: 0,
source: projects,
focus: function( event, ui ) {
$( ".project-label" ).val( ui.item.label );
return false;
},
select: function( event, ui ) {
$( ".project-label" ).val( ui.item.label );
$( ".project-id" ).val( ui.item.value );
return false;
}
})
.autocomplete( "instance" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( "<div>" + item.label + "</div>" )
.appendTo( ul );
};
} );
you have 2 probs here:
1.Your code only for one input textfield. if u add more textfields, all value of textfields will have the same value. u need call autocomplete in foreach
2.After u press add input jquery not call autocomplete again(new input doesn't have autocomplete). So you need call it after new input added.
fixed here:
declare global function:
/**
* jQuery Autocomplete
*/
$( function() {
var projects = [
{
value: "jquery",
label: "jQuery"
},
{
value: "jquery-ui",
label: "jQuery UI"
},
{
value: "sizzlejs",
label: "Sizzle JS"
}
];
refreshAuto = function(){
$(".project-label").each(function(idx,ele){
var item = $(ele);
item.autocomplete({
minLength: 0,
source: projects,
focus: function( event, ui ) {
item.val( ui.item.label );
return false;
},
select: function( event, ui ) {
item.val( ui.item.label );
item.attr('id',ui.item.value);
return false;
}
})
.autocomplete( "instance" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( "<div>" + item.label + "</div>" )
.appendTo( ul );
};
});
}
refreshAuto(); // call to init once
} );
at "jQuery Multifield plugin" find '// Add section' add the line so:
// Add section
this.$elem.on('click',this.config.btnAdd,function(e){
e.preventDefault();
$this.cloneSection();
refreshAuto(); //call autocomplete new input
});
hope this help !
I am working on jquery autocomplete custom data and display.I want to display some static dropdown on keypress in textbox.when user select that list item i want to add it to textbox.
the code which i have tested is
$('#uinput').keyup(function() {
var val = $('#uinput').val();
if(val.length>1) { // check length
// handle successful DWR response
//alert(data);
var b=[{value: "jquery-ui",
label: "jQuery UI",}];
$('#uinput').autocomplete({source:b,
select: function( event, ui ) {
$( "#uinput" ).val( ui.item.label+"="+document.getElementById('uinput').value );
return false;
}
}).data("autocomplete")._renderItem = function( ul, item ) {
return $( "<li>" )
.data('item.autocomplete', item)
.append( "<a>" + item.label + "=" + document.getElementById('uinput').value + "</a>" )
.appendTo( ul );
};
} else {
$('#uinput').autocomplete([]); // clean
}
});
For reference what i want to do
custom autocomplete
I'm not exactly sure what you're trying to accomplish but I think I've put together this example that I think might help you
https://jsfiddle.net/mgxnxhs8/5/
here's my javascript
$(function () {
var availableTags = [{
label: "jQuery 1.9.1",
value: "http://code.jquery.com/jquery-1.9.1.js",
}, {
label: "jQuery 2.1.4",
value: "http://code.jquery.com/jquery-2.1.4.js",
}];
$('#uinput').autocomplete({
source: availableTags,
minLength: 0,
select: function (event, ui) {
$('#uoutput').val(ui.item.value);
return false;
}
}).focus(function () {
$(this).autocomplete("search");
});
});
The dropdown opens up when you enter the textbox and displays the "label" key of the tags. On Select(), it sets the value of another textbox to the "value" key of the selected tag.
Let me know if theres something I missed. Hope this helps
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;
}
});
});
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/
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;
}
});
});