Search code examples
javascriptinternet-explorer-8prototypejs

Observing event after stopObserving


I'm working on a pop-up calendar to enter dates in a form field. This works fine in Firefox, Chrome and Safari, but not in IE8. The code included is the minimum where the problem occurs.

Desired functionality is:

  • Clicking on the image, create and display the calendar.
  • Clicking again, remove the calendar.

What happens:

IE8 shows and removes the div $('calendari') only the first time; after that nothing happens and no error is displayed.

HTML

<form id="form1" name="form1" method="post" action="">
  <div class="refCal">
    <input type="text" name="data" id="data" />
    <img class="unCal" src="gestio/imatges/16/calendari.png" width="16" height="16" />
  </div>
</form>

CSS

.refCal {position:relative; display:inline;} /*Container for calendar*/
.unCal {cursor:pointer;}
.calendari {position:absolute;width:200px;height:200px;border:1px solid #999;z-index:1000;background-color:#FFC;}

JavaScript (with Prototype 1.7.2)

window.onload = iniciar;

function iniciar() {
  $$('div.unCal').each(function(el) {
    Event.observe(el,'click',obreCalendari);
  });
}

function obreCalendari(evt) {
  calendar = new Calendari(evt);
}

var Calendari = Class.create({
  initialize: function(evt) {
    obj = Event.element(evt);
    Event.stopObserving(obj,'click',obreCalendari);
    Event.observe(obj, 'click', function() {
      $$('.calendari').invoke('remove');
        Event.observe(obj,'click',obreCalendari);
      });
    cnt = new Element('div',{'class':'calendari','id':'calendari'}); // the calendar
    obj.up('div').insert(cnt); // inserts calendar in container
  }
})

Thank you for your help. Please, don't recommend me JQuery.


Solution

  • Well, God helps those who help themselves. I found the problem and, therefore, the solution. It seems that Internet Explorer is very finicky assigning event handlers. In the function to close the calendar I had forgotten the Event.stopObserving for the previous event click:

    Event.observe(obj, 'click', function() {
      Event.stopObserving(obj,'click'); // <--- Added line
      $$('.calendari').invoke('remove');
        Event.observe(obj,'click',obreCalendari);
      });
      cnt = new Element('div',{'class':'calendari','id':'calendari'}); // the calendar
      obj.up('div').insert(cnt); // inserts calendar in container
    }