jQuery chains, closures and anonymous functions in Drupal

Popular open source CMS
Post Reply
KBleivik
Site Admin
Posts: 184
Joined: Tue Sep 29, 2009 6:25 pm
Location: Moss Norway
Contact:

jQuery chains, closures and anonymous functions in Drupal

Post by KBleivik »

Drupal is fast to adabt o new technologies:
  1. New versions of PHP
  2. New JavaScript technologies
We have already written about

jQuery closures, anonymous / lambda functions in the jQuery sub forum. We found a very interesting example of this subject in this

http://www.packtpub.com/drupal-6-javasc ... query/book

book chapter 4. It uses the drupal.js JavaScript library as well as jQuery to make a simple text editor in less than 100 lines of JavaScript code. Even if it is written for Drupal version 6, it is still of interest and shows an efficient use of jQuery chaining, closures and anonymous functions. Here is the code for:

simpleeditor.js

Code: Select all

// $Id$
/**
 * Simple text editing controls for a textarea.
 */
 
var SimpleEditor = SimpleEditor || {};

SimpleEditor.buttonBar = 
  '<div class="button-bar">' +
  '<div class="editor-button bold"><strong>B</strong></div>' +
  '<div class="editor-button italics"><em>I</em></div>' +
  '</div>';

SimpleEditor.selection = null;

/**
 * Record changes to a select box.
 */
SimpleEditor.watchSelection = function () {
  SimpleEditor.selection = Drupal.getSelection(this);
  SimpleEditor.selection.id = $(this).attr('id');
};

/**
 * Attaches the editor toolbar.
 */ 
Drupal.behaviors.editor = function () {
  $('textarea:not(.editor-processed)')
    .addClass('editor-processed')
    .mouseup(SimpleEditor.watchSelection)
    .keyup(SimpleEditor.watchSelection)
    .each(function (item) {
      var txtarea = $(this);
      var txtareaID = txtarea.attr('id');
      var bar = SimpleEditor.buttonBar;
      
      $(bar).attr('id', 'buttons-' + txtareaID)
        .insertBefore('#' + txtareaID)
        .children('.editor-button')
        .click(function () {
          var txtareaEle = $('#' + txtareaID).get(0);
          var sel = SimpleEditor.selection;
          if (sel.id == txtareaID && sel.start != sel.end) {
            txtareaEle.value = SimpleEditor.insertTag(
              sel.start, 
              sel.end, 
              $(this).hasClass('bold') ? 'strong' : 'em', 
              txtareaEle.value
            );
            sel.start = sel.end = -1;
          }      
        });
    });
};

/**
 * Insert a tag.
 * @param start 
 *  Location to insert start tag.
 * @param end 
 *  Location to insert end tag.
 * @param tag 
 *  Tag to insert.
 * @param value 
 *  String to insert tag into.
 */
SimpleEditor.insertTag = function (start, end, tag, value) {
  var front = value.substring(0, start);
  var middle = value.substring(start, end);
  var back = value.substring(end);
  return front + '<' + tag + '>' + middle + 
    '</' + tag + '>' + back;
};

The jQuery factory function $() (that is based on the factory design pattern) starts on the second code line below. The jQuery chain creates a list of jQuery objects where the last line below calls the jQuery each() function

Code: Select all

Drupal.behaviors.editor = function () {
  $('textarea:not(.editor-processed)')
    .addClass('editor-processed')
    .mouseup(SimpleEditor.watchSelection)
    .keyup(SimpleEditor.watchSelection)
    .each(function (item) {
that operates on the list of objects created with the jQuery factory engine $(). The each() function takes an anonymous function as a parameter that defines the txtareaID

Code: Select all

 var txtareaID = txtarea.attr('id');
variable. Here we have an iterated chain of anonymous functions, since the click() function lower in the chain also takes an anonymous function as an argument. Since the txtareaID defined outside of this function is used in that functions scope, a closure is created. We have defined a function that carries with it som values it got from its original context, but which is now closed off to any outside context.

For the full code of the text editor and the complete explanation of the code and closueres see chapter 4 and 9 of the book. The author Matt Butcher has his own site:
http://technosophos.com/ and he has contributed to the Drupal platform as explained here: http://drupal.org/user/201798. Even if the Book is about Drupal 6 it has a lot of interesting subjects like:
  1. Explaining the lanugage translation engine that is one of the reasons of the sucess of Drupal.
  2. JavaScript theming that is also good illustration of how you can translate PHP functionality to JavaScript functionality.
  3. AJAX and Drupal Web Services.
  4. Building your own modules. That is more thoroughly explained in his last book Drupal 7 Module Development: http://www.packtpub.com/drupal-7-module ... pment/book
  5. Integrating existing Drupal JavaScript tools with your own site design and how to extend the JavaScript libraries with jQuery UI libraries http://jqueryui.com/
Matt Butcher is (has?) working (worked) for http://www.palantir.net/ where I found this interesting article about migrating wordpress content to Drupal http://www.palantir.net/blog/new-way-mi ... ent-drupal.

The conslusion of this example should be that combining Drupal with its inbuilt JavaScript library and external libraries that is included in the platfrom, powerful applications can be written with a minimum of code.

Related information: http://drupal.org/project/wysiwyg

If you are new to the drupal.js library, query that term on the Drupal site or Google it for more general hits.

Post Reply

Who is online

Users browsing this forum: No registered users and 10 guests