fetch and remove innerHTML from JSON using the same button - javascript

I have an external JSON file that looks like this:
[
{
"id": "1",
"label": "2017-03-30",
"value": "1675000",
"accessories": "true"
},
{
"id": "2",
"label": "2017-04-01",
"value": "1440000",
"accessories": "true"
},
{
"id": "3",
"label": "2017-04-02",
"value": "830000",
"accessories": "false"
}
]
I can fetch the JSON using the following button and it displays in the div ID of accessories:
<button id="button2">Get Customers</button>
<h1>Brands that sell Accessories:</h1>
<div id="accessories"></div>
The JavaScript I am using is:
document.getElementById('button2').addEventListener
('click', loadData);
function loadData(e) {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'data.json', true);
xhr.onload = function() {
if(this.status === 200) {
// console.log(this.responseText);
const customers = JSON.parse(this.responseText);
let output = '';
customers.forEach(function(customer) {
output += `
<ul>
<li>Company ID: ${customer.id}</li>
<li>Company label: ${customer.label}</li>
<li>Company value: ${customer.value}</li>
<li>Company Accessories: ${customer.accessories}</li>
</ul>
`;
})
document.getElementById('accessories').innerHTML = output;
}
}
xhr.send();
};
This outputs the company information in bullet points.
What I want to do next is remove the HTML by pressing the same button but I'm struggling to keep it removed.
I've tried:
function removeAcc() {
document.getElementById('accessories').innerHTML = '';
}
But it just flashes back to the same list.
Help will be very much appreciated.

you need to save the current state of your program somewhere so that you know if the "external JSON" was already loaded or not. This way you can switch the action in the eventListener like so:
document.getElementById('button2').addEventListener('click', toggleData);
function toggleData(e) {
if(hasData) {
removeAcc()
hasData = false;
} else {
loadData(e)
hasData = true;
}
}

Related

Javascript HTTP POST input JSON error

I am trying to add JSON request into a HTTP POST javascript code like below. Please see the code below.
My problem is, I need to input following format JSON and send it. But, I am getting Uncaught SyntaxError: Unexpected token : Could you please advise, What is wrong formatting JSON in my code below?
Sample JSON format to be sent=> {"records":[{"value":{"foo":"bar"}}]}
Code:
function savedata() {
var membernameStr = parseInt(document.getElementById("MemberID").value).toString();
var data = JSON.stringify({
"records": [["value":{"MemberID":membernameStr,"MemberName":"Anna", "AccountNo":"7623", "Address":"Peter", "AccountType":"Peter"}]]
});
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.status == 200) {
console.log(this.responseText);
// Based on successful response, call next POST API.
var xhr1 = new XMLHttpRequest();
xhr1.open("POST", "http://localhost:3500");
xhr1.send(data);
}
});
xhr.open("POST", "http://localhost:8082/topics/topictest");
xhr.setRequestHeader("Content-Type", "application/vnd.kafka.json.v2+json; charset=utf-8");
xhr.setRequestHeader("Accept", "application/vnd.kafka.v2+json; charset=utf-8");
xhr.send(data);
}
Your JSON was incorrect in the syntax, please have a look at below JSON:
{
"records": [
[
{
"value": {
"MemberID": membernameStr ,
"MemberName": "Anna",
"AccountNo": "7623",
"Address": "Peter",
"AccountType": "Peter"
}
}
]
]
}
why did you use array within array ? you can also use as below ..
{
"records": [
{
"value": {
"MemberID": membernameStr ,
"MemberName": "Anna",
"AccountNo": "7623",
"Address": "Peter",
"AccountType": "Peter"
}
}
]
}

Knockout bindings from JSON file

