Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Thursday, May 17, 2012

jQuery find function

I've recently been using Tilava Table on a few different projects. At one point I ran into a situation where I wanted to change all of the visible rows as well as the template, but the row template was no longer found when using a traditional jQuery selection. The solution to my problem was a combination of holding on to the template as well and using jQuery find to select the td elements I was interested in altering.

In Tilava Table you create a template, but that template row isn't displayed within the table. We could use that as an example, but it seems easier to simplify the example to the following code:
<script src="http://code.jquery.com/jquery-1.7.2.min.js">
</script>
<label><input type="checkbox" id="hideMoreData"/>hide more data</label>
<table id="myTable" style="border:1px solid black">
  <tr class="template">
    <td>row data</td><td class="additional-field">more data</td>
  </tr>
</table>
<button id="addButton">Add</button>
<script>
$(document).ready(function () {
  function addRow(template) {
    $('#myTable').append(template.clone().removeClass('template'));
  }
  var template = $(".template");
  $('#myTable').html("");
  $("#addButton").click(function () {
    addRow(template);
  });
  $("#hideMoreData").click(function () {
    $(".additional-field").toggle(!$('#hideMoreData').is(':checked'));
  });
  addRow(template);
  addRow(template);
});
</script>
The executing version of that code can be found below.

row datamore data


In the above example we have a table in which we can dynamically add rows by clicking the 'Add' button. We also have a checkbox that determines whether or not the additional data is displayed in our table. Click the add button a few times and show and hide the additional data, just to make sure everything is working as you'd expect.

You may have noticed (either by reading the code, or by playing with the example) that when you hide the additional data it hides what is already in the table; however, if you add additional rows the additional data for the new rows will be shown. This is due to the fact that when you select all td elements with the class 'additional-field' the template is not included in the results. Even though the template is not returned in our 'additional-field' selection, it does still exist and is accessible as the var 'template'. When we clone the template var the cloned row will contain the additional-field td, but it will not be 'correctly' toggled.

One solution would be to append the row and rerun the toggle code, but that wouldn't be as efficient - and, jQuery gives us a better solution anyway: find
find: Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
The simple solution is to add the following line in the #hideMoreData click handler.
template.find(".additional-field").toggle(!$('#hideMoreData').is(':checked'));
The finished code is below in it's entirety, and the working version of the code can also be found at the bottom.
<label><input type="checkbox" id="hideMoreData2"/>hide more data</label>
<table id="myTable2" style="border:1px solid black">
  <tr class="template2">
    <td>row data</td><td class="additional-field2">more data</td>
  </tr>
</table>
<button id="addButton2">Add</button>
<script>
$(document).ready(function () {
  function addRow(template) {
    $('#myTable2').append(template.clone().removeClass('template2'));
  }
  var template = $(".template2");
  $('#myTable2').html("");
  $("#addButton2").click(function () {
    addRow(template);
  });
  $("#hideMoreData2").click(function () {
    $(".additional-field2").toggle(!$('#hideMoreData2').is(':checked'));
    template.find(".additional-field2").toggle(!$('#hideMoreData2').is(':checked'));
  });
  addRow(template);
  addRow(template);
});
</script>
row datamore data

Tuesday, September 30, 2008

Testing Dynamic Web Applications

At RailsConf Europe, in the Q & A portion of my talk on Functional Testing someone asked what I recommend for testing Javascript.

Ugh. Testing Javascript. Is it possible to recommend something when everything you've seen is terrible? Usually I'm cool with picking the tool that sucks the least, but when it comes to Javascript testing the only words that come to mind are: epic fail.

In the past I've failed in two different ways.
  • Selenium: Too slow and to brittle for any decent size test suite. There's more on that if you wish.
  • Some javascript unit testing framework. I can't even remember the name. The syntax was ugly, the tests weren't easy to write, and the runner didn't integrate with any automated tools we used -- lame.
My response in Berlin was "The pivotal guys are smart, so if I were going to try something new it would be Screw Unit." Of course, I just googled and found the RubyForge project and two with the same name on GitHub. I'm sure one of those is the current trunk.

A few days later it occurred to me what the correct answer was -- Don't use Javascript and you won't have to test it.

No, I'm not suggesting that we should all go back to mostly static websites. Static content is fine for some things, but GMail is an obvious example of a site that is better done dynamically.

However, Javascript isn't your only choice for highly dynamic websites.

These days, if I were writing a website that required any dynamic interaction I would absolutely use Flex or Silverlight. I've done Flex, and it was nice to work with, but I must admit that I'm lured to Silverlight because it's going to (or does already?) support Ruby.

