Rails 3: Make "link_to :remote => true" replace HTML elements with jQuery
In Rails 2, you could use link_to_remote ... :update => 'id'
to automatically replace the content of $('#id')
.
To do the same in Rails 3, include usual rails-ujs JavaScript, and put this into your application.js
:
$(function() {
$('[data-remote][data-replace]')
.data('type', 'html')
.live('ajax:success', function(event, data) {
var $this = $(this);
$($this.data('replace')).html(data);
$this.trigger('ajax:replaced');...
Failtale
Free Hoptoad/Airbrake alternative which can capture exceptions from any platform. It comes with a Rails notifier and a RESTful API to write your own notifiers for Javascript, etc.
Should we some day wish to do away with the current way we deal with exceptions, this might be a good place to start.
Disable text selection on iOS and Android devices
When you double-tap a string of text on an iPhone or iPad a complicated context menu for copying and pasting will appear. This can confuse unexperienced users.
Use the Javascript hack below to disable text selection on mobile devices:
// Deactivating distracting Text Selection:
// from: http://stackoverflow.com/questions/1794220/how-to-disable-mobilesafari-auto-selection
$.fn.extend({
disableSelection : function() {
this.each(function() {
this.onselectstart = function() {
return false;
...
Popular mistakes when using nested forms
Here are some popular mistakes when using nested forms:
- You are using
fields_for
instead ofform.fields_for
. - You forgot to use
accepts_nested_attributes
in the containing model. Rails won't complain, but nothing will work. In particular,nested_form.object
will benil
. - The
:reject_if
option lambda in youraccepts_nested_attributes
call is defined incorrectly. Raise the attributes hash given to your:reject_if
lambda to see if it looks like you expect. - If you are nesting forms into nested forms, each model involved ne...
Check whether an element is visible or hidden with Javascript
jQuery
You can say:
$(element).is(':visible')
and
$(element).is(':hidden')
jQuery considers an element to be visible if it consumes space in the document. For most purposes, this is exactly what you want.
Native DOM API
Emulate jQuery's implementation :
element.offsetWidth > 0 && element.offsetHeight > 0;
jQuery > 3
Query 3 slightly modifies the meaning of :visible (and therefore of :hidden).
Emulate jQuery'...
markbates/coffeebeans
When CoffeeScript was added to Rails 3.1 they forgot one very important part, the ability to use it when responding to JavaScript (JS) requests!
In Rails 3.1 it’s incredibly easy to build your application’s JavaScript using CoffeeScript, however if you fire off an AJAX request to your application you can only write your response using regular JavaScript and not CoffeeScript, at least until CoffeeBeans came along.
A nicer way to run RSpec and/or Cucumber
geordi, our collection of awesome shell scripts, has been extended by three scripts to help you call RSpec or Cucumber:
cuc
This script runs Cucumber the way you want it:
- Prints some line feeds to easily find your test results when you come back to the console later
- Configures Cucumber to use cucumber_spinner if it is available in your
Gemfile
- Runs Cucumber under
bundle exec
- Uses an old version of Firefox for Selenium (Javascript) features...
Soft-scroll to an anchor with jQuery
This snippet makes links that refer to an anchor (like "<a href="#something">...</a>
") scroll softly to it.\
In this example we only do it for links that also own a data-animate
attribute.
$('a[href^="#"][data-animate]').live('click', function() {
var hash = $(this).attr('href');
var offset = $(hash).offset();
if (offset) {
$('html, body').animate({ scrollTop: offset.top }, 'slow');
location.hash = hash;
return false;
}
});
Note that this could basically work for any element whos...
IE7 not properly redrawing elements with position: relative
If you manipulate the DOM with JavaScript and your page contains nested elements with position: relative
, chances are Internet Explorer 7 will not properly move to the right position.
I have not found a fool-proof workaround, but these are options that have worked for me:
- Try to lose some
position: relative
attributes, so they do not nest. This is often impossible, though. - Force the correct redrawing of the elements using JavaScript. Adding a bogus class (
$(element).addClass('touch')
) seems to suffice. - Try to give the off...
Cucumber steps to travel through time with Timecop
These steps are now part of Spreewald.
Here are some useful examples how to use the attached Cucumber Timecop steps:
When the date is 2011-05-06
When the time is 2011-05-06 17:30
There is also one really awesome step that lets you travel to the past or to the future:
When /^it is (\d+|a|some) (seconds?|minutes?|hours?|days?|months?|years?) (later|earlier)$/
As yo...
Rails 3.1: Release candidate
Asset pipeline, HTTP streaming, jQuery as default framework, auto-reversable migrations, identity map for ActiveRecord.
Ruby 1.8.x support will be dropped with or after Rails 4.
Matching line feeds with regular expressions works differently in every language
Although regular expression syntax is 99% interchangeable between languages, keep this in mind:
- By default, the dot character (
"."
) does not match a line feed (newline, line break,"\n"
) in any language. - Some languages allow you to modify the behavior of a regular expression by appending a modifier to the pattern expression. E.g.
/foo/i
makes the pattern case-insensitive in many languages. Note however that some of these modifiers may not exist or mean entirely different things in different languages. - Some languages have a m...
Playing audio in a browser
If you want to play music or sounds from a browser, your choice is to use either Flash or the new <audio>
tag in HTML5. Each method has issues, but depending on your requirements you might not care about all of them.
Flash
- Works in all desktop browsers, even Internet Explorer. Does not work on iPads or iPhones.
- Requires you to embed a Flash component into your page which will later play the audio for you.
- Can play MP3s or Wave files. Cannot play OGG Vorbis audio.
- Cannot reliably seek to a given position when playing VBR-enco...
Apprise - The attractive alert alternative for jQuery
An alert alternative for jQuery that looks good. Apprise is a very simple, fast, attractive, and unobtrusive way to communicate with your users. Also, this gives you complete control over style, content, position, and functionality. Apprise is, more or less, for the developer who wants an attractive alert or dialog box without having to download a massive UI framework.
Rails jQuery UJS: Now Interactive
We can now plug into every facet of the Rails jQuery UJS adapter, binding to custom events, and even customizing internal functions, without hacking or monkey-patching the rails.js file itself.
Open the on-screen keyboard on an iPhone or iPad with Javascript
There is no way to do it. This behavior is by design. You lose.
Cancelling event propagation
Within an event handler, there are multiple methods to cancel event propagation, each with different semantics.
-
event.preventDefault()
Only prevents the default browser behavior for the click, i.e. going to a different url or submitting a form.
When invoked on a
touchstart
event, this also prevents mouse events likeclick
to be triggered. -
event.stopPropagation()
Prevents the event from bubbling up the DOM.
-
`event.st...
Making IE 9 happy
If you're using jQuery, you need to update to 1.5.1 to get Internet Explorer 9 to work.
Apart from that there seem to be surprisingly few problems. Many CSS3 attributes work and no major layout problems at first glance.
I only recommend to take a look at your box shadows, since IE does render those a bit differently (generally lighter and offset by what looks to be half a pixel).
Liquid Canvas
Liquid Canvas is a JavaScript library which allows you to draw inside an HTML canvas element with an easy yet powerful description language.
It can be used to add graphics to your web page without ever touching an image creation tool such as The Gimp, Inkscape or Photoshop.
Check out the Demo and the basic example and then download version 0.3.
PhantomJS: Headless WebKit with JavaScript API
PhantomJS is a minimalistic headless WebKit.
It has fast and native support for various web standards:
DOM handling, CSS selector, JSON, Canvas, and SVG.
PhantomJS can be fully scripted using JavaScript. It is an optimal solution for headless testing of web-based applications, site scraping, pages capture, SVG renderer, PDF converter and many other usages.
Upgrading Cucumber and Capybara to the latest versions available for Rails 2
Specify these gem versions in your Gemfile:
gem 'cucumber', '~> 1.3.0'
gem 'cucumber-rails', '= 0.3.2' # max version for Rails 2
gem 'capybara', '< 2' # capybara 2+ requires Rails 3
gem 'mime-types', '< 2' # dependeny of capybara
gem 'nokogiri', '< 1.6' # dependency of capybara
gem 'rubyzip', '< 1' # dependency of selenium-webdriver, rubyzip 1+ requires Ruby 1.9
gem 'cucumber_factory'
gem 'database_cleaner', '< 1'
gem 'cucumber_spinner', '~> 0.2.5'
gem 'launchy', '~> 2.1.2'
With these versions set, `...
Onload callback for dynamically loaded images
Sometimes you need to dynamically load an image and do something as soon as its loaded (when for example its size is already available).
With jQuery, this seems to work across browsers:
$('<img>')
.attr('src', '')
.load(function() {
alert('fully loaded!');
})
.attr('src', '/the/real/image/url');
Skip Selenium scenarios in a Cucumber run
Cucumber scenarios that are tagged with @javascript
so they run with Selenium are very slow. You might not want to run them every time.
In order to skip all Selenium scenarios, call Cucumber like this:
cucumber --tags ~@javascript
Note that you should still run all the scenarios, including the Selenium ones, before you push a change.
CSS3 Pie: Element not properly redrawn
Pie sometimes does not properly redraw elements upon changes. This often happens when the change comes from somewhere further up the DOM.
Consider something like:
<ul>
<li class="active"><div class="content">Active element</div></li>
<li class="inactive"><div class="content">Inactive element</div></li>
</ul>
with CSS
li .content {
-webkit-box-shadow: #666 0px 2px 3px;
-moz-box-shadow: #666 0px 2px 3px;
box-shadow: #666 0px 2px 3px;
behavior: url(/PIE.htc);
back...