jQuery AutoComplete not rendering correctly - javascript

I have two jQuery autocomplete components on my site. Both nearly exactly the same however, one displays correctly and one doesnt.
The code for the working one is:
#Html.TextBoxFor(model => model.Part, new { #id = "txtPartCode" })
$('#txtPartCode').autocomplete({
minLength: 3,
source: function (request, response) {
$.ajax({
url: apiEndpoint + 'api/Part/Filtered/' + $('#txtPartCode').val(),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
response(data);
}
});
}
});
The code for the failing one is:
#Html.TextBoxFor(model => model.ParentRequestId, new { #id = "txtParentRequest" })
$('#txtParentRequest').autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: apiEndpoint + 'api/Request/' + $('#txtParentRequest').val(),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
response(data);
}
});
}
});
As you can see they are very similar. The response from the API for the working one is ["string1", "string2", "string3"] and for the broken one is [1,2,3,4].
The jQuery libraries are included in my bundles so should be the same on all pages. I have used jquery.js, jquery-ui.js and jquery-ui.css.
I cant work out the difference between them as to why the one does not display correctly.
The broken one displays as follows:
Any help with this would be greatly appreciated. Please let me know if more info is required
EDIT - Solution But Why?
So the issue appeared to be that the jQuery Autocomplete component did not like an input of an array of integers.
This seems quite strange to me and I believe an autocomplete should be able to cope with integers. Does anybody know why this is or if there is a setting to handle it?

jquery-ui autocomplete would work good with String responses. Your response data should be a list of strings and not integers (as the value attribute for the input element is always a string).
Try converting the response data to string either at client side or server side. I prefer doing it at the client side.
$('#txtParentRequest').autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: apiEndpoint + 'api/Request/' + $('#txtParentRequest').val(),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
// Convert the integer list to a string list
var stringList = $.map(data, function(element){
return element + "";
})
response(stringList );
}
});
}
});

It's because JQuery autocomplete supports only two array formats as explained below:-
source Type:
Array or String or Function( Object request, Function
response( Object data ) ) Default: none; must be specified Defines the
data to use, must be specified. Independent of the variant you use,
the label is always treated as text. If you want the label to be
treated as html you can use Scott González' html extension. The demos
all focus on different variations of the source option - look for one
that matches your use case, and check out the code.
Multiple types supported: Array: An array can be used for local data.
There are two supported formats: An array of strings: [ "Choice1",
"Choice2" ] An array of objects with label and value properties: [ {
label: "Choice1", value: "value1" }, ... ] The label property is
displayed in the suggestion menu. The value will be inserted into the
input element when a user selects an item.
You can have a look at API documentation for more details:
http://api.jqueryui.com/autocomplete/
So as per me you can convert your array to string from backend or you can convert it by Javascript like this:-
$('#txtParentRequest').autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: apiEndpoint + 'api/Request/' + $('#txtParentRequest').val(),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
success: function (data) {
if(data!=null && data.length>0){
var numberArray=data.map(String);
response(numberArray);
//Or response(data.map(String));
}
}
});
}
});

Related

Jquery Ajax passing array inside data obect

