Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker
Ken Mayer

SF Standup – Feb 13, 2012 – The Sound of One Hand

Ken Mayer
Monday, February 13, 2012

Cries for help

Capybara is reporting “stale elements” for no good reason.

Any experience, war stories upgrading from jQuery 1.6 to 1.7, especially with the whole event delegation API change? [crickets] See interestings…

Interestings

Have a really big spec file that takes a long time to run? http://rubygems.org/gems/parallel_split_test, from our own Michael Grosser, will run a big spec file in smaller chunks.

url helpers cache results for better performance, but they seem to be losing custom options (in this case a locales setting).

In jQuery 1.6, triggering an event in an unattached DOM node would propagate the event up into the document, even though it was never attached to it. jQuery 1.7 (maybe 1.7.1) fixes this behavior.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mike Grafton

SF Standup 5/5/2011: The Most Interesting Standup in the World

Mike Grafton
Thursday, May 5, 2011

Interesting Things

  • jQuery mobile: awesome!
  • jQuery 1.6 is out and will break you. Read the change notes and upgrade with care. [Ed.: you do have JS tests, don't you?]
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Mike Gehard

Waiting for jQuery Ajax calls to finish in Cucumber

Mike Gehard
Tuesday, May 3, 2011

You may be asking yourself why you’d want to do this in the first place. Well here’s why I would want to do it.

We had some Webdriver based Cucumber tests that passed fine locally but kept failing on our CI box. Our CI box is a bit underpowered at the moment so I thought what might be happening is that our tests weren’t waiting long enough for the Ajaxy stuff to happen because the Ajax responses were taking a long time.

After some poking around in the source code of jQuery, I found the $.active property. This property keeps track of the number of active Ajax requests that are going on and I thought this might help us out.

What I came up with was this gist:

I added this step right after my Cucumber step that caused the Ajax call so that Cucumber would wait to move on until I knew that everything was done.

This step solved our CI failures and all was good in our test suite again.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Ken Mayer

Standup 2010-11-19: TGIF

Ken Mayer
Friday, November 19, 2010

Helps

What options exist for mobile application development?

  • Titanium
  • Sencha Touch
  • WebView
  • PhoneGap
  • jQuery Mobile
  • … many others …

The general consensus seems to be that many of these frameworks work fine for simple applications, but quickly run into walls, bugs, and fails once things are less than straightforward. If you’re writing a simple application, it probably falls in the mobile web application category and then all you need is a web view. YMMV, but know what you want your application to do before making a choice. Most likely, you have to write a native application for each platform.

Interestings

  • jQuery 1.4.4 Released Read the blog entry for details; if you’re having issues, they might be solved in this release.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
JB Steadman

more page dynamics, less client logic

JB Steadman
Saturday, January 23, 2010

Ajaxed pages frequently need to update many parts of the page within ajax callbacks. Here I’ll outline how we use jQuery and Rails do this on Mavenlink. Our approach encodes behavior declaratively in markup and minimizes client-side logic.

Mavenlink provides a rich collaborative workspace for clients and consultants. All workspace activity happens within a single page. When a user adds a new deliverable to the workspace, we need to update three parts of the page. The dynamic page areas are highlighted in this screenshot of a typical workspace:

Mavenlink workspace

See the page in action yourself by creating your own workspace on Mavenlink.

To add a deliverable, the user submits the ajaxed form circled at right. Upon success, we need to update the deliverable module (A), the list of deliverables in the popup (B), and the event feed (C).

However, we’d like to avoid having our javascript know this. We try to avoid callback code along the lines of “when X happens, do A, B, and C”. Additionally, we want to avoid creating multiple event listeners responsible for dealing with something like a “deliverableCreated” event.

Instead, we mark up the parts of our document that can be updated dynamically. When new content arrives via ajax, we match the new content to the marked up dynamic elements, using shared attribute values to perform the match.

Specifically, we define a custom attribute called ‘content-key’ on our dynamic elements. Here’s three sections of the page’s original markup defining the three elements outlined in the screen shot:

<!-- deliverable module (A) -->
<div content-key="deliverable-module">
  ...
</div>

<!-- the deliverable popup (B) -->
<ul content-key="deliverable-popup">
  ...
</ul>

<!-- the event feed (C) -->
<ul content-key="events">
  ...
</ul>

In handling an ajax request to create a deliverable, we generate response markup with matching elements. The response looks something like this:

<div content-key="deliverable-module">
 <!-- new html -->
</div>
<ul content-key="deliverable-popup">
 <!-- new html -->
</ul>
<ul content-key="events">
 <!-- new html -->
</ul>

Our ajax success callback invokes a function that uses jQuery to inject the new html into the page’s original content-key elements:

function updateContent(event, newContent) {
  var $contentKeyElements = $(newContent).filter('[content-key]');

  // iterate through each new content-key element

  $contentKeyElements.each(function() {
    var contentKey = $(this).attr("content-key");

    // replace existing content-key html with new content-key html

    $("[content-key="+contentKey+"]").html($(this).html());
  });

  $(document).trigger('content-updated');
}

One advantage of this approach is that we can add new behavior without adding client-side logic. For example, if we want to show a flash message when a deliverable is created, we add a <div content-key='flash-notice'> element to the page, and match it with markup returned in the ajax response. The new behavior is encoded declaratively in our markup.

This approach keeps the server side pretty simple as well. In our create() action, we render the same partial whether the xhr request succeeds or fails:

class DeliverablesController < ApplicationController
  ...

  def create
    @deliverable = @workspace.deliverables.build(params[:deliverable])
    status = @deliverable.save ? 200 : 400
    render :partial => 'deliverables/deliverable_response', :status => status
  end
end

The deliverable_response partial renders secondary partials that each render a content-key element reflecting the new state of the page:

<%= render :partial => 'deliverables/deliverables_module' %>
<%= render :partial => 'workspaces/deliverable_popup' %>
<%= render :partial => 'workspaces/events' %>

These secondary partials are the same ones used to build the original page, so we’re not writing any new rendering code for ajax. Validation error messages are rendered within deliverables/deliverables_module in the manner of normal Rails forms.

You may have noticed that in our ajax responses, we render more than we strictly need to. For example, when a deliverable is created, we could just add a single new <li> element within our <ul>s instead of rebuilding the <ul>s entirely. For moderately-sized, moderately dynamic pages like our workspace page, micro-optimizing responses can needlessly complicate code without providing any meaningful performance benefits. When reality permits, we prefer blunt stupidity over intricate precision. It’s much easier to deal with.

Watch out for replacing markup that carries dynamic state, such as tab selection and expand/collapse state, both of which we use on Mavenlink’s workspace page. You can either avoid destroying state by narrowing the scope of your content-key elements, or restore the state in javascript after new markup is loaded. In a later post, I’ll detail how we deal with it on the workspace page.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

NYC Standup Roundup – Thanksgiving Week

Pivotal Labs
Wednesday, November 25, 2009

Help

Is there a way to ensure at_exit will always be ran regardless of how the program exits without wrapping all code in an ensure block?

Ideas included:

  1. Use a runner class to execute the program and wrap that in an ensure block.

  2. trap(”EXIT”) { block } should get triggered no matter how the program terminates (sigint, exception, etc)

What are the likely causes of RangeError exceptions during test runs?

<RangeError: 0x23513ec is recycled object>
  1. This is generally caused by C extensions.

  2. Their appearance coincided with a Darwin ports update — perhaps you’re running native gems against different versions of libraries than they were compiled against.

Are there any techniques out there to take a series of bytes and run some heuristics on them to determine the likely encoding of the string it represents?

Anybody out there have any ideas? Please let us know in the comments!

Interesting

  • Passing :multiple => false or nil to the select helpers causes unpredictable results — the helper still builds input element names assuming an array of items will be passed back. The helper checks only that the key is present in the options hash and not the value which means if you need to conditionally render a multiple, you’ll have to make sure you don’t specify the :multiple key at all.

  • Using $(’textarea’).val() causes unpredictable results as a textarea doesn’t keep its data in a value attribute. Use text()) instead.

  • IE 7 and 8 (and more than likely 6) seem to have a problem with jQuery selectors that match links based upon the href attribute — changing the href of the matched elements does not get reflected in the document.

  • From a Blabs comment: Taps is a Sinatra web service from Heroku that’s used to move data from one database to another. It transmits data as serialized arrays and loads them using ActiveRecord so it’s DB agnostic.

  • Disabling a label via jQuery will not disable the input that it refers to in the for attribute as the label is not a container.

Happy Thanksgiving!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Abhijit Hiremagalur

Standup 01/16/2009: onReady() for AJAX, Web Sprites & Detecting UTF-8

Abhijit Hiremagalur
Monday, January 19, 2009

Interesting Things

  • Web based sprite generator – here

This also makes the generated sprite really small which is great if you care about page load times. A Ruby+ImageMagick sprite generator might also be a good thing to build.

  • Cool way of detecting if a file is UTF-8 enconded using Ruby+IConv – here

Ask for Help

“Is there an onReady() for AJAX events?”

  • onAJAXReady() ?
  • JQuery Live Events might do the trick
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (781)
  • rails (113)
  • testing (88)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (55)
  • techtalk (44)
  • rspec (38)
  • ironblogger (32)
  • productivity (30)
  • activerecord (29)
  • gogaruco (29)
  • git (28)
  • nyc (27)
  • rubymine (26)
  • bloggerdome (23)
  • mobile (22)
  • process (21)
  • pivotal tracker (21)
  • cucumber (20)
  • design (19)
  • jasmine (19)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • tracker ecosystem (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • css (13)
  • tdd (13)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to jquery Feed
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >