Update div with new image only when user uploaded new image - javascript

I have two separate pages: one where user uploads new image, other where that images is loaded inside a div through ajax.
The script is looking at filenames inside a txt file and only the first filename is being fetched (file_name2.jpg|file_name1.jpg)
Here is the script:
$(function(){
var GALLERY = {
container: "#gallery",
url: "getImages.txt",
delay: 10000,
load: function(){
var _gallery = this;
var number = 1 + Math.floor(Math.random() * 9999999999);
$.ajax({
type: "get",
url: this.url + '?rand=' + number,
beforeSend: function(){
$(_gallery.container).find('img').remove();
},
success: function(data){
var images = data.split('|', 1);
$.each(images, function(){
_gallery.display(this);
});
},
complete: function(){
setTimeout(function(){
_gallery.load();
}, _gallery.delay);
}
});
},
display: function(image_url){
$('<img />').attr('src', 'images/' + image_url).load(function(){
$(this);
}).prependTo(this.container);
}
}
GALLERY.load();
});
The problem is: The script always executes and replaces the image, even when no new image was uploaded.
Ideal the image should only refresh when a new image was uploaded.
How can I achieve this behavior?

You need to store result data in a variable or like GALLERY.lastdata then the setTimeout will request another and see if new data is the same the image won't refresh.
$(function(){
var GALLERY = {
lastdata : "",
container: "#gallery",
url: "getImages.txt",
delay: 10000,
load: function(){
var _gallery = this;
var number = 1 + Math.floor(Math.random() * 9999999999);
$.ajax({
type: "get",
url: this.url + '?rand=' + number,
success: function(data){
//detect new images
if(_gallery.lastdata != data){
var images = data.split('|', 1);
$.each(images, function(){
_gallery.lastdata = data;
_gallery.display(this);
});
}
},
complete: function(data){
setTimeout(function(){
_gallery.load();
}, _gallery.delay);
}
});
},
display: function(image_url){
$('<img />').attr('src', 'images/' + image_url).load(function(){
$(this);
}).prependTo(this.container);
}
}
GALLERY.load();
});

In your success or display function, add code to check the image filenames received against the image filenames currently displayed and only update when they differ.

Related

The second ajax request does not change the DOM after loading the first one jQuery

I have two very similar jquery AJAX codes. Both work correctly when I use them separately. However, if I load the first code, if I want to load the second it probably works (because I tested different places "console.log(''test'')"), but it doesn't change the DOM. Please help.
I have tried many different solutions and none have provided a solution. I have searched on many forums but have not found an answer.
1st
var basketAddTimeout;
var ajaxSubmitForm;
app_shop.run(function() {
ajaxSubmitForm = function() {
$this = $('#projector_button_basket');
var url = $('#projector_form').attr('action');
var txt = $this.text().trim();
clearTimeout(basketAddTimeout);
$.ajax({
type: 'POST',
url: url,
data: $('#projector_form').serializeArray(),
success: function(data) {
basketAddTimeout = setTimeout(function() {
$('#Basket').load(' #projector-basket-form');
}, 1000)
fetch('/ajax/basket.php').then(res => res.json()).then(({
basket
}) => {
const number = basket.productsNumber;
const number12 = basket.worth_formatted;
$('#kwota-basket').text(number12);
document.getElementById('badgekoszyka').style.display = 'block';
$( "#badgekoszyka" ).fadeOut( "slow");
$( "#badgekoszyka" ).fadeIn( "slow");
$('#menu_basket .badge').text(number);
$('#badgekoszyka').text(number);
})
},
error: function() {
classObj.alert(classObj.txt.dodano_produkt_blad);
$('#projector_button_basket').html(txt);
$('#projector_button_basket').removeClass('loader');
}
});
}
}, 'all');
second
var basketAddTimeout2;
var ajaxSubmitForm2;
app_shop.run(function() {
ajaxSubmitForm2 = function() {
var url = $('#projector-basket-form').attr('action');
$('#loaders').addClass('loader-koszyk');
$('#blok-koszyk').css('filter','blur(3px)');
clearTimeout(basketAddTimeout2);
$.ajax({
type: 'POST',
url: url,
data: $('#projector-basket-form').serializeArray(),
success: function(data) {
basketAddTimeout2 = setTimeout(function() {
}, 1000)
fetch('/ajax/basket.php').then(res => res.json()).then(({
basket
}) => {
const number = basket.productsNumber;
const number12 = basket.worth_formatted;
$('#kwota-basket').text(number12);
$('#menu_basket .badge').text(number);
$('#badgekoszyka').text(number);
$('.topBasket').load('/basketchange.php?type=multiproduct&mode=2 .topBasket>*', function() {});
$('#loaders').removeClass('loader-koszyk');
$('#blok-koszyk').css('filter','blur(0px)');
document.getElementById("Basket").innerHTML = contentt;
})
},
error: function() {
classObj.alert(classObj.txt.dodano_produkt_blad);
}
});
}
}, 'all')
$(document).on('click', '#usuwanie-koszyk, #dodawanie-koszyk, #usuwanie-calkowite ', function(e) {
ajaxSubmitForm2();
e.preventDefault();
});
You Should call e.preventDefault() at the priority to defend the default action on the element in the second request.
$(document).on('click', '#usuwanie-koszyk, #dodawanie-koszyk, #usuwanie-calkowite ', function(e) {
e.preventDefault()
ajaxSubmitForm2()
});