I'm not sure what the Silverlight testing story is, but I found Flex (and ActionScript) to be quite testable. The single biggest win (as I've said before) is that I no longer need to do in-browser testing. Removing the browser from the equation is huge. No more IE bugs causing your tests to fail, no long start up times as the browser is run, etc.

Testing with FlexUnit (with it's drawbacks) is an order of magnitude better than any experience I've had testing Javascript.

I'm comfortable saying that I would still use Javascript for trivial features that provided so little business value that they did not warrant testing. However, any features that provide noticeable business value must be tested, and I would move to a RIA solution instead.

In my experience, the benefits of switching to a RIA solution are dramatic, one of the largest being: you no longer need to worry about testing Javascript.

Saturday, September 29, 2007

Learning Rails is Easy, Mastering Rails is Hard

There's plenty of hype and momentum around Ruby on Rails. The screencasts give quick demos of how easy it is to craft a solution using Ruby on Rails. There's even a humorous picture implying how simple it is to learn and use Rails to build web applications.

The screencasts and pictures don't lie. It is easy to learn Rails and quickly become productive. However, the dirty little secret is that it's very hard to be come an expert at utilizing Rails.

Anatomy of a Rails Web 2.0 Application
Rails provides many helpers that make your life easy. But, you can't entirely hide the fact that you'll need to be proficient with Ruby, JavaScript, YAML, and SQL. Just like Rails, getting started with any of the above languages is easy, it's mastering them that takes time and effort.

Becoming an expert with each of the above languages involves gaining knowledge and becoming proficient with several aspects of the language.

Development Environment
There's no IDE that can provide all the features you'd like for Ruby, JavaScript, YAML, and SQL. Some are (hopefully) on the way, but they still suffer from speed, feature, and stability issues. That generally means is you'll have two options:
  • Find a productive development environment that specializes in one or two of them and use a different IDE/Text Editor for each language
  • Find an editor that provides decent support for all of them.
As of today, I use TextMate, which I find acceptable for all 4 languages. If I couldn't use TextMate, I'd be using IntelliJ. Those are my preferences, but I suggest you try a few different options and see what works.

Language Features
Look for documentation and try out the examples for each language you are looking to master. Ruby has decent documentation on http://www.ruby-doc.org/. YAML documentation can be found on http://www.yaml.org/. JavaScript and SQL have seemingly endless documentation resources. I've always been a fan of the O'Reilly books, so I'd recommend Safari Books Online, but there's plenty of other options if you'd like.

But, don't stop with reading. Reading documentation and trying examples isn't going to bring you to the expert level. Another great way to get some insight into a language is to look at the successful frameworks and see how they are implemented. Browsing the Rails codebase should provide examples of almost every feature available in Ruby. Likewise, understanding the Prototype and Script.aculo.us libraries should greatly improve your JavaScript skills.

Testing
Testing is valuable in any language. Ruby provides a few different testing solutions, but the most popular are still Test::Unit and RSpec. JavaScript also provides several options for testing. I can't say there's a clear winner, but JsUnit and Crosscheck seem to be gaining momentum. As far as testing SQL and YAML, I generally functionally test them through Ruby. Additionally, Selenium is a great resource for acceptance testing Rails applications.

Frameworks
Both Ruby and JavaScript provide a plethora of framework options. Ruby provides RubyGems for distributing shared Ruby code. RubyGems are frameworks that can provide all kinds of building blocks for creating applications. In the past I've used the Prototype and Scriptaculous JavaScript libraries, but my current team is enjoying using JQuery.

Debugging
Debugging Ruby is a bit primitive these days. The simplest form of debugging is printing to standard out. You can roll your own simple debugging solution also. Additionally, ruby-debug looks promising. None of the solutions are great, so it's good to have all 3 tools at your disposal. For JavaScript debugging I suggest getting proficient with FireBug. SQL debugging solutions are generally vendor specific, check the docs of the database that you choose for a good suggestion. YAML doesn't generally require a debugger since most errors simply result in parsing problems.

What else makes Rails difficult to master?
Mastering languages is important, but it's not enough to run a high traffic Rails application. You'll still need to understand performance optimization and deployment strategies. There's an abundance of Rails production heuristics available, but little of it is well documented. I'd suggest reading the following blogs: Brainspl.at, Err the Blog, and RailsExpress. Beyond those blogs the web provides several other resources. A Google search should provide more than enough reference material.

That's a ton to learn
It's true, that is a lot of information to digest. But, experts aren't made overnight. The good news is, you can get started very easily and expand your knowledge as needed. There is a large amount of information available, but don't feel overwhelmed: The majority of the information is very straightforward. Becoming an expert with Rails takes time more than anything else.