0

I have the following jQuery code in my Nagios extension for Mediawiki which refreshes content in a page at given intervals. This works fine for the divs, but is not updating the images (graphs). For example, here is the html for one of the graphs embedded in the page,

<img id="pnp4img1" class="graph" src="http://rouser:ropass@192.168.1.2/pnp4nagios/image?host=aws-us&amp;srv=Check_MK&amp;view=0&amp;graph_width=500&amp;graph_height=100">

I know there are other ways of updating the image by updating the src attribute but I'm really trying to stick with the function below and pull the image data from the ajax response.

Hope someone can help :)

(function(mw, $) {

    var nagiosRefreshInterval = mw.config.get('wgNagiosRefresh') * 1000;
    mw.hook('wikipage.content').add(function($content) {
        setTimeout(worker, nagiosRefreshInterval);
    });

    function worker() {
        $.ajax({
            url: location.href,
            success: function(data) {
                var $data = $(data);
                $(".qtip").remove();
                $('.status, .stateInfoPanel, img.graph').each(function(i, obj) {
                        if (obj.id != "") {
                        var id = '#' + obj.id;
                        console.log("id=" + id);
                        $(this).html($data.find(id));
                    }
                })
            },
            error: function() {
                console.log("An error occured with the refresh");
            }
        });
        // Schedule the next request when the current one's complete
        setTimeout(worker, nagiosRefreshInterval);
    }

})(mediaWiki, jQuery);
Edward
  • 33
  • 8
  • 1
    Can we have fiddle of the same ? – Rayon May 03 '15 at 10:51
  • `if (obj.id != "") { }` what happend to `else`? what if the `obj.id` is an empty string? please provide a jsfiddle. – odedta May 03 '15 at 10:52
  • To reload the image you can change the src of the image by adding an extra parameter time to forcefully reload tue graph image. – Marin Bînzari May 03 '15 at 11:03
  • @SpartakusMd yes I realise that but as I said above I wanted to pull the image data from the ajax response. This is to avoid making more than one call to the server for the same resource. – Edward May 03 '15 at 11:14
  • @RayonDabre, I just wanted the code to skip elements if there wasn't an id. Showing this in jsfiddle is a little tricky as it's a wiki page, but I added the parsed output here jsfiddle.net/5fzp3wrt – Edward May 03 '15 at 11:17
  • @Edward, can you check whether src attribute value of imag tag is being changed or not ? – Rayon May 03 '15 at 11:20
  • No it's always the same eg, /pnp4nagios/image?host=aws-us&srv=Check_MK&view=0&graph_width=500&graph_height=100. The server shows this getting requested and a 200 returned. I have caching disabled and if I hit the browser refresh button, the image does get updated. – Edward May 03 '15 at 11:25

1 Answers1

3

You can't use .html() on image, since it dosen't have HTML content. That's why it only works on divs.

If element is image, you should use .replaceWith() to replace it with new.

(function(mw, $) {

    var nagiosRefreshInterval = mw.config.get('wgNagiosRefresh') * 1000;
    mw.hook('wikipage.content').add(function($content) {
        setTimeout(worker, nagiosRefreshInterval);
    });

    function worker() {
        $.ajax({
            url: location.href,
            success: function(data) {
                var $data = $(data);
                $(".qtip").remove();
                $('.status, .stateInfoPanel, img.graph').each(function(i, obj) {
                    if (obj.id != "") {
                        var id = '#' + obj.id;
                        console.log("id=" + id);

                        // If is image, replace it
                        if(this.tagName == 'IMG'){
                            $(this).replaceWith($data.find(id).clone());
                        }
                        // Other elements
                        else{
                            $(this).html($data.find(id));
                        }
                    }
                })
            },
            error: function() {
                console.log("An error occured with the refresh");
            }
        });
        // Schedule the next request when the current one's complete
        setTimeout(worker, nagiosRefreshInterval);
    }

})(mediaWiki, jQuery);

Alternative would be to have wrappers for every image. Let's say .imageWrapper and refresh those instead of img.graph.

Your selector would be

$('.status, .stateInfoPanel, .imgWrapper')
Rene Korss
  • 5,414
  • 3
  • 31
  • 38
  • or better: `if( this.tagName == 'img' )` – vsync May 03 '15 at 12:52
  • Yes, @vsync, thats better. Edited my answer. Thanks! – Rene Korss May 03 '15 at 12:58
  • @ReneKorss/@vsync Thank you so much! I was stuck on this over a week so this really helps me. It seems to work without the .clone() call on the end there so not sure if that adds any benefits? One issue is that the page flashes when the images get updated. Do you know how to prevent that? – Edward May 03 '15 at 14:35
  • Yes, it works without `.clone()` too. If you are not using `.clone()` then element will be removed from original source. In your case, it's no problem. Page flashing probably gomes from loading images again. For small time there is no content for image and all elements move in page to fill it. You should preload images before replacing them. See [this](http://stackoverflow.com/questions/476679/preloading-images-with-jquery) question. – Rene Korss May 03 '15 at 14:43
  • @ReneKorss Thanks again. I tried to do that but couldn't get it to work so for now have resorted to using `// If is image, replace it if(this.tagName == 'IMG'){ //$(this).replaceWith($data.find(id)); var imgsrc=$data.find(id).attr('src'); $(this).attr('src', imgsrc)}` which is doing the job, but unfortunately makes 2 requests instead of one. – Edward May 04 '15 at 15:24
  • @Edward Does it make 2 requests if you load new data or first on page load and second if content is reloaded? Maybe you have two images with same `src`? Also, could you accept my answer so it wont stay as unaswered? – Rene Korss May 04 '15 at 16:01
  • @ReneKorss, apologies I didn't know about accepting the answer. That should be done now assuming that's the green tick :) Also not sure if this is what you meant but the first request comes from the ajax call which gets the whole page, then second request comes from updating the src attribute. This is what the server logs when the refresh kicks in http://fpaste.org/218261/30756336/ – Edward May 04 '15 at 16:20
  • @ReneKorss on second thoughts ignore that. I still see those 2 requests when using the replaceWith method. I've confused myself now :) – Edward May 04 '15 at 16:32
  • @Edward Yes, green tick means accepted answer. This is perfectly normal. After making call to `.ajax()` jQuery instantly loads whole page. You option is to change `src` attribute, so they wont be loaded. For examlpe to `data-src` and then get it with `$data.find(id).data('src')`. Read [this answer](http://stackoverflow.com/a/6485092/1960712). Hope it makes it more understandable for you. – Rene Korss May 04 '15 at 16:36