I am trying to pass an object into the data property of this jquery ajax request. All work's fine, but the fields property, which is an array, does not get recognized (returns all fields, when these are the two I am requesting).
I've tried JSON.stringify, but this returns an error for 'bad request'. How do I pass this object with an array inside correctly?
function energyQuery(token){
$.ajax({
type: 'GET',
url: url,
headers: {'Content-Type': 'application/json', 'Authorization': 'Token token=' + token},
data: {
'start': '2019-01-05',
'end': '2019-01-10',
'limit': 0,
'measurement': 'analysis',
'fields': ['energy_out', 'energy_in'] // if I pass 'energy_out' it works
},
success: function(data){
//console.log(data);
response = JSON.stringify(data);
console.log(response);
},
error: function(errMsg) {
console.log('Query:' + JSON.stringify(errMsg));
}
});
}
error message:
Please note that fields MUST either be a single valid field string or a list of valid field strings.
Send it as post and point to correct datatype
var array = ['energy_out', 'energy_in'];
var dataObj = {
'start': '2019-01-05',
'end': '2019-01-10',
'limit': 0,
'measurement': 'analysis',
'fields': array
};
var data = JSON.stringify(dataObj);
$.ajax({
url: url,
type: "POST",
dataType: "json",
data: data,
contentType: "application/json"
});
Also on back-end side create correct model to recieve data.
If you are implementing also the server side, please consider to change the array of strings to a "particular string".
What I mean?
CASE 1 : pass array as string
'fields': '[\'energy_out\', \'energy_in\'])'
Then in the server side read the string and convert it to an array.
This is the solution that I use in Java: I read a String then I convert it to an array of integer,strings,... and so on.
CASE 2: use a particular separator, pass the field as a string;
'fields': 'value1,value2,value3'
Supposing you use , as separator, then you must split string by ,.
It's better to ask (via web service) arrays as a single string so each client can implement in a simple way of to pass data in the get method.
'fields': ['energy_out', 'energy_in']
It's not a standard json format. just change the type of parameter 0 'fields': 'energy_out,energy_in' and when receive use split,

Pass object from javascript to Perl dancer framework

I have following ajax code to pass values to dancer framework.
BookSave: function(data) {
### data is an object that contain more than one key value pair
var book = Book.code;
$.ajax ({
type: "GET",
url : 'textbook/save/' + book + '/' + data,
success: function(data) {
if(data.status == 1) {
alert("success");
} else {
alert("fail");
}
},
});
},
In dancer:
any [ 'ajax', 'get' ] => '/save/:book/:data' => sub {
set serializer => 'JSON';
my $book = params->{book};
my $data = params->{data}; ## This I am getting as object object instead of hash
};
Is there any way to pass object from js and getting as hash in dancer?
First and foremost, consider using the http PUT or POST verbs, and not GET. Not only is doing so more semantically correct, it allows you to include more complex objects in the http body, such as your 'data' hash (serialized, per my comments below).
I've had limited success with Dancer's native AJAXy methods, plus there is a bug that causes problems in some versions of Firefox. So instead, I serialize and then deserialize the JSON object.
Suggested changes (note I suggested changes to your routes as well):
$.ajax ({
type: "PUT",
url : '/textbook/' + book,
data: {
myhash : JSON.stringify(data)
},
dataType: 'json',
contentType: 'application/json',
success: function (response) {
if (response.status == 1) {
alert("success")
} else {
alert("fail")
}
}
})
and your Perl Dancer code changes as follows:
any [ 'ajax', 'put' ] => '/textbook/:book' => sub {
set serializer => 'JSON';
my $book = param('book');
my $data = from_json(param('myhash'));
};
I did not go as far as testing this code, but it should at least give you a good starting point to finish solving this problem.
Good luck with your project!

Update a Table Per Hierarchy entity from JS or JQUERY

I have created a ENTITY FRAMEWORK model of a CARS table and made two TPH entities on EDMX designer and named them OLD CAR and NEW CAR, have set me CARS table to Abstract.
Now, I am accessing the CARS entity from JQUERY and I can do the following:
GET (working fine)
DELETE (working fine)
but I am not able to CREATE (POST) or UPDATE (PUT) into the derived inherited entities, it gives me the following error " Types information must be specified for types which are inherited"
I have exposed all of my entities from WCF Data Services
below is my code;
function putData() {
var url = "http://localhost:55153/WebSite3/WcfDataService1.svc/Cars(2)";
var obj = '{"CarName": "Margalla", "CarModel" : "Honda"}';
var r = window.JSON.stringify(obj);
$.ajax({
type: "PUT",
url: url,
data: obj,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert("Updated successful");
},
error: function (msg) {
alert(msg.responseText);
}
});
}
The problem here is that the server doesn't know which type of car you're trying to insert (or modify).
Try changing your payload to include the "odata.type" property. For example:
var obj = '{
"odata.type": "YourNamespace.OldCar",
"CarName": "Margalla",
"CarModel" : "Honda"
}';
The "odata.type" property is specific to the new JSON format (v3 OData only), so I would also suggest including the "DataServiceVersion" header on the request to make it clear to the server that you are sending a v3 payload. For example:
$.ajax({
...
beforeSend: function (request)
{
request.setRequestHeader("DataServiceVersion", "3.0");
},
...
});

