Autocomplete field with JSON data from external url (Steam API) - javascript

I am working on an input field that is autocompleted with names from this link(steam API):
http://api.steampowered.com/ISteamApps/GetAppList/v0002/?format=json
or
http://api.steampowered.com/ISteamApps/GetAppList/v0001
I would also like the field to return the id of the game despite the name being insered into it.
So far after browsing the forums I put together this but it doesn't quite work:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$("#tags").autocomplete({
source: function (request, response) {
$.ajax({
url: "http://api.steampowered.com/ISteamApps/GetAppList/v0002/?format=json",
data: { query: request.term },
success: function (data) {
var transformed = $.map(data, function (el) {
return {
label: el.appid + " - " + el.name,
id: el.appid
};
});
response(transformed);
},
error: function () {
response([]);
}
});
}
});
});
</script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
</body>
</html>
For the autocomplete part I chose to use jQuery autocomplete function: https://jqueryui.com/autocomplete/ however I am open to other methods.
Edit: Fixed syntax error on line 31 but the code still isn't working.
JSFiddle: https://jsfiddle.net/vxej2L5g/

In the success block you are assigning a label and id. In the label you have assigned name, and in id the appid. We can modify this to format the label like this:
success: function (data) {
var transformed = $.map(data, function (el) {
return {
label: el.appid + " - " + el.name,
id: el.appid
};
});
response(transformed);
},

There is a syntax error in your Javascript on line 31 (basically you have an extra closing parenthesis and semicolon).
The JSON response for the API you are calling wraps the list of apps.

Related

Run a script only after another one completes

