danialfarid/angular-file-upload

Lightweight Angular JS directive to upload files

Includes polyfills for old IEs. Unfortunately, their auto-loading mechanism may not work properly on your Rails application due to the asset pipeline. They use FileAPI, so you could just include it manually for old browsers, or when you want to use FileAPI's toolkit anyway.

How to emulate simple classes with plain JavaScript

If you want a class-like construct in JavaScript, you can use the module pattern below. The module pattern gives you basic class concepts like a constructor, private state, public methods.

Since the module pattern only uses basic JavaScript, your code will run in any browser. You don't need CoffeeScript or an ES6 transpiler like Babel.

A cosmetic benefit is that the module pattern works without the use of this or prototypes.

Example

Here is an example for a Ruby class that we want to translate into Javascript using the module patter...

Managing vendor libraries with the Rails asset pipeline

The benefit of the Rails asset pipeline is that it compiles your stylesheets and javascripts to a single file, respectively. However, the consequences are startling if you don't understand them. Among others, the raw asset pipeline requires you to have all your asset libraries in the same folder, which quickly becomes confusing as your set of assets grows. To overcome this, we have two different solutions.

Custom solution

We are using a custom workaround to keep library files apart in their own directories. To avoid b...

Asset Pipeline Basics

The Rails asset pipeline improves delivery of application assets (javascripts, stylesheets, images, fonts). Here are some basic facts about its inner workings.

No magic

Manifests are the handle on your assets:

app/assets/stylesheets/application.css # use via: stylesheet_link_tag 'application'

The asset pipeline only considers files you explicitly require within your manifest files. The most common directives used in manifests are require some/file and require_tree some/directory. Paths may be **relative to the current director...

josephschmitt/Clamp.js

Clamps (ie. cuts off) an HTML element's content by adding ellipsis to it if the content inside is too long.

While you can only truncate single lines with CSS by using text-overflow, this small JavaScript library also allows truncating text after multiple lines.