Animation effect before ajax call

I've watched several tutorials on how to load content without having to refresh the browser. I'm also using history pushState and popstate to update the url dynamically depending on what site that is displaying. However even if this code works, I would like to be able to make som page transition animation effects > call the Ajax function > then make some fadeIn animation effects. So far i've had no luck in trying to do so. I tried to read up on Ajax (beforeSend: function(){}), but the success function seems to execute before the (beforeSend) function. Is there anyone that could point me in the right direction, or tell me what i possibly am doing wrong? I'd appriciate it!
$(document).ready(function() {
var content, fetchAndInsert;
content = $('div#content');
// Fetches and inserts content into the container
fetchAndInsert = function(href) {
$.ajax({
url: 'http://localhost:8000/phpexample/content/' + href.split('/').pop(),
method: 'GET',
cache: false,
success: function(data) {
content.html(data);
}
});
};
// User goes back/forward
$(window).on('popstate', function() {
fetchAndInsert(location.pathname);
});
$('.buttonlink').click(function(){
var href = $(this).attr('href');
// Manipulate history
history.pushState(null, null, href);
// Fetch and insert content
fetchAndInsert(href);
return false;
});
});
Questions? Just ask!
Thanks beforehand!
/// E !
You need to use callbacks. The provided solutions will work, but not necessarily sequentially. $.animate() and $.ajax both run asynchronously. If unfamiliar with this term, here's a good intro: http://code.tutsplus.com/tutorials/event-based-programming-what-async-has-over-sync--net-30027
Here's what I might do:
fetchAndInsert = function(href) {
$('#some-element').animate({'opacity':'0.0'}, 1000, function () {
$.ajax({
url: 'http://localhost:8000/phpexample/content/' + href.split('/').pop(),
method: 'GET',
cache: false,
success: function(data) {
content.html(data);
content.animate({'opacity':'1.0'}, 1000);
}
});
});
};
That will fade out whatever is currently in content, fetch the new data, replace what's currently in content, and then fade back in.
I tried to read up on Ajax (beforeSend: function(){}), but the success
function seems to execute before the (beforeSend) function
You can wait for animation to complete before appending new content to html using .queue(), .promise(), .finish()
beforeSend: function() {
element.queue(function() {
$(this).animate({/* do animation stuff */:500}, {duration:5000}).dequeue()
});
},
success: function(content) {
element.finish().promise("fx").then(function() {
container.append(content).fadeIn()
})
}
var element = $("#loading").hide();
var container = $("#content");
var button = $("button");
var ajax = {
// do asynchronous stuff
request: function() {
return new $.Deferred(function(d) {
setTimeout(function() {
d.resolve("complete")
}, Math.random() * 5000)
})
},
beforeSend: function() {
element.fadeIn().queue(function() {
$(this).animate({
fontSize: 100
}, {
duration: 2500
}).dequeue()
});
},
success: function(content) {
element.finish().promise("fx").then(function() {
element.fadeOut("slow", function() {
$(this).css("fontSize", "inherit");
container.append(content + "<br>").fadeIn("slow");
button.removeAttr("disabled")
})
})
}
}
button.click(function() {
$(this).attr("disabled", "disabled");
$.when(ajax.beforeSend()).then(ajax.request).then(ajax.success)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div id="loading">loading...</div>
<div id="content"></div>
<button>load content</button>
jsfiddle https://jsfiddle.net/ajmL5g1a/
Try this:
fetchAndInsert = function(href) {
// Before send ajax. Do some effects here
$.ajax({
url: 'http://localhost:8000/phpexample/content/' + href.split('/').pop(),
method: 'GET',
cache: false,
success: function(data) {
// After loading. Do some effects here
content.html(data);
}
});
};
My solution:
fetchAndInsert = function(href) {
var timeBeforeAnimation = Date.now(), animationDuration = 500;
/* Do some animation, I assume that with jQuery,
so you probably know how much time is takes - store that
time in variable `animationDuration`. */
/* Run your "before" animation here. */
$.ajax({ ...,
success: function(data) {
/* Check, if request processing was longer than
animation time... */
var timeoutDuration = animationDuration -
(Date.now() - timeBeforeAnimation);
/* ...and if so, delay refreshing the content,
and perform the final animation. */
setTimeout(function() {
content.html(data);
/* Perfom final animation. */
}, Math.max(0, timeoutDuration);
}
});
};
I would probably try using some css for this.
#content {
opacity: 0;
transition: all 1s;
}
#content.fade-in {
opacity: 1;
}
...
const content = $('#content');
const btn = $('.buttonlink');
const success = data =>
content.html(data).addClass('fade-in');
const fetchAndInsert = url =>
$.ajax({ url, cache: 'false' }).done(success);
const getData = function(e) {
e.preventDefault();
content.removeClass('fade-in');
fetchAndInsert($(this).attr('href'));
};
btn.on('click', getData)

Rename file with AjaxForm Jquery

How can I rename my picture before upload ?
I tried this : $('#sortpicture').prop('files')[0] = $('#namePicture').val(); but it doesn't work.
I would like rename my picture with the value from #namePicture
//elements
var progressbox = $('#progressbox');
var progressbar = $('#progressbar');
var statustxt = $('#statustxt');
var submitbutton = $("#SubmitButton");
var myform = $("#UploadForm");
var output = $("#output");
var completed = '0%';
console.log($('#namePicture').val());
$('#sortpicture').prop('files')[0] = $('#namePicture').val();
$(myform).ajaxForm({
beforeSend: function() {
submitbutton.attr('disabled', '');
statustxt.empty();
progressbox.slideDown();
progressbar.width(completed);
statustxt.html(completed);
statustxt.css('color','#000');
},
uploadProgress: function(event, position, total, percentComplete) {
progressbar.width(percentComplete + '%');
statustxt.html(percentComplete + '%');
if(percentComplete>50)
{
statustxt.css('color','#fff');
}
},
complete: function(response) { // on complete
console.log(response.responseText);
myform.resetForm(); // reset form
submitbutton.removeAttr('disabled'); //enable submit button
progressbox.slideUp(); // hide progressbar
}
});
Input[type=file] is readonly, you can only set the value by browsing, not via JavaScript.(security!)
However if you want to send a different name to the server, you can make a input[type=hidden] and set it's value to he filename you want. Then on the server, you give it that name.

Adding Gritter Message After Second Deletion

I'm trying to find out why when a user is deleted by clicking on the ajax-delete class icon and performs the deletion process it shows the gritter message after deletion however if you were to immediately delete another user afterwards it removes the previous gritter message but doesn't show another for that second deletion. Any ideas on why this could be?
EDIT: I have figured out that the issue belongs to the $.gritter.removeAll(); code line. When there is another existing notification it removes it but doesn't add the next notification.
Any ideas what I should do here?
var rowToDelete = null;
var basicTable = null;
var api_url = null;
$(document).ready(function() {});
$(document).on('click', '.ajax-delete', function(e)
{
console.log(basicTable);
e.preventDefault();
//defining it like this captures and optimizing the need to cycle over the DOM more than once
//in subsequent calls to the element specifically
$elem = $(this);
$parentElem = $elem.closest('tr');
rowToDelete = $parentElem.get(0);
api_url = $elem.attr('href');
runConfirmation($('td:eq(1)', $parentElem).text());
});
function runConfirmation(nameSting)
{
$mymodal = $('#myModal');
$('.modal-body p', $mymodal).html('Are you sure you want to delete this <strong>'+nameSting+'</strong>?');
$mymodal.modal('show');
}
$('#myModalConfirm').on('click', function(e) {
$.ajax({
type: 'post',
url: api_url,
data: { _method: 'DELETE' },
dataType: 'json',
success: function(response) {
$.gritter.removeAll();
var className = 'growl-danger';
if (response.status == "SUCCESS") {
className = 'growl-success';
basicTable.fnDeleteRow(basicTable.fnGetPosition(rowToDelete));
rowToDelete = null;
api_url = null;
}
$.gritter.add({
position: 'top-right',
fade_in_speed: 'medium',
fade_out_speed: 2000,
time: 6000,
title: response.title,
text: response.message,
class_name: className,
sticky: false
});
}
});
$('#myModal').modal('hide');
});
Replace the following line:
$.gritter.removeAll();
With
$('.gritter-item-wrapper').remove();

Get the width of an image getted by Ajax

I receive images using an Ajax fonction after clicking on a link, so I don't know their widths.. I want to change the css of the images if they are bigger than 650 px. All the images have the same class name .popup_pics so I did :
$(document).ready(function (e) {
$('a[class*="popup"]').click(function(){
showPics(current); //Ajax call
if ($(".popup_pics").clientWidth > 649) {
alert($("img.popup_pics").width());
}
else {
alert($("img.popup_pics").width());
}
}
}
But it gives me undefined so I think that's because the image isn't loaded yet.
How can I do this ?
Thank you
Wait for the image to load, and then get its width. Something like this should work:
$("img.popup_pics").each(function() {
var img = $(this),
src = img.attr('src'),
image = new Image();
image.onload = function() {
// detect width here
alert(img.width());
};
image.src = src;
});
Don't forget to execute this code only after the AJAX has returned successfully and changed the HTML.
.width (http://api.jquery.com/width/) and .height (http://api.jquery.com/height/) are no properties but jquery functions, so this code works:
http://jsfiddle.net/nQvK3/1/
$(".popup_pics").each(function(index, domElement) {
if (domElement.clientWidth > 649) {
alert(domElement.id + ' is bigger then 649: ' + $("img.popup_pics").width());
}
else {
alert(domElement.id + ' is smaller then 649: ' + $("img.popup_pics").width());
}
});
I have added some more code, here is the new fiddle: http://jsfiddle.net/nQvK3/4/
first do the ajax call to your images source (i commented it out in the fiddle as i can not do an ajax call to your source)
when the ajax call is a success we call the showImages function and pass the response object as first parameter
this function uses jquery each to go through the images array
for each image we create an image tag and then add the image to the dom
we finally measure its width and if it is bigger we apply a class to it to resize it
//-- updated code
$(document).ready(function() {
/*
var request = $.ajax({
url: "images.php?gallery_id=1",
type: "GET",
data: {id : menuId},
dataType: "json"
});
request.done(function(ajaxImagesResultObject) {*/
// this is what ajax returns to you, probably an array of objects
// to test it in your code uncomment the ajax call and comment out the following object
var ajaxImagesResultObject = { imagesArray:
[
{
name: 'stackoverflow small',
url: 'http://blog.stackoverflow.com/wp-content/uploads/stackoverflow-logo-300.png'
},
{
name: 'stackoverflow big',
url: 'http://cdn.sstatic.net/stackexchange/img/logos/careers/careers-logo.png'
}
]
};
console.log(ajaxImagesResultObject);
showPics(ajaxImagesResultObject);
/*});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
*/
});
var showPics = function(ajaxImagesResultObject) {
// foreach image that is contained in the result array
$.each(ajaxImagesResultObject.imagesArray, function(index, imageData) {
var imageElement = $('<img src="' + imageData.url + '" id="' + index+1 + '" title="' + imageData.name + '" />');
// now we add (append) the image inside of the imagesBox element
$('#imagesBox').append(imageElement);
// now we check its width and if it is bigger then 649 we add a resize class
// to save bandwidth images that are too big should get resized on the server not the client
if ($('#' + index+1).width() > 649) {
$('#' + index+1).addClass('imageResizer');
} else {
// do nothing
}
});
};

Categories