views:

62

answers:

3

Hello,

I have a table which repeats an image link to a file download for every row of data. I want to use Jquery or Javascript to detect if a image link returns a 404 error, meaning the file its trying to find doesn’t exist, then set the image link to display:none so its hidden.

Any help is much appreciated!

Jamie.

---Edit---

This is my url which needs to be set to hidden if it cant find the .igs file

<a href="/path/to/file.igs"><img src="pic.jpg" alt="My Image Link"></a>

Unfortunately I cannot utilize server-side processing.

+4  A: 

You can use the error() event handler:

$("img").error(function () {
    $(this).css("display", "none");
});


I see that a few of us misunderstood your origin question, your edit clears it up a little. You can achieve what you want only by using AJAX. Just requesting the headers for the file should be enough:

// Find all <a> tags where href ends with .igs, hide and loop over them 
$("a[href$=.igs]").hide().each(function (i, el) {
    $.ajax({
        type: "HEAD",
        url: el.href,
        success: function () {
            // Success, we can unhide the element.
            el.show();
        }
    });        
});

Of course, this won't work if the files are on other domains. Also, this can be quite a costly procedure for both the client and the server if there's a lot of them.

Andy E
note that any loading error will trigger this, not just 404
Matthew Lock
@Matt: yes, that's right. Thank you for pointing that out :)
Andy E
Thank you for your rapid response! Actually rather than detect if an image exists im trying to detect if a file exists.Here is my image link, if it returns with a 404 error I dont want it to display the image. <a href="path/to/file/file.igs"><img src="cad.jpg" alt="My Image Link"></a>
Macker
The issue here is that the url of the <a> element is not invoked until the user clicks on it, but I assume that you want to display/hide the image as soon as the page loads.In which case, if you are dynamically generating the HTML on the server side, I'd tend to do the checks as the page is being rendered and relieve the client side of a task that is better suited to server-side processing. This would then also work for browseers with javascript disabled.
belugabob
I agree that is how I would do it in an ideal world but unfortunately we have no server-side processing available, which is why im trying to find a work around.
Macker
@user: I've updated my answer with a possible solution.
Andy E
Thanky you Andy E, think that is what I need!What would I need to change if anything to get this to work, at the moment Im using your code in the head of the page which contains the repeat url element. Do I need to set an ID? how do I get it to work?
Macker
@Macker: I would use a *className* for the links if possible, to make it a little more dynamic. The selector I used here will only work for links to *.igs* files. Make sure you're running it after the `<a>` elements have been parsed, either place the script below them in the document's body (recommended) or place it inside `$(document).ready(function () { /* code here */ });`.
Andy E
+1  A: 

you can also use this trick,

$('img').hide().load(function(){
    $(this).show();
});

this will hide all the images then show it when it loads completely.

Reigel
+1  A: 

Or you could use a combination of the two answers provided by Reigel & Andy E, by having an extra image that gets displayed when an error occurs...

.downloadedImage, .downloadFailed { display:none; }

<table>
    <tr>
        <td>
            <img class="downloadedImage" src="imageUrl1.jpg"/>
            <img class="downloadFailed" src="downloadFailed.jpg"/>
        </td>
    </tr>
    <tr>
        <td>
            <img class="downloadedImage" src="imageUrl2.jpg"/>
            <img class="downloadFailed" src="downloadFailed.jpg"/>
        </td>
    </tr>
    <tr>
        <td>
            <img class="downloadedImage" src="imageUrl3.jpg"/>
            <img class="downloadFailed" src="downloadFailed.jpg"/>
        </td>
    </tr>
</table>

$("img.downloadedImage").load(function(){
    $(this).show();
}).error(function(){
    $(this).next().show();
});

The important thing to note here (If my thinking is correct) is the timing of the jQuery execution. If it's run too soon, the DOM elements won't be available to assigne the event handlers to them - if it's run too late, the event handlers will be attached after the events have occurred. You may have to experiment between placing the jQuery snippet at the end of the page and placing it in a $(document).ready handler.

UPDATE A quick experiment shows that the script snippet performs best at the end of the page (Or just after the table definition), rathe that in the $(document).ready handler.

belugabob