How to deal with MethodNotAllowed errors
One of the most common production errors are ActionController::MethodNotAllowed
errors. They usually happen when someone reloads a form by pressing enter
/return
in the URL field, or by opening JavaScript links incorrectly.
The attached initializer provides a default way to deal with this.
You'll get the following behaviour:
- if the incorrect request has a
HTTP_REFERER
coming from the same application, set a flash, and redirect back - if the incorrect request has no
HTTP_REFERER
or one coming from an external source, set a flash...
Embed Google Analytics code for some environments only
When you use google analytics to track your visitors interactions, you should ensure that it runs on your production site only. Otherwise it will spoil your statistics. To prevent this, test for the right environment and place the JS-code afterwards:
- if Rails.env.production?
:javascript
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXXX-X']);
_gaq.push(['_trackPageview']);
...
jQuery 1.7 Released
Two new methods on
and off
are the new way of declaring event handlers. bind
, delegate
and live
area deprecated. Also better performance for delegated events.
Multi-line Ruby block in Haml
There are several options, but most of them are impractical. The best way is to use the :ruby
filter:
:ruby
puts javascript_include_tag(
'lib/jquery-1.6.1.min.js',
'lib/jquery-rails-ujs.js',
'lib/jquery-ui-1.8.13.custom.min.js',
'lib/jquery.ui.datepicker-de.js',
'lib/jquery-ui-timepicker-addon.min.js',
'lib/jquery.tools.min.js',
'application.js',
'google-maps.js',
:cache => true
)
...
Rails 3.1 error message: Could not find a JavaScript runtime
After starting the Rails server in a freshly generated Rails 3.1 project you could see an error message such as
/usr/lib/ruby/gems/1.8/gems/execjs-1.3.0/lib/execjs/runtimes.rb:50:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
Just add a JavaScript runtime to your Gemfile and the error vanishes.
Examples:
gem 'therubyracer'
gem 'extjs'
Fix multiple CKEditor instances using jQuery adapter - fixed since 4.2
Using the jQuery adapter breaks the built-in save function of CKEditor.
Phenomenon: The page is submitted correctly, but the original values of the form fields were posted instead of what was typed in the editors.
Work around: Basicly instead of initiating the editor using the above example I ended up using the following:
$( 'textarea.editor').each( function() {
CKEDITOR.replace( $(this).attr('id') );
});
Note: This assumes that each field using the editor has its own unique ID.
Parse & sort unique hits in logfiles
If you want to know the exact hits on your website (or whatever logfile you want) for a specific date without duplicates, here's how.
"Unique" means you don't want to count hits to an URL originating from the same IP twice.
You can use the attached script to do so:
# ./log_parser.rb 2011-10-04
27 hits on /rss.xml
36 hits on /stylesheets/fonts/slkscr-webfont.woff
37 hits on /stylesheets/fonts/slkscrb-webfont.woff
37 hits on /images/bullet.png
38 hits on /images/download.png
38 hits on /images/play.png
39...
Javascript equivalent of Ruby's array.collect(&:method)
The most common use case for Ruby's #collect
is to call a method on each list element and collect the return values in a new array:
['hello', 'world', 'this', 'is', 'nice'].collect(&:length)
# => [5, 5, 4, 2, 4]
Although there is no equivalent to this idiom in naked Javascript, there is a way to collect object properties (but not method results) if you are using common Javascript libraries.
If you are using jQuery with the Underscore.js utility library, you can use [pluck
](htt...
Single step and slow motion for cucumber scenarios using @javascript selenium
Single step and slow motion for Cucumber scenarios can come in handy, especially in @javascript
scenarios.
# features/support/examiners.rb
AfterStep('@slow_motion') do
sleep 2
end
AfterStep('@single_step') do
print "Single Stepping. Hit enter to continue"
STDIN.getc
end
If you're using spreewald, these tags are available as @slow-motion
and @single-step
(with dashes instead of underscores).
Note: You can also [prevent the selenium webbrowser wind...
Prevent the selenium webbrowser window from closing after a failed @javascript step
When cucumber encounters a failing step in a @javascript feature, the selenium browser window instantly closes. Sometimes you do not want that, because you need to see what is going on. You can click through the data your feature created, when you add the following file to your features/support directory:
#features/support/examiners.rb
After('@leave_the_window_open') do |scenario|
if scenario.respond_to?(:status) && scenario.status == :failed
print "Step Failed. Press return to close browser"
STDIN.getc
...
sstephenson/execjs - GitHub
ExecJS lets you run JavaScript code from Ruby. It automatically picks the best runtime available to evaluate your JavaScript program, then returns the result to you as a Ruby object.
How to accept or deny JavaScript confirmation dialogs in Capybara/Selenium
These methods are available to you:
page.driver.browser.switch_to.alert.accept
page.driver.browser.switch_to.alert.dismiss
page.driver.browser.switch_to.alert.text # the confirmation text
Spreewald gives you steps like these:
When I confirm the browser dialog
When I cancel the browser dialog
Also see Type text into Javascript prompt dialogs in Capybara/Selenium.
Rails 3.1.0 has been released!
jQuery as new default Javascript library, streaming response support, attr_accessible with roles, prepared statements, easier migrations.
Detect the current Rails environment from JavaScript or CSS
Detecting if a Javascript is running under Selenium WebDriver is super-painful. It's much easier to detect the current Rails environment instead.
You might be better of checking against the name of the current Rails environment. To do this, store the environment name in a data-environment
of your <html>
. E.g., in your application layout:
<html data-environment=<%= Rails.env %>>
Now you can say in a pi...
Chosen - makes select boxes better
Chosen is a JavaScript plugin that makes long, unwieldy select boxes much more user-friendly. It is currently available in both jQuery and Prototype flavors.
JSONP - Wikipedia
Under the same origin policy, a web page served from server1.example.com cannot normally connect to or communicate with a server other than server1.example.com. An exception is the HTML <script> element. Taking advantage of the open policy for <script> elements, some pages use them to retrieve Javascript code that operates on dynamically-generated JSON-formatted data from other origins. This usage pattern is known as JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code.
Cross-Origin Resource Sharing - Wikipedia
Cross-Origin Resource Sharing (CORS) is a browser technology specification, which defines ways for a web service to provide interfaces for sandboxed scripts coming from a different domain under same origin policy. CORS is a modern alternative to the JSONP pattern. While JSONP supports only the GET request method, CORS also supports other types of HTTP requests. Using CORS enables a web programmer to use regular XMLHttpRequest which supports better error handling than JSONP. On the other hand, JSONP works on legacy browsers that do not have C...
simple_format helper for Javascript
The Javascript code below is a rough equivalent to the simple_format helper that ships with Rails:
function simpleFormat(str) {
str = str.replace(/\r\n?/, "\n");
str = $.trim(str);
if (str.length > 0) {
str = str.replace(/\n\n+/g, '</p><p>');
str = str.replace(/\n/g, '<br />');
str = '<p>' + str + '</p>';
}
return str;
}
Unlike the Rails helper, this does not preserve whitespace. You probably don't care.
How to hide your selenium browser window with "headless"
Note: While the solution in this card should still work, we prefer another solution now: Hide your Selenium browser window with a VNC server.
If you would like to hide the annoying selenium browser window that always gets the focus and prevents you from working, you can use the headless gem. This note provides some instructions how you can get it to work with your cucumber accepta...
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'...