I am using Brad Birdsall's Swipe.js plugin as a touch friendly, library agnostic plugin for a slider in my current mobile project. When I populate the slider on page load, everything works great. However if I try and populate the slider with $.ajax() on click, the slider will receive all of the slides, but is not responsive to touch events, or any of the methods associated with the slider.
The general slider HTML structure looks like this:
<div id="slider" class="swipe">
<ul>
<li style='display:block;'>
<img src="/someImageUrl.jpg" />
</li>
<li style='display:none;'>
<img src="/someImageUrl.jpg" />
</li>
</ul>
</div><!-- .swipe -->
<nav>
PREV
NEXT
</nav>
I am using an $.ajax() response to populate the <li><img src="..." /></li> on a click event handler in my doc.
Here's my JS:
$.ajax({
url: "process.inc.php?vehicleId=" + vehicleId,
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var swipeSlides = "";
for (i = 0 ; i < data.length; i++) {
var photoUrl = data[i].photoUrl;
var photoArray = photoUrl.split("|");
if (photoArray.length <= 1) {
list += "<img src="+photoArray[i]+" />"
} else {
for (i = 0; i < photoArray.length; i++) {
swipeSlides += "<li><img src='"+photoArray[i]+"' /></li>"
}
var prevNext = "<nav>PREVNEXT</nav>"
var sliderElement = $(self).parent().find("#data #slider ul");
sliderElement.find("li, nav").remove();
sliderElement.append(swipeSlides, prevNext);
$.getScript('../assets/js/swipe.js');
var slider = new Swipe(
document.getElementById('slider')
);
};
};
} // end success function
}); // end AJAX
This will sucessfully populate my page with all of the necessary content, but when I click one of the previous or next puttons, I get this error in my console:
Uncaught TypeError: Object #<HTMLCollection> has no method 'next'
Which tells me that my script is not being loaded into the page appropriately, or, my slider is not being instantiated at the proper time.
I have tried executing my code inside of the $.getScript() method like this:
$.getScript('../assets/js/swipe.js', function(data, textStatus, jqxhr) {
for (i = 0; i < photoArray.length; i++) {
swipeSlides += "<li><img src='"+photoArray[i]+"' /></li>"
}
var prevNext = "<nav>PREVNEXT</nav>"
var sliderElement = $(self).parent().find("#data #slider ul");
sliderElement.find("li, nav").remove();
sliderElement.append(swipeSlides, prevNext);
var slider = new Swipe(
document.getElementById('slider')
);
});
Or even just using a good old fashioned <script src="/assets/js/swipe.js"></script> before my jQuery script executes, and I keep getting the same exact error.
If anyone has any suggestions I will be forever grateful.
I figured out the problem.
In order to make the instantiation of the Swipe element recognized, I needed to use $.globalEval() inside of the $.getScript() function.
Heres my working code:
$.ajax({
url: "process.inc.php?vehicleId=" + vehicleId,
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var list = "";
for (i = 0 ; i < data.length; i++) {
var photoUrl = data[i].photoUrl;
var photoArray = photoUrl.split("|");
if (photoArray.length === 1) {
list += "<img class='noPhoto' src="+photoArray[i]+" />";
var parent = $(self).parent().find("#data");
parent.find("table, .noPhoto").remove();
parent.append(list);
} else {
list += "<div id=\"slider\" class=\"swipe\"><ul>";
for (i = 0; i < photoArray.length; i++) {
list += "<li><img src='"+photoArray[i]+"' /></li>"
}
list += "</ul><nav>PREVNEXT</nav></div>";
var parent = $(self).parent().find("#data");
parent.find("table, div").remove();
parent.append(list);
$.getScript("../assets/js/swipe.js", function(data, textStatus, jqxhr) {
$.globalEval("var slider = new Swipe(document.getElementById('slider'));")
});
};
};
} // end success function
}); // end AJAX
Hopefully this helps someone else down the road.
Why use getScript in the first place? Append it to your other javascript files as (before your javascript file), then new Swipe() should work.
Also, if you want to call functions of your Swipe object later, you should declare the var outside your ajax function. Example:
var mySwipe;
document.ready(function(){
//...
});
function pullFromAjaxFunction() {
//... do some more stuff
mySwipe = new Swipe(...)
}
Related
I'm trying to print the most recent row from a Google Sheet, which updates daily. I'm making an API call to it and returning it in Json and whilst I can grab the most recent value, I can only seem to print the whole column of data:
I apologise the code is a bit slap and dash, I'm new to this.
Javascript
var sheetsuUrl = "https://sheetsu.com/apis/v1.0/3e242af0";
$.ajax({
url: sheetsuUrl,
dataType: 'json',
type: 'GET',
// place for handling successful response
success: function(data) {
console.log(data[data.length-1]['moved'])
addCharacters(data);
},
// handling error response
error: function(data) {
console.log(data);
}
});
addCharacters = function(characters) {
var list = $('#ponies');
for(var i=0; i<characters.length; i+=1) {
char = characters[i];
function lastNoZero(myRange) {
lastRow = myRange.length;
for (; myRange[lastRow - 1] == "" || myRange[lastRow - 1] == 0 && lastRow > 0 ; lastRow--) {
/*nothing to do*/
}
return myRange[lastRow - 1];
}
myRange = char.moved;
if (char.moved == 'entered') {
html = "<img src='https://media.firebox.com/pic/p5294_column_grid_12.jpg'/>";
} else {
html = "<img src='http://41.media.tumblr.com/30b1b0d0a42bca3759610242a1ff0348/tumblr_nnjxy1GQAA1tpo3v2o1_540.jpg'/>";
};
list.append(html);
}
}
HTML
<script src="https://code.jquery.com/jquery-3.0.0-alpha1.js"></script>
<div id="ponies"></div>
CSS
html img{
width:100px;
height:100px;
}
You needed to reference the last item in the array returned by your GET request.
characters[characters.length - 1]; will get the last character in the characters array. Then, to ensure that the html is not added on each run of the loop, you needed to move list.append(html); outside the loop, ensuring that it only appends the content to the page once.
Run the code snippet below to see in action.
var sheetsuUrl = "https://sheetsu.com/apis/v1.0/3e242af0";
$.ajax({
url: sheetsuUrl,
dataType: 'json',
type: 'GET',
// place for handling successful response
success: function(data) {
addCharacters(data);
},
// handling error response
error: function(data) {
console.log(data);
}
});
addCharacters = function(characters) {
var list = $('#ponies');
for(var i=0; i<characters.length; i+=1) {
char = characters[characters.length - 1];
myRange = char.moved;
if (char.moved == 'entered') {
html = "<img src='https://media.firebox.com/pic/p5294_column_grid_12.jpg'/>";
} else {
html = "<img src='http://41.media.tumblr.com/30b1b0d0a42bca3759610242a1ff0348/tumblr_nnjxy1GQAA1tpo3v2o1_540.jpg'/>";
};
}
//for illustration purposes
list.append(characters[characters.length - 1].time)
//the code to attach the image
list.append(html);
}
<script src="https://code.jquery.com/jquery-3.0.0-alpha1.js"></script>
<div id="ponies"></div>
Hello i am getting data from a php file in json format,all works fine.I would however desire that this function reloads every say 3000millisecs thus updating the data.
How do I achieve this?
function loadFbill(hsid)
{
// Display a loading icon in our display element
$('.list-item-display').html('<span><img src="img/progress.gif" /></span>');
// Request the JSON and process it
$.ajax({
type:'GET',
url:""+xhr_path+"js_on.php",
data:"hid="+hsid+"&subscribers=paid",
success:function(feed) {
// Create an empty array to store images
var thumbs = [];
// Loop through the items
for(var i=0, l=feed.response.length; i < l && i < 6; ++i)
{
// Manipulate the image to get thumb and medium sizes
var payee = feed.response[i].result_paid;
var transaction_m = feed.response[i].result_payment_details;
var ptime = feed.response[i].result_time;
var plan = feed.response[i].result_plan;
var payee_num = feed.response[i].result_num;
var localhs = feed.response[i].result_hs;
var transaction_date = feed.response[i].result_payment_date;
var diff_date = feed.response[i].result_time_diff;
// Add the new element to the array
thumbs.push("<div class=list-item><div class=list-datetime><div class=time>"+ptime+"</div></div><div class=list-info><img src=img/pesa/ps_"+transaction_m+".jpg height=28 width=28 class=img-circle img-thumbnail/></div><div class=list-text><a href=# class=list-text-name> "+payee+" </a><p>"+payee_num+" <span class=icon-calendar></span> "+transaction_date+" <span class=icon-calendar-empty></span>"+diff_date+"<span class=icon-globe></span> "+localhs+" </p></div><div class=list-controls> "+plan+"</div></div>");
}
// Display the thumbnails on the page
$('.list-item-display').html(""+thumbs.join('')+"");
// A function to add a lightbox effect
addLB();
},
dataType:'json'
});
}
You can simply add setTimeout into ajax request callback function:
function loadFbill(hsid) {
// Display a loading icon in our display element
$('.list-item-display').html('<span><img src="img/progress.gif" /></span>');
// Request the JSON and process it
$.ajax({
type: 'GET',
url: "" + xhr_path + "js_on.php",
data: "hid=" + hsid + "&subscribers=paid",
success: function (feed) {
// ... all your code untouched
setTimeout(loadFbill, 3000); // <-- and reload again
},
dataType: 'json'
});
}
I'm trying to integrate two jQuery scripts into one but because the elements of the first part are created dynamically using jQuery I can't get the second part of the project working.
The project:
1.Instagram pictures are parsed as JSON into li elements.
Here's a portion of the code:
<ul id="elasticstack" class="elasticstack">
</ul>
<script>
$("#elasticstack").append("<li><div class='peri-pic'><img class='instagram-image' src='" + data.data[i].images.low_resolution.url +"' /><span class='name'>"+ data.data[i].caption.from.username +"</span> <span class='likes'><span class='glyphicon glyphicon-heart'></span><p>"+data.data[i].likes.count +"</p></span></div></li>"
);
</script>
Source: LINK
2.This works fine but when I try to add the slider none of the functions work. Even if I wrap the callout function in a $( document ).ready(function() { });
Here's the call out code:
<script>
new ElastiStack( document.getElementById( 'elasticstack' ) );
</script>
Source: LINK
Here's the JS Fiddle with all my code: LINK
Where am I going wrong?
You're looking for this. After the initial loadImages(start_url) call, you should be able to call loadImages(next_url) to load and display more. new ElastiStack had to be called after the images had been appended.
var access_token = "18360510.5b9e1e6.de870cc4d5344ffeaae178542029e98b",
user_id = "18360510", //userid
start_url = "https://api.instagram.com/v1/users/"+user_id+"/media/recent/?access_token="+access_token,
next_url;
function loadImages(url){
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
success: function(data){
displayImages(data);
next_url = data.pagination.next_url;
}
})
}
function displayImages(images){
for(var i = 0; i < 20; i++){
if(images.data[i]){
$("#elasticstack").append("<li><img class='instagram-image' src='" + images.data[i].images.low_resolution.url + "'></li>");
}
}
// Call it after the images have been appended
new ElastiStack(document.getElementById('elasticstack'));
}
$(document).ready(function(){
loadImages(start_url);
});
Try to initialize the ElastiStack after data (HTML elements) has been appended into the DOM in your ajax, for example:
for (var i = 0; i < count; i++) {
// ...
$("#elasticstack").append(...);
}
new ElastiStack(...);
It should work.
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url ,
success: function(data) {
next_url = data.pagination.next_url;
//count = data.data.length;
//three rows of four
count = 20;
//uncommment to see da codez
//console.log("count: " + count );
//console.log("next_url: " + next_url );
//console.log("data: " + JSON.stringify(data) );
for (var i = 0; i < count; i++) {
if (typeof data.data[i] !== 'undefined' ) {
//console.log("id: " + data.data[i].id);
$("#elasticstack").append("<li><img class='instagram-image' src='" + data.data[i].images.low_resolution.url +"' /></li>"
);
}
}
new ElastiStack(document.getElementById('elasticstack'));
}
});
You have to move your new ElastiStack(document.getElementById('elasticstack')); inside the ajax success event. You don't have to change anything else in your. I also updated your JSFiddle.
I'm writing a script to parse a JSON file, and I seem to have got myself into a tricky situation. Can I append half of the returned items in one div element and the other half in another div elemet?
Here is the original markup:
<div class="feed"><div class="displayfeed main"></div></div>
<div class="feed"><div class="displayfeed second"></div></div>
I want the page to display like this after appending the returned data:
<div class="feed">
<div class="displayfeed main">
<h3>item1's title</h3> //Half of the items in "div.main"
.......
</div>
</div>
<div class="feed">
<div class="displayfeed second">
<h3>item2's title</h3> //Half of the items in "div.second"
...........
</div>
</div>
JS Code:
$.ajax({
url: source,
success: function (data) {
var item_html =
$(data.items).each(function (index, item) {
'<h3>'+item.title+'</h3>';
});
//Any way to append some of them in ('.main') and the rest in ('.second')?
$('.displayfeed').append(item_html);
},
error: function () {$searcharea.append("<b>No Results Returned</b>");}
});
I'm looking for any possible suggestions, otherwise I have no choice but to parse the same feed twice. Any help would be appreciated.
Updated:
I've set up a FIDDLE using Gogole news feed in JSON format converted by YQL as an example
Use multiply selector.
$.ajax({
url: source,
success: function (data) {
var item_html_main = "";
var item_html_second = "";
// assign values to item_html_main and item_html_second variables
$('.displayfeed.main').append(item_html_main);
$('.displayfeed.second').append(item_html_second);
},
error: function () {$searcharea.append("<b>No Results Returned</b>");}
});
I don't know what structure you have but you can try this:
$.ajax({
url: source,
success: function (data) {
var item_html_main = "";
var item_html_second = "";
// assign values to item_html_main and item_html_second variables
var count = data.count;
var half = count/2;
var counter = 0;
for(item in data) {
if(counter < half) {
item_html_main += item;
} else {
item_html_secodn += item;
}
counter++;
}
$('.displayfeed.main').append(item_html_main);
$('.displayfeed.second').append(item_html_second);
},
error: function () {$searcharea.append("<b>No Results Returned</b>");}
});
You can try something like this. if it does not matter which posts is displayed in which container
$.ajax({
url: "<your-URL>",
success: function (data) {
var length = 0;
var items = data.query.results.item;
items = items.map(function(item){
return '<h3>'+item.title+'</h3>';
});
var half = items.length/2;
for(var i = 0; i < items.length; i++)
if(i < half)
$('.main').append(items[i]);
else
$('.second').append(items[i]);
length++;
},
error: function () {$searcharea.append("<b>No Results Returned</b>");}
});
Of course, but you need some separator or something
You can append all to your first div and then copy the part you want in the second div out of the first.
Example
item_html
<h2>Headline</h2>
<span>
News Text
</span>
js
$('.displayfeed').append(item_html);
sec = $('.displayfeed').find('span').html();
$('.displayfeed').find('span').remove();
$('.displayfeed second').append(sec);
Im trying to fill a select with elements from a database using Ajax but it wont work.
If have pinned down the problem to the javascript function but I don't seem to find the problem myself.
What am I missing here? :/
$(document).ready(function()
{
$(function()
{
$.ajax(
{
url:"<?php echo site_url("c_admin/ajaxCategorie");?>",
type: 'POST',
success: function(msg)
{
var jsonMsg = $.parseJSON(msg);
var count = Object.keys(jsonMsg).length;
for(var x = 0; x < count; x++)
{
$("#categorieSelect").apend($("<option></option>").val(jsonMsg[x].CategorieID).html(jsonMsg[x].CategorieNaam));
}
}
});
});
})
It seems to me you made a simple typo;
$("#categorieSelect").apend($("<option></option>").val(jsonMsg[x].CategorieID).html(jsonMsg[x].CategorieNaam));
Change apend to append.
Your code should be ok !