Hello everyone,

We've started working on the module that is, in short, is used for Adding / Searching nodes and users all in one input. Since the module is at beginning, I'd like to better check out possible problems regarding jQuery versioning for this specific module before we dive too deep into jQuery.

We are aware of possible solutions, but we want this module to be contributed to Drupal and we'd like to be able to have this module ready to be used by community out of the box.

Problem is, this is quite feature-rich front-end tool and we'll be having problems with deprecated/removed methods and similar.

There are few roads to take here,
Whether to code this for 1.4.4 version, which is completely possible, but I'm pretty certain that it won't work on high-up versions of jQuery, updated with jQuery update module for instance.

Another option is to use new version of jQuery specifically for this module, if current version on the site is too old to be used with our module. I'm not sure if I want to add another 200+ kb download to the resources, that's why I'm not sure which road to take.

We want this to not be slow(ish) like most of heavy modules on Drupal, so we really want to avoid slowing it down by another resource download or by using old version that's not really optimized well (check performance tests between jQ versions).

We'll also be using Drupal behaviors, attach functions, etc, which is built on top of jQuery (right?), so that's another thing to consider when making this decision.

Since this is going to be quite a long jQuery code, which road would you guys take, sacrifice which part of users? The one using the 1.4.x version or those using > 1.9.x or somehow make it work on both of them? Any suggestions/ideas are appreciated.

Comments

Jaypan’s picture

I personally code for jQuery 1.4.4 (Drupal 7.x default).

I'm curious what code won't work in later versions of jQuery. Usually jQuery is pretty backwards compatible. If you run into specific conflicts, maybe you can post them and we (the community) can work together to come up with solutions that will work for different jQuery versions.

ntucakovic’s picture

It completely makes sense that we develop for Drupal's core jQuery version. I guess it's most commonly used in Drupal development? To optimize your code for core's jQuery version?

I'm just starting on writing jQuery for this project and on top of my mind .on isn't working in jQuery 1.4.4 which I've personally used mostly in jQuery dev (mostly outside of Drupal) for attaching event handlers, delegation, custom events, etc.

Of course, there are alternatives to it, which can be used in both version. Then, event delegation. Well, the solution is to attach event handlers when the element is added, which will make it work in both versions.

That's just from the top of my mind, haven't spent much time thinking about which problems in specific I might encounter.

If someone else has an approach he/she would like to share, I'm eager to hear it.

Jaypan’s picture

One of the major difference is jQuery versions is $.live(), $.on() and... the newest one is escaping my memory at the moment ($.delegate() maybe?)

However with Drupal's JavaScript API, there is no need to use any of these. Instead, as you say, handlers are added when the elements are added, using a combination of Drupal.behaviors and $.once().

Let's say for example, I was creating twitter in Drupal. As people post tweets, they are automatically loaded onto my page. These new tweets have a 'repost' link on them. This link needs to have a click handler added to it, to repost the link using AJAX. Let's say the repost link looks like this:

<a href="/repost/xyz" class="repost_link">Repost</a>

This means that new .repost_link elements will periodically be added to the DOM. In Drupal, any time something new is added to the DOM, Drupal.attachBehaviors() is (or is supposed to be) executed. This function then goes through and executes Drupal.behaviors everywhere it is defined.

So we will define our Drupal.behaviors as follows:

Drupal.behaviors.twitterStuff = {
  attach:function()
  {
    repostLinkListener();
  }
};

We can then define repostLinkListener() as follows:

function repostLinkListener()
{
  // Note $.once() ensures that the code inside is only
  // executed a single time on the selected elements. It
  // also acts like $.each(), in that it loops through each
  // of the elements.
  $(".repost_link").once("repost-link-listener", function()
  {
    // $(this) refers to the current $(".repost_link") being looped through
    $(this).click(function(e)
    {
      e.preventDefault();
      // Do some ajax stuff to repost the post the link belongs to
    });
  });
}

With this combination of code, the following happens:
1) The page is loaded
2) Drupal.attachBehaviors() is called
3) Drupal.behaviors.twitterStuff.attach() is called
4) repostLinkListener() is called
5) The click handler is attached to every .repost_link element on the page
6) New content is added to the DOM
7) Drupal.attachBehaviors() is called
8) repostLinkListener() is called
9) The click handler is attached to every .repost_link element on the page that hasn't already had it attached.

This way handlers are always attached as elements are added to the page, and there is no need to use $.live() or $.on() or... whatever the other one is.

ntucakovic’s picture

You're completely right. It slipped my mind I will actually use attach func to do the same thing .on()/.live() was used for.

I'm developing several components separate of Drupal in order to do some usability tests, so that's why it slipped my mind about behaviors :)

Thank you.

Jaypan’s picture

No problem. If you run into any other incompatibilities, feel free to post them, and maybe we (the community) can work on them with you.