appendTo custom element not updating with autocomplete - javascript

I have a search box and am using Jquery autocomplete to get the search results which I want to return to a custom element.
At the moment it appends every time the search changes which leads to duplicates.
I was wondering if there is an option which will delete the contents of the custom element when the search term changes.
var $searchFriends = $("#searchFriends");
$searchFriends.autocomplete({
source: "search/findFriends",
minLength: 3,
appendTo: "#searchResults",
select: function(event, ui) {
$('#searchFriends').val(ui.item.value);
return false;
}
})
.data("uiAutocomplete")._renderItem = function( ul, item){
return $("<li class='friendResult' id='"+item.id+"'>")
.append("<a>"+item.value+"</a>")
.appendTo('#searchResults')
};
I currently have a work around which is working fine (below) but there must be another way.
$searchFriends.on('change textInput input', function (){
$('#searchResults').empty();
});

You can use html() to replace the html in an element (instead of using append() to append it).
var $searchFriends = $("#searchFriends");
$searchFriends.autocomplete({
source: "search/findFriends",
minLength: 3,
appendTo: "#searchResults",
select: function(event, ui) {
$('#searchFriends').val(ui.item.value);
return false;
}
})
.data("uiAutocomplete")._renderItem = function( ul, item){
var content = $("<li class='friendResult' id='"+item.id+"'>").append("<a>"+item.value+"</a>");
$('#searchResults').html(content);
};

Related

Autocomplete: how to get automatically value on focus if no values selected

From the comment in this question, I've seen how to set an autocomplete field to empty if no element from the list has been selected.
What I am trying to implement is that when a user does not select any element from the autocomplete list and switches to the next field, one of the following should happen:
If there was at least on element displayed in the autocomplete list, take automatically the first element of that list. In the screenshot below, Mannheim should be automatically selected if the user goes to another field without selecting any element.
If no element was displayed, make the field empty again.
If tried the suggestions from here and here, but without success.
This is my code:
var cities = //function that provides a list of cities depending on the input string (edited to clarify)
$('.autocomplete-city').autocomplete({
source: function (request, response) {
response($.map(cities( request.term ), function (value, key) {
return {
label: value.label,
value: value.value
}
}));
},
// manage what happens if user does not click any option from autocomplete
change: function(event, ui){
if (ui.item == null){
if ( list_from_autocomplete == null ){ // I tried here several possibilities but none seem to work
$(this).val('');
$(this).focus();
} else {
$(this).val( first_item_in_list ); // Despite the existing questions, I could not make it work...
}
}
},
minLength: 2,
autoFocus: true,
});
How could this be done?
You could search all the cities that contains the user input and if you get only one result, put it in the autocomplete.
1) So, in the change event you could check if user selected an item:
change: function(event, ui){
if(ui.item){
//user select an item
}
else{
//here let's try to set the autocomplete
}
2) Search the cities that contains the user's input:
var result = cities.filter(function( obj ) {
return obj.label.indexOf(searched);
});
3) Finally, if you get just one result, set the autocomplete with that value:
if(result.length==1){
$(this).val(result[0].label);
}
Please see following snippet:
var cities = [
{"label":"Alessandria","id":"AL"},
{"label":"Milano","id":"MI"},
{"label":"Pisa","id":"PI"},
{"label":"Pistoia","id":"PT"}
];
$(".autocomplete-city").autocomplete({
source: cities,
select: function(event, ui){
if(ui.item){
console.log('select', ui.item.label);
return ui.item.label;
}
else{
console.log('select with null value');
}
},
change: function(event, ui){
var searched = this.value;
console.log("Searched: " + searched);
if(ui.item){
console.log('change', ui.item.id);
}
else{
console.log('change with null value');
var result = cities.filter(function( obj ) {
return obj.label.toLowerCase().indexOf(searched.toLowerCase()) !== -1;
});
if(result.length>0){
$(this).val(result[0].label);
}
else{
//clear the autocomplete
$(this).val("");
}
}
}
});
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<input class="autocomplete-city"/>
In the above example there are following cities: Alessandria, Milano, Pisa, Pistoia.
If you digit in textbox "Mil" or "Ale" and just press the tab, the autocomplete will be filled with the single result starting with "Mil" or "Ale".
Instead, when you digit "Pis" the autocomplete will be cleared.
I hope it was clear, bye.
Updated:
In order to get the first result when user leaves the autocomplete without selecting any city, you could check result.length>0 and set the first value from result in to the autocomplete:
var result = cities.filter(function( obj ) {
return obj.label.toLowerCase().indexOf(searched.toLowerCase()) !== -1;
});
if(result.length>0){
$(this).val(result[0].label);
}
else{
//clear the autocomplete
$(this).val("");
}

Auto select the top autocomplete result into hidden input

I'm trying to do a search by id, but the autocomplete by name.
So I put an hidden input, that is updated on select.
The problem is that if the user presses Esc or some how initiates a search without selecting, the search fails (doesn't return the desired value), because the hidden value isn't updated. I'm trying to force the autocomplete to choose the top result as long as no other result is selected.
My code is:
$('#search_box').focus(function () {
$(hidden).val("");
});
$('#search_box').autocomplete({
source: "autocomplete_empl.asp",
minLength: 2,
autoFocus: true,
select: function (event, ui) {
$('#hidden').val((ui.item ? ui.item.id : 0));
}
});
Thanks!
P.S
The returned list comes in json form.
I would check if autocomplete val() is empty.
If it is empty do nothing( or you need to select the first value?)
$('#search_box').focus(function () {
$(hidden).val("");
});
$('#search_box').autocomplete({
source: "autocomplete_empl.asp",
minLength: 2,
autoFocus: true,
select: function (event, ui) {
if($('#search_box').val() !== ""){
$('#hidden').val((ui.item ? ui.item.id : 0));
}
}
});
If you need to select the first option just trigger the search event with the data you need
select: function (event, ui) {
if($('#search_box').val() !== ""){
$('#hidden').val((ui.item ? ui.item.id : 0));
}
else{
$('#search_box').autocomplete('search', 'DataYouNeed');
}
}
Here is the link on the API page, which explains it a bit
http://api.jqueryui.com/autocomplete/#method-search

Use Methods from Dropped Object in JQuery

I would like to use a method of an dragged and dropped Object.
function Controller(){
$( "#container" ).droppable({
drop: function( event, ui ) {
var draggable = ui.draggable;
alert( "Dropped:" + draggable.attr('id'));
draggable.myMethod();
}
});
Could you explain why this doesnt work?
The alert shows that the right Object ist dropped,
but i cant use the method.
The Object looks like this:
function Icon(name) {
var name = name;
this.myMethod = function() {
alert("test")};
this.getInfo = function() {
var dataname = this.getName();
//BErtram
$("#" + dataname).draggable({ revert: "valid" });
//Bertram Ende
}
}
Edit:
If I invoke the Method this way:
drop: function( event, ui ) {
var draggable = ui.draggable;
alert(...);
var ic = new Icon("asdsa");
ic.myMethod();
},
it works, but I want to use the Method on the dragged Object, do I have to do some sort of typecasting?
Edit: Workaround
Finally i used a workaround, using a bool to check if there was a succesfull drop and invoking the method in draggable.stop if the boolean ist true. The state of the boolean is set to true in the droppable on a succesfull drop and set to false in draggable.start.
The problem is that myMethod is a function on the Icon object you create, however the ui.draggable is not an instance of Icon - so it has no myMethod method.
The ui.draggable value is a DOM element contained inside a jQuery object. You need a mechanism to map from the element back to the Icon that's responsible for it.
The simplest method is to use .data():
function Icon(name) {
$('#' + name).data('self', this);
...
}
and then retrieve that object in the event handler:
drop: function(event, ui) {
var draggable = ui.draggable;
var icon = draggable.data('self');
icon.myMethod();
}

JQuery autocomplete Search method

I am using JQuery UI autocomplete on my website. I am creating the auto complete object like so:
$.widget( "custom.code_complete", $.ui.autocomplete, {
_renderMenu: function( ul, items ) {
var self = this,
currentCategory = "";
$ul = ul;
$.each( items, function( index, item ) {
if ( item.category != currentCategory ) {
ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
currentCategory = item.category;
}
self._renderItem( ul, item );
});
}
});
$("#r-code").code_complete({
source: "URL",
minLength: 2,
select: function(event, ui) {
$(".button-row").fadeIn();
get_details(ui.item.url);
}
});
This setups the autocomplete field fine. I can search inside the field fine and it brings back results without a problem. Sometimes however the users will be redirected from another page with the autocomplete value set as a parameter and if this is the case the autocomplete will be triggered programmatically, I am trying to do this with the following code:
function parse_param_code(code) {
console.log(code);
$("#r-code").autocomplete('search', code);
}
This method is called successfully and the code is put out to the console but the autocomplete search is not triggered and does not do anything. Am I doing something wrong in my code for this not to trigger a search? I have read the JQuery UI documentation and the above code is supposed to trigger the search method. Any help would be appreciated.
Thanks
Eef
Changing the
$("#r-code").autocomplete('search', code);
to your own widget name, i.e:
$("#r-code").code_complete('search', code);
produces the desired result.
example: http://jsfiddle.net/vHJsu/
If you do a console.log($("#r-code").data("autocomplete")); you'll notice there isn't a widget with that name attached to the element.

Force a user to select from JQuery UI Autocomplete and populate a hidden field after selecting

I have a large HTML form that contains many fields that need an autocomplete for accounts. I tag these fields with the class AccountLookup and jQuery does the dirty work for the autocomplete:
$(".AccountLookup").autocomplete({
source: function (request, response) {
$.ajax({
url: "Lookup.asmx/GetAccounts",
data: "{ 'Search': '" + request.term + "' }",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
response($.map(data.d, function (item) {
return {
value: item.Value
}
}))
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
minLength: 3
});
Now, when a user selects something from the autocomplete I need it to populate a hidden field just BEFORE the tagged input field; probably using something like:
$(this).prev().val(item.Key);
How do I incorporate this functionality? Also, how do I force a user to select from the auto complete? (All the values are pre-defined, the user cannot add new ones.)
EDIT:
As far as I understand from inspecting the DOM, the select option is currently filling in the hidden form field.
select: function (event, ui) {
$(this).prev().val(ui.item.key);
}
I know this is an old post--- but I ran into it in trying to solve a similar problem (forcing the user to select an item from the list)...
$("#ac").autocomplete({
source: function (req, resp) {
//add code here...
},
select: function (e, ui) {
$(this).next().val(ui.item.id);
},
change: function (ev, ui) {
if (!ui.item)
$(this).val("");
}
});
$(".AccountLookup").autocomplete({
/*...*/
}).result(function(event, item) {
$(this).prev().val(item.Key);
});
You could also use a jQuery validate to ensure that the field is populated.
for force selection, you can use "change" event of Autocomplete
var availableTags = [
"ActionScript",
"AppleScript"
];
$("#tags").autocomplete({
source: availableTags,
change: function (event, ui) {
if(!ui.item){
//http://api.jqueryui.com/autocomplete/#event-change -
// The item selected from the menu, if any. Otherwise the property is null
//so clear the item for force selection
$("#tags").val("");
}
}
});
For the selection action, try using the formatItem option. You can format each result to have an onclick event that will populate the other textbox.
For the forcing to select from autocomplete, you need to use the mustMatch option.
http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions
I ran into this same problem quite awhile ago and some post helped me along with it. I have since modified the code as I found that there were cases I wanted one or more fields to fill in from the information returned. In the select option of the autocomplete I added a function.
select: function (e, ui) {ReSetField({'txtID':'id','txtPrice':'price' [,etc...]}, ui) }
The function "ResetFields" then takes in a JSON list of element names paired with fieldnames and uses the fieldnames to match the elements in the ui object. The value can then be pulled from the ui item and put into the html element.
function ReSetField(_flds, _vals) {
//Set up the flds to be reset with values passed in.
try {
if (_flds != undefined) {
if ($.type(_flds) == 'string') {
_flds = JSON.parse(_flds);
};
var _fld = null;
var _val = '';
$.each(_flds, function (index) {
if (index.length > 0) {
_fld = '#' + index; //Set the forms field name to set
_val = _flds[index]; //Pick up the field name to set the fields value
$fld = $(_fld);
$fld.val(_vals.item[_val]); //Set the fields value to the returned value
}
}
})
};
}
catch (e) {
alert('Cannot set field ' + _fld + '.');
}
}
By sticking the "fieldlist" into the HTML element as an attribute like "fieldlist" and using a class like "comboBox" I can then use a single function to find all ComboBox elements and set up the autocomplete on a form reducing the amount of code required to handle 2 or more lookups on a form.

Categories