How to change a div background image? - javascript

Peace and Blessing be Upon us all.
Basically I have a div say:
<div class="divele" style="background: url("/image/bkimg.jpg") top center no-repeat;background-size:cover;"></div>
Then I have an upload button which the user can select an image from his/her computer and save it in the database. After the XHR response with file being saved. The server respond with the new image link the same as /image/bkimg.jpg which this time the old image has replaced with the new uploaded one. Now I need the div to re-request the new image from the server. and this is what i'm doing:
var parts = result;
$('.divele').css({"background": "url("+parts+") top center no-repeat", "background-size": "cover"});
Don't really know why But this does not load the new image.
Much regards

Thanks to this Answer: How to reload/refresh an element(image) in jQuery
Which Explains because both names are the same the browser uses the cached version, which in order to fix it you can simply add an extra unnecessary parameter which will look like:
d = new Date();
$('.divele').css({"background-image": "url("+result+"?"+d.getTime()+")"});

Related

Angular-Cli force component to reload image cache

I have a project in Angular CLI, it has the lft menu (where I store some navigation and user informations include user image. On the right side there is other part of page.
I have a feature that user can change his image. Its working like charm but when I change it, the picture in the left menu is old one (the URL is the same, when I past URL to the browser I can see the new image). I guess its becouse the left panel wont refresh when I upload new image si It has cache of old image.
Is there any way how to solve it? Something like force component to refresh, delete image cache etc?
If I understand, the browser doesn't do request to image, because it's cached. It's because image path is the same.
So you can put timestamp to image path at the end:
// <img [src] = '/path/to/image?timeStamp=123123' />
class SomeComponent{
imageSrc: string = '/path/to/image';
// getTimeStamp(): number{
// return Date.now();
// }
// or call this when you need update image
updateImageSrc(): string{
this.imageSrc= `/path/to/image?timeStamp=${Date.now()}`
}
}
Update:
<img [src] = "imageSrc" />
Code example. Look at network tab

Dynamically replace data inside a div container

What is the best way to load data dynamically inside a DIV container?
Let's say I have a number of pictures on a page. Clicking a picture opens a DIV container on the screen (no page refresh) which contains all comments for that image.
At the moment I am sending an AJAX request to load comments from the DB and echo them out in another page. I am then appending that data, with jQuery, inside the DIV container. Clicking on another image clears the container and new data is loaded vie new AJAX request.
It just seems to me that this might not be the most efficient way of doing it, because if the user is going back and forth clicking on images on the page, then data has to be reloaded every single time.
I see that facebook changes the URL every time when a new image is selected. So may be they use an ID from the URL to load the data without sending an AJAX request?
May be once data is loaded and another image is selected, it will be better to just hide the old image comments on the page rather than discard them ? So that if the image is clicked again, it will not be required to reload its data?
Here is an idea as to how you may avoid making frequent/duplicate ajax requests for the same image.
Say you've a function to draw comments in your div that acepts the reponse from the server, such as:
function displayComments(resp) {
//Do stuff
}
And let's assume an ajax call on image click looks like the following.
//We're probably better of using the wrapper (class/ID) of images to
//delegate events since setting/unsetting data may cause problems
//if we'd used bind on images directly
$("imagesContainerSelector").on("click", "img", function() {
var $this = $(this);
//See if comments have already been fetched previously.
//If yes, we'd have stored them as that image's data and
//we'd now simply use that data to display the comments.
if ( $this.data("comments") ) {
displayComments($this.data("comments"));
} else {
//We've not fetched comments for this image yet, so, fetch it
$.ajax({
url: '...',
data: '...'
//more options
}).done(function(data) {
//When done, display comments
displayComments(data);
//Set the resp as data for later use
$this.data("comments", data);
});
}
});
If you respecify the < img >-Tag inside some div so the pictures get loaded after you do that. If you specify the same picture twice or more times, the image is already in the cache of most browsers. Thatwhy you can just do something like
$('#divid').html(' < img src="..." > ');
If you want to preload your pictures, I would put some images into some very small div aside somewhere. If you put pictures into a hidden container some browsers wont preload them.
In case you stored your pictures into some database or memcache, use caching-headers. You might program some outputpicture.php?id=12345.
In that case something like
header('Content-Type: '.get_img_type($data));
header('Content-Length: '.strlen($data));
header("Pragma: public");
$expires = 60*60*24*14;
header("Cache-Control: maxage=".$expires);
header("Last-Modified: Mon, 26 Jul 1984 05:00:00 GMT");
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
could help alot.
you can add your get address in javascript object , and map the content loaded to it, every time you make ajax request.
then when user clicks on the image, instead of sending an ajax request, first check if you have that request in the object to load it from there, if you haven't the address in the object then you can proceed and send an ajax request and save its result to the object I mentioned.

dynamic img-src with placeholder image

I all I have the following predicament. I unfortunately can't share a plunkr as the image is coming from a protected site and I am not aware of any open URL that serves constantly changing images. I can't switch to a local animated image as it needs to be on an external server to demonstrate the problem. But the concept is pretty straight forward.
I have the following URL that I am using to display an image. Now the server that is sending this image is constantly changing this image at approximately 3 frames per second.
<img ng-src="{{LoginData.url}}/cgi-bin/nph-zms?mode=jpeg&monitor={{monitorId}}&maxfps=3&buffer=1000&user={{LoginData.username}}&pass{{LoginData.password}}&rand={{rand}}" width="100%" style="backgroundimage:url('http://placeholder.com/placeholder.jpg');"/>
Now here is the problem: -- I want to show a place holder text or image for the following instances:
a) Sometimes, it takes time for the server to render the first frame
b) Sometimes the server just does not seem to send images
What I really want to avoid is the screen not remaining blank - that confuses the user
The problem I am facing is that the moment img-src start, the screen turns white and in a few seconds the images start streaming (situation a above) or the screen remains blank for a long time (situation b)
I've tried various methods:
a) As you see in the code above, I've tried a background image. That only shows if an error is returned by the img-src (for example, I forcibly change the url to an invalid one or its not reachable). What is happening with me is that it shows up momentarily, but the moment img-src is encountered the screen turns white (till images start coming from the server)
b) I've tried various methods including the app.directive global image trap method in if a ngSrc path resolves to a 404, is there a way to fallback to a default?
But the core problem really is that my situation does not involve an error in the image. It seems like as if the server gets stuck or delayed but its not returning an error in HTTP ==> and in that duration, my window for the image turns white. And I'd like to solve that by putting in a text on top of it (or an image on top of it), but only till real images start being received.
Thank you
for my own need, I made a directive displaying a placeholder image if the servers has an error :
.directive('placeholderImg', function() {
//default place holder
return {
restrict: 'A',
link: function(scope, element, attr) {
var img = window.scriptRoot + 'img/divers/avatar_min.jpg';
if (attr.placeholderImg) {
switch (attr.placeholderImg) {
case 'profile':
img = 'img/avatar.png';
break;
case 'profile_small':
img = 'img/avatar_min.png';
break;
case 'profile_large':
img = '/img/nothumb.png';
break;
//Add more placeholders
}
}
//If ngSrc is empty
if (!attr.ngSrc)
element[0].src = img;
//If there is an error (404)
element.on('error', function() {
element[0].src = img;
});
}
};
});
And I use it like this:
<img data-ng-src="{{app.picture}}" data-placeholder-img="profile_large">
I understand that your main issue is that you want to display something while the image is loading. Maybe you can modify my directive, to set element[0].src to a placeholder at the beginning of the code and overloading it by binding the load event once it's loaded (the same way I have bound the error event).
Moving away from having most of the logic on the JS size I propose using background image in css instead. We can have a tiny little icon on top of a grey background as our placeholder and then when the image url has loaded we use the power of zindex to overlay the image on top of the color and icon. I wrote a post about it here.

