Why your javascripts should be executed after the dom has been loaded
Most of the JavaScript snippets have code that manipulates the DOM. For that reason dom manipulating javascript code should have been executed after the DOM has loaded completely. That means when the browser has finished HTML parsing and built the DOM tree. At that time, you can manipualte the DOM although not all resources (like images) are fully loaded.
The following snippets show how you can do this with plain JavaScript, jquery or prototype ([dom ready ...
jQuery UI Bootstrap
Twitter's Bootstrap CSS blueprint as a jQuery UI theme. Even if you don't want to use Bootstrap as a CSS framework, this theme looks better than jQuery UI's default theme.
Date or datetime picker for touch devices
jQuery UI's date picker and date time picker doesn't work on touch interfaces.
Solution 1: Use Mobiscroll
Another way is to detect touch devices and for those devices use the Date and DateTime picker from Mobiscroll instead:
if (isTouchDevice()) {
$('.date_picker').scroller();
} else...
Detect mobile or touch devices on both server and client
Although it's tempting flirt with detecting mobile/touch devices with CSS media queries or Javascript feature detection alone, this approach will be painful when heavily customizing a feature beyond just tweaking the looks. Eventually you will want want the same detection logic to be available on both server and client side.
This card shows how to get a Ruby method touch_device?
for your Rails views and a method TouchDevice.isPresent()
for your Javascripts.
Note that we are detecting touch devices by grepping the user agent, and the ke...
How to click hidden submit buttons with Selenium
In your Cucumber features you can't really click hidden elements when using Selenium (it does work for a plain Webrat scenario, though).
Unfortunately you need to hack around it, like this:
When /^I press the hidden "([^\"]+)" submit button$/ do |label|
page.evaluate_script <<-JS
$('input[type=submit][value="#{label}"]').show().click();
JS
end
If your button is nested into a container that is hidden this will not do the trick. You need a more complex method to also show surrounding containers:
When /^I pre...
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
Note that recent versions of Selenium will automatically dismiss confirmation dialogs. [Here is how to fix that](https://makandracards.com/makandra/617366-configure-selenium-webdriv...
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...