Jquery: Autocomplete with label - javascript

I am trying to learn website development.
While learning autocomplete feature of jquery, I tried to put in the labels.
function autocomplete (data) {
var data = data.toString();
var availableTags = data.split(',');
var autocompleteData = [];
for (var i = 0; i < availableTags.length; i++){
autocompleteData[i] = {};
autocompleteData[i].label = i.toString();
autocompleteData[i].value = availableTags[i];
}
$("#tags").autocomplete({
source: autocompleteData,
select: function (event, ui) {
printautocomplete(event, ui)
}
});
};
The autocomplete[i].value is a valid string.
autocompleteData[0]
Object {label: 0, value: "Peter"}
However, I do not see any suggestions.
What is wrong with the way I am using the API?
The API says:
"Array: An array can be used for local data. There are two supported formats:
An array of strings: [ "Choice1", "Choice2" ]
OR 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. If just one property is specified, it will be used for both, e.g., if you provide only value properties, the value will also be used as the label. "
Thank you.

$('#sidebarSearch').autocomplete(
{
source: function(query, result)
{
var query = $('#sidebarSearch').val ();
$.ajax(
{
url:"sidebarSearchFetch.php",
method:"POST",
data:{query:query},
dataType:"json",
success:function(data)
{
result($.map(data, function(item)
{
return {
label: item.name,
value: item.usrId
};
}));
}
})
},
appendTo: "#sidebar-form"
});