plupload - upload button works only if click is triggered programatically

I am using plupload 1.5.7. I have two buttons on page:
First one (Add new attachment) was used as browse_button in plupload configuration. When I click it, it doesn't work. Click event is executed, but file browser is not opened. But there is second button (Trigger add new attachment click), which only does this:
$('#TriggerAddNewAttachmentClickButton').click(function() {
$("#AddNewAttachmentButton").click();
})
So it only triggers click of the first button. It works fine. Clicking it opens file browser.
How is this possible? This behavior is consistent between Firefox, Chrome and Internet Explorer.
Obviously this is security related, because plupload uses tricks to hide input, but second method is not safer. I can't reproduce this issue in jsfiddle, it exists only in specific context, but maybe there is someone, who ecountered similar behaviour.
I got a similar issue with plupload. I digged into this issue for hours, and finally I find the reason. As #jbl said:
I guess I remember I had this kind of problem when the container was not visible upon plupload initialization. Could it be the same problem ?
The way of plupload working is as following:
Remember you need to set a browse_button? Actually the plupload will create an input[type="file"] for each browse_button. In normal situation, the size and position of the input[type="file"] will be the same with the browse_button exactly. So when you click the browse_button, it's not the button trigger a file chooser dialog popping up, it's the input[type="file"].
But when you set the browse_button container something like: display:none(we say, inactive), and after that even you set back the display:block(we say, active), the width and height of the input[type="file"]'s parent container would be zero some time.
My quick fix solution for this issue is as following:
I measure the position and size of the browse_button when change the state of the container from inactive to active. Then I'll manually set the position and size to the hidden input[type="file"];
Following is some sample code:
var $btn = $currPanel.find(".browse_button");
var w = $btn.outerWidth();
var h = $btn.outerHeight();
var position = $btn.position();
var $hiddenInputDiv = $currPanel.find(".moxie-shim");
$hiddenInputDiv.height(h);
$hiddenInputDiv.width(w);
$hiddenInputDiv.css(
{
top: $btn.css("margin-top"),
left: position.left
});

