UI Sortable on table rows with dynamic height

UI sortable helps reordering items with drag 'n drop. It works quite fine.

Proven configuration for sorting table rows

When invoking the plugin, you may pass several options. This set is working fine with table rows:

$tbody.sortable # Invoke on TBODY when ordering tables
  axis: 'y' # Restrict drag direction to "vertically"
  cancel: 'tr:first-child:last-child, input' # Disable sorting a single tr to prevent jumpy table headers
  containment: 'parent' # Only drag within this container
  placehol...

Javascript: Wait until an image has finished loading

The attached ImageLoader helper will start fetching an image and return an image that is resolved once the image is loaded:

ImageLoader.load('/my/image.png').then(function(image) {
  ...
});

The image argument that is yielded to the promise callback is an HTMLImageElement. This is the kind of object you get when you call new Image().

PSA: When Redis (on LRU noeviction) reaches memory limits, keys with (any) expiry are removed, and keys without are not

In production, you (or your ops team) should configure a maximum number of bytes that Redis can use to store data (maxmemory setting).
They may even want to set maxmemory-policy to noeviction to avoid keys being removed that you want to keep around (e.g. for Sidekiq queues!).

The following applies to the noeviction LRU approach.


When you ask Redis to store a value that would exceed this limit, it tries to clean up:

  • Keys for which an expiry value (TTL) was set (explicitly, or when written via SETEX) will be removed.
    ...

jQuery: Find a selector in both descendants and the element itself

jQuery's find looks in the element's descendants. It will never return the current element itself, even if the element matches the given selector.

Require the attached file and you can now say:

$('.container').findWithSelf('.selector')

This is sort of like closest, but it looks in descendants instead of ancestors.

Preloading images with CSS

Sometimes you want to preload images that you will be using later. E.g. if hovering over a an area changes its background image, the new image should be preloaded. If you only load it once the user starts hovering, there will be a delay until the background image flips.

The attached article explains how to preload images with only CSS. No Javascript required.

The gist is:

.element:after {
  content: url(img01.jpg) url(img02.jpg) url(img03.jpg);
  display: none;
}

Testing Cookie Limits

TL;DR If you want to support most browsers, then don't exceed 50 cookies per domain, and don't exceed 4093 bytes per domain (i.e. total size of all cookies <= 4093 bytes)

Behind the link, you'll find a simple HTML page that offers some cookie tests (how large, how many etc) and an overview of this data for various browsers.

Fun fact: You cannot delete cookies with a key that hits the size limit and has a small value.

How to inspect RSS feeds with Spreewald, XPath, and Selenium

Spreewald gives you the <step> within <selector> meta step that will constrain page inspection to a given scope.

Unfortunately, this does not work with RSS feeds, as they're XML documents and not valid when viewed from Capybara's internal browser (e.g. a <link> tag cannot have content in HTML).

Inspecting XML

If you're inspecting XML that is invalid in HTML, you need to inspect the page source instead of the DOM. You may use Spreewald's "... in the HTML" meta step, or add this proxy step fo...

IMAP: Check credentials

Connect to your IMAP server. If you have SSL enabled:

openssl s_client -connect your-server:993

if your server supports STARTTLS:

openssl s_client -starttls imap -connect your-server:143

otherwise use netcat or telnet (you shouldn't do cleartext stuff nowadays...).
You should see something like this:

...
. OK Pre-login capabilities listed, post-login capabilities have more.

To log into IMAP, send the following string (incl. "01"!):

01 LOGIN user@domani.io $password

The server should return something like:

* C...

Enable debugging for BIND 9 on Ubuntu

Edit /etc/default/bind9 and change

OPTIONS="-u bind"

to

OPTIONS="-u bind -d 50 -g"

Restart BIND and you'll see debug log on your console.

How to fix: RubyMine / IntelliJ "find file" dialog losing focus on awesome wm

Many of our developers love to use the "awesome" window manager on Linux. However, RubyMine dialogs occasionally defocus while typing.

Here is a fix for that, tested on awesome 3.4, 3.5 and 4.0 (Ubuntu 14.04 and 16.04).

Problem

Consider the following:

  1. Press Ctrl+Shift+N
  2. "Find file" dialog opens
  3. Type to search, file list appears
  4. Type more, file list is being replaced

If your mouse pointer hovers the file list, the main window is focused when the list is being replaced (or simply when it shrinks and your mouse pointe...

Delay your Jasmine tests until the document is ready

To delay your entire Jasmine test suite until the DOM is ready, add the following:

beforeAll(function(done) {
  $(done);
});

jQuery Core 3.0 Upgrade Guide | jQuery

Since jQuery 3 saw it's first release candidate today, the links has a list of (breaking) changes.

Official Color Codes for the World's Biggest Brands

brandcolors.net provides you with the colors of the world's biggest brands, easily searchable.

How to: Client-side language detection

When you have a localized website, you may want to redirect users to their preferred language when they visit the root path.
Here is how to do it without a server-side component (like a Rails application).

  • Use JavaScript's navigator.language (real browsers and IE11+) and navigator.userLanguage (old IEs).
  • Use a <meta> refresh as fallback
  • Provide buttons for paranoid users that disabled JavaScript and meta refreshs.

JavaScript

The following JavaScript will try to auto-detect a user's preferred language.

It understands string...

thoughtbot/fake_stripe: A Stripe fake so that you can avoid hitting Stripe servers in tests.

fake_stripe spins up a local server that acts like Stripe’s and also serves a fake version of Stripe.js, Stripe’s JavaScript library that allows you to collect your customers’ payment information without ever having it touch your servers. It spins up when you run your feature specs, so that you can test your purchase flow without hitting Stripe’s servers or making any external HTTP requests.

We've also had tests actually hitting the testing sandbox of Stripe, which worked OK most of the time (can be flakey).

How to fix: "rake db:rollback" does not work

When you run rake db:rollback and nothing happens, you are probably missing the latest migration file (or have not migrated yet).

$ rake db:rollback
$ 

If that happens to you, check your migration status.

$ rake db:migrate:status
   up     20160503143434  Create users
   up     20160506134137  Create pages
   up     20160517112656  Migrate pages to page versions
   up     20160518112023  ********** NO FILE **********

When you tell Rails to roll back, it tries to roll back the latest change that was mi...

postgres_ext: additional Rails bindings for PostgreSQL

Adds missing native PostgreSQL data types to ActiveRecord and convenient querying extensions for ActiveRecord and Arel for Rails 4.x

Common table expressions

  • Relation#with
  • Model.from_cte

Arrays

Face.where.contains tags: %w[happy smiling] # Matching faces have both 'happy' and 'smiling' tags
Face.where.overlap tags: %w[happy smiling] # Matching faces have at least one of these tags
Face.where.any tags: 'happy' # Matching faces include the 'happy' tag
Face.where.all tags: 'dunno' # Not documented, try for yourself

...

Prevent RubyMine from reformatting pasted code

When you paste copied code with CTRL+V, RubyMine will change the indentation of the pasted code. You can prevent this by pasting with CTRL+ALT+Shift+V instead ("Paste Simple").

To change this behavior entirely, you can open your settings and navigate to Editor / General / Smart Keys. Here you can select one of three options for Reformat on paste:

  • None
  • Indent Each Line (default)
  • Indent Block
  • Reformat Block

You might want to try "Indent Block".

How to change the hostname in Cucumber features

Capybara uses www.example.com as the default hostname when making requests.
If your application does something specific on certain hostnames and you want to test this in a feature, you need to tell Capybara to assume a different host.

Given /^our host is "([^\"]+)"$/ do |host|
  page.config.stub app_host: "http://#{host}"
  
  # In older Capybaras (< 2.15) you needed to do this instead:
  Capybara.stub app_host: "http://#{host}"
end

You can now say:

When I go to the start page
Then I should not see "Home ...

FreeBSD pkg can't find any packages

If you're trying to searching or installing packages via pkg the your repository data might be broken. If pkg update shows that your repositories are up to date try:

pkg update -f

Afterwards you should be able to search and install packages again.

Introducing Helix: Rust + Ruby, Without The Glue

Helix allows you to implement performance-critical code of your Ruby app in Rust, without requiring glue code to bridge between both languages.

See attached article for a longer write-up about the why and how.

How to preview an image before uploading it

When building a form with a file select field, you may want to offer your users a live preview before they upload the file to the server.

HTML5 via jQuery

Luckily, HTML5 has simple support for this. Just create an object URL and set it on an <img> tag's src attribute:

$('img').attr('src', URL.createObjectURL(this.files[0]))

Unpoly Compiler

As an Unpoly compiler, it looks like this:

up.compiler '[image_p...

rroblak/seed_dump

This gem gives you a rake task db:seed:dump do create a db/seeds.rb from your current database state.

The generated db/seeds.rb will look this:

Product.create!([
  { category_id: 1, description: "Long Sleeve Shirt", name: "Long Sleeve Shirt" },
  { category_id: 3, description: "Plain White Tee Shirt", name: "Plain T-Shirt" }
])
User.create!([
  { password: "123456", username: "test_1" },
  { password: "234567", username: "test_2" }
])