Mootools hasEvent

Wednesday, 18 June 2008

If you have ever dealt with events in JavaScript then you know that it can often be a cumbersome task. The Mootools library makes it dead simple to add or remove events to any given element. The problem I discovered when working with Mootools and events was checking to see whether a given element has an event. Natively Mootools does not come with a prepackaged method to check elements for the existance of any event. I use the following snippet of code to extend the Mootools library to have a hasEvent method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Native.implement([Element, Window, Document], {

    hasEvent: function(type) {
        var events = this.retrieve('events', {});

        if (events && events[type]) { return true; }

        else { return false; }
    }
});

Leave a comment

Django-threaded-comments with Mootools

Thursday, 22 May 2008

NOTE: This article is deprecated for I have not touched this in 2 years and one could assume that this does not work anymore.

Most Django fanatics have heard of an application called Django-Threaded comments. I discovered this application back in January and decided to make use of it on my site. After playing around with it in my spare time, I decided to write a Javascript frontend that would control how users could post comments. So I used one of my favorite javascript libraries called Mootools.

An amazing feature that Mootools has is the 'each' method. This core mootools feature allows for a programmer to group similar html elements by using parent/child relationships to reference your html elements, you can easily traverse through the tree of elements and manipulate anything.

Last weekend I finally had the chance to code this. Below is the fully working code that I created. Sadly, it was created with mootools 1.1 but I suspect an upgrade at some point, that is when I have 'free time'

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
window.addEvent('domready', function() {
  var replies = $$("#comments span.comment-reply");
  var selectedReply = ""
  var eventToggler = "";
  replies.each(function(item) {
    var form = item.getParent().getParent().getLast();
    if($E('input[id=id_name]', form) && 
    !$E('input[id=id_name]', form).hasClass("fValidate['required']")){          
        $E('input[id=id_name]', form).addClass("fValidate['required']");
    }         
    if($E('input[id=id_email]', form) && 
    !$E('input[id=id_email]', form).hasClass("fValidate['required','email']")) {
      $E('input[id=id_email]', form).addClass("fValidate['required','email']");
    }
    if(!$E('textarea[id=id_comment]', form).hasClass("fValidate['required']")) {
      $E('textarea[id=id_comment]', form).addClass("fValidate['required']");
    }       var Validator = new fValidator($E('form', form));
    Validator.options.msgContainerTag = "span";
    Validator.options.required.msg="";
    Validator.options.alpha.msg="";
    Validator.options.email.msg="";
    Validator.options.url.msg="";
    var formToggle = new Fx.Slide(form);
    item.addEvent('click', function(e) {
      toggle = new Event(e);
      if (selectedReply) {
        if (selectedReply == item) {
          item.setText('Reply');
          item.removeClass('active');
          $E('form', form).reset();
          selectedReply = "";
          eventToggle = "";
        } else {
          selectedReply.setText('Reply');
          selectedReply.removeClass('active');
          $E('form', item.getParent().getParent()).reset();
          eventToggle.toggle();
          selectedReply = item;
          eventToggle = formToggle;
          item.setText('Reply');
          item.addClass('active');
        }
      } else {
        item.addClass('active');
        item.setText('Cancel reply');
        selectedReply = item;
        eventToggle = formToggle;
      }
      formToggle.toggle();
      toggle.stop();
    });

    $(form.getElement('form','')).addEvent('submit', function(e) {
      new Event(e).stop();
      if($E('input[id=id_website]', form) &&
      $E('input[id=id_website]', form).getValue() != '' &&
      !$E('input[id=id_website]', form).hasClass("fValidate['url']")) {
        $E('input[id=id_website]', form).addClass("fValidate['url']");
        Validator = new fValidator($E('form', form));
        Validator.options.msgContainerTag = "span";
      }

      if(Validator._onSubmit(e)) {
        this.send({
          onSuccess: function() {
            selectedReply.setText('Reply');
            selectedReply.removeClass('active');
            eventToggle.toggle();
            selectedReply = "";
            eventToggle = "";
            document.location.reload(true);
            }
        });
      }
    });
    formToggle.hide();
  });
});

I am sure that there is betters way of doing this but for now I have something that works and I am sharing with others to use, see, and perfect. There are some issues that I have found this implementation.

You might have noticed that I used a library called fvalidator . It is a rather simple mootools library that allows a programmer to perform error checking on your form prior to form submission. One of the main problems that I found is that mootools v1.1 is required , Not v1.11 because there is a compatibility issue. Perhaps there will be a future fix for fvalidator. I should have used the accordion effect instead of manually coding how my effects work which is not really a technical issue but would be nice to fix in the future.

Another thing that you may have noticed is how I send a comment to the server. Instead of feeding Mootools some variables containing paths and other information I simply reference the 'action' attribute of the form tag through an ajax call upon submission of the comment. The nice part about submitting a form the way that I do is that javascript does not need to be enabled in order for it to work correctly. So, if for some reason a user did not have javascipt enabled or their browser does not support so portion of the javascript code, then a user can still post (Although it may look a little ugly!) through the regular submit method. I realize that we are not living in '95 and most people have and use javascript in their browsers but I wanted to create a failsafe in the event that my javascript code broke for some reason. Another benefit is that I keep my javascript code out of the body of the html file and only manipulate what I need to manipulate.

Feel free to play around with the above code. Just remember a few things:

You need to have mootools v1.1 (not v1.11) the fvalidator library. django threaded comments I will leave the overall intgration of the js comment module up to you.

Leave a comment