I have multiple scripts in my HTML header. the two of concern are as follows:
1) JS script ('Infected Data') produces an object with data. The data is retrieved and computed from a google scripts file, so naturally it takes a bit.
2) A script which generates a map. The map is color coded depending on the values of the Infected Object Data.
The problem is the map loads before i can get the object, so it is not colored.
Map should look like this:
Map looks like this:
HTML Header:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>JQVMap - World Map</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<link href="../dist/jqvmap.css" media="screen" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="../dist/jquery.vmap.js"></script>
<script type="text/javascript" src="../dist/maps/jquery.vmap.world.js" charset="utf-8"></script>
<script type="text/javascript" src="js/jquery.vmap.sampledata.deaths.js"></script>
<script type="text/javascript" src="js/jquery.vmap.sampledata.infected.js"></script>
<script>
jQuery(document).ready(function () {
jQuery('#vmap').vectorMap({
map: 'world_en',
backgroundColor: '#333333',
color: '#ffffff',
hoverOpacity: 0.8,
selectedColor: '#3498DB',
enableZoom: true,
showTooltip: true,
scaleColors: ['#F3A291', '#FF4F3B'],
values: infected_data,
normalizeFunction: 'polynomial',
onLabelShow: function(event, label, code)
{
// Remove for Russian Joke
/*if (code == 'ru')
{
// Plain TEXT labels
label.text('Bears, vodka, balalaika');
}
else*/
label.html('<div class="map-tooltip"><h1 class="header">'+label.html()+'</h1><p class="description">Infected: '+infected_data[code]+'</p><p class="description">Deaths: '+death_data[code]+'</p></div>');
/*else if (code == 'us')
{
label.html(label.html()+' (GDP - '+sample_data[code]+')');
}*/
},
/*onRegionOver: function(event, code)
{
if (code == 'ca')
{
event.preventDefault();
}
}, */
});
});
</script>
</head>
Infected Data JS FIle:
var infected_dataINT = {};
var infected_data = {};
const url = "https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec";
// Declare an async function
const getData = async () => {
// Use the await keyword to let JS know this variable has some latency so it should wait for it to be filled
// When the variable is fetched, use the .then() callback to carry on
const DataJSON = await fetch(url).then(response =>
response.json()
)
return await DataJSON
};
console.log(getData());
getData().then(result => {
console.log(result);
infected_dataINT = result;
console.log(infected_dataINT);
function toString(o) {
Object.keys(o).forEach(k => {
if (typeof o[k] === 'object') {
return toString(o[k]);
}
o[k] = '' + o[k];
});
return o;
}
console.log(toString(infected_dataINT));
infected_data = toString(infected_dataINT);
})
How can i slow down the jQuery(document).ready(function () {.... to run only after <script type="text/javascript" src="js/jquery.vmap.sampledata.infected.js"></script> has ran
You can dynamically append the script element to the document after the response has been recieved from the server like this:
let script = document.createElement('script');
script.src = 'myJqueryFile.js';
document.head.appendChild(script);
You just have to put those jquery codes inside a .js file.
Sounds like an asynch problem...
Where do you close the header?
</head>
And where is your onload event to synchrinise things?
<body onload="Function_That_KickStarts_Everything();">
Please use the correct document structure and ensure everything begins with the ONLOAD event so that 3rd party libraries may all load and synchronize... follow this please:
<html>
<head>
<style type="text/css">
</style>
</head>
<body onload="Function_That_KickStarts_Everything();">
<script src="Third_Party_Library_1.js"></script>
<script src="Third_Party_Library_2.js"></script>
<script type="text/javascript">
</script>
</body>
</html>

Angular content not working in Kendo Tab Strip

I am not able to figure out why remove tab is not invoked when I use ng-click but it works fine in non Angular way! I referred help available in http://docs.telerik.com/kendo-ui/controls/navigation/tabstrip/how-to/AngularJS/add-new-tabs-dynamically.html.
I have written code in dojo.telerik.com/#datha_k/oNuBI. I'm clueless here, tried a lot, please help.
I think my issue related to this discussion at http://www.telerik.com/forums/use-angularjs-directive-in-tab-content 'The tabstrip widget does not support angularjs binding expressions'. Any work around to suggest?
Hi ,due to some reason i m unable to login in DOJO to edit ur code,below code will work -
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/tabstrip/index">
<style>
html {
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
}
</style>
<title></title>
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.2.714/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.2.714/styles/kendo.material.min.css" />
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.2.714/styles/kendo.default.mobile.min.css" />
<script src="//kendo.cdn.telerik.com/2016.2.714/js/jquery.min.js"></script>
<script src="//kendo.cdn.telerik.com/2016.2.607/js/angular.min.js"></script>
<script src="//kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example" ng-app="app-myapp" ng-controller="my-controller as my">
<button ng-click="newTab($event)">Click to add new tab</button>{{show}}
<hr />
<div kendo-tab-strip="tabstrip" id="tabstrip" k-options="tabOptions"></div>
</div>
<script>
function removeMeNonNg(e) {
e.preventDefault();
e.stopPropagation();
var item = $(e.target).closest(".k-item");
var tabstrip = $("#tabstrip").data("kendoTabStrip");
tabstrip.remove(item.index());
tabstrip.select(0);
}
angular.module("app-myapp", ["kendo.directives"]) // Create module and pass kendo dependency
.controller("my-controller", function ($scope, $timeout) { // Create controller
var index = 1;
$scope.tabOptions = {
dataTextField: "text",
dataContentField: "content",
dataSource: [{
text: index,
content: '<div>Hello World!</div>' + index
}]
}; // tabOptions
$scope.newTab = function newTab(event) {
index++;
$scope.tabstrip.append({
text: index + ' <button onclick="removeMeNonNg(event)">Remove me in non NG!</button> ',
encoded: false,
content: '<div><button ng-click="removeTab(\''+index+'\')">Remove me!</button>Hello World, Again!</div>' + index
});
}; // newtab
$scope.removeTab = function (index) {
$scope.tabstrip.remove(index-1);
};
$timeout(function () {
$("#tabstrip").data("kendoTabStrip").select(0);
}, 50);
});
</script>
</body>
</html>
The problem with your code are 2-
1)Either use jquery or ANgular for components or else u will face anonymous behaviour.I have corrected your code for appending tabs in angular kendo.
2)You have to call ng-click from content attribute and not text attribute of kendo-tabstrip

Backbone.js: Clicking U.I list elements to show them in a different section of the page

