Chris McMichael
...

Main

Categories

Popular Tags

django


Powered by Django.

ponybadge

GigaNews

Year Archives

Recent Photos

View More...
MAY 22 2008
django-threaded-comments with Mootools

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
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:

  1. You need to have mootools v1.1 (not v1.11)
  2. the fvalidator library.
  3. django threaded comments

I will leave the overall intgration of the js comment module up to you.

Posted By: Chris| 22nd May 2008 7:36 a.m. | Tags - comments, django, javascript, mootools