Manually trigger a delegated DOM event
When you register a delegated event using on (or the deprecated delegate / live), it is somewhat hard to manually trigger these events manually, e.g. for testing.
After trying jQuery's trigger to no avail, I had success by using native Javascript methods to create and dispatch an event. For instance, to trigger a mousedown event:
element = $('...').get(0);
event = new MouseEvent('mousedown', { view: window, cancelable: true, bubbles: true }...
Upgrading from Capistrano 2 to 3
Capistrano 3 is a major rework of the framework and requires several adjustments to your deploy configuration files. The biggest change is that they moved away from their custom DSL and use Rake instead. For connecting with and operating on the servers, they bring a new gem SSHKit which does the heavy lifting. It's SSHKit's DSL that is used anywhere inside the Rake tasks. See #Resources at the bottom for examples.
Step 1: Upgrade guide
For migration from 2 to 3, follow this tutorial: [Capistrano 3 Upgrade Guide](https://semaphorec...
Cucumber step to pick a datetime in Rails' horrible datetime_select
Please don't use the horrible datetime_select helper. It has a terrible UI. Always prefer to use a visual time picker like Rome instead.
In case everything has failed and you do need a Cucumber step to pick a datetime datetime_select, here it is:
When(/^I select the time (\d+)\-(\d+)\-(\d+) (\d+):(\d+) from "(.*?)"$/) do |year, month, day, hour, minute, label_text|
label = page.find('label', text: label_text)
id = label[...
Savon testing: How to expect any message
When using Savon to connect a SOAP API, you may want to use Savon::SpecHelper to mock requests in your tests as described in their documentation.
When sending a message body, the savon mock object requires a message to be set, like this:
savon.expects(:action_name).with(message: { user_id: 123 }).returns('<some xml>')
If you want to stub only the returned XML and do not care about request arguments, you can not omit with as Savon's helper will complain:
savo...
Testing setTimeout and setInterval with Jasmine
Jasmine has a jasmine.clock() helper that you can use to travel through time and trigger setTimeout and setInterval callbacks:
beforeEach(function() {
timerCallback = jasmine.createSpy("timerCallback");
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
it("causes a timeout to be called", function() {
setTimeout(function() {
timerCallback();
}, 100);
expect(timerCallba...
A solid and unobtrusive plugin for form field placeholders
jquery-placeholder is a simple jQuery plugin that enables form placeholders in browsers that do not support them natively, i.e. IE < 10.
Properties
- Works in IE6.
- Automatically checks whether the browser natively supports the HTML5 placeholder attribute for input and textarea elements. If this is the case, the plugin won’t do anything. If @placeholder is only supported for input elements, the plugin will leave those alone and apply to textareas exclusively. (This is the case for Safari 4, Opera 11.00, and possibly other browsers.)
...
Make "rake notes" learn about Haml, Sass, CoffeeScript, and other file types
Rails comes with a Rake task notes that shows code comments that start with "TODO", "FIXME", or "OPTIMIZE".
While it's generally not good practice to leave them in your code (your work is not done until it's done), in larger projects you will occasionally have to use them as other parts of the application that you depend upon are not yet available.
To keep track of them, run rake notes. Its output looks something like this:
$ rake notes
app/controllers/fron...
Using form models (aka decorators) with Devise
To use a form model with devise, you can simply override #resource_class in a controller. A typical use case would be the registrations controller, as users will need some fields only on sign-up. Example:
class Frontend::Authentication::RegistrationsController < Devise::RegistrationsController
private
def resource_class
FrontendUser::AsSignUp # my decorator class, extending from FrontendUser
end
end
Fontawesome 4 helper classes
Fontawesome 4 ships with many useful CSS helper classes.
Enlarge Icon
Add fa-lg (133%), fa-2x, fa-3x, fa-4x or fa-5x.
Fixed-width Icon
Add fa-fw. Will give all icons the same width.
Styling Lists
Add fa-ul to a <UL> and fa fa-<icon name> fa-li to a <LI> to give the list items custom "bullets".
Bordered Icon
Add fa-border to get a border around the icon.
Spinning Icon
Add fa-spin to make any icon rotate. Suggested icons: fa-spinner, fa-refresh, fa-cog. Doesn't work in IE <10.
Ro...
Rails 4 introduced collection_check_boxes
Starting from Rails 4.0, you can use a special form options helper called #collection_check_boxes. It behaves similar to #collection_select, but instead of a single select field it renders a checkbox and a label for each item in the collection.
= form_for @post do |form|
= form.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial
How generated form params look like
---------------------------------...
Thread-safe collections in Ruby
When using threads, you must make your code thread-safe. This can be done by either locking (mutexes) all data shared between threads, or by only using immutable data structures. Ruby core classes like String or Array are not immutable.
There are several gems providing thread-safe collection classes in Ruby.
concurrent-ruby
The concurrent-ruby gem provides thread-safe versions of Array and Hash:
sa = Concurrent::Array.new # supports standard Array.new forms
sh = Co...
Add an alternative image source for broken images
Awesome hack by Tim VanFosson:
<img src="some.jpg" onerror="this.src='alternative.jpg'" />
Differences between transactions and locking
Web applications can be used by multiple users at the same time. A typical application server like Passenger has multiple worker processes for a single app. In a distributed deployment setup like we use at makandra you will even have multiple application servers, each with their own worker pool.
This means that your code needs to deal with concurrent data access. The two main tools we use to cope with concurrency are database transactions and distributed locks. These two are not interchangeable. You ca...
Verifying doubles in RSpec 3
RSpec 3 has verifying doubles. This breed of mock objects check that any methods being stubbed are present on an instance of a given class. They also check methods aren't called with the wrong number of arguments.
This dual approach allows you to move very quickly and test components in isolation, while
giving you confidence that your doubles are not a complete fiction.
You should always prefer using a verifying double to using an old-school mock...
Communication between collaborating directives in Angular
What if a complicated component comes along that is naturally modeled by multiple directives? This group of directives, as a whole, form a single self contained component. None of directives in the group can stand alone because they only make sense when used together; they collaborate; they are aware of each other and need to communicate with each other.
This post will discuss best practices for managing communication among collaborating directives and illustrate these practices with an example.
How to enable WebGL in Chrome
Check your GPU state on chrome://gpu. If it reads "WebGL: Hardware accelerated" in the first list, you're set. Else:
- Make sure chrome://flags/#disable-webgl is disabled (there should be a link "Enable")
- If that does not help, try to additionally enable chrome://flags/#ignore-gpu-blacklist.
Exporting to Excel from Rails without a gem
See this Railscast.
Basically you can simply write views like index.xlsx.erb:
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
<Table>
<Row>
<Cell><Data ss:Type="String">ID</Data></Ce...
Be careful when using buttons without a "type" attribute
Be careful when using buttons without a type attribute, since browsers will consider them the default submit button of a form.
Suppose you have this form:
<form action="/save">
<input type="text" />
<button onclick="alert('Alert!')">Alert</button>
<button type="submit">Save</button>
</form>
If you press the enter key inside in the text input, browsers will trigger the first button and show the alert.
To fix this, add a type="button" attribute to the first button.
How to create memory leaks in jQuery
jQuery doesn't store information about event listeners and data values with the element itself. This information is instead stored in a global, internal jQuery cache object. Every time you add an event listener or data value to a jQuery object, the jQuery cache gains another entry.
The only way that a jQuery cache entry gets deleted is when you call remove() on the element that put it there!
Since cache entries also have a pointer back to the element that spawned them, it is easy to create DOM elements that can never be garbage-co...
An auto-mapper for BEM classes in Cucumber selectors
When you are using the #selector_for helper in Cucumber steps, as e.g. Spreewald does, the following snippet will save you typing. It recognizes a prose BEM-style selector and maps it to the corresponding BEM class.
For a variation on this idea, see An auto-mapper for ARIA labels and BEM classes in Cucumber selectors.
Examples
"the main menu" -> '.main-menu'
"the item box's header" -> '.item-box--header'
Here are some examples of steps (using Spreewald, too):
T...
Did you know 'tig status' ?
It's like a GUI for the famous git add [-p].
Select files with the up/down-keys and hit
-
ufor staging/unstaging the whole file -
Enterfor showing the diff of a file-
jandkto navigate in the diff -
uagain to stage/unstage chunks -
1to stage/unstage only lines -
\to split large chunks
-
-
F5to refresh the view
Git: How to get a useful diff when renaming files
tldr; Use git diff -M or git diff --find-renames when you've moved a few files around.
Usage
$ git diff --help
Options:
-M[<n>], --find-renames[=<n>]
Detect renames. If n is specified, it is a threshold on the similarity index
(i.e. amount of addition/deletions compared to the file’s size). For example,
-M90% means Git should consider a delete/add pair to be a rename if more than
90% of the file hasn’t changed. Without a % sign, the number is to be read as
a fraction, with a decimal point...
Angular + ui-router: Make links work in a new tab
If your angular app is not served on /, but on a different url (say /admin), links generated with ui-router will not work when you open them in a new tab.
Fix this by adding this tag in your <head>:
<base href='/admin#/'>
Helper method:
def base_tag
tag(:base, href: request.path_info + "#/")
end
Debugging "INTERNAL ERROR!!! wrong argument type StringIO (expected File)"
If you're getting this strange error message when setting debugging breakpoints, probably HAML is the culprit.
Cause
As far as I could find out, the error is the result of setting a breakpoint (debugger) in a helper method that's called from a haml partial.
Suggestions
Try putting the breakpoint into the HAML view.