JSON and HTML troubles - ajax

i'm currently having some troubles with displaying the information from a JSON file to html. I'm currently using AJAX to get the data from the JSON file.
The main problem that i'm facing is with displaying all the data into one div.
function Test(){
request.open('GET','/json/anime.json');
request.onreadystatechange = function() {
if((request.readyState===4) && (request.status===200)) {
var json = JSON.parse(request.responseText);
for(var title in json.Title ) {
for(var ep in json.Episode) {
for(var img in json.Image) {
for(var link in json.Link) {
_title = json.Image[title];
episode = json.Image[ep];
image = json.Image[img];
_link = json.Image[link];
var div = document.createElement('div');
div.className = 'card card-inverse';
div.innerHTML = `<img class="card-img img-fluid img-responsive" src="${image}" data-toggle="modal">`;
document.getElementById('anime').appendChild(div);
}
}
}
}
}
}
request.send();
}
The JSON file looks like this...
{
Episode: [
...
],
Image: [
...
],
Link: [
...
],
Title: [
...
]
}
The way above is working if i'm only looping over one of the four arrays, however crashes chrome when trying to do the above task.
Any help would be appreciated.
Thanks

I decided to take a different approach moving away from ajax a little and moving more towards jquery. Below is what has so far worked out for me. Thanks to the people who commented above, really helped me think of ways to tackling it.
function DisplayCards() {
var i = 0;
$.getJSON('/json/anime.json', function(data) {
$.each(data, function(index) {
for(key in data[index]){
e = data.Image.length;
console.log(e);
if(i < e)
{
image = data.Image[key];
link = data.Link[key];
console.log(i += 1);
var div = document.createElement('div');
div.className = 'card card-inverse';
div.innerHTML = `<img class="card-img img-fluid img-responsive" src="${image}" data-toggle="modal">`;
var p = document.createElement('p');
p.innerHTML = 'id="wrapper" class="text"';
document.getElementById('anime').appendChild(div);
}
}
console.log(data);
});
});
}

Related

Dropzone createThumbnailFromUrl() issue

