views:

212

answers:

2

Hi everyone, I am trying to achieve this task using MooTools.

Description:

I have three buttons. Two buttons outside myDiv and one button inside myDiv.
A click on any of these buttons initiates an AJAX request (passing button variable to "button.php") and updates myDiv content based on the response text.
So, after update, myDiv shows Button3 link + a message showing which button has been clicked.

The problem:

Everything seems to work fine but after several clicks, it happens that myDiv shows loader.gif image and stops. After this, if I wait a few moments, the browser sometimes stops working (gets blocked).
I noticed this problem with IE6.

Can somebody tell what does this problem mean and if it can be avoided?


index.html

<html>
<head>
<script type="text/javascript" src="mootools/mootools-1.2.4-core-nc.js"></script>
<script type="text/javascript" src="mootools/mootools-1.2.4.4-more.js"></script>
<script type="text/javascript">
window.addEvent('domready', function() {
  $("myPage").addEvent("click:relay(a)", function(e) {
    e.stop();
    var myRequest = new Request({
      method: 'post',
      url: 'button.php',
      data: {
        button : this.get('id'), test : 'test'
      },
      onRequest: function() {
        $('myDiv').innerHTML = '<img src="images/loader.gif" />';
      },
      onComplete: function(response) {
        $('myDiv').innerHTML = response;
      }
    });
    myRequest.send();
  });
});
</script>
</head>
<body>
<div id="myPage">
  <a href="#" id="button1">Button1</a> 
  <a href="#" id="button2">Button2</a> 
  <div id="myDiv">
    <a href="#" id="button3">Button3</a>
  </div>
</div>
</body>
</html>

button.php

<a href="#" id="button3">Button3</a>
<br><br>
<?php echo 'You clicked ['.$_REQUEST['button'].']'; ?>

+1  A: 

Well, there's nothing wrong with the code itself. Here's what you can try to do:

  1. Use onSuccess instead of onComplete and console.log the response - check if there's something suspicious going on. Perhaps you're getting a bad response at some point which causes a JS error on IE (not trying to inject a block element inside an inline one, or some non-semantic oddities?)

  2. Just in case use el.set('html', response) instead of el.innerHTML

  3. Check if Element.Delegation doesn't get lost at some point

  4. Create a working example on http://jsfiddle.net so we can poke around with the code and debug more.

Oskar Krawczyk
onSuccess and el.set('html', response) did not solve the issue.I am not sure how to use console.log or how to check if Element.Delegation doesn't get lost..As you said, the problem might be in bad response.A few times I got the following message:"Bad RequestYour browser sent a request that this server could not understand.Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request."
Add `console.log(response)` to see what's exactly happening. Be sure to open up IE's developer tools (or whatever it's calling it).Do validation for the responses, if you catch an odd response, just don't do any additional operation on this response - otherwise it'll be erroneous.A bunch of if-statements, here and there will suffice.
Oskar Krawczyk
A: 

http://www.jsfiddle.net/dimitar/VZuGz/

works fine - notice i have added a boolean that stores the clicked state - it will only allow the handling of 1 ajax request at a time in case that was being a problem (queueing up of requests).

in a way, this is now synchronous w/o being synchronous. if you MUST log every click, no matter how fast, then you can use http://mootools.net/docs/more/Request/Request.Queue but disable the output of an element that is being relayed for (clickable).

p.s. i have recently written a class for heatmap logging in mootools - which does similar to what you do, let me know if thats towards the direction you are headed into and i will be happy to share the code.

(function() {
    var clicked = false;    
    $("myPage").addEvent("click:relay(a)", function(e) {
        e.stop();
        if (clicked)
            return; // do 1 ajax at a time.

        new Request.HTML({
            method: 'POST',
            url: '/ajax_html_echo/',
            data: {
                button : this.get('id'), test : 'test',
                html: '<a href="#" id="button3">Button3</a><br><br>You clicked id ' + this.get("id")
            },
            onRequest: function() {
                $('myDiv').set("html", 'loading...');
                clicked = true;
            },
            onComplete: function() {
                $('myDiv').set("html", this.response.text);
                clicked = false;
            }
        }).send();
    });
})();
Dimitar Christoff