0

I have a weird issue regarding jquery Dialog. I am using Jquery dialog for showing jcaptcha image. I have a refresh button on dialog. On click of a link, this captcha dialog should open. My issue is, image refresh button on dialog box. This refresh button works perfectly fine in Google chrome. Refresh button and new image works n number of times in chrome, but in IE 11, my refresh button works only once. It doesn't response anything on second time. I checked DOM values of new rendered image.New image gives new value from server, but still dialog is showing old image. Here is some bit code I am using

I am using JSF h:commandLink to initialize and open the dialog

<h:commandLink id="linkClicked" onclick="return srchPartyNameCaptchaCheck(this)"></h:commandLink>

Below is my Dialog Box content

<h:panelGrid id="captchaGrid" columns="2" styleClass="captchaGridClass" style="display: none;">
        <h:panelGrid columns="1">
            <h:graphicImage id="captchaText" value="/captcha"></h:graphicImage>
        </h:panelGrid>
        <h:panelGrid styleClass="captchaGridClass" columns="1">
        <h:commandButton id="imgCaptchaReload" image="/resources/images/captcha/captchaReload.gif" immediate="true" onclick="return reloadCaptchaPartyName()">
            </h:commandButton>
        </h:panelGrid>
        <h:panelGrid columns="1">
            <h:inputText id="captchaSubmitted" required="true" validatorMessage="Insert text as shown in image" value="#{civilCaseSearchBean.captchaSubmitted}"></h:inputText>
        </h:panelGrid>
    </h:panelGrid> 

Below is my jquery dialog code in javascript

