plugins/incrementable.js
/**
 * Constructor
 * @param textField {HTMLElement} An input or textarea element
 * @param modifiers {Object} An object with params ctrlKey, altKey and/or shiftKey. The key combination must have a sum of >= 3.
 * 							For example, {altKey: 1, ctrlKey: 3, shiftKey: 2} means that either Ctrl has to be pressed with the arrows, or alt+shift, or alt+ctrl, or all three.
 *							The default is 0, which means no modifiers needed.
 */
Constructor
@param textField {HTMLElement} An input or textarea element
@param modifiers {Object} An object with params ctrlKey, altKey and/or shiftKey. The key combination must have a sum of >= 3.
For example, {altKey: 1, ctrlKey: 3, shiftKey: 2} means that either Ctrl has to be pressed with the arrows, or alt+shift, or alt+ctrl, or all three.
The default is 0, which means no modifiers needed.
Constructor @param textField { HTMLElement } An input or textarea element @param modifiers { Object } An object with params ctrlKey altKey and / or shiftKey . The key combination must have a sum of > = 3 . For example { altKey : 1 ctrlKey : 3 shiftKey : 2 } means that either Ctrl has to be pressed with the arrows or alt + shift or alt + ctrl or all three . The default is 0 which means no modifiers needed .
function Incrementable(textField, modifiers, units) {
	var me = this;
	this.textField = textField;
	this.step = +textField.getAttribute('step') || 
				+textField.getAttribute('data-step') || 1;
	modifiers = modifiers || {};
	this.modifiers = {
		ctrlKey: modifiers.ctrlKey || 0,
		altKey: modifiers.altKey || 0,
		shiftKey: modifiers.shiftKey || 0
	};
	if(units) {
		this.units = units;
	}
	this.changed = false;
	this.textField.addEventListener('keydown', function(evt) {
		if(me.checkModifiers(evt) && (evt.keyCode == 38 || evt.keyCode == 40)) {
			me.changed = false;
			var caret = this.selectionStart, text = this.value,
				regex = new RegExp('^([\\s\\S]{0,' + caret + '}[^-0-9\\.])(-?[0-9]*(?:\\.?[0-9]+)(?:' + me.units + '))\\b', 'i');
			this.value = this.value.replace(regex, function($0, $1, $2) {
				if($1.length <= caret && $1.length + $2.length >= caret) {
					me.changed = true;
					return $1 + me.stepValue($2, evt.keyCode == 40, evt.shiftKey);
				}
				else {
					return $1 + $2;
				}
			});
			if(me.changed) {
				this.selectionEnd = this.selectionStart = caret;
				evt.preventDefault();
				evt.stopPropagation();
			}
		}
	}, false);
	this.textField.addEventListener('keypress', function(evt) {
		if(me.changed && me.checkModifiers(evt) 
			&& (evt.keyCode == 38 || evt.keyCode == 40))
			evt.preventDefault();
			evt.stopPropagation();
			me.changed = false;
	}, false);
}
function Incrementable ( textField , modifiers , units ) { var me = this ; this . textField = textField ; this . step = + textField . getAttribute ( 'step' ) || + textField . getAttribute ( 'data-step' ) || 1 ; modifiers = modifiers || { } ; this . modifiers = { ctrlKey : modifiers . ctrlKey || 0 , altKey : modifiers . altKey || 0 , shiftKey : modifiers . shiftKey || 0 } ; if ( units ) { this . units = units ; } this . changed = false ; this . textField . addEventListener ( 'keydown' , function ( evt ) { if ( me . checkModifiers ( evt ) && ( evt . keyCode == 38 || evt . keyCode == 40 ) ) { me . changed = false ; var caret = this . selectionStart , text = this . value , regex = new RegExp ( '^([\\s\\S]{0,' + caret + '}[^-0-9\\.])(-?[0-9]*(?:\\.?[0-9]+)(?:' + me . units + '))\\b' , 'i' ) ; this . value = this . value . replace ( regex , function ( $0 , $1 , $2 ) { if ( $1 . length <= caret && $1 . length + $2 . length >= caret ) { me . changed = true ; return $1 + me . stepValue ( $2 , evt . keyCode == 40 , evt . shiftKey ) ; } else { return $1 + $2 ; } } ) ; if ( me . changed ) { this . selectionEnd = this . selectionStart = caret ; evt . preventDefault ( ) ; evt . stopPropagation ( ) ; } } } , false ) ; this . textField . addEventListener ( 'keypress' , function ( evt ) { if ( me . changed && me . checkModifiers ( evt ) && ( evt . keyCode == 38 || evt . keyCode == 40 ) ) evt . preventDefault ( ) ; evt . stopPropagation ( ) ; me . changed = false ; } , false ) ; }
Constructor
 @param textField {HTMLElement} An input or textarea element
 @param modifiers {Object} An object with params ctrlKey, altKey and/or shiftKey.
Constructor @param textField { HTMLElement } An input or textarea element @param modifiers { Object } An object with params ctrlKey altKey and / or shiftKey .
// Up or down arrow pressed, check if there's something // increment/decrement-able where the caret is