Please note:

  • For Internet Explorer, the element you clamp on needs to have its line-height set in pixels. A relative value will not work.
  • There is also the [-webkit-line-clamp](http:...

The Easiest Way to Parse URLs with JavaScript

A very clever hack to parse a structured URL object is to create a <a> element and set its href to the URL you want to parse.

You can then query the <a> element for its components like schema, hostname, port, pathname, query, hash:

var parser = document.createElement('a');
parser.href = 'http://heise.de/bar';
parser.hostname; // => 'heise.de'
pathname = parser.pathname; // => '/bar'

if (pathname[0] != '/')
  pathname = '/' + pathname // Fix IE11

One advantag...

BubbletreeJS: A Javascript data visualization library

BubbleTree is a library for interactive visualization of hierarchical data. Originally developed mainly for spending data, the library is now completely independent from the OpenSpending platform. BubbleTree is built on top of jQuery and RaphaelJS.

See the Demo or the tutorial.

RaphaelJS: A Javascript vector graphics library

Raphaƫl is a small JavaScript library that should simplify your work with vector graphics on the web. If you want to create your own specific chart or image crop and rotate widget, for example, you can achieve it simply and easily with this library.

MetricsGraphics.js

MetricsGraphics.js is a library built on top of D3 that is optimized for visualizing and laying out time-series data. It provides a simple way to produce common types of graphics in a principled, consistent and responsive way. The library currently supports line charts, scatterplots and histograms as well as features like rug plots and basic linear regression.

Draggabilly

Javascript library for drag'n'drop that seems to have more options than native HTML5 drag'n'drop.

They also claim to support "multi-touch", which would be awesome if it means that you can drag on touch devices.


Another library with similar aims is interact.js (Github).

They're pitching JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE8+).

Angular: Binding an HTML value

To bind an HTML value to ng-bind-html, you need to mark it as "trusted" first. Among other ways, you can do so with a custom filter.

# Filter in Coffeescript...:
@app.filter 'htmlSafe', ['$sce', ($sce) -> $sce.trustAsHtml ]

# ...or JS:
app.filter('htmlSafe', [
  '$sce', function($sce) {
    return $sce.trustAsHtml;
  }
]);

# Usage:
<div ng-bind-html="item.value | htmlSafe"></div>

This is a replacement for the ng-bind-html-unsafe directive which has been removed in Angular 1.2.
:party:

LoDash: isBlank and isPresent mixins

When you need to check a value for presence, don't rely on JavaScript since it considers 0 or "0" false. Also don't rely on LoDash's _.isEmpty:

if ('0') { ... } // false
if (0) { ... } // false

^
if (!.isEmpty('0')) { ... } // true (= good)
if (!
.isEmpty(0)) { ... } // false (= not good)

This is because isEmpty it is only meant for objects with a length.

While the name implies that it's meant only for collections, you probably still want something like isBlank or `is...

Heads up: JavaScript does not like big numbers

In a JavaScript console, type this:

> 9112347935156469760
9112347935156470000

Ooops. And that's not a float!

This occurs because JavaScript uses double precision floats to store numbers.

So according to IEEE floating point definition only numbers between -(2^53 - 1) (-9007199254740991) and 2^53 - 1 (9007199254740991) can safely be represented in JavaScript.

Note that ECMAScript 6 will probably also offer [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/W...

Scroll a textarea to a given position with jQuery

Browsers make this very hard. Even when you explicitely set the selection inside the textarea (e. g. using jquery-fieldselection) the browser will not scroll the textarea to this selection.

What you can do instead is abuse browsers' behavior that they scroll to the end of a textarea when it gets focus. So we set the textarea's value to the text before the position, then focus it, then reset it to its original value:

function scrollTextareaToPosition($textarea, position) {
  var text...

bower-rails can rewrite your relative asset paths

The asset pipeline changes the paths of CSS files during precompilation. This opens a world of pain when CSS files reference images (like jQuery UI) or fonts (like webfont kits from Font Squirrel), since all those url(images/icon.png) will now point to a broken path.

In the past we have been using the vendor/asset-libs folder ...

JavaScript: How to check if an object is NaN

JavaScript's NaN ("Not a Number") is hard to compare against. It never equals anything, not even itself:

NaN === NaN;        // false
Number.NaN === NaN; // false

There is the isNaN method, but it is not really what you are looking for:

isNaN(NaN)     // true
isNaN('hello') // true

Option 1: ES6

The Object.is() method determines whether two values are the same value. It even works for NaN:

Object.is(NaN, NaN) // true

Option 2: ES5

The example above shows that simply using isNaN would match other ...

jQuery: Run an event handler only once

Simply use one(...) instead of on(...). It takes the same arguments.

Dealing with "TypeError: Converting circular structure to JSON" on JavaScript

JavaScript structures that include circular references can't be serialized with a"plain" JSON.stringify. Example:

a = { name: 'Groucho' };
b = { name: 'Harpo', sibling: a };
a.sibling = b;

Doing a JSON.stringify(a) will throw an error:

TypeError: Converting circular structure to JSON

There is not much you can do about that except specifying a custom serializer function that detects and cleans up circular references. There are existing solutions so you do not need to think of one yourself, like <https://githu...

Chartkick

Create beautiful Javascript charts with one line of Ruby.

Promising chart library for easily rendering charts with Google Charts.

This seems to not submit your data points to Google.

Pete Hunt: React - Rethinking Best Practices

Great introduction to React.js and the ideas behind it.

Capybara will not find links without an href attribute

Capybara will fail to find <a> tags that are missing an href attribute. This will probably happen to you every now and then on JavaScript-heavy applications.

An example would be an AngularJS application where the following HTML actually works. [1]

<a ng-click="hello()">Hello</a>

Capybara will fail to find that link, even though looking it up via the DOM shows it:

>> find_link("Hello")
Capybara::ElementNotFound: Unable to find link "Hello"

>> find("a").text
=> "Hello"

To make find_link and click_link work, ...

What we know about PDFKit

What PDFKit is

  • PDFKit converts a web page to a PDF document. It uses a Webkit engine under the hood.
  • For you as a web developer this means you can keep using the technology you are familar with and don't need to learn LaTeX. All you need is a pretty print-stylesheet.

How to use it from your Rails application

  • You can have PDFKit render a website by simply calling PDFKit.new('http://google.com').to_file('google.pdf'). You can then send the...

JavaScript: Moving elements inside an array, modifying the array in place

If you want to move an element inside an array, neither JavaScript/ES6+ nor libraries like LoDash offet that natively.

Here is a simple function instead that modifies the input array in place.

function moveArrayElement(array, element, offset) {
  const index = array.indexOf(element)
  const newIndex = index + offset
  
  if (newIndex > -1 && newIndex < array.length) {
    // Remove the element from the array
    const removedElement = array.splice(index, 1)[0]

    // At "newIndex", remove 0 elements and insert the removed el...

Testing drag&drop with Selenium

When using jQueryUI's Sortable plugin (either directly or via Angular's ui.sortable), you might struggle testing your nice drag&drop GUI since Selenium webdriver does not support native dragging events.

But jQueryUI uses jquery.simulate for their testing, so why shouldn't you? There is even an extension to it that makes testing drag & drop quite easy.

Here is what you need:

  1. jquery.simulate.js
  2. [`jquery.simula...