I am developing an app where I use 2 API's a.k.a Instagram API and Google Map API. Using AJAX, I get the first set of Images filtered by a tag name. In the 1st set we receive 20 images. Among the received images, the images that have the latitude and longitude info (geotagged images) are displayed on the map.
Now the first time when my page loads, I cannot see the map. But when I press the load more button to get the next set of images, the Map works fine showing my previous images too.
Here is the code for what happens on page load:
$( window ).load(function() {
$.ajax({
type: "GET",
url: "https://api.instagram.com/v1/tags/nyc/media/recent?client_id=02e****",
dataType:'JSONP',
success: function(result) {
onAction(result, 2, tag);
instaMap(result, 2, from);
}
});
});
These are the functions being called:
/**
* [initialize description]
* Initialize the map with markers showing all photos that are geotagged.
*/
var initialize = function(markers) {
var bounds = new google.maps.LatLngBounds(),
mapOptions = {
scrollwheel: false,
mapTypeId: 'roadmap',
center: new google.maps.LatLng(22.50, 6.50),
minZoom: 2
},
gmarkers = [],
map,
positions,
markCluster;
markers = remDuplicate(markers);
// Info Window Content
var infoWindowContent = [];
for (var j = 0; j < markers.length; j++ ) {
var content = [
'<div class="info_content">' +
'<h3>' + markers[j][2] + '</h3>' +
'<a href="' + markers[j][3] + '" target="_blank">' +
'<img src="' + markers[j][4] + '" style="z-index:99999">' + '</a>' +
'</div>'
];
infoWindowContent.push(content);
}
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Display multiple markers on a map
var oms = new OverlappingMarkerSpiderfier(map);
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
positions = new google.maps.LatLng(markers[i][0], markers[i][1]);
marker = new google.maps.Marker({
position: positions,
map: map,
animation:google.maps.Animation.BOUNCE,
title: markers[i][2]
});
oms.addMarker(marker);
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.close();
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
map.setCenter(marker.getPosition());
};
})(marker, i));
gmarkers.push(marker);
}
google.maps.event.addListener(map, 'click', function() {
infoWindow.setMap(null);
});
markCluster = new MarkerClusterer(map, gmarkers);
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
map.setZoom(2);
google.maps.event.removeListener(boundsListener);
});
};
/**
* [onAction]
* OnAction() function helps in loading non-geotagged pics.
*
* #param {[type]} result [Result retruned from the Instagram API in json format]
* #param {[type]} likey [hearts the user has entered as per which the posts will be filtered]
*/
var onAction = function (result, likey, tag) {
$('.load-pics').remove();
if (result.pagination.next_url) {
paginate = removeURLParameter(result.pagination.next_url, 'count');
}
$.each(result, function(key, value) {
if (key === 'data') {
$.each(value, function(index, val) {
liked = val.likes.count;
link = val.link;
imgUrl = val.images.low_resolution.url;
locations = val.location;
if (liked >= likey) {
if (locations === null) {
output = '<li class="img-wrap">' + '<div class="main-img">' +
'<a href="' + link + '" target="_blank">' +
'<img src="' + imgUrl + '" ><span class="hover-lay"></span></a>' +'<p>' +
'<span class="heart"></span><span class="likes-no">' + liked + '</span>' +
'<span class="comment-box"></span><span class="comment-no">' +
val.comments.count + '</span> ' + '</p>' + '</div>' +
'<div class="img-bottom-part">'+ '' + '<div class="headin-hastag">' +
'by ' + '<h2>Sebastien Dekoninck</h2>#hello <span>#kanye</span> #helloagain #tagsgohere</div>'
+'</div></li>';
$('#instafeed').append(output);
}
}
});
}
});
if ($('#instafeed').children().length === 0) {
alert('There are no pics with ' + likey + ' likes or #' + tag + ' was not found.');
} else {
// $('.not-geo').remove();
// $('#instafeed').before('<button class="not-geo">Click To See Images That Are Not Geotagged <img src="assets/imgs/down.png" ></button>');
}
$('#instafeed').append('<div class="load-pics"><button id="show-more">Show more <span></span></button> </div>');
};
/**
* [instaMap]
* instaMap() will be the function which will deal with all map based functionalities.
*/
var instaMap = function(result, likey, from) {
$('.load-mark').remove();
if (result.pagination.next_url) {
pagiMap = removeURLParameter(result.pagination.next_url, 'count');
}
$.each(result, function(key, value) {
if (key === 'data') {
$.each(value, function(index, val) {
liked = val.likes.count;
link = val.link;
imgUrl = val.images.low_resolution.url;
locations = val.location;
if (liked >= likey) {
if (locations && locations.latitude !== null) {
tempArr = [
locations.latitude,
locations.longitude,
val.user.username,
val.link,
val.images.low_resolution.url
];
mark.push(tempArr);
}
}
});
}
});
if (mark.length) {
initialize(mark);
$('.map-parent-wrapper').append('<div class="load-mark"><button id="show-mark">See More </button></div>');
} else {
alert('No geotagged pics found in the retrieved set. Click see more');
$('.map-parent-wrapper').append('<div class="load-mark"><button id="show-mark">See More </button></div>');
}
};
I have created a See More button to retrieve the next set of images and load those on the Map. When clicking see more, everything seems to work fine. Not sure why it's happening so. Console.log does not show any error. Also, all the values I feed does flow appropriately. I even tried clearing cache. Not sure, why it's happening.
If instaMap is the function which is going to handle all your map based functionality, it has to be the one that loads map in your $( window ).load function ();
Otherwise, if you want Google maps to load on initial window load you need to put below in there:
google.maps.event.addDomListener(window, 'load', initialize);
Related
Does anyone have suggestions on how to complete the following assignment? I've listed the instructions from the teacher below along with my JavaScript code. Thanks in advance!
Instructions:
The primary task is to dynamically generate the "genre" buttons that are currently hardcoded into the correlating HTML file.
The genre buttons should work the same way the hardcoded buttons currently work meaning they should have an event listener attached to them that should display podcasts from the ajax response that match the genre that was clicked.
JavaScript Code:
/**
* Ajax GET requester
*
*/
function get(url){
// Return a new promise.
return new Promise(function (resolve, reject){
// Do the usual XHR stuff
var req = new XMLHttpRequest();
req.open('GET', 'js/data.json');
req.onload = function(){
// This is called even on 404 etc
// so check the status
if(req.status === 200){
// Resolve the promise with the response text
resolve(req.response);
}else{
// Otherwise reject with the status text
// which will hopefully be a meaningful error
reject(Error(req.statusText));
}
};
// Make the request
req.send();
});
}
function get_podcasts(genre){
var url = 'js/data.json';
get(url).then(function (response){
var body = document.getElementById('mainContent');
response = JSON.parse(response);
if(response.results.length > 0){
body.innerHTML = '';
for(var i = 0; i < response.results.length; i++ ){
if(response.results[i].primaryGenreName === genre ){
var image = '<img src="' + response.results[i].artworkUrl100 + '">';
var image = document.createElement('img');
image.src = response.results[i].artworkUrl100;
body.appendChild(image);
body.innerHTML += '<div>' + response.results[i].trackName + '</div>' ;
}
}
}else{
body.innerHTML = 'No results found.';
}
console.log(response);
}, function (error){
console.log('No hits Found');
});
}
window.onload = function(){
//create an array with all button names
var genreNames = ['TV & Film', 'News & Politics', 'Society & Culture', 'Music', 'Hobbies'];
//loop through the array
for(var i = 0; i < genreNames.length; i++){
//create button element called "TV and Film" or whatever
var dynamicButtons = document.createElement('BUTTON');
var buttonText = document.createTextNode(genreNames);
//add it to the DOM (document)
dynamicButtons.appendChild(buttonText);
document.body.appendChild(dynamicButtons);
}
/*
for(i =0; i <= response.results.length; i++) {
for (key in response.results[i].primaryGenreName) {
if(response.results[i].primaryGenreName.hasOwnProperty(key)) {
output += '<li><button type="button">' + response.results[i].primaryGenreName + '</button></li>';
var update = document.getElementById('genres');
update.innerHTML = output;
}
}
}
*/
};
I'm pulling data from mySQL through Laravel, generating a map, which works well, now I just want buttons that jump to each marker. For some reason it only goes to the last position.
$.ajax({
url: '/lookup',
type: "post",
data: {'lat':$("#lat").val() ,'lng':$("#lng").val(), '_token': $('input[name=_token]').val()},
success: function(data){
var nearest = data;
var markers = data;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i].lat, markers[i].lng);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i].name,
icon: 'http://website.com/assets/images/icons/love_google.png'
});
google.maps.event.addDomListener(document.getElementById("link_"+i), "click", function(e) {
alert(position);
map.setCenter(position);
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
//infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.setContent('<div class="info_content"><h3>' + markers[i].name + '</h3><p>' + markers[i].address + '<br />' + markers[i].city + ', ' + markers[i].state + ' ' + markers[i].zip + '<br />' + markers[i].phone + '</p></div>' );
infoWindow.open(map, marker);
}
})(marker, i));
}
}
});
You should construct the event listener for the button click in the same way you're doing it for the marker click. The problem is that position at the time you click the button will be just whatever that variable is at that point in time, not whatever it was on the iteration of the loop when you constructed the event listener.
Try something like:
google.maps.event.addDomListener(document.getElementById("link_"+i), "click", (function(position) {
return function() {
alert(position);
map.setCenter(position);
}
})(position));
I want to parse the below mentioned RSS in order to get the title, description, image and date. Currently i'm able to get the all other details except image. Im using google api feed to parse the rss. Please can anyone me in this context.
RSS:https://news.google.com/news/feeds?cf=all&ned=in&hl=en&q=cricket&output=rss
// Google Feed API: https://developers.google.com/feed/
// Inspiration: http://designshack.net/articles/javascript/build-an-automated-rss-feed-list-with-jquery/
function parseFeed(url, container) {
$.ajax({
url: document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=5&callback=?&q=' + encodeURIComponent(url),
dataType: 'json',
success: function (data) {
// log object data in console
console.log(data.responseData.feed);
// append feed link and title in container
$(container).append('<span class="iconicstroke-rss-alt"></span>');
$(container).append('<h1 class="feed">' + data.responseData.feed.title + '</h1>');
// for each entry... *
$.each(data.responseData.feed.entries, function (key, value) {
// * create new date object and pass in entry date
var date = new Date(value.publishedDate);
// var thumbnail = entry.mediaGroups[0].contents[0].url;
// * create months array
var months = new Array(12);
months[0] = 'January';
months[1] = 'February';
months[2] = 'March';
months[3] = 'April';
months[4] = 'May';
months[5] = 'June';
months[6] = 'July';
months[7] = 'August';
months[8] = 'September';
months[9] = 'October';
months[10] = 'November';
months[11] = 'December';
// * parse month, day and year
var month = date.getMonth();
var day = date.getDate();
var year = date.getFullYear();
// * assign entry variables
var title = '<h3 class="title">' + value.title + '</h3>';
var time = '<p class="time">' + months[month] + ' ' + day + ', ' + year + '</p>';
var snippet = '<p class="snippet">' + value.contentSnippet + '</p>';
var img = '<p class="snippet">' + value.thumbnail + '</p>';
var entry = '<div class="entry">' + title + time + snippet + '</div>';
// * append entire entry in container
$(container).append(entry);
});
},
// if there's an error... *
error: function (errorThrown) {
// * log error message in console
console.log(errorThrown);
// * show error message
alert('Houston, we have a problem.');
}
});
}
$(document).ready(function () {
parseFeed('https://news.google.com/news/feeds?pz=1&cf=all&ned=en&hl=in&q=aishwarya%20rai&output=rss', '#csstricks');
});
Just add this to your script
var content = document.createElement("content");
content.innerHTML = value.content;
var images = "";
$(content).find('img').each(function() {
images += this.outerHTML;
});
var img = '<p class="snippet">' + images + '</p>';
Same answer as here: https://stackoverflow.com/a/26369373/989257
Codepen example: http://codepen.io/janih/pen/JdPMZX
I am working on a sort of aggregator/tweet wall. At the mo it only uses data from an XML file (of our latest news). I made a bit of a mistake in the logic, though.
At present it only pulls items from the last 30 days. Live demo takes a few secs to load (using last 240 days for extra content to work with). However, I need it to:
Pull the last 4 items in chrono order.
Shuffle that array so they are
random ordered (but will all be "fresh" news).
Output that array.
jQuery(function () {
$.ajax({
url: 'http://www.sagittarius-digital.com/news.rss',
dataType: 'xml',
complete: function() {
/*Init masonry.js*/
var container = document.querySelector('#container');
var msnry = new Masonry( container, {
// options
gutter: 20,
columnWidth: 320,
itemSelector: '.item'
});
}
}).done(function (xml) {
var items = [];
$(xml).find('item').each(function () {
var $item = $(this);
var date = new Date($item.find('pubDate').text());
var date_30 = new Date().getTime() - (1000*60*60*24*240); /* last figure = number of days to sort back from */
var yyyymmdd = date.getFullYear() + '' + (date.getMonth() + 1) + '' + date.getDate();
if ( date_30 < date.getTime() ) { // newer than 30 days
var array = '<div class="item"><h2>News</h2>';
array += '<p>' + yyyymmdd + '</p>';
array += '<a href="' + $item.find('link').text() + '">';
array += '<h2>' + $item.find('title').text() + '</h2>';
array += '<p>' + $item.find('description').text() + '</p>';>
array += '<p>Category: ' + $item.find('category').text() + '</p>';
array += '</a>';
array += '</div>';
items.push(array);
}
});
$('div.item').after(items.join(' '));
}).fail(function () {
console.log('error', arguments)
});
});
Basically after that I need to add a second RSS feed with different info doing the same, a Twitter ajax call and facebook ajax call. So I will have 12 bits of data that are all the 4 "freshest", these will then shuffle into a random order and output, so there is a nice even mix.
I'm using a ajax script to load content from other pages, without having to reload the browser.
For now I'm retrieving the content of the #inside div, but I'm using a full-background slideshow (#full) wich needs to be loaded as wel.
Maybe this can be achieved by loading the content of the #full div also, but I don't know how I could do that.
This is my code:
// Self-Executing Anonymous Function to avoid more globals
(function() {
// Home link isn't dynamic, so default set class name to it to match how dynamic classes work in WordPress
$(".home li.home").removeClass("home").addClass("current_page_item");
// Add spinner via JS, cuz would never need it otherweise
$("body").append("<img src='http://themeclubhouse.digwp.com/images/ajax-loader.gif' id='ajax-loader' />");
var
$mainContent = $("#wrapper"),
$ajaxSpinner = $("#ajax-loader"),
$searchInput = $("#s"),
$allLinks = $("a"),
$el;
// Auto-clear search field
$searchInput.focus(function() {
if ($(this).val() == "Search...") {
$(this).val("");
}
});
$('a:urlInternal').live('click', function(e) {
// Caching
$el = $(this);
if ((!$el.hasClass("comment-reply-link")) && ($el.attr("id") != 'cancel-comment-reply-link')) {
var path = $(this).attr('href').replace(base, '');
$.address.value(path);
$(".current_page_item").removeClass("current_page_item");
$allLinks.removeClass("current_link");
$el.addClass("current_link").parent().addClass("current_page_item");
return false;
}
// Default action (go to link) prevented for comment-related links (which use onclick attributes)
e.preventDefault();
});
// Fancy ALL AJAX Stuff
$.address.change(function(event) {
if (event.value) {
$ajaxSpinner.fadeIn();
$mainContent
.empty()
.load(base + event.value + ' #content', function() {
$ajaxSpinner.fadeOut();
$mainContent.fadeIn();
});
}
var current = location.protocol + '//' + location.hostname + location.pathname;
if (base + '/' != current) {
var diff = current.replace(base, '');
location = base + '/#' + diff;
}
});
})(); // End SEAF
try to repeat the procedure:
// Fancy ALL AJAX Stuff
$.address.change(function(event) {
if (event.value) {
//load ajax image
$ajaxSpinner.fadeIn();
$mainContent.empty().load(base + event.value + ' #content', function() {
$ajaxSpinner.fadeOut();
$mainContent.fadeIn();
});
// repeat here
//load another div
$mainContent.empty().load(base + event.value + ' #mydiv1', function() {
$mainContent
});
//load another div
$mainContent.empty().load(base + event.value + ' #mydiv2', function() {
$mainContent
});
}
let me know if it works, Ciao! :)