views:

102

answers:

3

I have the following snippets of code. Basically what I'm trying to do is in the 1st click function I loop through my cached JSON data and display any values that exist for that id. In the 2nd change function I capturing whenever one of the elements changes values (i.e. yes to no and vice versa).

These elements are all generated dynamically though the JSON data I'm receiving from a webservice. From my understanding that is why I have to use the .live functionality.

In Firefox everything works as expected (of course). However, in IE7 it does not. In IE7, if I select a radio button that displays an alert from the click function then it also adds to the array for the changed function. However, if the radio button does not do anything from the click function then the array is not added to for the change.

As I look at this code I'm thinking that I might be able to combine these 2 functions together however, right now I just want it to work in IE7.

$(document).ready(function () {
    //This function is run whenever a 'radio button' is selected.
    //It then goes into the CPItemMetaInfoList in the cached JSON data
    //($.myglobals) and checks to see if there are currently any 
    //scripts to display.

$("input:radio").live("click", function () {
    var index = parseInt(this.name.split(':')[0]);
    for (i = 0; i <= $.myglobals.result.length - 1; i++) {
        if ($.myglobals.result[i].CPItemMetaInfoList.length > 0) {
           for (j = 0; j <= $.myglobals.result[i].CPItemMetaInfoList.length - 1; j++) {
                if (index == $.myglobals.result[i].QuestionId) {
                    alert($.myglobals.result[i].CPItemMetaInfoList[j].KeyStringValue);
                    return;
                }
            }
        }
    }
});
});

$(document).ready(function () {
    var blnCheck = false;
    //Checks to see if values have changed.
    //If a value has been changed then the isDirty array gets populated.
    //This array is used when the questionSubmit button is clickeds
    $('input').live('change', function () {
        blnCheck = false;

        for (i = 0; i <= isDirty.length - 1; i++) {
            if (isDirty[i] == $(this).attr("name")) {
                blnCheck = true;
                break
            }
        }


    if (blnCheck == false) {
        isDirty[arrayCount] = $(this).attr("name");
        arrayCount += 1;
        alert($(this).attr("name"));
    }
});

$('textarea').live('change', function () {
    blnCheck = false;
    for (i = 0; i <= isDirty.length - 1; i++) {
        if (isDirty[i] == $(this).attr("id")) {
            blnCheck = true;
            break
        }
    }

    if (blnCheck == false) {
        isDirty[arrayCount] = $(this).attr("id");
        arrayCount += 1;
        //alert($(this).attr("name"));
    }
});
});

UPDATE:

I had to move this chunk of code into the click function:

   blnCheck = false;
   for (i = 0; i <= isDirty.length - 1; i++) {
        if (isDirty[i] == $(this).attr("name")) {
            blnCheck = true;
            break
        }
    }


    if (blnCheck == false) {
        isDirty[arrayCount] = $(this).attr("name");
        arrayCount += 1;
        alert($(this).attr("name"));
    }

Like this:

     $(document).ready(function () {
     //This function is run whenever a 'radio button' is selected.
     //It then goes into the CPItemMetaInfoList in the cached JSON data
     //($.myglobals) and checks to see if there are currently any 
     //scripts to display.

     $("input:radio").live("click", function () {
         var index = parseInt(this.name.split(':')[0]);
         for (i = 0; i <= $.myglobals.result.length - 1; i++) {
             if ($.myglobals.result[i].CPItemMetaInfoList.length > 0) {
                for (j = 0; j <= $.myglobals.result[i].CPItemMetaInfoList.length - 1; j++) {
                     if (index == $.myglobals.result[i].QuestionId) {
                         alert($.myglobals.result[i].CPItemMetaInfoList[j].KeyStringValue);
                         return;
                     }
                 }
             }
         }
         blnCheck = false;

         for (i = 0; i <= isDirty.length - 1; i++) {
             if (isDirty[i] == $(this).attr("name")) {
                 blnCheck = true;
                 break
             }
         }

      if (blnCheck == false) {
          isDirty[arrayCount] = $(this).attr("name");
          arrayCount += 1;
      }

     });
});

But...

I had to leave the change function the same. From my testing I found that the .click function worked for IE7 for the radio buttons and checkbox elements, but the .change functionality worked for the textboxes and textareas in IE7 and FF as well as the original functionality of the radio buttons and checkbox elements.

This one got real messy. Thanks to @Patricia for looking at it. Here suggestions did lead me to this solution. I'm going to leave the question unanswered as I wonder if there isn't a cleaner solution to this.

+1  A: 

I think this is because IE fires the change when focus is lost on checks and radios. so if the alert is popping up, focus is being lost and therefor the change event is firing.

EDIT:

try changing the $('input') selector to $('input:not(:radio)')

so the click will fire for your radios and the change for all your others.

Edit #2:

How bout putting the stuff that happens on change into a separate function. with the index as a parameter. then you can call that function from the change() and the click(). put the call to that function after your done with the click stuff.

Patricia
OK, I was actually just testing again and noticed that it appeared to be doing the change first and then the click (only on the ones that have a result in the click event). So how would I correct this? Is there a different way for me to arrange my code that would be "better"?
Jeff V
that, i am not entirely sure of. would moving everything tha tyou have in the "change" section to after the code you have in the "click" section produce your expected results?
Patricia
scratch that. see my edit
Patricia
I still need the change to fire for the radios too though.
Jeff V
oooooh.... see my new edit.
Patricia
@Patricia - your first suggestion was sort of right. It is really weird though. As the radio buttons and the checkboxes needed to be moved to the click function for IE7, but I had to leave the functionality in the change function for textboxes. So I had to do a little duplication. Thanks for your help. I'll update my question. If anyone has a better solution then I'm up to hearing it.
Jeff V
A: 

You're declaring your blnCheck variable inside one of your document.ready() functions (you don't need two of these either, it could all be in one.

This means that the variable that you're declaring there won't be the one used when your change function is actually called, instead you're going to get some kind of implicit global. Don't know if this is part of it, but might be worth looking at. You should declare this at the top of your JS file instead.

Paddy
+2  A: 

Fact: change event on radio buttons and checkboxes only get fired when the focus is lost (i.e. when the blur event is about to occur). To achieve the "expected" behaviour, you really want to hook on the click event instead.

You basically want to change

$('input').live('change', function() {
    // Code.
});

to

$('input:radio').live('click', functionName);
$('input:not(:radio)').live('change', functionName);

function functionName() {
    // Code.
}

(I'd however also take checkboxes into account using :checkbox selector for the case that you have any in your form, you'd like to treat them equally as radiobuttons)

BalusC
@Jeff: Since you marked this answer accepted, may I assume that your problem is solved? Don't forget the bounty, it's not automatically awarded on accepting of the answer. It needs to be done separately.
BalusC
@BalusC - yes that is a good solution. There is a time limit for the bounty... I can't do it for another 46 minutes!
Jeff V
@Jeff: Good, you're welcome. Ah OK, didn't knew about that limit. Thanks for reminding!
BalusC