I am working on a project in Backbone.js were I get the results from a Food API and then display them. I have this piece of functionality working. The next piece of functionality I need is to be able to click an item from the results list and be able to save that result, showing it in the foods tracked list on the right side of the page. The foods tracked list would show the information about the Food (Food Name, Brand and Calories) as well as a total amount of calories from all the foods tracked. I am having trouble creating this functionality because I do not know how to click a list item and have it take the item information in the html list element and place it in another part of the page.
Here is my JSfiddle link- https://jsfiddle.net/Tiquismiquis/2nLezvmg/3/
Here is my JAVASCRIPT-
$(function(){
var SearchList = Backbone.Collection.extend({
initialize: function(){
this.bind("reset", function(model, options){
console.log("Inside event");
console.log(model);
});
},
//** 1. Function "parse" is a Backbone function to parse the response properly
parse:function(response){
//** return the array inside response, when returning the array
//** we left to Backone populate this collection
return response.hits;
}
});
// The main view of the application
var App = Backbone.View.extend({
el: 'body',
events: {
"input #searchBox" : "prepCollection",
"click li" : "track"
},
initialize: function () {
this.model = new SearchList();
this.prepCollection =_.debounce(this.prepCollection, 1000);
this.$list = $('#listing');
// this.saved =$('#tracked');
},
prepCollection: function(){
var name = $('input').val();
var newUrl = "https://api.nutritionix.com/v1_1/search/" + name + "?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name,brand_name,item_id,nf_calories&appId=26952a04&appKey=private_key";
if (name == ""){
this.$list.html("")
}
else{
this.model.url = newUrl;
this.model.fetch({
success: function (response, xhr) {
console.log("Inside success");
console.log(response.toJSON());
},
error: function (errorResponse) {
console.log(errorResponse)
}
});
this.listenTo(this.model, 'sync', this.render);
}
},
// track: function(){
// },
render: function(){
var terms = this.model;
var wordhtml = "";
terms.each(function (term) {
wordhtml = wordhtml + "<li>" +"<strong>" + term.get('fields')["item_name"] + '</strong>'+ ' ('+ term.get('fields')["brand_name"] + ')'+' - '+ term.get('fields')["nf_calories"] + ' Calories' + "</li>"
}, this);
this.$list.html(wordhtml);
}
});
var app = new App();
});
Here is my HTML-
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Food Guide App</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-6">
<h1>Interactive Food Guide</h1>
<input type="text" id="searchBox"> <br/><br/>
<ul id="listing"></ul>
</div>
<div class="col-xs-6">
<h1>Foods Tracked</h1>
<ul id="tracked"></ul>
<p id="total">total calories: <span>0</span></p>
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Backbone and Underscore -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
<!-- apps functionality -->
<script src="js/app.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
There are many ways to do it - through a backbone listView or simply by adding data-* attributes to the element.
Below is an example demonstrating the latter :
Template change :
var liTemplate = '<li data-brand="<%-data.brand_name%>" data-name="<%-data.item_name%>"><strong><%-data.item_name%> (<%-data.brand_name%>)</strong></li>';
wordhtml = _.template(liTemplate)({ data : term.get('fields')});
View change :
events:{
'click li': 'track'
},
track: function(e){
var $target = $(e.currentTarget);
var itemName = $target.attr('data-name');
var brandName = $target.attr('data-brand');
//do whatever you need
}
Find the working fiddle at https://jsfiddle.net/nitincool4urchat/2nLezvmg/8/

Errors when I use a fancytree instance

