Simple auto-completion function in javascript - javascript

I am trying to get a simple auto-complete function to work based off the usernames that a 3rd party app provides.
The app outputs data in this general format:
"{
"UserA":{"IP":"XXX.XXX.XXX.XXX","ConnectTime":"/Date(1435769694510)/","LastAskSource":"","LastAskType":2,"Name":"UserA"},
"UserB":{"IP":"XXX.XXX.XXX.XXX","ConnectTime":"/Date(1435769694510)/","LastAskSource":"","LastAskType":2,"Name":"UserB"},
"UserC":{"IP":"XXX.XXX.XXX.XXX","ConnectTime":"/Date(1435769694510)/","LastAskSource":"","LastAskType":2,"Name":"UserC"}
}"
Now, I want to use the general auto-complete function listed below:
$("#chatEntryBox").autocomplete({
source: usersOnline.Name
});
I have defined the array as such:
OnlineUsers = data.userinfo;
for (var i in OnlineUsers) {
var user = OnlineUsers[i];
usersOnline = $.map(OnlineUsers, function(el) { return el; })
}
Now, this part above works the way I would expect. I can test in the console what the values are of the array by doing JSON.stringify(usersOnline[0].Name);
I have looked at the documentation on the website for Jquery... I just think I am missing something or misunderstanding. If someone could point me in the right direction that would be great.
The end goal would be typing the first few letters of the users name, and it auto-completing the rest.

I made a fiddle for your problem here.
Loop to take out names from json can be as simple as this
var usersOnline = $.map(input, function(el) { return el.Name; })
$( "#chatEntryBox" ).autocomplete({
source: usersOnline
});

Related

Turning API data into HTML

sorry for the newbie question.
I'm new to using API's and I want to take the data from here
https://api.guildwars2.com/v2/commerce/prices/24615 (specifically the unit price under sells:) and display this in HTML.
This project will be using the unit price data across roughly 100 id's and I'd like to organize these numbers and run some basic math with them.
How can I go about this?
fetch('https://api.guildwars2.com/v2/commerce/prices/24615')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
So far I can get the data into the console, but I'm not sure how to turn this into something I can work with.
There is function in jQuery to make API calls, the following code makes you access api data,
$(document).ready( function() {
var info;
var whitelisted;
var quantity;
$.get("https://api.guildwars2.com/v2/commerce/prices/24615",function(obj){
info = obj['id'];
whitelisted = obj["whitlelisted"]
quantity = obj.buys['quantity']
$("#id1").html("id :"+info);
$("#whitelist").html("whitelisted :"+whitelisted);
$("#quan").html("quantity :"+quantity);
});
});
for more info you could look into the following pen link to the code
ignore these jerk moderators.
In your callback function, where you log myJson, edit your previously created html file,
like if you have a div, <div id="myDiv"> </div>, in the response function do something like this
const myDiv = document.getElementById("myDiv")
myDiv.textContent = myJson.name
And your div will show the name from json, or whatever you need. Play around with these ideas and you'll get far

Changing data returned from service changes data in service too

When I store data returned from a service in my controller and then edit it, it also changes the data in the service.
JSFiddle Demo
/* The backend connection part and the actual markdown editor JS have been removed because it would just make the code huge and is irrelevant to the problem */
var myApp = angular.module('myApp', []);
// In my app, this service caches blog post data from my server on the client side and returns single posts from it
myApp.factory('PostService', function ($log, $filter, $http) {
var data;
// Just an example for data pulled from server
data = [{
id: 99999,
text: "Hello"
}];
// Function for returning a post out of the data array loaded from the server
var getData = function (id) {
if (id !== undefined) {
var arr = $filter('filter')(data, {
id: id
});
if (arr.length === 0) {
$log.error('PostService:: getData(' + id + '):: Post Not Found');
return 'not_found';
} else {
$log.debug('PostService:: getData(' + id + '):: Post returned');
return arr[0];
}
} else {
return data;
}
};
return {
getData: getData
};
});
function ctrl($log, $scope, PostService) {
var edit = this;
// Sample post id
edit.editingId = 99999;
// "Copy" (apparrently more "bind") the blog post data to edit.data
edit.data = PostService.getData(edit.editingId);
}
This is used for a markdown editor. I wanted to load the data from the service into the controller, then edit it, and give the service the new version on pressing a "Save" button.
If the aforementioned behaviour is correct in the sense of Angular's databinding, what is a better solution to achieve what I want?
Update
Based on PSL's comment and Thibaud Sowa's answer I changed the getData() function to return a copy using angular.copy(). However, it seems not to be possible to copy one object out of an array (like angular.copy(arr[0])), as it will still return the whole array. See the updated JSFiddle.
Update 2
Well, I was dumb. I corrected it in the fiddle. Thank you for your answers.
This is because you are returning an object. In javascript when you do that it's like if you are passing a pointer.
You should use angular.copy to copy the object field by field, like this:
return angular.copy(data);
See the doc here https://docs.angularjs.org/api/ng/function/angular.copy
Response to your update
Well, I edited your fiddle, to show you that you can copy an item of an array. Actually it's seems that every thing works like you want... (Or I didn't understand your need!)
The updated fiddle:
https://jsfiddle.net/thibaudsowa/aybLwa2L/3/
There is a very simple solution to your problem:
If you dont want to change the data you get from the service make a copy
There are plenty of threads on SO discussing the fastes or most elegant way to deep copy a Javascript object. A simple and rather fast solution is using json parse and stringify like this:
var copyOfA = JSON.parse(JSON.stringify(a));
Apply this to the data you get from your service and you are good to go :)

