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...
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:
jquery.simulate.js
- [`jquery.simula...