Commit aa41aed9 by marco

prototype for polyfill on number input fields, minimal styling to up down buttons

parent b16e17a2
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label class="label setting-label" for="<%= uniqueId %>"><%= model.get('display_name') %></label> <label class="label setting-label" for="<%= uniqueId %>"><%= model.get('display_name') %></label>
<input class="input setting-input" type="number" id="<%= uniqueId %>" value='<%= model.get("value") %>' onkeyup="checkNumberSettingValidity(this);"/> <input class="input setting-input setting-input-number" type="number" id="<%= uniqueId %>" value='<%= model.get("value") %>' onkeyup="checkNumberValidity(this)"/>
<button class="action setting-clear inactive" type="button" name="setting-clear" value="Clear" data-tooltip="Clear"> <button class="action setting-clear inactive" type="button" name="setting-clear" value="Clear" data-tooltip="Clear">
<i class="ss-icon ss-symbolicons-block undo">&#x21A9;</i><span class="sr">Clear Value</span> <i class="ss-icon ss-symbolicons-block undo">&#x21A9;</i><span class="sr">Clear Value</span>
</button> </button>
......
...@@ -30,8 +30,7 @@ class CMS.Views.ModuleEdit extends Backbone.View ...@@ -30,8 +30,7 @@ class CMS.Views.ModuleEdit extends Backbone.View
}); });
#Manually runs polyfill for input number types to correct for Firefox non-support #Manually runs polyfill for input number types to correct for Firefox non-support
#wrapperSettings = @$el.find(".wrapper-comp-settings") #numberPolyfill()
#wrapperSettings.inputNumber()
# Need to update set "active" class on data editor if there is one. # Need to update set "active" class on data editor if there is one.
# If we are only showing settings, hide the data editor controls and update settings accordingly. # If we are only showing settings, hide the data editor controls and update settings accordingly.
......
...@@ -897,16 +897,9 @@ function saveSetSectionScheduleDate(e) { ...@@ -897,16 +897,9 @@ function saveSetSectionScheduleDate(e) {
}); });
} }
function checkNumberSettingValidity(e) { function checkNumberValidity(e) {
e.preventDefault(); e.preventDefault;
$(e).val($(e).val().match(/\d*\.?\d+/));
if (!e.checkNumberSettingValidity())
{
alert("You have invalid input. Correct it!");
obj.focus();
$('this').val('');
}
} }
...@@ -619,9 +619,11 @@ body.course.unit { ...@@ -619,9 +619,11 @@ body.course.unit {
.wrapper-comp-setting{ .wrapper-comp-setting{
display: inline-block; display: inline-block;
width: 360px; min-width: 300px;
width: 45%;
top: 0; top: 0;
vertical-align: top; vertical-align: top;
margin-bottom:5px;
} }
label.setting-label { label.setting-label {
...@@ -669,7 +671,7 @@ body.course.unit { ...@@ -669,7 +671,7 @@ body.course.unit {
} }
input[type="number"] { input[type="number"] {
width: 39%; width: 36%;
@include box-shadow(0 1px 2px $shadow-l1 inset); @include box-shadow(0 1px 2px $shadow-l1 inset);
&:active { &:active {
...@@ -720,7 +722,6 @@ body.course.unit { ...@@ -720,7 +722,6 @@ body.course.unit {
.tip.setting-help { .tip.setting-help {
@include font-size(12); @include font-size(12);
margin-top: 5px;
display: inline-block; display: inline-block;
font-color: $gray-l6; font-color: $gray-l6;
min-width: 260px; min-width: 260px;
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
div.number-spin-btn-container { div.number-spin-btn-container {
display: inline-block; display: inline-block;
position: relative; position: relative;
vertical-align: bottom; vertical-align: top;
margin: 0; margin: 0;
margin-left: 3px;
padding: 0; } padding: 0; }
div.number-spin-btn { div.number-spin-btn {
...@@ -13,9 +14,11 @@ div.number-spin-btn { ...@@ -13,9 +14,11 @@ div.number-spin-btn {
border-width: 2px; border-width: 2px;
border-color: #ededed #777777 #777777 #ededed; border-color: #ededed #777777 #777777 #ededed;
border-style: solid; border-style: solid;
background-color: #cccccc; background-color: #eeeeee;
width: 1.2em; } width: 1.2em; }
div.number-spin-btn:hover { div.number-spin-btn:hover {
/* added blue hover color */
background-color: rgb(85, 151, 221);
cursor: pointer; } cursor: pointer; }
div.number-spin-btn:active { div.number-spin-btn:active {
border-width: 2px; border-width: 2px;
......
...@@ -3,296 +3,299 @@ ...@@ -3,296 +3,299 @@
/* /*
HTML5 Number polyfill | Jonathan Stipe | https://github.com/jonstipe/number-polyfill HTML5 Number polyfill | Jonathan Stipe | https://github.com/jonstipe/number-polyfill
*/ */
function numberPolyfill() {
(function() { (function() {
(function($) { (function($) {
var i; var i;
i = document.createElement("input"); i = document.createElement("input");
i.setAttribute("type", "number"); i.setAttribute("type", "number");
if (i.type === "text") { if (i.type === "text") {
$.fn.inputNumber = function() { $.fn.inputNumber = function() {
var clipValues, decrement, domMouseScrollHandler, extractNumDecimalDigits, getParams, increment, matchStep, mouseWheelHandler; var clipValues, decrement, domMouseScrollHandler, extractNumDecimalDigits, getParams, increment, matchStep, mouseWheelHandler;
getParams = function(elem) { getParams = function(elem) {
var $elem, max, min, step, val; var $elem, max, min, step, val;
$elem = $(elem); $elem = $(elem);
step = $elem.attr('step'); step = $elem.attr('step');
min = $elem.attr('min'); min = $elem.attr('min');
max = $elem.attr('max'); max = $elem.attr('max');
val = parseFloat($elem.val()); val = parseFloat($elem.val());
step = /^-?\d+(?:\.\d+)?$/.test(step) ? parseFloat(step) : null; step = /^-?\d+(?:\.\d+)?$/.test(step) ? parseFloat(step) : null;
min = /^-?\d+(?:\.\d+)?$/.test(min) ? parseFloat(min) : null; min = /^-?\d+(?:\.\d+)?$/.test(min) ? parseFloat(min) : null;
max = /^-?\d+(?:\.\d+)?$/.test(max) ? parseFloat(max) : null; max = /^-?\d+(?:\.\d+)?$/.test(max) ? parseFloat(max) : null;
if (isNaN(val)) { if (isNaN(val)) {
val = min || 0; val = min || 0;
}
return {
min: min,
max: max,
step: step,
val: val
};
};
clipValues = function(value, min, max) {
if ((max != null) && value > max) {
return max;
} else if ((min != null) && value < min) {
return min;
} else {
return value;
}
};
extractNumDecimalDigits = function(input) {
var num, raisedNum;
if (input != null) {
num = 0;
raisedNum = input;
while (raisedNum !== Math.round(raisedNum)) {
num += 1;
raisedNum = input * Math.pow(10, num);
} }
return num; return {
} else { min: min,
return 0; max: max,
} step: step,
}; val: val
matchStep = function(value, min, max, step) { };
var mod, raiseTo, raisedMod, raisedStep, raisedStepDown, raisedStepUp, raisedValue, stepDecimalDigits, stepDown, stepUp; };
stepDecimalDigits = extractNumDecimalDigits(step); clipValues = function(value, min, max) {
if (step == null) { if ((max != null) && value > max) {
return value; return max;
} else if (stepDecimalDigits === 0) { } else if ((min != null) && value < min) {
mod = (value - (min || 0)) % step; return min;
if (mod === 0) {
return value;
} else { } else {
stepDown = value - mod; return value;
stepUp = stepDown + step; }
if ((stepUp > max) || ((value - stepDown) < (stepUp - value))) { };
return stepDown; extractNumDecimalDigits = function(input) {
} else { var num, raisedNum;
return stepUp; if (input != null) {
num = 0;
raisedNum = input;
while (raisedNum !== Math.round(raisedNum)) {
num += 1;
raisedNum = input * Math.pow(10, num);
} }
return num;
} else {
return 0;
} }
} else { };
raiseTo = Math.pow(10, stepDecimalDigits); matchStep = function(value, min, max, step) {
raisedStep = step * raiseTo; var mod, raiseTo, raisedMod, raisedStep, raisedStepDown, raisedStepUp, raisedValue, stepDecimalDigits, stepDown, stepUp;
raisedMod = (value - (min || 0)) * raiseTo % raisedStep; stepDecimalDigits = extractNumDecimalDigits(step);
if (raisedMod === 0) { if (step == null) {
return value; return value;
} else if (stepDecimalDigits === 0) {
mod = (value - (min || 0)) % step;
if (mod === 0) {
return value;
} else {
stepDown = value - mod;
stepUp = stepDown + step;
if ((stepUp > max) || ((value - stepDown) < (stepUp - value))) {
return stepDown;
} else {
return stepUp;
}
}
} else { } else {
raisedValue = value * raiseTo; raiseTo = Math.pow(10, stepDecimalDigits);
raisedStepDown = raisedValue - raisedMod; raisedStep = step * raiseTo;
raisedStepUp = raisedStepDown + raisedStep; raisedMod = (value - (min || 0)) * raiseTo % raisedStep;
if (((raisedStepUp / raiseTo) > max) || ((raisedValue - raisedStepDown) < (raisedStepUp - raisedValue))) { if (raisedMod === 0) {
return raisedStepDown / raiseTo; return value;
} else { } else {
return raisedStepUp / raiseTo; raisedValue = value * raiseTo;
raisedStepDown = raisedValue - raisedMod;
raisedStepUp = raisedStepDown + raisedStep;
if (((raisedStepUp / raiseTo) > max) || ((raisedValue - raisedStepDown) < (raisedStepUp - raisedValue))) {
return raisedStepDown / raiseTo;
} else {
return raisedStepUp / raiseTo;
}
} }
} }
} };
}; increment = function(elem) {
increment = function(elem) { var newVal, params, raiseTo;
var newVal, params, raiseTo; if (!$(elem).is(":disabled")) {
if (!$(elem).is(":disabled")) { params = getParams(elem);
params = getParams(elem); raiseTo = Math.pow(10, Math.max(extractNumDecimalDigits(params['val']), extractNumDecimalDigits(params['step'])));
raiseTo = Math.pow(10, Math.max(extractNumDecimalDigits(params['val']), extractNumDecimalDigits(params['step']))); newVal = (Math.round(params['val'] * raiseTo) + Math.round((params['step'] || 1) * raiseTo)) / raiseTo;
newVal = (Math.round(params['val'] * raiseTo) + Math.round((params['step'] || 1) * raiseTo)) / raiseTo; if ((params['max'] != null) && newVal > params['max']) {
if ((params['max'] != null) && newVal > params['max']) { newVal = params['max'];
newVal = params['max'];
}
newVal = matchStep(newVal, params['min'], params['max'], params['step']);
$(elem).val(newVal).change();
}
return null;
};
decrement = function(elem) {
var newVal, params, raiseTo;
if (!$(elem).is(":disabled")) {
params = getParams(elem);
raiseTo = Math.pow(10, Math.max(extractNumDecimalDigits(params['val']), extractNumDecimalDigits(params['step'])));
newVal = (Math.round(params['val'] * raiseTo) - Math.round((params['step'] || 1) * raiseTo)) / raiseTo;
if ((params['min'] != null) && newVal < params['min']) {
newVal = params['min'];
}
newVal = matchStep(newVal, params['min'], params['max'], params['step']);
$(elem).val(newVal).change();
}
return null;
};
domMouseScrollHandler = function(e) {
e.preventDefault();
if (e.originalEvent.detail < 0) {
increment(this);
} else {
decrement(this);
}
return null;
};
mouseWheelHandler = function(e) {
e.preventDefault();
if (e.originalEvent.wheelDelta > 0) {
increment(this);
} else {
decrement(this);
}
return null;
};
$(this).filter('input[type="number"]').each(function() {
var $downBtn, $elem, $upBtn, attrMutationCallback, attrObserver, btnContainer, downBtn, elem, halfHeight, upBtn;
elem = this;
$elem = $(elem);
halfHeight = ($elem.outerHeight() / 2) + 'px';
upBtn = document.createElement('div');
downBtn = document.createElement('div');
$upBtn = $(upBtn);
$downBtn = $(downBtn);
btnContainer = document.createElement('div');
$upBtn.addClass('number-spin-btn number-spin-btn-up').css('height', halfHeight);
$downBtn.addClass('number-spin-btn number-spin-btn-down').css('height', halfHeight);
btnContainer.appendChild(upBtn);
btnContainer.appendChild(downBtn);
$(btnContainer).addClass('number-spin-btn-container').insertAfter(elem);
$elem.on({
focus: function(e) {
$elem.on({
DOMMouseScroll: domMouseScrollHandler,
mousewheel: mouseWheelHandler
});
return null;
},
blur: function(e) {
$elem.off({
DOMMouseScroll: domMouseScrollHandler,
mousewheel: mouseWheelHandler
});
return null;
},
keypress: function(e) {
var _ref, _ref1;
if (e.keyCode === 38) {
increment(this);
} else if (e.keyCode === 40) {
decrement(this);
} else if (((_ref = e.keyCode) !== 8 && _ref !== 9 && _ref !== 35 && _ref !== 36 && _ref !== 37 && _ref !== 39) && ((_ref1 = e.which) !== 45 && _ref1 !== 46 && _ref1 !== 48 && _ref1 !== 49 && _ref1 !== 50 && _ref1 !== 51 && _ref1 !== 52 && _ref1 !== 53 && _ref1 !== 54 && _ref1 !== 55 && _ref1 !== 56 && _ref1 !== 57)) {
e.preventDefault();
} }
return null; newVal = matchStep(newVal, params['min'], params['max'], params['step']);
}, $(elem).val(newVal).change();
change: function(e) { }
var newVal, params; return null;
if (e.originalEvent != null) { };
params = getParams(this); decrement = function(elem) {
newVal = clipValues(params['val'], params['min'], params['max']); var newVal, params, raiseTo;
newVal = matchStep(newVal, params['min'], params['max'], params['step'], params['stepDecimal']); if (!$(elem).is(":disabled")) {
$(this).val(newVal); params = getParams(elem);
raiseTo = Math.pow(10, Math.max(extractNumDecimalDigits(params['val']), extractNumDecimalDigits(params['step'])));
newVal = (Math.round(params['val'] * raiseTo) - Math.round((params['step'] || 1) * raiseTo)) / raiseTo;
if ((params['min'] != null) && newVal < params['min']) {
newVal = params['min'];
} }
return null; newVal = matchStep(newVal, params['min'], params['max'], params['step']);
$(elem).val(newVal).change();
} }
});
$upBtn.on("mousedown", function(e) {
var releaseFunc, timeoutFunc;
increment(elem);
timeoutFunc = function(elem, incFunc) {
incFunc(elem);
$elem.data("timeoutID", window.setTimeout(timeoutFunc, 10, elem, incFunc));
return null;
};
releaseFunc = function(e) {
window.clearTimeout($elem.data("timeoutID"));
$(document).off('mouseup', releaseFunc);
$upBtn.off('mouseleave', releaseFunc);
return null;
};
$(document).on('mouseup', releaseFunc);
$upBtn.on('mouseleave', releaseFunc);
$elem.data("timeoutID", window.setTimeout(timeoutFunc, 700, elem, increment));
return null; return null;
}); };
$downBtn.on("mousedown", function(e) { domMouseScrollHandler = function(e) {
var releaseFunc, timeoutFunc; e.preventDefault();
decrement(elem); if (e.originalEvent.detail < 0) {
timeoutFunc = function(elem, decFunc) { increment(this);
decFunc(elem); } else {
$elem.data("timeoutID", window.setTimeout(timeoutFunc, 10, elem, decFunc)); decrement(this);
return null; }
};
releaseFunc = function(e) {
window.clearTimeout($elem.data("timeoutID"));
$(document).off('mouseup', releaseFunc);
$downBtn.off('mouseleave', releaseFunc);
return null;
};
$(document).on('mouseup', releaseFunc);
$downBtn.on('mouseleave', releaseFunc);
$elem.data("timeoutID", window.setTimeout(timeoutFunc, 700, elem, decrement));
return null; return null;
}); };
$elem.css("textAlign", 'right'); mouseWheelHandler = function(e) {
if ($elem.css("opacity") !== "1") { e.preventDefault();
$(btnContainer).css("opacity", $elem.css("opacity")); if (e.originalEvent.wheelDelta > 0) {
} increment(this);
if ($elem.css("visibility") !== "visible") { } else {
$(btnContainer).css("visibility", $elem.css("visibility")); decrement(this);
} }
if (elem.style.display !== "") { return null;
$(btnContainer).css("display", $elem.css("display")); };
} $(this).filter('input[type="number"]').each(function() {
if ((typeof WebKitMutationObserver !== "undefined" && WebKitMutationObserver !== null) || (typeof MutationObserver !== "undefined" && MutationObserver !== null)) { var $downBtn, $elem, $upBtn, attrMutationCallback, attrObserver, btnContainer, downBtn, elem, halfHeight, upBtn;
attrMutationCallback = function(mutations, observer) { elem = this;
var mutation, _i, _len; $elem = $(elem);
for (_i = 0, _len = mutations.length; _i < _len; _i++) { halfHeight = ($elem.outerHeight() / 2) + 'px';
mutation = mutations[_i]; upBtn = document.createElement('div');
if (mutation.type === "attributes") { downBtn = document.createElement('div');
if (mutation.attributeName === "class") { $upBtn = $(upBtn);
$(btnContainer).removeClass(mutation.oldValue).addClass(elem.className); $downBtn = $(downBtn);
} else if (mutation.attributeName === "style") { btnContainer = document.createElement('div');
$(btnContainer).css({ $upBtn.addClass('number-spin-btn number-spin-btn-up').css('height', halfHeight);
"opacity": elem.style.opacity, $downBtn.addClass('number-spin-btn number-spin-btn-down').css('height', halfHeight);
"visibility": elem.style.visibility, btnContainer.appendChild(upBtn);
"display": elem.style.display btnContainer.appendChild(downBtn);
}); $(btnContainer).addClass('number-spin-btn-container').insertAfter(elem);
} $elem.on({
focus: function(e) {
$elem.on({
DOMMouseScroll: domMouseScrollHandler,
mousewheel: mouseWheelHandler
});
return null;
},
blur: function(e) {
$elem.off({
DOMMouseScroll: domMouseScrollHandler,
mousewheel: mouseWheelHandler
});
return null;
},
keypress: function(e) {
var _ref, _ref1;
if (e.keyCode === 38) {
increment(this);
} else if (e.keyCode === 40) {
decrement(this);
} else if (((_ref = e.keyCode) !== 8 && _ref !== 9 && _ref !== 35 && _ref !== 36 && _ref !== 37 && _ref !== 39) && ((_ref1 = e.which) !== 45 && _ref1 !== 46 && _ref1 !== 48 && _ref1 !== 49 && _ref1 !== 50 && _ref1 !== 51 && _ref1 !== 52 && _ref1 !== 53 && _ref1 !== 54 && _ref1 !== 55 && _ref1 !== 56 && _ref1 !== 57)) {
e.preventDefault();
} }
return null;
},
change: function(e) {
var newVal, params;
if (e.originalEvent != null) {
params = getParams(this);
newVal = clipValues(params['val'], params['min'], params['max']);
newVal = matchStep(newVal, params['min'], params['max'], params['step'], params['stepDecimal']);
$(this).val(newVal);
}
return null;
} }
});
$upBtn.on("mousedown", function(e) {
var releaseFunc, timeoutFunc;
increment(elem);
timeoutFunc = function(elem, incFunc) {
incFunc(elem);
$elem.data("timeoutID", window.setTimeout(timeoutFunc, 10, elem, incFunc));
return null;
};
releaseFunc = function(e) {
window.clearTimeout($elem.data("timeoutID"));
$(document).off('mouseup', releaseFunc);
$upBtn.off('mouseleave', releaseFunc);
return null;
};
$(document).on('mouseup', releaseFunc);
$upBtn.on('mouseleave', releaseFunc);
$elem.data("timeoutID", window.setTimeout(timeoutFunc, 700, elem, increment));
return null; return null;
};
attrObserver = (typeof WebKitMutationObserver !== "undefined" && WebKitMutationObserver !== null) ? new WebKitMutationObserver(attrMutationCallback) : ((typeof MutationObserver !== "undefined" && MutationObserver !== null) ? new MutationObserver(attrMutationCallback) : null);
attrObserver.observe(elem, {
attributes: true,
attributeOldValue: true,
attributeFilter: ["class", "style"]
}); });
} else if (typeof MutationEvent !== "undefined" && MutationEvent !== null) { $downBtn.on("mousedown", function(e) {
$elem.on("DOMAttrModified", function(evt) { var releaseFunc, timeoutFunc;
if (evt.originalEvent.attrName === "class") { decrement(elem);
$(btnContainer).removeClass(evt.originalEvent.prevValue).addClass(evt.originalEvent.newValue); timeoutFunc = function(elem, decFunc) {
} else if (evt.originalEvent.attrName === "style") { decFunc(elem);
$(btnContainer).css({ $elem.data("timeoutID", window.setTimeout(timeoutFunc, 10, elem, decFunc));
"display": elem.style.display, return null;
"visibility": elem.style.visibility, };
"opacity": elem.style.opacity releaseFunc = function(e) {
}); window.clearTimeout($elem.data("timeoutID"));
} $(document).off('mouseup', releaseFunc);
$downBtn.off('mouseleave', releaseFunc);
return null;
};
$(document).on('mouseup', releaseFunc);
$downBtn.on('mouseleave', releaseFunc);
$elem.data("timeoutID", window.setTimeout(timeoutFunc, 700, elem, decrement));
return null; return null;
}); });
} $elem.css("textAlign", 'right');
if ($elem.css("opacity") !== "1") {
$(btnContainer).css("opacity", $elem.css("opacity"));
}
if ($elem.css("visibility") !== "visible") {
$(btnContainer).css("visibility", $elem.css("visibility"));
}
if (elem.style.display !== "") {
$(btnContainer).css("display", $elem.css("display"));
}
if ((typeof WebKitMutationObserver !== "undefined" && WebKitMutationObserver !== null) || (typeof MutationObserver !== "undefined" && MutationObserver !== null)) {
attrMutationCallback = function(mutations, observer) {
var mutation, _i, _len;
for (_i = 0, _len = mutations.length; _i < _len; _i++) {
mutation = mutations[_i];
if (mutation.type === "attributes") {
if (mutation.attributeName === "class") {
$(btnContainer).removeClass(mutation.oldValue).addClass(elem.className);
} else if (mutation.attributeName === "style") {
$(btnContainer).css({
"opacity": elem.style.opacity,
"visibility": elem.style.visibility,
"display": elem.style.display
});
}
}
}
return null;
};
attrObserver = (typeof WebKitMutationObserver !== "undefined" && WebKitMutationObserver !== null) ? new WebKitMutationObserver(attrMutationCallback) : ((typeof MutationObserver !== "undefined" && MutationObserver !== null) ? new MutationObserver(attrMutationCallback) : null);
attrObserver.observe(elem, {
attributes: true,
attributeOldValue: true,
attributeFilter: ["class", "style"]
});
} else if (typeof MutationEvent !== "undefined" && MutationEvent !== null) {
$elem.on("DOMAttrModified", function(evt) {
if (evt.originalEvent.attrName === "class") {
$(btnContainer).removeClass(evt.originalEvent.prevValue).addClass(evt.originalEvent.newValue);
} else if (evt.originalEvent.attrName === "style") {
$(btnContainer).css({
"display": elem.style.display,
"visibility": elem.style.visibility,
"opacity": elem.style.opacity
});
}
return null;
});
}
return null;
});
return $(this);
};
$(function() {
$('input[type="number"]').inputNumber();
return null; return null;
}); });
return $(this); null;
}; } else {
$(function() { $.fn.inputNumber = function() {
$('input[type="number"]').inputNumber(); return $(this);
return null; };
}); null;
null; }
} else { return null;
$.fn.inputNumber = function() { })(jQuery);
return $(this);
}; }).call(this);
null;
}
return null;
})(jQuery);
}).call(this); };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment