jQuery UI Autocomplete - Search based on a json node - javascript

I'm trying to search based on a school name, once the school name is selected populate a form.
I'm having a few issues searching on that particular jSON node, which in this case is name I have got the JSON response working, But it's just returning everything back. Not the specific term.
An example of my jSON Data :
[
{
"name":"The Mendip School",
"ta":"ta552023",
"address1":"Longfellow Road",
"address2":"Radstock",
"town":"",
"postcode":"BA3 3AL"
}
]
My jQuery is as follows :
// School Search....
var data_source = 'schools.json';
$(".school_name").autocomplete({
source: function ( request, response ) {
$.ajax({
url: data_source,
dataType: "json",
data: {
term: request.term
},
success: function (data) {
response( $.map( data, function ( item )
{
return {
label: item.name,
value: item.name
};
}));
}
});
},
minLength: 3,
focus: function (event, ui) {
$(event.target).val(ui.item.label);
return false;
},
select: function (event, ui) {
$(event.target).val(ui.item.label);
window.location = ui.item.value;
return false;
}
});
How do I modify my JQuery to search on the name field? I will also need to get the other fields to populate input fields.
Thanks

Here is something that may suit your needs:
$("#school_name").autocomplete({
source: function ( request, response ) {
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( request.term ), "i" );
$.getJSON("/schools.json?term=" + request.term, function (data) {
var x = $.grep(data, function (item, index) {
return matcher.test( item.name );
});
console.log(x);
response($.map(x, function (item) {
return {
label: item.name,
value: item.name
};
}));
});
}
The code above will filter the data using the regex(new RegExp( "^" + $.ui.autocomplete.escapeRegex( request.term ), "i" )). This regex will search for names which start-begin(^) with the typed text(by the user). The 'i' in the regex is for case-insensitive while the escapeRegex will just escape any special characters in user input.
You can also use your code and do the respective changes, I think it will also work. I just prefer to use $.getJSON. Take care of the #school_name for id(in your code you are using '.')
Try it here: http://jsbin.com/vawozutepu

Related

Remove autocomplete selected item from the list in asp.net and Ajax

I am in the biggest problem
**PLEASE DONT REPORT MY QUESTION DUPLICATE BECAUSE I DID NOT GET ANSWER FOR ASP.NET IN GOOGLE.
I am using jquery Autocomplete textbox in asp.net using web service.
my code
$('input.txtE').autocomplete({
source: function (request, response) {
$.ajax({
url: "WebServices.asmx/GetNames",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: "{ 'txtInput' : '" + request.term + "','userName':'" + userName + "'}",
dataFilter: function (data) { return data; },
success: function (data) {
mydata = data.d;
response($.map(data.d, function (item) {
return {
label: item.split('/')[0],
val: item.split('/')[1]
}
}))
},
error: function (result) {
alert("Error");
}
});
},
multiselect: false,
minLength: 1,
delay: 0,
select: function (e, ui) {
$(hfId).val(ui.item.val);
}
});
<input type="hidden" id="hfId"/>
And my API return data in array format
 ["Abhishek/128", "Abyss/71", "athansiah/53", "blvsian/138", "DesmondH/91", "destined2hold/62", "dnbdesigns/94", "Dvus_lotus/85", "gserranof/47", "Illusions/89", "isaacwu111/111", "js/39"]
What I need if a user selected remove him from the autocomplete list so we can't select him again.
Please help me to short out it.
Preparation
In first, you need to store setected values. It is possible by using a global variable, hidden input control or arbitrary data associated with your control. In the following example I create an array that is associated with autocomplete control and then store selected values to the array:
$('#my-control').autocomplete({
create: function( e, ui ) {
// initialize array
$(this).data('selected', []);
},
select: function( e, ui ) {
// store unique selected values
var selected = $(this).data('selected');
if(!~selected.indexOf(ui.item.value)) {
selected.push(ui.item.value);
}
},
// another options here
});
Now it is possible to consider the selected values for list filtering.
Server-side solution
The best way is to filter the list on API server side, because it reduces transferred data amount. Just send the stored values through an AJAX request, using data option:
var $control = $('#my-control');
$control.autocomplete({
source: function (request, response) {
$.ajax({
// some AJAX options
data: {
term: request.term,
selected: $control.data('selected') // send stored values
}
});
},
// some autocomplete options here
});
Then you have to implement server-side filtration in accordance to selected query string parameter.
For example
public class AutocompleteSourceController : ApiController
{
[HttpGet]
public JsonResult<IEnumerable<MyClass>> GetItems(
[FromUri]string term,
[FromUri]int[] selected)
{
// Load data
// Fliter by term substring
// Exclude selected items
// Return the result
}
}
Client-side solution
Another way is to filter responded list on client side, using success AJAX callback. In my example I will use fake online REST API server. The server ignores the term field of query string, so I also have to implement it on client-side.
$control = $('#my-input');
$control.autocomplete({
create: function(e, ui) {
$(this).data('selected', []);
},
source: function(request, response) {
$.ajax({
url: "https://jsonplaceholder.typicode.com/users",
type: "GET",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data) {
var items = data
// filter by term
.filter(function(user) {
return ~user.name.toLowerCase().indexOf(request.term.toLowerCase());
})
// exclude stored selected values
.filter(function(user) {
return !~$control.data('selected').indexOf(user.id);
})
// cast to an objects with label and value properties
.map(function(user) {
return {
label: user.name,
value: user.id
}
});
response(items);
},
error: function(result) {
alert("Error");
}
});
},
multiselect: false,
minLength: 1,
delay: 0,
select: function(e, ui) {
e.preventDefault();
$ctrl = $(this);
var selected = $control.data('selected');
if (!~selected.indexOf(ui.item.value)) {
// store selected value
selected.push(ui.item.value);
// set label instead of value
$ctrl.val(ui.item.label);
}
},
});
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<input id="my-input" type="text">
Type L to the input control. The first item will be Leanne Graham, select it. Then clean the input field and type L again, there will no Leanne Graham in the dropdown menu. Select Ervin Howell, then clean the input field and type L again. There will be neither Leanne Graham nor Ervin Howell in the dropdown menu.
If you want to consider only current selected value, you could store only latest value instead of an array and modify the success callback and the select event handler.
Try to remove selected value from array using jQuery.
x = jQuery.grep(x, function(val) {return val != Item;});

How would I sort list items that I am getting from a document library with javascript?

Currently I have some JavaScript that retrieves list items and displays them as part of an unordered list. I've been given the task of modifying the javascript below to sort items.
<script type="text/javascript" defer="defer">
$.ajax({
url: "/NewsEvents/_api/web/lists/GetByTitle('Newsletters')/items?$select=Title,FileRef",
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
},
success: function (data) {
returnedvalue = data;
var count = 0;
$.each(data.d.results, function (index, item) {
$('#NL ul').append("<li>" + "<a href='" + item.FileRef + "'>" + item.Title + "</a>" + "</li>");
count++;
});
},
error: function (error) {
alert(JSON.stringify(error));
}
});
</script>
I haven't done much javascript before and am willing to learn. Would love to be pointed in the right direction rather than just given an answer.
I'm assuming that data.d.results is a JavaScript array that resembles the following example:
results: [
{
Title: "Article Title",
FileRef: "something/or/other"
},
{
Title: "Another Article Title",
FileRef: "something/or/other/again"
},
]
JavaScript's Array type has a built-in sort method, which accepts a custom comparator ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort ).
I use the localeCompare ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare ) method to compare the Title values of each array element.
I specify sensitivity: "base" to perform a case and and accent invariant comparison, so "article" and "Article" are considered equal when compared.
success: function( data ) {
data.d.results.sort(
function( left, right ) {
return left.Title.localeCompare( right.Title, { sensitivity: "base" } );
}
);
// rest of your code here
}

C# Webservice json data jquery ui with custom formatting

I'm using asp.net webservice to use it in jQuery UI autocomplete plugin and here is the data I'm getting.
{"d":[
{
"__type":"WebS.Model.SearchModel",
"MainCommodityId":1,
"MainCommodityName":"Pulses",
"SubcommodityId":3,
"SubCommodityName":"Urid Dal",
"BrandId":3,
"BrandName":"President"
},
{
"__type":"WebS.Model.SearchModel",
"MainCommodityId":1,
"MainCommodityName":"Pulses",
"SubcommodityId":1,
"SubCommodityName":"Red Gram",
"BrandId":4,
"BrandName":"President"
}
]
}
This is the script I'm using:
$(document).ready(function () {
$(".input-search").autocomplete({
source: function (request, response) {
$.ajax({
url: '/WebServices/GetAllBrandNames.asmx/getAllBrands',
data: "{ 'data': '" + request.term + "'}",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.d, function (item) {
return {
value: item.BrandName,
label: item.SubCommodityName
}
}))
},
error: function (response) {
alert('error');
},
failure: function (response) {
alert('faii');
}
});
},
select: function (e, i) {
console.log(i.MainCommodityId);
console.log(i.SubcommodityId);
console.log(i.BrandId);
},
minLength: 1
}).autocomplete("instance")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + "" + item.BrandName + " in " + item.MainCommodityName + " - " + item.SubCommodityName + "</a>")
.appendTo(ul);
};
});
The issues are:
When I tried to enter keyword say: pre the aforesaid output is coming in json. However, the list is returning only one "President" item where it should display 2 items.
The list is displaying "undefined in undefined - undefined" instead of values after adding .autocomplete("instance")._renderItem function.
console.logs are also undefined after selecting an item.
How can these issues fixed?
The default behavior of the select event is to update the input with ui.item.value. This code runs after your event handler.
Simply prevent the default action on select and focus using event.preventDefault() or by return false and use _renderItem for custom dropdown.
focus: function(event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault(); // or return false;
}
select: function(event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault();
//do something
}
References:
jQuery UI Autocomplete Examples
Example 2
Finally, I was able to achieve what I wanted. Answering my question as it may helpful to someone.
javascript:
$(document).ready(function () {
$(".input-search").autocomplete({
source: function (request, response) {
$.ajax({
url: '/WebServices/GetAllBrandNames.asmx/getAllBrands',
data: "{ 'data': '" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.d, function (item) {
// don't forget to $.map to (data.d where d is the top node
return {
// assign values from json response for further use
brandid: item.BrandId,
brand: item.BrandName,
maincommodityid: item.MainCommodityId,
maincommodity: item.MainCommodityName,
subcommodityid: item.SubcommodityId,
subcommodity: item.SubCommodityName
}
}));
},
error: function (response) {
alert('Server Error. Please try again.');
},
failure: function (response) {
alert('Failed to get result');
}
});
},
focus: function (event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault();
},
select: function (event, ui) {
// prevent autocomplete from updating the textbox
event.preventDefault();
// do further action here such as assigning id to hidden field etc.
$(".input-search").val(ui.item.brand);
// navigate to the selected item's url ex: /catalogue/1/1/pulses/red-gram/4/president
var str = "/catalogue/" + ui.item.maincommodityid + "/" +
ui.item.subcommodityid + "/" + $.trim(ui.item.maincommodity.replace(/\s+/g, '-').toLowerCase()) + "/" +
$.trim(ui.item.subcommodity.replace(/\s+/g, '-').toLowerCase()) + "/" + ui.item.brandid + "/" +
$.trim(ui.item.brand.replace(/\s+/g, '-').toLowerCase());
window.location = str;
},
minLength: 3
}).autocomplete("instance")._renderItem = function (ul, item) {
// get values and create custom display
var $a = $("<a></a>");
$("<strong></strong>").text(item.brand).appendTo($a);
$("<span></span>").text(" in ").appendTo($a);
$("<span></span>").text(item.subcommodity).appendTo($a);
return $("<li></li>").append($a).appendTo(ul);
};
});
CSS:
ul.ui-front {
z-index: 1200; // change z-index according to your UI.
}
Usually I do this way and Its work.
$(document).ready(function () {
var jsondata=array();
$.post("/WebServices/GetAllBrandNames.asmx/getAllBrands",{data: request.term},function(data){
var data=JSON.parse(data);
$.each(data.d, function( index, value ) {
jsondata[index].value=value;
});
$(".input-search").autocomplete({
source:jsondata,
//other property and events
})
});
I mean apply source JSON after completing request because sometimes if AJAX takes some time to load execution pointer still execute rest of code without waiting for response.
I did not test this code but I always do this way and never get your kind of error. Good Luck

Jquery UI Autocomplete custom data doesn't works as expected

I'm trying to make an autocomplete with custom data like JQUI docs illustrate
Here is my Javascript code :
$.ajax({
type : 'POST',
url : '/loadUserCompanyByAjax',
dataType : 'json',
success: function (result) {
if (result.error == null) {
var dataArray = [];
$.each(result.companies,function(index,element){
dataArray.push({
name : element.name,
id : element._id
});
});
$( '.companyNameFromCreateMoe:empty' ).autocomplete({
minLength: 0,
source: dataArray,
focus: function( event, ui ) {
$(this ).val( ui.item.name );
return false;
},
select: function( event, ui ) {
alert(ui.item.id);
return false;
}
})
.autocomplete( "instance" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( "<a>" + item.name +"</a>" )
.appendTo( ul );
};
}
else {
alert('AN ERROR HAS OCCURED DURING GETTING COMPANIES : ' + result.error);
}
}
});
The problem is that when i begin to type a letter nothing is happening excepted if i type the letter "e"...
And when i type the following the autocomplete list disapears..
If i change my dataArray by the Array given in exemple it works.
Here the content of my dataArray :
[
{
"name":"SARL salut ça va",
"id":"55bdd266b1257b401d405ead"
},
{
"name":"EURL Marco plomberie",
"id":"55bde8b3e633d33c1ecfbecc"
}
]
The source list objects should have the keys "label" and "value".
Read the documentation for the source property: http://api.jqueryui.com/autocomplete/
you should change your loop to create dataArray like this
$.each(result.companies, function (index, element) {
dataArray.push({
label: element.name,
value: element._id
});
});
Here is the detailed fiddle.
http://jsfiddle.net/sqfwhxmj/1/
Hope it helps.

jquery autocomplete 'Disable' show all terms

Hey could someone guide me out of this problem....
I successfully created the jquery autocomplete function , but my problem is that autocomplete suggestions shows all the available labels . Autocomplete is showing the results which are not even matching the search term . I mean it showing all available label . Is their any solution to show only matching labels. here is the java function.
Any help will be gladly appreciated . Thank You
$(document).ready(function () {
$("#search-title").autocomplete({
source: function ( request, response ) {
$.ajax({
url: "availabletags.json",
dataType: "json",
data: {
term: request.term
},
success: function (data) {
response( $.map( data.stuff, function ( item ) {
return {
label: item.label,
value: item.value
};
}));
}
});
},
minLength: 2,
select: function (event, ui) {
$(event.target).val(ui.item.label);
window.location = ui.item.value;
return false;
}
});
});
EDIT : - Here is the Json File
{"stuff":[ {"label" : "Dragon", "value" : "eg.com"} ,
{"label" : "testing", "value" : "eg2.com"}]}
Successful Edited Code
<script>
$(document).ready(function () {
$("#search-title").autocomplete({
source: function ( request, response ) {
$.ajax({
url: "availabletags.json",
dataType: "json",
success: function (data) {
var sData = data.stuff.filter(function(v) {
var re = new RegExp( request.term, "i" );
return re.test( v.label );
});
response( $.map( sData, function ( item ) {
return {
label: item.label,
value: item.value
};
}));
}
});
},
minLength: 2,
focus: function (event, ui) {
this.value = ui.item.label;
event.preventDefault(); // Prevent the default focus behavior.
},
select: function (event, ui) {
$(event.target).val(ui.item.label);
window.location = ui.item.value;
return false;
}
});
});
</script>
Here is the change you want to make:
dataType: "json",
success: function (data) {
var sData = data.stuff.filter(function(v) {
return v.value.indexOf( request.term ) > -1;
});
response( $.map( sData, function ( item ) {
This search will be done by value. To search by label, in other words for the user's input to be compared to the label in your JSON use the following instead:
return v.label.indexOf( ........
UPDATE
To make your search case insensitive, use the following:
var re = new RegExp( request.term, "i" );
return re.test( v.label );
instead of return v.value.indexOf( request.term ) > -1;

Categories

Resources