I need to add pre-existing image files to dropzone by using Laravel 5.4. This is why I use createThumbnailFromUrl() function. But it does not generate images properly. Instead it shows them in blank way. I used that link (jsfiddle) for that purpose. I googled a lot, tried several ways, but it did not help:
Below is my code:
<script type="text/javascript" src='{{asset("js/dropzone/min/dropzone.min.js")}}'></script>
<script type="text/javascript">
Dropzone.options.addImages = {
paramName: "file", // The name that will be used to transfer the file
addRemoveLinks: true,
// The setting up of the dropzone
init:function() {
// Add server images
var myDropzone = this;
var existingFiles = [
{ name: "Filename 1.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' },
{ name: "Filename 2.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' },
{ name: "Filename 3.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' },
{ name: "Filename 4.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' },
{ name: "Filename 5.pdf", size: 12345678,imageUrl:'http://img.tfd.com/wn/93/17E8B3-awful.png' }
];
for (i = 0; i < existingFiles.length; i++) {
// alert(existingFiles[i].imageUrl);
myDropzone.emit("addedfile",existingFiles[i]);
myDropzone.files.push(existingFiles[i]);
myDropzone.createThumbnailFromUrl(existingFiles[i], existingFiles[i].imageUrl, function() {
myDropzone.emit("complete", existingFiles[i]);
}, "anonymous");
}
},
};
</script>
Here is the result :( :
P.S: Any kind of help would be appreciated.
had the same issue with dropzone 5.3
this fixed it for me
let mockFile = { name: "Loaded File", dataURL: relURL };
dropzoneInst.files.push(mockFile);
dropzoneInst.emit("addedfile", mockFile);
dropzoneInst.createThumbnailFromUrl(mockFile,
dropzoneInst.options.thumbnailWidth,
dropzoneInst.options.thumbnailHeight,
dropzoneInst.options.thumbnailMethod, true, function (thumbnail)
{
dropzoneInst.emit('thumbnail', mockFile, thumbnail);
});
dropzoneInst.emit('complete', mockFile);
I am attaching for reference my solution, based on many previous answers, but mostly on Raphael Eckmayer. This is how it is done to make it work well with Django 3.0.5 and dropzone.js 5.7.0. Maybe it is not the best solution, but it works.
I am sending my current images from Django view using new template tag json_script that packs my list of files prepared in Django into JSON. Basically in my template I have this:
{{ images|json_script:"images" }}
Then I process this in my script. Here is entire script from my site, hope that will help someone.
EDIT:
I had an issue with this code that if I add new pictures to the dropzone together with the old one from database I got this form submitted twice. In first pass I get pictures from dropzone.js, but also all fields since I am copying them from the form. And then, on second pass, I am submitting form again but now without pictures. My view actually was handling this well and storing data, but when I started to write down how to handle removed pictures on form edit I had issue with this, so I decided to handle this differently. Please note that code is now changed and instead of submitting form twice I am sending entire form and pictures with dropzone, but after successmultiple I am just redirecting to other page. Everything is updated and stored then. So the change is in the successmultiple part.
<script type="text/javascript">
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
Dropzone.autoDiscover = false;
var first_time = true;
var old_images = JSON.parse(document.getElementById('images').textContent)
var myDropzoneX = new Dropzone("div#mydropzone", {
autoProcessQueue: false,
url: "{% url 'site_report_edit' report_id=1 %}",
addRemoveLinks: true,
thumbnailWidth: 400,
thumbnailHeight: 400,
uploadMultiple: true,
parallelUploads: 12,
init: function() {
var myDropzone = this;
var addButton = document.getElementById("submit-btn");
if (old_images) {
console.log(old_images);
for (x in old_images) {
var mockFile = {
name: old_images[x].name,
size: old_images[x].size,
kind: 'image',
dataURL: old_images[x].urlich,
accepted: true
}
myDropzone.files.push(mockFile);
myDropzone.emit('addedfile', mockFile);
createThumbnail(mockFile);
console.log(old_images[x].name, old_images[x].urlich);
}
function createThumbnail(temp) {
myDropzone.createThumbnailFromUrl(temp,
myDropzone.options.thumbnailWidth,
myDropzone.options.thumbnailHeight,
myDropzone.options.thumbnailMethod, true, function (thumbnail) {
myDropzone.emit('thumbnail', temp, thumbnail);
myDropzone.emit("complete", temp);
});
}
myDropzone._updateMaxFilesReachedClass();
}
addButton.addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
document.getElementById("dropzone-form").submit();
}
});
this.on("successmultiple", function (files, response) {
setTimeout(function (){
{#document.getElementById("dropzone-form").submit();#}
window.location.href = "/admin/report/{{ report_id }}";
}, 1000);
});
},
sending: function (file, xhr, formData) {
var formEl = document.getElementById("dropzone-form");
if (first_time) {
for (var i=0; i<formEl.elements.length; i++){
formData.append(formEl.elements[i].name, formEl.elements[i].value)
first_time = false;
}
}
formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
formData.append("image", file.name);
}
});
</script>
Please note that there are some comments and some writing to console.log, but you can obviously get rid of this.
I had the same problem. Use these files:
https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/dropzone.js
https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.3.0/dropzone.css
It worked for me.
I know it's a bit late, however I was facing the same issue. The problem I was having was a race condition where only the last thumbnail was loaded and the others were stuck before completing, because i changed before createThumbnailFromUrl was getting it's data. Putting the call inside function did the trick for me:
for (var i = 0; i < images.length; i++) {
var temp = { name: images[i], dataURL: images[i] };
myDropzone.files.push(temp);
myDropzone.emit("addedfile", temp);
createThumbnail(temp);
}
function createThumbnail(temp) {
myDropzone.createThumbnailFromUrl(temp,
myDropzone.options.thumbnailWidth,
myDropzone.options.thumbnailHeight,
myDropzone.options.thumbnailMethod, true, function (thumbnail) {
myDropzone.emit('thumbnail', temp, thumbnail);
myDropzone.emit("complete", temp);
});
}
My answer is inspired by BLitande's, which helped me getting it to kind of work in the first place.

CasperJS scraping assistance required

I am trying to go to this page and scrape from each link the 'Title' and 'Authors' for each thesis. So far I have this (my issues that I require assistance with are in the comments within code):
var utils = require('utils');
var casper = require('casper').create({
verbose: true,
logLevel: 'error',
pageSettings: {
loadImages: false,
loadPlugins: false,
userAgent: 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.2 Safari/537.36'
},
clientScripts: ['lib/jquery.min.js']
});
var i = 0;
var links = [];
var thesis_data = [];
function getThesisLinks () {
var links = document.querySelectorAll('');//Not sure what should go in ('')
return [].map.call(links, function(link) {
return link.getAttribute('href');
});
}
function loopThroughThesisLinks() {
// Recurses until all links are processed
if (i < links.length) {
this.echo('[LINK #' + i + '] ' + links[i]);
getThesisData.call(this, links[i]);
i++;
this.run(loopThroughThesisLinks);
} else {
utils.dump(thesis_data);
this.exit();
}
}
function getThesisData(link) {
this.start(link, function() {
// Get title of thesis - not sure what element to insert for this.fetchText
var title = this.fetchText('');
// Get name of authors - not sure what element to insert for this.fetchText
var author = this.fetchText('');
// Add the title & author data to the thesis_data array
var data = {
title: title,
author: author
};
thesis_data.push(data);
});
}
casper.start('http://ses.library.usyd.edu.au/handle/2123/345/browse?type=dateissued&sort_by=2&order=DESC&rpp=1495&etal=0&submit_browse=Update', function() {
links = this.evaluate(getThesisLinks);
// Convert relative links to absolute URLs
for (var i = 0; i < links.length; i++) {
links[i] = "http://ses.library.usyd.edu.au/handle/" + links[i];
}
utils.dump(links);
});
casper.run(loopThroughThesisLinks);
Any assistance would be appreciated.
This is a simple CSS selector for all links:
var links = document.querySelectorAll(
'table.misctable > tbody > tr > td:nth-of-type(3) > a');
You can also use XPath like this:
var x = require('casper').selectXPath; // goes to the beginning of the file
var title = this.fetchText(x('//table//tr/td[1][contains(text(),"Title:")]/../td[2]'));
I think you can figure out the authors-query. I probably would have done the crawling differently using casper.thenOpen in a loop, because this is rather hard to read with the additional start and run calls being in different functions.
With casper.thenOpen it would look like this:
var x = require('casper').selectXPath; // goes to the beginning of the file
function loopThroughThesisLinks() {
// Recurses until all links are processed
if (i < links.length) {
this.echo('[LINK #' + i + '] ' + links[i]);
getThesisData.call(this, links[i]);
i++;
this.then(loopThroughThesisLinks);
} else {
utils.dump(thesis_data);
this.exit();
}
}
function getThesisData(link) {
this.thenOpen(link, function() {
var title = this.fetchText(x('//table//tr/td[1][contains(text(),"Title:")]/../td[2]'));
var author = this.fetchText(x('//table//tr/td[1][contains(text(),"Authors:")]/../td[2]'));
// Add the title & author data to the thesis_data array
var data = {
title: title,
author: author
};
thesis_data.push(data);
});
}

AJAX works in IE but not in Firefox or Chrome

I'm new to using AJAX and my code works in Internet Explorer but not in Firefox or Chrome.
I do not know what it is exactly what should change in the code ...
// I think that error should be here :-)
function cerrar(div)
{
document.getElementById(div).style.display = 'none';
document.getElementById(div).innerHTML = '';
}
function get_ajax(url,capa,metodo){
var ajax=creaAjax();
var capaContenedora = document.getElementById(capa);
if (metodo.toUpperCase()=='GET'){
ajax.open ('GET', url, true);
ajax.onreadystatechange = function() {
if (ajax.readyState==1){
capaContenedora.innerHTML= "<center><img src=\"imagenes/down.gif\" /><br><font color='000000'><b>Cargando...</b></font></center>";
} else if (ajax.readyState==4){
if(ajax.status==200){
document.getElementById(capa).innerHTML=ajax.responseText;
}else if(ajax.status==404){
capaContenedora.innerHTML = "<CENTER><H2><B>ERROR 404</B></H2>EL ARTISTA NO ESTA</CENTER>";
} else {
capaContenedora.innerHTML = "Error: ".ajax.status;
}
} // ****
}
ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
ajax.send(null);
return
}
}
function creaAjax(){
var objetoAjax=false;
try{objetoAjax = new ActiveXObject("Msxml2.XMLHTTP");}
catch(e){try {objetoAjax = new ActiveXObject("Microsoft.XMLHTTP");}
catch (E){objetoAjax = false;}}
if(!objetoAjax && typeof XMLHttpRequest!='undefined') {
objetoAjax = new XMLHttpRequest();} return objetoAjax;
}
//These functions are connected with a form
function resultado(contenido){
var url='ajax/buscar.php?'+ contenido +'';// Vota Resultado
var capa='resultado';
var metodo='get';
get_ajax(url,capa,metodo);
}
function paginas(contenido){
var url='ajax/paginar.php?'+ contenido +'';// Vota Paginas
var capa='paginas';
var metodo='get';
get_ajax(url,capa,metodo);
}
Strongly suggest that you use a lib like jQuery that encapsulates a lot of what you're doing above, masking cross-browser issues (current and future). Even if you don't want to use jQuery site-wide, you could still use it just for its AJAX functionality.

Slideshow using Prototype and Scriptaculous

I wrote my first scriptaculous script to create a slideshow between some div element :
var SlideShow = Class.create({
initialize:function(element, delayStart){
this.element = element;
this.delayStart = delayStart;
this.slides = this.element.childElements();
this.numberOfSlides = this.slides.size();
this.numberActiveSlide = 1;
this.start_slideshow();
},
start_slideshow: function()
{
this.switch_slides.delay(this.delayStart);
},
switch_slides: function()
{
this.slides[this.numberActiveSlide].fade();
if (this.numberActiveSlide == this.numberOfSlides) { this.numberActiveSlide = 1; } else { this.numberActiveSlide = this.numberActiveSlide + 1; }
Effect.Appear.delay(this.slides[this.numberActiveSlide], 850);
this.switch_slides.delay(this.delay + 850);
}
});
document.observe("dom:loaded", function(){
var slideshows = $$('div.slideshow');
slideshows.each(
function(slideshow) {
s = new SlideShow(slideshow, 2);
});
});
But I always get this error and It's been hours I can't figure it out where my problem is!
Undefined is not an object (evaluating this.slides[this.numberActiveSlide]);
Thanks you !
Nick
99% sure it's a context issue. Make sure you bind your function calls so that this is retained throughout your code.
Debug what this is in switch_slides: it should be the same thing as this in start_slideshow. If it's not, bind your call to switch_slides to your instance:
start_slideshow: function()
{
this.switch_slides.bind(this).delay(this.delayStart);
},
You'll probably have to do the same in switch_slides where it calls itself.

What is the correct JSON structure for this while loop?

I'm a little new to JSON so trying to understand what is the best way to do this. I have two variables: postcode and energyrating that I want to put into JSON and then parse to a for loop.
I can get it to work with one variable but when I have two it doesn't work.
Here is my JSON:
header('Content-type: application/json');
$postcodeArray = array('postcodes' => array("E6 2JG","SE1 2AQ","DA1 1DZ"), 'energyrating' => array("A","B","C","D","E","F","G"));
die(json_encode($postcodeArray));
Here is my jQuery:
function addNew(postcodes) {
if(postcodes.length > 0) {
for(var i = 0; i < postcodes.length; i++) {
var address = postcodes[i];
var rating = energyrating[i];
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var image = '../img/markers/' + rating + '.png';
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: image
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
} else {
alert("Sorry, no data was found.");
}
}
How do I get this to work with both variables?
What does not work exactly ?
Reading your code, I would say there is an error into your code. The energyrating argument is missing into your addNew function:
function addNew(postcodes, energyrating) {
Assuming that you call your function like this:
addNew(jsonData.postcodes, jsonData.energyrating);
Use json variables to store the data like that :
$postcodeArray = '{"postcodes":{"0":E6, "1":"2JG", "3":"SE1 2AQ","4":"DA1 1DZ"}, "energyrating":{"0":"A","1":"B","2":"C","3":"D","4":"E","5":"F","6":"G"}}';
In the place of
$postcodeArray = JSON.parse('postcodes' => array("E6 2JG","SE1 2AQ","DA1 1DZ"), 'energyrating' => array("A","B","C","D","E","F","G"));
And you can access the values.
Or try json_decode(postcodes) in the function addNew in first line.

Resources