What am I doing wrong with my bindings? I simply get [object HTMLElement] returned for each one.
Please note this is a pared-down version and I will be wanting to access the full range of the JSON values.
Fiddle:
https://jsfiddle.net/0416f0s7/2/
Code:
<div data-bind="text: intro"></div>
function ViewModel(stories) {
var self = this;
self.stories = ko.observableArray(ko.utils.arrayMap(stories, function(story) {
return story.stories;
}));
};
$.getJSON('data.json', function(data) {
window.storyViewModel = new ViewModel(data.stories);
ko.applyBindings(window.storyViewModel);
});
JSON (filename data.json):
{
"stories": [
{
"intro": "Hi",
"outro": "Bye",
"elements": [
{
"title": "Title 1",
"image": "img/image1.jpg",
"paragraph": "Wordswordswords"
},
{
"title": "Title 2",
"image": "img/image2.jpg",
"paragraph": "More wordswordswords"
}
]
}
]
}
Your html change to
`<div data-bind="foreach:stories">
<div data-bind="text: intro"></div>
</div>
your code change to
function test(stories) {
var self = this;
self.stories = ko.observableArray(ko.utils.arrayMap(stories, function (story) {
return story;
}));
}

jQuery autocomplete suggests all options regardless of input entry

I have a jQuery script that will get a JSON response and create as many "player" objects as there are in the response.
It will then add to availablePlayers which I then use as the variable for the source: field of autocomplete
When a user selects a player name and clicks the "add" button it will, at the moment, just display the guid and name of a player.
However, no matter what letters I type, all the players are given as an option. To illustrate this, if I type "Z" and none of the players have Z in their name, they options are still displayed.
How can I refine this functionality?
HTML
<div class="player-widget">
<label for "players">Players</label>
<input id="player" />
<input id="playerGUID" hidden />
<button id="add">Add</button>
</div>
jQuery
$(document).ready(function(){
var availablePlayers = []; // BLANK ARRAY OF PLAYERS
$("#player").autocomplete({
source: availablePlayers,
response: function (event, ui) {
ui.content = $.map(ui.content, function(value, key) {
return {
label: value.name,
value: value.guid
}
});
},
focus: function(event, ui) {
$("#player").val(ui.item.label);
return false;
},
select: function (event, ui) {
$("#player").val(ui.item.label); // display the selected text
$("#playerGUID").val(ui.item.value); // save selected id to hidden input
return false;
}
});
$.getJSON("http://localhost/Websites/Player-Widgets/service.php", function(data) {
var feedHTML = '';
// LOOP THROUGH EACH PLAYER
$.each(data.players, function(i, player) {
// DEFINE VARIABLES - BASED ON PLAYER ATTRIBUTES
var guid = player.guid;
var name = player.name;
var dob = player.date_of_birth;
var birth = player.birthplace;
var height = player.height;
var weight = player.weight;
var position = player.position;
var honours = player.honours;
// CREATE NEW PLAYER (OBJECT)
var player = {
guid: guid,
name: name,
position: position
};
// ADD TO PLAYER TAG ARRAY
availablePlayers.push(player);
});
console.log("User friendly array");
$.each(availablePlayers, function(i, val) {
console.log(val.guid + " - " + val.name + " [" + val.position + "]");
});
console.log("Array printout");
console.log(JSON.stringify(availablePlayers));
}).done(function(){
console.log("Done! Success!");
$("#player").autocomplete("option", "source", availablePlayers);
});
$("#add").click(function() {
alert($("#playerGUID").val() + " - " + $("#player").val());
});
});
Sample JSON response
{
"players": [
{
"guid": "1",
"name": "Matias Aguero",
"date_of_birth": "1981-02-13",
"birthplace": "San Nicolas, Argentina",
"height": "1.83m (6' 0\")",
"weight": "109kg (17st 2lb)",
"position": "Prop",
"honours": "40 caps"
},
{
"guid": "2",
"name": "George Catchpole",
"date_of_birth": "1994-02-22",
"birthplace": "Norwich, England",
"height": "1.85em (6ft 1\")",
"weight": "104kg (16st 5lb)",
"position": "Centre",
"honours": ""
}
]
}
Your problem is in the source function.
Source function uses request to pass term param to query, and you are ignoring it.
If you're using availablePlayers to query, you should use
source: availablePlayers
and your current function to map {label, text} object in response parameter.
response: function (event, ui) {
ui.content = $.map(ui.content, function(value, key) {
return {
label: value.name,
value: value.guid
}
});
}

How to access HTML element attribute in jQuery JSON

I am trying to access the specific HTML element attribute and assign it to JSON property.
At first I get the JSON object from file and load it into settings. Then I go through the rows and create text inputs with various attributes.
Since I am using iris plugin, I am firing that right after. You can see that I am using changeElements function, where iris-id is being used (which works).
So the question is... why the color property in iris part is empty?
function startCorr(jsonFile) {
request = new XMLHttpRequest();
request.open('GET', jsonFile, true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
settings = JSON.parse(request.responseText);
$.each(settings, function(key, jsonRow) {
$(sidePanel).append(createInput(key, jsonRow));
});
// iris
$('.iris').iris({
color: $(this).attr("iris-color"), // doesn't work
width: 200,
border: false,
hide: false,
change: function(event, ui) {
changeElements($(this).attr("iris-id"), ui);
}
});
} else {
console.log("Error getting JSON file");
}
};
request.send();
}
function createInput(key, jsonRow) {
input = "<label>" + jsonRow.name + "<input type='text' class='iris' id='" + jsonRow.section + "' ";
input += "iris-color='" + getColor(jsonRow.selectors[0]) + "' iris-id='" + key + "'>";
input += "</label>"
return input;
}
function getColor(selectorObject) {
return $(selectorObject.selector).css(selectorObject.style);
}
JSON
[
{
"name": "Global text",
"section": "text-global",
"input": "color",
"selectors": [
{
"selector": ".button.special",
"style": "background-color"
},
{
"selector": ".button.notSoSpecial",
"style": "color"
}
],
"areas": ["homepage", "detail", "category", "basket"]
},
{
"name": "Text on hover",
"section": "text-hover",
"input": "color",
"selectors": [
{
"selector": "#banner p",
"style": "color"
}
],
"areas": ["homepage", "detail", "category", "basket"]
}
]
When you need to access data specific to an element to pass into the options of a plugin one very common approach is to initialize the plugin within a $.each loop. Within the loop this is the current element
$('.iris').each(function() {
var $el = $(this);
$el.iris({
color: $el.attr("iris-color"),
width: 200,
border: false,
hide: false,
change: function(event, ui) {
changeElements($el.attr("iris-id"), ui);
}
});
});

Ajax call loop only one object

I have the following ajax call but instead to show me all objects it shows me only the last object from json file. Why is this?
Ajax Call
var ajax = new XMLHttpRequest();
var data = 'data.json';
var url = 'http://localhost:8888/';
ajax.onreadystatechange = function() {
if (ajax.readyState === 4 ) {
if(ajax.status === 200){
callback(ajax.responseText);
} else if(ajax.status === 400) {
console.warn('404');
} else {
console.warn('bad' + ajax.responseText);
}
}
};
ajax.open('GET', url+data, true);
ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
ajax.setRequestHeader('Access-Control-Allow-Origin', '*');
ajax.send(data);
JSON
{
"video": {
"mp4": "http://localhost:8888/500x.mp4",
"webm": "http://localhost:8888/500x.webm",
"title": "video1" },
"video": {
"mp4": "http://localhost:8888/dodge.mp4",
"webm": "http://localhost:8888/dodge.webm",
"title": "video2" },
"video": {
"mp4": "http://localhost:8888/500x.mp4",
"webm": "http://localhost:8888/500x.webm",
"title": "video3" }
}
Callback function where getVideoURL is my Ajax Call Function
inject : function(tabId, infos, tab){
if(doner.activated && infos.status === 'complete' && doner.filters.isYoutubeUrl(tab.url)){
doner.getVideoUrls(function(data){
chrome.tabs.executeScript(tabId,{
code : '!function(e){"use strict";console.debug("starting injection");var t=document.createElement("script");t.src=chrome.extension.getURL("scripts/injectedScript.js"),t.onload=function(){this.parentNode.removeChild(this)},(document.head||document.documentElement).appendChild(t);var o=document.getElementById("extAdd");o&&o.parentNode&&(console.log("removing",o),o.parentNode.removeChild(o));var n=document.createElement("iframe");document.getElementById("player-api").setAttribute("style","padding:0;");n.id="extAdd",n.setAttribute("style","border-style:none;-webkit-appearance:none;border:0;outline:none;"),n.className="html5-video-player el-detailpage ps-null hide-info-bar autohide-controls-aspect autohide-controls-fullscreen autominimize-progress-bar-non-aspect ad-created endscreen-created captions-created captions-loaded ytp-block-autohide paused-mode",n.setAttribute("allowfullscreen","true"),n.src=chrome.extension.getURL("iframe/iframe.html?id="+e);var d=document.getElementById("player-api");d.insertBefore(n,d.childNodes[0]);}("' + encodeURIComponent(JSON.stringify(data)) + '");',
runAt: 'document_start'
}, function(){
// get the popup and increase the watched value
chrome.storage.local.get({ 'watched' : 0 },function(item){
console.log(item);
chrome.storage.local.set({'watched':item.watched + 1});
});
console.log('injected');
});
});
}
}
Your JSON is an object, and the property video is declared three times. So the last declaration stay in the memory.
Maybe you should change your JSON structure and use an array :
[
{
"video": {
"mp4": "http://localhost:8888/500x.mp4",
"webm": "http://localhost:8888/500x.webm",
"title": "video1"
}
},
{
"video": {
"mp4": "http://localhost:8888/dodge.mp4",
"webm": "http://localhost:8888/dodge.webm",
"title": "video2"
}
},
{
"video": {
"mp4": "http://localhost:8888/500x.mp4",
"webm": "http://localhost:8888/500x.webm",
"title": "video3"
}
}
]

Categories