Return arrays from meteor mongo

ajduke:bootstrap-tagsinput
I am using the above package to create a tags system. I have used <select multiple> from the True Input Value from the link above and have inserted each tags as Strings within the tag array.
This is what my db looks like.
Posts
tags //Array
[0] : sometag //String
[1] : sometag //String
[2] : sometag //String
//and so forth..
So my question is...
I want to return all the tags within a post to the following format, so that I can reuse it to show the tags when my users try to edit their posts.
Wanted Format
['sometag', 'sometag', 'sometag', and so forth]
Edit1
this is what I've done so far.
Post_Edit.js
Template.postEdit.rendered = function() {
myTags = Posts.findOne({_id: this._id}).tags.fetch(); //AAA
$('.tagsinput').tagsinput('add', myTags); //From above link API
}
I've tried other methods for //AAA line but I am having no luck.I've tried things such as Posts.findOne.map... Maybe my english comprehension is not up to par but the documentations in meteor did not help me understand any better.
Edit 2
Posts.findOne({_id: "ziZw3wLaxFyz3DYP4"}).tags
I've tried putting this in the browser console and got the array in the format that I wanted.
But the problem is, it won't work in my app when I use it.
When I use Posts.findOne({_id: this._id}).tags in my postEdit.rendered, I get this browser console error. Cannot read property 'tags' of undefined
Post_Edit.js
Template.postEdit.rendered = function() {
myTags = Posts.findOne({_id: this._id}).tags;
$('.tagsinput').tagsinput('add', myTags); //From above link API
}
What I don't understand is why is it working in browser console but not my Template.postEdit.rendered?
You are correct that your variable myTags is undefined when Template.postEdit.rendered is called because the Posts database has not finished loading when your function is called.
myTags = Posts.findOne({_id: this._id}).tags.fetch(); //AAA
Solution
There are multiple strategies including:
Updating DOM after subscription completes
http://docs.meteor.com/#/full/Blaze-TemplateInstance-subscribe
Re-run the function when Collection changes
http://docs.meteor.com/#/full/tracker_autorun
Template.postEdit.rendered = function() {
Tracker.autorun(function () { ** NEW LINE **
myTags = Posts.findOne({_id: this._id}).tags;
$('.tagsinput').tagsinput('add', myTags);
} ** NEW LINE **
}
I've approached a completely different way to figure this out.
But I'd still like to know why my method did not work...
post_edit.js
Template.postEdit.helpers({
tags: function(){
Posts.findOne({_id:this._id}).tags;
}
});
post_edit.html
<select class=tagsinput id="tagsinput" data-role="tagsinput">
{{#each}}
<option value="{{this}}">{{this}}</option>
{{/each}}

Reading Javascript local storage to populate autocomplete

I need to autocomplete a text field in a form. The data for the autocomplete will change from time to time, so I want to autopopulate the autocomplete. This will be running standalone with no net access, so I need a client side solution. Having the user select a file for the autopopulate is out of the question, so I wrote a .js file that creates a JSON object with the data to populate the autocomplete, as well as other data associated with the selection for the field.
I know the auto complete works if I give it a simple array:
$(function() {
var cityList= ["Arlington Heights","Winnipeg","Miami Gardens","Louisville","Del Mar","Wilmington","Berkeley","Vancouver",]
// var cityList= "Arlington Heights,Winnipeg,Miami Gardens,Louisville,Del Mar,Wilmington,Berkeley,Vancouver,"
$( "#autocomp" ).autocomplete({ source: cityList });
});
However, when I read in the data from the .js file, things get really weird. This is the code I am using:
$(function() {
citiesData ();
var city = JSON.parse(localStorage.getItem( ['cityData']));
var cityList = '[';
for(var row in city) {
cityList = cityList += '"' + city[row].city +'",';
};
cityList += ']';
// document.write('<br />' + cityList);
$( "#autocomp" ).autocomplete({ source: cityList });
// document.write('<br />; checkpoint 1');
})
By uncommenting the document.write above the autocomplete line, I can see that the variable cityList is exactly the same as the array entered in the first example. By uncommenting both document.write lines, I can see that they each get written, so the code is not hanging on the autocomplete. However, if I uncomment either or both of the document.write lines, the form never appears on the screen. I believe I mentioned that it got weird.
My real problem is not with that weirdness. My real problem is that the autocomplete never populates, although my solution is very similar to the one at tutorialspoint.com/jqueryui/jqueryui_autocomplete.htm. I would really appreciate any insights into what my problem is with this.
I would also be interested if anyone can explain the weirdness about the document.write lines.
I have posted both versions. The first is at http://mccalip.com/problem/index.html.
The problem version is at http://mccalip.com/problem/problem.html.
Here is the code that works:
$(function() {
readCity();
var cityList = new Array;
for (var c in arrayCity) {
cityList.push(arrayCity[c][0]);
};
$( "#autocomp" ).autocomplete({ source: cityList });
});
readCity() is a function that creates the 2D array, arrayCity. Each row in the array has the city name followed by other data.
I just need the city names in the array for the autocomplete function, so I loop through arrayCity and push the names into the 1D array, cityList.

Create a drop down from an xml file, with no repeated values. Do I need an array?

I am still learning javascript and xml and have recently been presented with an issue I'm sure is simple to solve. I'm hoping for some help on this if possible.
I have an xml file that is found here
http://mrblesid.com/blueprint/bookinglist.xml
I'm currently using this code to create a drop down list featuring the values from just one of the attributes "strArtistName"
$(document).ready(function(artists){
$.ajax({
type: "GET",
url: "bookinglist.xml",
dataType: "xml",
success: function(artists_list) {
var select = $('#mySelect');
$(artists_list).find('vw_ADM_BookingListNull[strArtistName]').each(function(){
var artists = $(this).attr('strArtistName');
select.append('<option value="'+artists+'">'+artists+'</option>');
});
select.children(":first").text("please make a selection").attr("selected",true);
}
});
});
This is then called into a dropdown via the following
<form>
<select id="mySelect">
<option>loading</option>
</select>
</form>
I would like to avoid repeating the artist names that are found for every entry, am I right to think I would need to use an array for this? If so how do I go about it?
The name selected from the list should populate a variable to use elsewhere in the report.
Any help would be greatly appreciates as I have deadlines looming.
Thanks in advance,
Mikey
An array will work. Update the main part to
var artistsArr = [];
$(artists_list).find('vw_ADM_BookingListNull[strArtistName]').each(function(){
var artists = $(this).attr('strArtistName');
if ($.inArray(artists, artistsArr) == -1) {
select.append('<option value="'+artists+'">'+artists+'</option>');
artistsArr.push(artists);
}
});
Some browsers don't support Array.indexOf, so you can use jQuery's inArray.
First off, you should batch the DOM insertions for performance reasons (You can also squeeze a little more performance out by using an array instead of pure string concatanation) Here is your success function with some performance optimizations as well as the check for duplicate artists:
function(artists_list) {
var select = $('#mySelect'),
html = [],
artistArray = [];
$(artists_list).find('vw_ADM_BookingListNull[strArtistName]').each(function(){
var artists = $(this).attr('strArtistName');
// Check the artistArray for a duplicate.
// This will only work in more recent browsers.
if (artistArray.indexOf(artists) === -1) {
html.push('<option value="'+artists+'">'+artists+'</option>');
artistArray.push(artists);
}
});
// Join the HTML array and add it to the select element
select.append(html.join(''))
.children(":first").text("please make a selection").attr("selected",true);
}

Categories

Resources