I like to try to do things the right way when I can. Often it’s so easy to do things the wrong way, for example misusing the HTTP verbs GET and POST. In case you’re curious about when to use GET and POST, check this out.
Sometimes I have simple views that change data in my database, like a delete view for example. If I have a list of objects on a page, it’s nice to have a little delete link for each object. I’ve run into this several times and each time I have the same dialogue with myself:
“I really should use POST for this view”
“But that means I’ll have to have a form for each delete link on the page, which feels way too heavy. Also it looks ugly to have buttons instead of links and styling buttons is a pain in the ass, blah blah blah, maybe I should just use GET this one time …”
“NO, NO, NO, I should do it right.”
“But that’s gonna be wooooorrrkkkkk…..”
So I decided to solve the problem once and for all and make a nice jQuery plugin. This is my first jQuery plugin, so I welcome any feedback on whether I could do it better or whatever.
Here it is:
function read_cookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } (function($) { $.fn.extend({ postlink: function(options) { var defaults = {'csrf_protected': false}; options = $.extend(defaults, options); return this.each(function() { $(this).click(function(e) { var frm = $("<form>"); frm.attr({'action':$(this).attr('href'), 'method': 'post'}); if (options.csrf_protected) { frm.append("<input name='csrfmiddlewaretoken' value='" + read_cookie('csrftoken') + "'>"); } frm.appendTo("body"); frm.submit(); e.preventDefault(); }); }); } }); })(jQuery);
Since I use Django which has automatic CSRF protection I added an option that will add the CSRF token. If you don’t use Django or don’t use CSRF, just don’t enable that option.
My HTML then looks like:
<script language="javascript"> $(document).ready(function() { $(".postlink").postlink({'csrf_protected': true}); }); </script> <ul> <li>object 1 <a class="postlink" href="/objects/delete/1/">delete</a></li> <li>object 2 <a class="postlink" href="/objects/delete/2/">delete</a></li> <li>object 3 <a class="postlink" href="/objects/delete/3/">delete</a></li> </ul>
I’ve uploaded the plugin to bit bucket. Enjoy!
thank you for this function Jeff. I’m using it.