I am a newbie of using fancytree. I have created a demo to display data in a table within a webpage. Now I hope to collect the data back after users updated them.
I was using so called tree methods as mentioned in the tutorial. There is an example that has two lines below:
var tree = $("#tree").fancytree("getTree");
alert("We have " + tree.count() + " nodes.");
I thought I can use the fancytree instance, the variable 'tree' in the above example, to access all nodes so that to collect the values they take. But when I put this two-lines example into my codes, I got errors.
For making it clear, I pasted the complete code below. Close to the end of the code, there are two comments marked by Place_1 and Place_2. When I put the two-lines example in each of these two places, I got errors, which are "Uncaught TypeError: undefined is not a function", or "Uncaught Error: cannot call methods on fancytree prior to initialization; attempted to call method 'getTree'" respectively.
I thought I must missed something. Any idea will be helpful. Thanks!
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<link type="text/css" rel="stylesheet" href="addtionals/jquery-ui.css" />
<script src="addtionals/jquery.min.js" type="text/javascript"></script>
<script src="addtionals/jquery-ui.min.js" type="text/javascript"></script>
<link href="fancytree/src/skin-win8/ui.fancytree.css" rel="stylesheet" type="text/css">
<script src="fancytree/src/jquery.fancytree.js" type="text/javascript"></script>
<script src="fancytree/src/jquery.fancytree.edit.js" type="text/javascript"></script>
<script src="fancytree/src/jquery.fancytree.table.js" type="text/javascript"></script>
<script type="text/javascript">
var Rigid_Package_SOURCE = [
{title: "Role-Based Statements", key: "1", folder: true, expanded: true, children: [
{title: "Text1", key: "2"},
{title: "Text2", key: "3"}
]}
];
$(function(){
$("#RB_Statements_tree").fancytree({
source: Rigid_Package_SOURCE,
extensions: ["edit", "table"],
edit: {
triggerCancel: ["esc"],
triggerStart: ["f2", "dblclick", "shift+click", "mac+enter"],
beforeEdit: function(event, data){
if (data.node.isFolder() ) {
var title = data.node.title;
data.node.editEnd();
data.node.setTitle(title);
return false;
}
},
beforeClose: function(event, data){
if (data.node.isFolder()) {
}else{
if (data.input.val() == ""){
data.node.setTitle("");
}
}
}
},
table: {
indentation: 20,
nodeColumnIdx: 1
},
renderColumns: function(event, data) {
var node = data.node,
$tdList = $(node.tr).find(">td"),
$select = $("<select />");
if( node.isFolder() ) {
}else{
$("<option > Tutor </option>").appendTo($select);
$("<option selected > Student </option>").appendTo($select);
$("<option > Teacher </option>").appendTo($select);
$tdList.eq(0).html($select);
}
}
});
});
</script>
</head>
<body>
<script type="text/javascript">
//Place_1: Uncaught TypeError: undefined is not a function
//var tree = $("#RB_Statements_tree").fancytree("getTree");
//alert("We have " + tree.count() + " nodes.");
</script>
<!--The title of this page-->
<h4> Vicarious Conversation</h4>
<!-- Table: Role-Based Statements -->
<table id="RB_Statements_tree">
<colgroup>
<col width="100px">
<col width="300px">
</colgroup>
<thead>
<tr> <th></th> <th></th>
</thead>
<tbody>
</tbody>
</table>
<br>
<script type="text/javascript">
//Place_2: Uncaught Error: cannot call methods on fancytree prior to initialization; attempted to call method 'getTree'
//var tree = $("#RB_Statements_tree").fancytree("getTree");
//alert("We have " + tree.count() + " nodes.");
</script>
</body>
</html>
Thanks for the suggestion from Chase.
I think the two-lines example should be added into somewhere after the initialization has been finished.
For example, I added the codes into a button's body and it works well. Here is the example about implementing a button in fancytree: http://wwwendt.de/tech/fancytree/demo/#sample-source.html

jquery function is looping twice

Each value of my json object is getting added to "listOfCountries" twice. I don't understand why it would be looping through the result object twice. Any help would be appreciated!
var listOfCountries = []
$(document).ready(function () {
$.ajax({
url: '/Json/GetCountries',
type: 'GET',
success: function (result) {
$.each(result, function (name, value) {
listOfCountries.push(value.Country);
});
$("#countriesAutoComplete").kendoAutoComplete(listOfCountries);
}
});
});
Json object being sent over the wire:
[{"Country": "United States Of America"},{"Country": "Australia"},{"Country": "Britain"}]
html
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<p>
Country: <input id="countriesAutoComplete" class="k-input" />
</p>
</div>
<script type="text/javascript" src="~/Scripts/Custom.js"></script>
</body>
</html>
Every time your code runs, you add more strings to listOfCountries.
You never remove the strings from last time, so the global array keeps growing.
You probably shouldn't make it a global variable.

Categories

Resources