.serialize() an array of variables in Javascript

I have a list of variables available to me and I want to send it via $.ajax post. What format would I have to keep these in to use the function .serialize? I keep getting this error:
Object 'blank' has no method 'serialize'
I've tried to make them an array and I've tried jQuery.param(). I have a feeling this is simple but I can't seem to get it. Thanks!
var $data = jQuery.makeArray(attachmentId = attachmentID, action = 'rename', oldName = filename, newName, bucketName, oldFolderName, newFolderName, projectId = PID, businessId = BID);
var serializedData = $data.serializeArray();
//alert(theurl);
$.ajax({ type: "post", url: theurl, data: serializedData, dataType: 'json', success: reCreateTree });
.serialize is for form elements:
Encode a set of form elements as a string for submission.
The $.ajax documentation says for the data option:
Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below).
So all you need to do is passing an object. For example:
$.ajax({
type: "post",
url: theurl,
data: { // <-- just pass an object
attachmentId: attachmentID,
action: 'rename',
// ...
},
dataType: 'json',
success: reCreateTree
});
It seems you're used to the PHP style of array's (associated arrays). In Javascript, objects are basically the same thing (though can be MUCH more complicated).
So if you are trying to create an array like this in php it would be
$array = array(
"foo" => "bar",
"bar" => "foo",
);
in Javascript using an object instead of an array it would be
var arr = {
foo: "bar",
bar: "foo"
}

jQuery autocomplete - pass targeted element attribute as an extra parameter?

I'm using the jQuery UI Autocomplete plug-in to make an ajax call and retrieve data. As well as passing the text of the input element I'm trying to pass in the 'id' attribute of the input element as an additional parameter. An extract of my code looks like this -
$("#autocomplete input").autocomplete({
source: function(request, response) {
$.ajax({
url: "search.php",
dataType: "json",
data: {
term: extractLast(request.term),
extra_param: $(this).attr('id')
},
success: function(data) {
response($.map(data, function(item) {
return {
label: item.label,
value: item.name
}
}))
}
})
},
});
The extra parameter is added to the 'data' property in the ajax call. It works okay if I specifically pass in a value e.g. '3' but I want to pass the 'id' attribute of the input element the function is being called on e.g. $(this).attr('id').
I assume it's a problem with 'this' not being evaluated in this part of the code, but I'm at a loss to see how else I can reference the element that is being targeted. Any help appreciated!
$('#autocomplete input').each(e, function() {
$(e).autocomplete('/path?param=' + $(e).attr('id'), function() { ... });
});
$('#autocomplete input').each(e, function() {
$(e).autocomplete({ source:function ... extra_param: $(e).attr('id') ... });
});
There maybe a more elegant way, but, I know autocomplete is somewhat sophisticated. I personally generate the request w/get parameters and use formatItem/formatResult instead of assigning the source to an ajax call.
I've got it working by breaking the autocomplete call out into an each. This allows me to capture the target element before I execute the autocomplete -
$("#autocomplete input").each(function() {
var that = this;
$(that).autocomplete({
source: function(request, response, this_element) {
$.ajax({
url: "search.php",
dataType: "json",
data: {
term: extractLast(request.term),
extra_param: $(that).attr('id')
}
....
"Source" is the ID of your input, you receive this item and save it in the variable, "that". When the input "Source" calls the autocomplete function, you can send the value of your id stored in the variable "that" for AJAX.
Example:
<script type="text/javascript">
$(document).ready(function() {
$("#Source").each(function() {
var that = this;
var url = "<?php echo constant('URL'); ?>";
$(that).autocomplete({
source: function(request, response){
$.ajax({
url: url+"models/queries/C_getOptions.php",
dataType:"json",
data:{
word:request.term,
id : $(that).attr('id')
},
success: function(data){
response(data);
}
});
},
minLength: 1,
select: function(event,ui){
//alert("Selecciono: "+ ui.item.label);
}
});
})
});

Categories

Resources