Related
I wrote a custom Google Script which outputs an object for me and I would like to be able to call it and assign it to a variable which is then used to display data on a website.
HTML Header:
<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) {
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>');
}
});
});
</script>
</head>
Google Scripts File:
function doGet() {
var result = {};
var infected = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getDataRange().getValues();
var death = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data').getDataRange().getValues();
result = makeObject(infected);
return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON);
}
function makeObject(multiArr) {
var obj = {};
var countrystats = {};
var headers = multiArr.shift();
for (var i = 0; i < headers.length; i++) {
countrystats[i] = multiArr.map(function (app) {
return app[i];
})
}
for (var m = 0; m < countrystats[1].length; m++) {
obj[countrystats[1][m]] = 0;
}
for (var j = 0; j < countrystats[1].length; j++) {
var TempVar;
TempVar = obj[countrystats[1][j]];
obj[countrystats[1][j]] = TempVar + countrystats[3][j];
}
return obj;
}
Google Scripts Output (using the JSON View chrome extension):
{
cn: 8134,
th: 23,
mo: 7,
us: 5,
jp: 11,
kr: 4,
sg: 10,
vn: 2,
fr: 5,
np: 1,
my: 8,
ca: 3,
ci: 1,
lk: 1,
au: 9,
de: 4,
fn: 1
}
This is a public link with the object/data i want on it (the same object shown above):web app: https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec
So basically anyone who uses it should be able to access it. I just need a way to assign that data to a local JS variable. The google sheets script is published as a web app. If I'm not mistaken there is a setting to allow anyone, even anonymous to access it.
Here is my attempt at an AJAX request:
var url = "https://script.google.com/macros/s/AKfycbzsyQNJwDvQc5SvNGEDZZOoNI3XxNar9PA9sRucZx7mgzfWpFQ/exec";
var infected_data = jQuery.ajax({
crossDomain: true,
url: url,
method: "GET",
//dataType: "jsonp"
});
If I uncomment the jsonp I get an error:
jquery-1.11.3.min.js:5 Cross-Origin Read Blocking (CORB) blocked cross-origin response https://script.googleusercontent.com/macros/echo?user_content_key=JXkCjiJjhcjndRREjoGyVNkZNkD-HvKpEPkpicQBm9nR9OkxjGXdYuOPsLxbJf-B9Rgifl5NWMtzgjfVGuMdGxTJrjKnRpdcOJmA1Yb3SEsKFZqtv3DaNYcMrmhZHmUMWojr9NvTBuBLhyHCd5hHazTNYZyoqG0ZuVXpWSNdoeLErB4AfUCNPKJHgELe5WaAmN5SlwIhonlWkkbFzR8kUwjKrMtdq9u-YqreD7W_KJ_aVqKVBTehAuogPCoZCfVc4yJf5ieDCdMDbXQ8FZZq8iSedsk1Px1LnPBLM8W-ZRcknnbJNT8dS525XG1pNEBR&lib=Mw_Scq3iKhByBS86NJpd_CngcdEShCw7K with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.
I don't get any errors if i remove it. However, i still can't see the data on my interactive map (My application).
Using Fetch:
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()
).then(parsedResponse => parsedResponse)
return await DataJSON
};
console.log(getData());
var infected_data = getData();
Converting Integers in object to Strings
The object needs to be in a format like this:
var infected_data = {
cn: "83",
th: "0",
mo: "0",
au: "0",
sg: "0",
tw: "0",
us: "0",
jp: "0",
my: "0",
kr: "0",
fx: "0",
vn: "0",
kh: "0",
ca: "0",
ci: "0",
np: "0",
lk: "0",
};
You're likely having issues with the call being asynchronous, which would mean you're reading the data before it is actually returned from Google's servers. Try using promises and the fetch API
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()
).then(parsedResponse => parsedResponse)
return await DataJSON
};
console.log(await getData())
Assuming the data is not sensitive, You could use jsonp to bypass cors:
Server side:
return ContentService.createTextOutput("infect(" +JSON.stringify(result)+ ")").setMimeType(ContentService.MimeType.JAVASCRIPT);
Client side:
<script>function infect(data){ infectedData = data }</script>
<script src="URL_OF_YOUR_SCRIPT"></script>
References:
Jsonp
Same origin policy
Answering the Question to Convert Integers to Strings:
Try something like this:
function toString(o) {
Object.keys(o).forEach(k => {
if (typeof o[k] === 'object') {
return toString(o[k]);
}
o[k] = '' + o[k];
});
return o;
}
I am using select2 in an express app to make an input box where users can select subjects from a list, and can update this list with any newly added options.
The thing I'm struggling with is that select2 runs client-side, whereas any data I use to seed my <option> tags (that I want to append new options to) is server-side.
I want users to be able to add subjects that don't exist in the original list, so that future users will be presented with newly added options (as well as the original ones)
These are the options I've considered for achieving this (in increasing desirability):
Add new <option>Subject</option> html tags for each added tag
Push new tags to an array, and seed the <option>s from this array
Seed the <option> from a json object, and update this object on tag creation
Seed the <option> from an external database (e.g. mongoose), and update this on tag creation
As far as I can see, all of these options require that my client-side code (select2-js) talks to server-side code (where my array, .json file or mongoose schema would be), and I have no idea how to go about doing this.
In my current approach I am attempting to to specify a "local" json file as my data source in my select2 call (see here). However, this doesn't seed the database with any options, so this isn't working as I expected.
I then check if each new tag exists in an array (dataBase), and add it to the database if not:
// Data to seed initial tags:
var dataBase = [
{ id: 0, text: 'Maths'},
{ id: 1, text: 'English'},
{ id: 2, text: 'Biology'},
{ id: 3, text: 'Chemistry'},
{ id: 4, text: 'Geography'}
];
$(document).ready(function() {
$('.select2-container').select2({
ajax: {
url: '../../subjects.json',
dataType: 'json',
},
width: 'style',
multiple: true,
tags: true,
createTag: function (tag) {
var isNew = false;
tag.term = tag.term.toLowerCase();
console.log(tag.term);
if(!search(tag.term, dataBase)){
if(confirm("Are you sure you want to add this tag:" + tag.term)){
dataBase.push({id:dataBase.length+1, text: tag.term});
isNew = true;
}
}
return {
id: tag.term,
text: tag.term,
isNew : isNew
};
},
tokenSeparators: [',', '.']
})
});
// Is tag in database?
function search(nameKey, myArray){
for (var i=0; i < myArray.length; i++) {
if (myArray[i].text.toLowerCase() === nameKey.toLowerCase()) {
return true
}
}
return false
};
However, this approach will add the new tags to an array that is destroyed once I refresh the page, and new tags are not stored.
How can I modify this to load server-side data (json, mongoose document or anything else that is considered a best practice), and update this data with newly added options (that pass my tests)?
On your server-side, you can have an api that maintains and returns the tag array.
If you want the array to persist even after server shutdown, you can store the tags array in a database.
Server side:
let dataBase = [
{ id: 0, text: 'Maths'},
{ id: 1, text: 'English'},
{ id: 2, text: 'Biology'},
{ id: 3, text: 'Chemistry'},
{ id: 4, text: 'Geography'}
];
//Assuming you have a nodejs-express backend
app.get('/tags', (req,res) => {
res.status(200).send({tags: dataBase});
} );
Client Side:
$(document).ready(function() {
dataBase=[];
$.get("YOUR_SERVER_ADDRESS/tags", function(data, status){
console.log("Data: " + data + "\nStatus: " + status);
dataBase = data;
});
$('.select2-container').select2({
data: dataBase,
placeholder: 'Start typing to add subjects...',
width: 'style',
multiple: true,
tags: true,
createTag: function (tag) {
var isNew = false;
tag.term = tag.term.toLowerCase();
console.log(tag.term);
if(!search(tag.term, dataBase)){
if(confirm("Are you sure you want to add this tag:" + tag.term)){
dataBase.push({id:dataBase.length+1, text: tag.term});
isNew = true;
//Update the tags array server side through a post request
}
}
return {
id: tag.term,
text: tag.term,
isNew : isNew
};
},
tokenSeparators: [',', '.']
})
});
// Is tag in database?
function search(nameKey, myArray){
for (var i=0; i < myArray.length; i++) {
if (myArray[i].text.toLowerCase() === nameKey.toLowerCase()) {
return true
}
}
return false
};
You can use select2:select and select2:unselect event for this.
var dataBase = [{
id: 0,
text: 'Maths'
},
{
id: 1,
text: 'English'
},
{
id: 2,
text: 'Biology'
},
{
id: 3,
text: 'Chemistry'
},
{
id: 4,
text: 'Geography'
}
];
$(document).ready(function() {
$('.select2-container').select2({
data: dataBase,
placeholder: 'Start typing to add subjects...',
width: 'style',
multiple: true,
tags: true,
createTag: function(tag) {
return {
id: tag.term,
text: tag.term,
isNew: true
};
},
tokenSeparators: [',', '.']
})
$(document).on("select2:select select2:unselect", '.select2-container', function(e) {
var allSelected = $('.select2-container').val();
console.log('All selected ' + allSelected);
var lastModified = e.params.data.id;
console.log('Last Modified ' + lastModified);
var dbIdArray = dataBase.map((i) => i.id.toString());
var allTagged = $('.select2-container').val().filter((i) => !(dbIdArray.indexOf(i) > -1))
console.log('All Tagged ' + allTagged);
});
});
.select2-container {
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<select class="select2-container"></select>
Here's what I've ended up with (thanks to both answers):
1. Set up a Mongoose DB to hold subjects:
models/subjects.js
var mongoose = require("mongoose");
var SubjectSchema = new mongoose.Schema({
subject: { type: String },
});
module.exports = mongoose.model("Subjects", SubjectSchema);
2. Set up api routes in node js express backend:
routes/api.js
var express = require("express");
var router = express.Router();
var Subjects = require("../models/subjects");
// GET route for all subjects in db
router.get("/api/subjects/all", function(req, res){
Subjects.find().lean().exec(function (err, subjects) {
return res.send(JSON.stringify(subjects));
})
});
// POST route for each added subject tag
router.post("/api/subjects/save", function(req, res){
var newSubject = {};
newSubject.subject = req.body.subject;
console.log("Updating db with:" + newSubject);
var query = {subject: req.body.subject};
var options = { upsert: true, new: true, setDefaultsOnInsert: true };
// Find the document
Subjects.findOneAndUpdate(query, options, function(error, subject) {
if (error) return;
console.log("Updated db enry: " + subject);
});
return res.send(newSubject);
});
3. Set up select2 input field:
public/js/select2.js
var dataBase=[];
$(document).ready(function() {
// Get all subjects from api (populated in step 2) and push to dataBase array
$.getJSON('/api/subjects/all')
.done(function(response) {
$.each(response, function(i, subject){
dataBase.push({id: subject._id, text: subject.subject});
})
console.log("dataBase: " + dataBase);
})
.fail(function(err){
console.log("$.getJSON('/api/subjects/all') failed")
})
// Get data from api, and on 'selecting' a subject (.on("select2:select"), check if it's in the dataBase. If it is, or the user confirms they want to add it to the database, send it to POST route, and save it to our Subjects db.
$('.select2-container')
.select2({
ajax: {
url : "/api/subjects/all",
dataType: 'json',
processResults: function (data) {
return {
results: $.map(data, function(obj) {
return { id: obj._id, text: obj.subject };
})
};
}
},
placeholder: 'Start typing to add subjects...',
width: 'style',
maximumSelectionLength: 5,
multiple: true,
createTag: function(tag) {
return {
id: tag.term,
text: tag.term.toLowerCase(),
isNew : true
};
},
tags: true,
tokenSeparators: [',', '.']
})
.on("select2:select", function(e) {
if(addSubject(dataBase, e.params.data.text)){
console.log(e.params.data.text + " has been approved for POST");
ajaxPost(e.params.data.text)
} else {
console.log(e.params.data.text + " has been rejected");
var tags = $('#selectSubject select').val();
var i = tags.indexOf(e.params.data.text);
console.log("Tags: " + tags);
if (i >= 0) {
tags.splice(i, 1);
console.log("post splice: " + tags);
$('select').val(tags).trigger('change.select2');
}
}
})
function ajaxPost(subject){
console.log("In ajaxPost");
var formData = {subject : subject}
$.ajax({
type : "POST",
contentType : "application/json",
url : "/api/subjects/save",
data : JSON.stringify(formData),
dataType : 'json'})
.done(console.log("Done posting " + JSON.stringify(formData)))
.fail(function(e) {
alert("Error!")
console.log("ERROR: ", e);
});
}
function addSubject(subjects, input) {
if (!input || input.length < 3) return false
var allSubjects = [];
$.each(subjects, function(i, subject){
if(subject.text) allSubjects.push(subject.text.toLowerCase())
});
console.log("Here is the entered subject: " + input);
if(allSubjects.includes(input)){
console.log(input + " already exists")
return true
}
if(confirm("Are you sure you want to add this new subject " + input + "?")){
console.log(input + " is going to be added to the database");
return true
}
console.log(input + " will NOT to added to the database");
return false
}
});
This works, but I would love to hear feedback on this approach!
I'm working of this code,
<script>
autocompleteRemote = new Backbone.AutocompleteList({
url: function() { return 'http://ws.audioscrobbler.com/2.0/?method=artist.search&api_key=cef6d600c717ecadfbe965380c9bac8b&format=json&' + $.param({ artist: $('form#autocomplete-remote input[name=search]').val() }); },
filter: null,
el: $('form#autocomplete-remote input[name=search]'),
template: _.template('<p><%= name.replace(new RegExp("(" + $("form#autocomplete-remote input[name=search]").val() + ")", "i") ,"<b>$1</b>") %></p>'),
delay: 500,
minLength: 3,
value: function(model) { return model.get('name') },
}).resultsView.collection.parse = function(resp) {
return resp.results.artistmatches.artist;
};
</script>
But I'm trying to connect it to the tmdb api like this,
autocompleteRemote = new Backbone.AutocompleteList({
url: function() {
return 'http://api.themoviedb.org/3/search/movie?api_key=' + api + '&' + $.param({query: $('form#autocomplete-remote input[name=search]').val()})
},
filter: null,
el: $('form#autocomplete-remote input[name=search]'),
template: _.template(
'<p><%= name.replace(new RegExp("(" + $("form#autocomplete-remote input[name=search]").val() + ")", "i") ,"<b>$1</b>") %></p>'
),
delay: 500,
minLength: 3,
value: function(model) { return model.get('name') }
,
})
.resultsView.collection.parse = function(resp) {
return resp.results.moviematches.query;
};
var api = 'a8f7039633f206xx42cd8a28d7cadad4'
As you can see I changed a few things like the url and put the api key in a var to clean up the code a bit. I also changed the word artist to query so it would give me back the right url. But I'm getting a error in the console log and I'm drawing a blanc.
Uncaught TypeError: Cannot read property 'query' of undefined
Backbone.AutocompleteList.resultsView.collection.parse
.extend.set
options.success
fire
self.fireWith
done
callback
The source material can be found here -> http://aghull.github.io/coding/2013/03/09/Backbone-autocomplete-lists/ Autocomplete using remote Collection
Here is a nice resource which will help to find out response body. As I can see from test response generated there, there is no moviematches property. You need resp.results which is just a collection (array) of objects (movies I guess).
So you need to change your code to:
var api = 'a8f7039633f206xx42cd8a28d7cadad4';
autocompleteRemote = new Backbone.AutocompleteList({
url: function() {
return 'http://api.themoviedb.org/3/search/movie?api_key=' + api + '&' + $.param({query: $('form#autocomplete-remote input[name=search]').val()})
},
filter: null,
el: $('form#autocomplete-remote input[name=search]'),
template: _.template(
'<p><%= name.replace(new RegExp("(" + $("form#autocomplete-remote input[name=search]").val() + ")", "i") ,"<b>$1</b>") %></p>'
),
delay: 500,
minLength: 3,
value: function(model) { return model.get('name') }
,
}).resultsView.collection.parse = function(resp) {
return resp.results;
};
I tried to make a comment but it became an answer :)
Edit:
Use this fiddle for tests. Place correct API_KEY and try again. I have tried with your existing api_key, but it's invalid.
I have a strange behavior of extjs file upload.
The file upload defined as:
items: [{
xtype: 'filefield',
itemId: 'uploadandsign',
buttonText: NG.getLabel('browse'),
buttonOnly: true,
hideLabel: true,
width: 100
}]
If the file uploading is success I show successful label on the screen with remove "X" button:
onOpenFileBrowserChange: function (filefield, newValue, oldValue, eOpts) {
var me = this,
form = filefield.up('form').getForm(),
infoBox = invoiceorigin.down('#fileuploadinfoplaceholder'),
fileDescription,
secondfilefield,
customerFileName = newValue.replace(/^.*[\\\/]/, ''),
draft = me.getDraft(),
isSigned = true,
files = draft.files();
if (filefield.itemId === 'uploadandsign') {
isSigned = false;
secondfilefield = invoiceorigin.down('#uploadnosign');
fileDescription = 'File system, Unsigned';
}
secondfilefield.disable();
if (form.isValid()) {
form.submit({
url: NG.getLatestApiPath('WebInvoice', 'UploadInvoiceFile'),
waitMsg: NG.getLabel('webinvoiceInvoiceOriginUploadingFile'),
success: function (fp, o) {
if (o.result.success) {
var file = o.result.file;
files.add({
fileName: file.fileName,
createDate: file.createDate,
isAttachment: false,
isSigned: isSigned,
fileOrigin: fileDescription,
customerFileName: customerFileName,
invoiceFileOrigin: 'Local'
});
filefield.disable();
infoBox.removeAll();
infoBox.add(Ext.create('NG.view.webinvoice.InformationBox', {
data: {
closable: true,
icon: true,
iconCls: 'n-pdf-icon',
content: '<div class="n-text-overflow" style="width:145px;">' + fileDescription + '<br/>' + customerFileName + '</div>'
}
}));
}
else {
}
},
failure: function (form, action) {
}
});
}
return false;
},
Then if I remove the file from #infobox, the reset() function called:
onRemoveFileClick: function (view) {
var me = this,
invoiceorigin = view.up('invoiceorigin'),
uploadNoSignBtn = invoiceorigin.down('#uploadnosign'),
uploadAndSignBtn = invoiceorigin.down('#uploadandsign'),
infoBox = invoiceorigin.down('#fileuploadinfoplaceholder'),
draft = me.getDraft(),
files = draft.files(),
pagemanager = view.up('webinvoicepagemanager'),
invoiceFilePlace = files.findExact('isAttachment', false);
me.deleteFileConfirmReject(
NG.getLabel('webinvoiceInvoiceOriginDeleteInvoiceFileTitle'),
NG.getLabel('webinvoiceInvoiceOriginDeleteInvoiceFileMsg'),
function (buttonId, text, opt) {
if (buttonId == 'yes') {
infoBox.removeAll();
if (invoiceFilePlace > -1) {
files.removeAt(invoiceFilePlace);
}
me.fillInvoiceOriginStep(pagemanager);
uploadNoSignBtn.reset();
uploadAndSignBtn.reset();
uploadNoSignBtn.enable();
uploadAndSignBtn.enable();
}
});
}
After this action if I will choose the same file.... nothing happens with page... no any change event fired on the page.. However if I choose different file the behavior is OK.
In the ExtJS documentation said that the reset() function have to clear previous files uploads... however it does not helps.
Is any body met such file upload ExtJS behaivour and could help with this issue?
Thanks a lot.
What I tried and worked quite good was to get the file from the form with a typical JS document.getElementsByName('[name you gave]'); and it got perfectly the file uploaded without mattering in wich execution you are in.
Hope it helps.
Below is my code where getJSON method is not working
function loadJson() {
$(document).ready(function () {
alert("inside");
var chart;
var url = "values.json";
var seriesData = [];
var xCategories = [];
var i, cat;
alert("outside");
$.getJSON(url, function (data) {
alert("inside JSON function");
for (i = 0; i < data.length; i++) {
cat = '' + data[i].period_name;
if (xCategories.indexOf(cat) === -1) {
xCategories[xCategories.length] = cat;
}
}
for (i = 0; i < data.length; i++) {
if (seriesData) {
var currSeries = seriesData.filter(function (seriesObject) {
return seriesObject.name == data[i].series_name;
}
);
if (currSeries.length === 0) {
seriesData[seriesData.length] = currSeries = { name: data[i].series_name, data: [] };
} else {
currSeries = currSeries[0];
}
var index = currSeries.data.length;
currSeries.data[index] = data[i].period_final_value;
}
else {
seriesData[0] = { name: data[i].series_name, data: [data[i].period_final_value] }
}
}
//var chart;
//$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: xCategories
},
yAxis: {
//min: 0,
//max: 100,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: false,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -100,
verticalAlign: 'top',
y: 20,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>'
}
},
series: seriesData
});
});
});
}
In url , values.json is my JSON file as follows
[{"series_name":"Actual","period_name":"Q1 / 2013","period_final_value":17},
{"series_name":"Actual","period_name":"Q2 / 2013","period_final_value":15},
{"series_name":"Actual","period_name":"Q3 / 2013","period_final_value":13},
{"series_name":"Actual","period_name":"Q4 / 2013","period_final_value":19},
{"series_name":"Alarm","period_name":"Q1 / 2013","period_final_value":14.103},
{"series_name":"Alarm","period_name":"Q2 / 2013","period_final_value":14.404499999999999},
{"series_name":"Alarm","period_name":"Q3 / 2013","period_final_value":14.966999999999999},
{"series_name":"Alarm","period_name":"Q4 / 2013","period_final_value":50},
{"series_name":"Target","period_name":"Q1 / 2013","period_final_value":15.67},
{"series_name":"Target","period_name":"Q2 / 2013","period_final_value":16.005},
{"series_name":"Target","period_name":"Q3 / 2013","period_final_value":16.63},
{"series_name":"Target","period_name":"Q4 / 2013","period_final_value":100}]
file renders but data is not shown on chart, only the alert outside the getJSON method works, inner one doesnot works, the same code if I try to run from html page then it works fine, but now I have written the entire code as it is in VS in ASP.NET Web Application and I have called the loadJson function on body onLoad in javascript as follows,
<body onload="loadJson();">
but the method doesn't run,
not able to solve this, any help will be greatly appreciated...
----------Additional work------
when I add my JSON data in any variable above the getJSON method and eliminate the getJSON method and access that then I get the Graph properly but when I am using getJSON method then it's not working
-----Error Inspected----------
I inspected the error in chrome and I got to know it is not able to get the json file, I have kept the JSON file in project folder , then also I tried by keeping the json file in localhost, still its saying same error..
Now I am thinking I am facing problem with mime type handling with aspx page..is it anything to link with it..??
1) Make sure you are using a valid json: www.jsonlint.com
2) Run your json file on localhost. Tell me if you see the json file on your browser run on localhost. Make sure you have this in your web.config
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
3) Alert info using getJSON function
$(document).ready(function () {
$.getJSON("values.json", function (data) {
$.each(data, function () {
alert(this.series_name);
});
});
});
4) When you pass these tests, continue building up your jQuery codes.
Is there any error with the call of file?
try the following:
$.getJSON(url)
.done(function(data) {
alert("INSIDE FUNCTION")
})
.fail(function(jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
I use this coding style mostly for all jquery ajax (and wrapper) calls, so that I can give the user a response if
the request failed.
Use $.getJSON not $.get like,
$.getJSON(url, function (data) {
alert("inside JSON function");
And Check your json is valid or not (Check a JSON tab is there in your console)
http://jsonlint.com/ found an issue with your JSON
[{"series_name":"Actual","period_name":"Q1 / 2013","period_final_value":17},
{"series_name":"Actual","period_name":"Q2 / 2013","period_final_value":15},
{"series_name":"Actual","period_name":"Q3 / 2013","period_final_value":13},
{"series_name":"Actual","period_name":"Q4 / 2013","period_final_value":19},]
Its not a valid JSON because of the , just before the ] bracket.