views:

828

answers:

7

I have a jQuery function that I'm having a minor problem with:

$(function() {
  $("a.CompletedCheckBox").click(function() {
    if($(this).hasClass("CheckedCompletedCheckBox")) {
      $(this).removeClass("CheckedCompletedCheckBox");
    } else {
      $(this).addClass("CheckedCompletedCheckBox");
    }
      $.get("/Tasks/Complete/" + this.id, "", function() {});
  });
});

The first time I click the link, the event function works as expected. However each subsequent time I click the link, the class toggles correctly, however the $.get request does not fire.

Any idea why the request to the server only fires the first time?

EDIT: Here is the markup that I am using:

<table>
  <tr>
    <th>
      Header Text
    </th>
    ... and so on ...
  </tr>
  <% foreach (var item in Model as Item[])
  {%>
  <tr>
    <td>
      <a href="#" 
         class='<%= "CompletedCheckBox " + (item.Complete ? "CheckedCompletedCheckBox" : "") %>' 
         id='<%= item.ID %>'></a>
    </td>
    ... and so on ...
  </tr>
  <% } %>
</table>

EDIT 2: This works fine in FireFox, but not IE7. I would like to support IE in my app, so I need to come up with why this isn't working for IE.

I'm loading jQuery from Google (http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js), if it make any difference.

A: 

Is this the exact code that your executing? So the a.CompletedCheckBox will also have a class of CheckedCompletedCheckBox also?

That seems like it should work... but if your using other selectors in your actual code i could see how this could go wrong.

Do you have any sample markup?

youdontmeanmuch
+2  A: 

Just one thing, you can simplfy one aspect:

$(function() {
  $("a.CompletedCheckBox").click(function() {
    $(this).toggleClass("CheckedCompletedCheckBox");
    $.get("/Tasks/Complete/" + this.id, "", function() {});
  });
});

Your .get() call looks OK. Remember though that browsers will tend to limit the number of simultaneous Ajax requests (to 2 or less typically). Are you sure your call is returning? Have you considered using the .ajax() call instead and specifying a timeout and/or error handler so you can see what's going on?

EDIT: Tried the following code and it works perfectly. You've got something else going on.

<html>
<head>
  <title>Test Get</title>
  <style type="text/css">
    .CompletedCheckBox { background-color: yellow; display: block; }
    .CheckedCompletedCheckBox { border: 2px solid black; }
  </style>
</head>
<body>
</body>
<a id="abcd" class="CompletedCheckBox">Click me</a>
<script src="http://www.google.com/jsapi"&gt;&lt;/script&gt;
<script>
  google.load("jquery", "1.3.1");
  google.setOnLoadCallback(function() {
      $(function() {
       $("a.CompletedCheckBox").click(function() {
          $(this).toggleClass("CheckedCompletedCheckBox");
          $.get("/test2.php?id=" + this.id, "", function() {});
        });
      });
    });
</script>
</html>

and

<?php
error_log("User pressed link for id $id");
?>

Well, the id wasn't coming through but the error log was with each click.

cletus
I am using Fiddler (http debugging proxy) to see requests made to the server, so I can see in real time what is returning, and what is not.
Kyle Trauberman
I followed your suggestion to use .ajax instead, and the same issue occurs.
Kyle Trauberman
+1  A: 

I had no problems executing your code locally. Each GET would return, even after setting a Thread.Sleep on the server.

Does your "/Tasks/Complete/" url return anything? HTML, plain-text, json?

What browser are you using? Does this problem persist across all browsers? I would try using FireFox with the FireBug add-on to see in its Console what is returned.

Let us know what you find!

Jarrod Dixon
I'm using IE7 on Windows XP SP3 (running in a VM). I had the same idea, and am downloading FireFox right now.
Kyle Trauberman
FireFox works fine. Its curious that this doesn't work in IE7. If it makes any difference (I don't think it does), I'm loading jQuery from google.
Kyle Trauberman
In my controller, I'm returning an EmptyResult. Could this be caused by nothing being returned?
Kyle Trauberman
A: 

Yes, post a demo please?

I tried using an excerpt of your code, but it works fine.

I suppose it could be that you are remove() -ing a.CompletedCheckBox from the DOM?

I encountered the issue in 1.2.6, where you remove (and add) some element, the event never fires again.

That's documented here:

http://docs.jquery.com/Manipulation/remove#expr

Since you're using 1.3.1, you can try using live().

Here's a demo:

http://waynekhan.com/sandbox/index.php/demo/get

The link in the red box will always work, because we don't call remove(). The link in the blue box works only once, because we call remove(). This could be your issue. The link in the green box works, because we call remove(), but we're using live(), not click().

Wayne Khan
+3  A: 

IE is likely caching the result of the $.get() request. Try adding a timestamp to the URL of the get request, as such:

var myDate = new Date();
var timestamp = myDate.getTime();
$.get("/Tasks/Complete/" + this.id + '?t=' + timestamp);
rmurphey
Found this thread as was having the same issue. Thanks for the tip rmurphey, it fixed it for me. Insert angry rant about IE here...
CountZero
A: 

I knowt his is an old question now... but IE7 is overzealous with caching the HTTPXML object... so you have to either:

  • put some random data at the end of your url (as rmurphy said)
  • use the $.post() method instead, as IE doesnt cache POSTs
  • set your cache timeouts in the server response so that IE doesnt cache:
    Cache-Control = "no-cache"
    Pragma = "no-cache"
    Expires = "0"
Nick Franceschina
A: 

this worked for me: Response.Expires = -1;

Michal Utikal