function srchPartyNameCaptchaCheck(e){
  $("#searchByPartyNameForm\\:captchaGrid").dialog({
    autoOpen : false,
    height : 260,
    width : 480,
    modal : true,
    buttons: {
      Submit: function () {//some ajax code for captcha validation},
      Close: function () {
        $(this).dialog("destroy");
      }
  }

Now final pieace of code, which is bothering me. javascript function which reloads image on dialog box. This works perfectly fine on Chrome, but on IE works only once!

function reloadCaptchaPartyName() {
    var d = new Date();

    $.ajax({
        type: "POST",
        url: "../captcha",
        //url: "../CaptchaValidationServlet",
        async: false,
        cache: false,
        success: function() {
        },

        error: function() {
            alert("error");
        },

        complete: function(e) {
            $('#searchByPartyNameForm\\:captchaText').removeAttr("src");
            $('#searchByPartyNameForm\\:captchaText').removeAttr("value");

            $('#searchByPartyNameForm\\:captchaText').attr("src","../captcha");
            $('#searchByPartyNameForm\\:captchaText').attr("value","../captcha"+d.getTime());

        }
    });
}

Only thing I could figure out is, my dialog reference is lost after initialization of it in IE. Due to compatible support of jquery UI, Chrome is working as expected. I am not sure what I am missing or doing wrong. Your help is well appreciated.

Thanks folks

Rohan
  • 23
  • 1
  • 5
  • Welcome to Stack Overflow. I would suggesting adding `console.log()` elements to your `success` and `complete` functions to see which is firing and when. You could add: `console.log($('#searchByPartyNameForm\\:captchaText').attr("src"), $('#searchByPartyNameForm\\:captchaText').attr("value"));` for example. Also I am not sure why you are removing the attributes and then setting them again. – Twisty May 25 '16 at 05:11
  • Thanks for welcome Twisty :). Complete and success both methods are called after the ajax call. I checked in console too for "captchaText" value which is showing "../captcha1464196502431". So captchaText value is changing on every ajax request. I am removing and adding attribute thinking that may be IE is not able to refresh content completely. Also my biggest concern is same piece of code is working fine with chrome, why not in IE! – Rohan May 25 '16 at 17:24
  • Would need to be able to test your code in IE. Can you construct a test at jsfiddle.net or another similar testing site. Then update the post with he link and the version of IE you are testing with. – Twisty May 25 '16 at 18:19
  • Sorry for the late reply. But its bit compilcated to describe my scenario in jsfiddle. But I can explain in detail about my dialog behaviour. My dialog renders image from servlet(SimpleCaptchaServlet from jcaptcha). so every time when I hit refresh button, I am calling servlet again using $ajax({url: /simpleCaptchaServlet}) and in success I overwrite my iamge with servlet value as $("myImageID").attr("value", "/captcha"+new Date().getTime()) – Rohan May 31 '16 at 18:06

1 Answers1

0

I would advise that you actually replace the image and not just the source attribute or property.

For example:

complete: function(e) {
  var newCaptcha = $('<img />', {
    id: "captchaText",
    src: "../captcha",
    value: "../captcha"+d.getTime()
  });
  $('#searchByPartyNameForm\\:captchaText').parent().html(newCaptcha);
}

If there is not a good wrapper, this may take away more than is needed. If this is the case, could also try replaceWith() like so:

complete: function(e) {
  var newCaptcha = $('<img />', {
    id: "captchaText",
    src: "../captcha",
    value: "../captcha"+d.getTime()
  });
  $('#searchByPartyNameForm\\:captchaText').replaceWith(newCaptcha);
}

If this does not help, please make use of the Developer Tools in IE to determine what is happening to these elements or provide the resulting HTML that can better clarify the issue.

UPDATE

If your Ajax call returns an image (JPEG/PNG/GIF), you'd want to handle it in a much different way. Like seen here: Display PNG image as response to jQuery AJAX request

$.ajax({
    type: "POST",
    url: "../captcha",
    contentType: "image/png",    
    error: function() {
        alert("error");
    },
    complete: function(image) {
        $('#searchByPartyNameForm\\:captchaText').attr("src", "data:image/png;base64," + image);
    }
});

The contentType and data will need to fit the Image MIME Type that is being returned by your Captcha script.

Community
  • 1
  • 1
Twisty
  • 30,304
  • 2
  • 26
  • 45
  • Thanks for suggestion @Twisty. I already tried parent.html() thing, it didnt work. One thing I need to mention about the captcha text component. When I see my captcha image source in IE developer tool, I see two different type of tags both time. First time it shows as **bold****bold** and second time it shows as **bold****bold**. Looks like second time my image tag just replace the text value of my servlet call, instead of actually render object value of the ajax response! Doest it make sense? – Rohan May 31 '16 at 19:21
  • @Rohan based on the way you wrote the script, it would replace the Source and Value with the exact string you provided. Based on the previous Source, you're calling the wrong path. If your AJAX call is returning an Image type, you need to handle that in a much different way. When you review your AJAX call in Console, what is being returned? – Twisty May 31 '16 at 19:35
  • Yes, my ajax response is returning png image from my servlet. So my response text would be something like this "�PNG\r\n\u001a\n" – Rohan May 31 '16 at 19:47
  • @Rohan I updated the answer with something that should resolve this. – Twisty May 31 '16 at 19:56
  • Your answer is very close. I tried this method too, but only difference is I was missing to write contentType: "image/png" in ajax request. So now I am adding that part as well and my response is like ""! – Rohan May 31 '16 at 20:18
  • It's interesting that an Object is being returned. I would add `console.log(image);` to your complete function to examine the response data. – Twisty May 31 '16 at 20:24
  • Yes, I wonder it is responding as a object! First time its absolutely fine with the code I wrote. I am not getting what is it happening different on second call! One thing I could doubt is, on first call my page is holding reference of jquery dialog. On second call, IE is not submitting my request at all! But I am not sure how to confirm that thing – Rohan May 31 '16 at 20:57
  • @Rohan you could create a `beforeSend` function like so: `beforeSend: function() { console.log("Calling Ajax now.") }`. Also, what should the source be? is it `../captcha` or just `/captcha`? They are pretty different. Maybe test by navigating directly to both paths. See what results come to the browser. – Twisty May 31 '16 at 21:04
  • source path is ../captcha. I just tried $("#searchByPartyNameForm\\:captchaGrid").dialog({....}).parent.appendTo("searchByPartyNameForm");. After adding this surprisingly my refresh button is working twice now! but not third time. I think I should look towards creation of my dialog box instead of server call. – Rohan May 31 '16 at 21:12
  • It might help to embed the script code into the Dialog's HTML. That way it's always available when the dialog loads (or reloads if the case may be). – Twisty May 31 '16 at 21:15
  • yes, I am going to try few things in dialog. I will surely update you if I am done. Thanks a lot for your time. I really appreciate – Rohan May 31 '16 at 21:33