How can I regain program control after <cfheader> opens a PDF file?

This is a ColdFusion 8 question.
I have a cfm page that has a button that onClick calls the following Javascript function located in the page header:
function confirm_expiration_letters() {
var resultOfConfirm = confirm("Would you like to send expiration and reminder letters?");
if (resultOfConfirm == true) {
document.body.style.cursor = "wait";
window.location="_expiration_letters.cfm";
}
}
On the page that is called, a series of emails are generated, then a PDF report file is generated and displayed using these two lines:
<cfheader name="Content-disposition" value="attachment;filename=#fileName#">
<cfcontent type="application/pdf" file="#docPath#/#fileName#" deletefile="true">
Notice in the JS function that the cursor is changed to "wait". But the program control appears to get lost after the above cfheader call and so I can't find anywhere that I can reset the cursor back to:
document.body.style.cursor = "default";
Do you have ideas on where I can place this to turn off the cursor animation? I tried multiple places and it doesn't work. Once the cfheader and cfcontent calls happen, control of previous window and cursor are lost it appears.
You might try something like this above the cfheader.
<script>
document.body.style.cursor = "default";
</script>
<cfflush/>
The problem is that doing so might (probably will) screw up the cfheaders since cfflush is designed to flush partial results and will include the headers. But it's the only thing I can think of.
If I understand you correctly, you want to have a "wait" cursor whilst the PDF is prepped, and then return to a standard cursor after that.
Don't web browsers do this automatically when you're waiting for a requested document? IE: as soon as you do your window.location, whilst the document is loading, the cursors automatically changes to a "wait", and then once the doc is served, returns to an "auto".
This is what I see (when running code similar to yours). Is this not what you see?
Instead of changing the cursor, display a loading message using HTML/animated gif. When the PDF loads, it will replace the loading screen.
I would suggest having a hidden div containing your loading message, then use JavaScript to make it appear when needed.
Here's some JavaScript. This is how it would be done with jQuery.
function confirm_expiration_letters() {
var resultOfConfirm = confirm("Would you like to send expiration and reminder letters?");
if (resultOfConfirm == true) {
$('#Loading').fadeIn(); //SHOW THE LOADING INDICATOR
$.post('PDFGenerator.cfm', function(returnData){ // AJAX POST, CALLBACK
//RETURN THE FILENAME OR LOCATION OF THE PDF
var FileName = $.trim(returnData); // TRIM THE RETURNED DATA
window.open("path_to_file/" + FileName,"_blank"); // NEW WINDOW
$('#Loading').fadeOut(); // HIDE THE LOADING INDICATOR
});
}
}

Categories