I am skeptical of line 2 in your code (var data = String()data;) I would use: var data = data.toString();
But if you are sure that the autocompleteData elements do indeed have valid strings, then my best guess would be that perhaps you forgot to give the '#tags' id to your html entry field element.
Finally, if this is not it, to troubleshoot, I would try removing the select: option from the object you are passing to autocomplete() in the line that begins: $("#tags").autocomplete(... so that only the source options is passed.
Another thing to check out is when the code is being run. It is possible that a document.ready() function is needed to ensure that that when the autocomplete feature is added to the DOM element with the id '#tags', that the element has already been created.

The autocomplete works fine. Instead of completing "value", it completes "label".
So when I type in "1", it suggests "1", "10", "11", etc.
Autocomplete applying value not label to textbox answers how to change to to by-value.

Related

Turn Observable Array into nested JSON

I'm having a problem getting an array of information stored properly as JSON.
I made a fiddle to illustrate the problem. Enter a set of tags and take a look at the console to see the output.
More explanation:
So I have an input that takes in a comma-separated list of tags, which I then format.
function createTagArray() {
// given an input value of 'tag1, tag2, tag3'
// returns array = ['tag1', 'tag2', 'tag3']
}
I thought what I needed to do next was the following:
loop over the array and create a 'tag' object for each item which also includes an id for the tag and the id of the contact the tag is associated with.
Each object is pushed to tags, an observable array.
function single_tag(id, contactId, tagLabel) {
var self = this;
self.id = id;
self.contactId = contactId;
self.tagLabel = tagLabel;
}
function createTags() {
var array = createTagArray();
for (var i = 0; i < array.length; i++) {
self.tags().push(new single_tag(uuid.generate(), self.contactId, array[i]));
}
}
Then, I converted it into JSON
self.contactInformation = function() {
return ko.toJS({
"id": self.contactId,
"firstname": self.firstname(),
"lastname": self.lastname(),
... other fields ...
"tags": self.tags(),
})
}
But, when I inspect the console output of calling this function, tags is a collection of arrays, not a nice json object.
How do I get it formatted correctly?
I tried this suggestion, and the tag json is structured correctly, but it is stored with escaped quotes, so that seems wrong.
Thanks for all the help!
I would recommend you knockout.mapping plugin for KO, it allow map complicated JSON structure to view model, even without declarations.
From the documentation
Let’s say you have a JavaScript object that looks like this:
var data = {
name: 'Scot',
children: [
{ id : 1, name : 'Alicw' }
]
}
You can map this to a view model without any problems:
var viewModel = ko.mapping.fromJS(data);
Now, let’s say the data is updated to be without any typos:
var data = {
name: 'Scott',
children: [
{ id : 1, name : 'Alice' }
]
}
Two things have happened here: name was changed from Scot to Scott and children[0].name was changed from Alicw to the typo-free Alice. You can update viewModel based on this new data:
ko.mapping.fromJS(data, viewModel);
And name would have changed as expected. However, in the children array, the child (Alicw) would have been completely removed and a new one (Alice) added. This is not completely what you would have expected. Instead, you would have expected that only the name property of the child was updated from Alicw to Alice, not that the entire child was replaced!
...
To solve this, you can specify which key the mapping plugin should use to determine if an object is new or old. You would set it up like this:
var mapping = {
'children': {
key: function(data) {
return ko.utils.unwrapObservable(data.id);
}
}
}
var viewModel = ko.mapping.fromJS(data, mapping);
In the jsfiddle you were using Knockout 3.0 which doesn't have support for textInput. This was added in 3.2. To use version 3.2 you need to use a cdn such as this: http://cdnjs.com/libraries/knockout
There was typeo in your binding. sumbit should be submit.
There was a problem with your constructor for single_tag. id was not used so I removed it:
function single_tag(contactId, tagLabel) {
var self = this;
self.contactId = contactId;
self.tagLabel = tagLabel;
}
Currently also contactId is not set because the observable has not been set to a value.
To convert to JSON you need to use ko.toJSON instead of ko.toJS:
self.contactInformation = function() {
return ko.toJSON({
"firstname": self.firstname(),
"tags": self.tags(),
})
}
Now when the console writes out an array appears:
{
"firstname":"test",
"tags":[
{"tagLabel":"test1"},
{"tagLabel":"test2"},
{"tagLabel":"test3"}
]
}
JsFiddle
So my problem was more basic than I was realizing. I'm using JSON Server to serve up my data, and I was pulling information from two parts of the database (contacts & tags).
When I tried to update my tags, I was trying to apply them to a property that didn't exist on the contact JSON in my database. Posting the tags separately worked though.

JQuery Datatables Row Data From AJAX Source

In the past I've always used this to get a hidden column's data. I would hide the column with a css class, but the responsive feature doesn't work well with these.
var td = $('td', this);
var ID = $(td[0]).text();
So I found an alternative, by hiding the columns with these classes with the responsive feature.
"columnDefs": [
//Responsive classes
{ className: 'never', targets: 0 }, //Hide on all devices
{ className: 'all', targets: 1 }, //Show on all devices
]
and then I use either one of these.
var rowData = oTable1.fnGetData(this);
var rowData = oTable1.api().row(this).data();
//Grab the first indexed item in the list
var ID = rowData[0];
That works well if you don't have an AJAX source. It will return a comma separated list of the row data. However, when I try to use this with an AJAX source I just get [object Object] back (instead of a comma separated list) if I output the rowData variable in an alert.
How do I get the row data out of a table with an AJAX source?
It seem to be stored as string so [1, 2, 3] became [object Object] when you turn it into string. Do yourString = yourList.join(',') and store yourString to keep the coma-separated string.
For an object:
yourString = (function () {
var list = [];
for(var i in yourList)
if(yourList.hasOwnProperty(i))
list.push(yourList[i]);
return list.join(',');
})();
The function is not needed, it's just to limit the variables scope.
I ended up using an answer I found here.
Converting a JS object to an array
I can pull the entire row data from the table with this.
var rowData = oTable1.api().row(this).data();
In the console log I can see that it returns a javascript object like this.
Object { id="123456", full_name="Samuel Smith", Last_name="Smith" }
I use this function to convert the object into an array.
var array = $.map(rowData, function (value, index) {
return [value];
});
In the console log, my array would appear like this.
["123456", "Samuel Smith", "Smith"]
I can then extract any item from the array like this.
alert(array[0]);
Simplifying madvora's example:
var rowData = oTable1.api().row(this).data().to$();
rowDataArray = rowData.toArray();

How to return an object using jQuery, not only the value

I'm looking for a way of replacing .val(); in jQuery with something like .array or .object. So instead of getting only the value of a drop down, i can return the full array for the selected value.
I have a drop down which allows a user to select multiple 'gameTypes', i'm outputting this to the screen and when the user clicks next the content of these 'gameTypes' should be sent as a JSON request.
The code i'm currently using is below however it only returns the 'gametype' name, so when i run the code i get 'RPG' in the console. What i need is the full object, so RPG, publishers, games etc.
Ive looked at the API documentation in jQuery and can't find a way of doing it, is it possible with jQuery?
Js Code:
$("#nextbutton").click(function () {
var datatosend = {
gametypes: [],
market: [] //This is populated using the same method however i don't need the whole object, just the name so this works
};
$("#comboGameType").find(":selected").each(function() {
var str = $(this).val();
datatosend.gametypes.push(str);
console.log(str);
});
});
JSON example:
{
"games": [{
"gameType": "RPG",
"publishers": [{
"publisher": "Square",
"titles": [{
"title": "Final Fantasy",
"gameReleases": [ 2006, 2008, 2010, 2012, 2013, 2014 ]
}]
}]
}]
}
The html is pretty standard, it's populated through js
<select id="comboGameType" class="selectpicker" multiple> </select>
JS to handle changes to drop down and display selections:
$('#comboGameType').change(function () {
var values = $('#comboGameType').val();
var parsedData = JSON.parse($myData);
for (var i = 0; i < values.length; i += 1) {
$('#output').append("<div>" + values[i] + "</div>")
}
});
Heres a fiddle to show as an example - when you view console see the value of the drop down is returned, however i'm trying to return the FULL object (so everything in RPG for example) http://jsfiddle.net/2Ma7U/
You can use jQuery data to store the entire object and retrieve it later.
$(parsedData.genres).each(function (i) {
$("#pubCombo").append($("<option/>", {
val: this.genre,
html: this.genre,
data: this
}));
});
$("#next").click(function () {
var datatosend = {
gametypes: [],
market: []
};
$("#pubCombo").find(":selected").each(function() {
var obj = $(this).data();
datatosend.gametypes.push(obj);
console.log(obj);
});
});
Updated fiddle http://jsfiddle.net/2Ma7U/1/

Issue with using JSON.stringify after using jQuery.map

I am writing a bookmarklet (that will eventually be a plugin) to scrape web pages for list items in jQuery under a specified div. I'm having an issue with using JSON.stringify
The following code allows me to convert each individual item to JSON, but has issues when using join to concatenate each string.
var dMap = $("div").filter($("#<div-id>")).find("li").map(function() {
var iObject = {
id: $(this).data('id'),
text: $(this).text(),
list_name: $(this).closest('div').attr('id')
};
return JSON.stringify(iObject);
});
console.log(dMap);
This second snippet of code creates each object in the array correctly, but the resulting array doesn't log the resulting JSON.
var dMap = $("div").filter($("#,div-id.")).find("li").map(function() {
return {
id: $(this).data('id'),
text: $(this).text(),
list_name: $(this).closest('div').attr('id')
};
});
console.log(dMap);
var json = JSON.stringify(dMap);
console.log(json);
Any ideas?
According to the documentation for .map:
As the return value is a jQuery-wrapped array, it's very common to get() the returned object to work with a basic array.
Have you tried:
var json = JSON.stringify(dMap.get());

What does formatResult and formatItem options do in JQuery Autocomplete?

Am a bit confused here, what does the formatResult and formatItem do in the JQuery Autocomplete plugin?
I have a function that is returning a comma separated string (from Django), but my autocomplete function is unable to split the string into individual entries/rows, how can i achieve this using autocomplete functions?
e.g the returned result looks like this and this what autocomplete is showing :-
["one","oneTwo", "Onethree", "anotherOne"]
I want when showing in the autocomplete field to have it split like this:-
one
oneTwo
Onethree
anotherOne
I have a feeling i can use the formatResult and formatItem but i dont know how, there are no good examples out there !!
my code in the html template:
function autoFill(){
$("#tags").autocomplete("/taglookup/", {
width: 320,
max: 4,
highlight: false,
multiple: true,
multipleSeparator: " ",
scroll: true,
scrollHeight: 300
});
}
Am using Dajango to process the GET request.
Gath
formatItem formats an item for display in the dropdown list, while formatResult formats the item for display in the inputbox once it is selected.
By default, autocomplete expects to get data from the specified url formatted as:
foo|bar|baz|bing
zaz|ding|blop|grok
where each line is a row of data; each row being the data that it passes to formatItem and formatResult. You may want to take the path of least resistance and return data in the way it likes.
If you want to use data that doesn't fit autocomplete's assumptions, you'll need to use the (undocumented, as far as I can tell) parse option to identify a function to parse the results of your ajax request. It appears to me that your django view is returning an array rather than returning a formatted string. To format your array as jquery would like it:
return HttpResponse('|'.join(your_array), mimetype='text/plain')
Here is an example of doing autocomplete using non-standard autocomplete data (JSON):
<script type="text/javascript">
format_item = function (item, position, length){
return item.title;
}
// Handle data from ajax request
prep_data = function(data){
tmp = $.evalJSON(data);
parsed_data = [];
for (i=0; i < tmp.length; i++) {
obj = tmp[i];
// Other internal autocomplete operations expect
// the data to be split into associative arrays of this sort
parsed_data[i] = {
data: obj ,
value: obj.isbn13,
result: obj.title
};
}
return parsed_data
}
$(document).ready(function(){
$("#fop").autocomplete({
url : "{% url book-search %}",
// undocumented
parse: prep_data,
formatItem: format_item,
});
})
</script>
I have not been able to get formatMatch and formatResult to work so far. I am still working on the 'correct' way to use them. However, as a workaround you can use the parse option as follows. Just to be clear, in this example, formatItem and parse are functional while formatResult and formatMatch are not functional.
jQuery(function(){
$('#profile-tabs_addresses_grid_b_a_PostalCode').autocomplete
('http://test.mydomain.com/locality/postalcodes/', {
minChars:1,
delay:400,
cacheLength:100,
matchContains:true,
max:10,
formatItem:function(item, index, total, query){
return item.PostalCode + ': ' + item.Region + ', ' +
item.City + ', ' + item.Country;
},
formatMatch:function(item){
return item.PostalCode;
},
formatResult:function(item){
return item.PostalCode;
},
dataType:'json',
parse:function(data) {
return $.map(data, function(item) {
return {
data: item,
value: item.PostalCode,
result: item.PostalCode
}
});
}});
});
here is the json data that comes back from the data url ( whitespace
added for easier viewing ):
[
{City:"St. Louis", Country:"USA", PostalCode:"63103", ID:3,
Region:"Missouri"},
{City:"St. Louis", Country:"USA", PostalCode:"63109", ID:1,
Region:"Missouri"},
{City:"St. Louis", Country:"USA", PostalCode:"63119", ID:2,
Region:"Missouri"}
]
When I type a 6 in the postal code box, it shows all three options
properly formatted as:
63103: Missouri, St. Louis, USA
63109: Missouri, St. Louis, USA
63119: Missouri, St. Louis, USA
and when I select one the textbox receives just the selected
postal code.

Categories

Resources