Skip to content

Commit

Permalink
* implemented oninput method for form elements for unsupported
Browse files Browse the repository at this point in the history
  browsers
* fix IE9 to ensure backspace and delete keys fire an
  oninput event.

Change-Id: Ie7ad580fc8c556bd5cac58df096b39a2549e30e3
  • Loading branch information
zoltan-dulac committed May 12, 2011
1 parent cc2229d commit db1ae81
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 48 deletions.
20 changes: 19 additions & 1 deletion shared/js/EventHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,25 @@ var EventHelpers = new function(){
} else {
return false;
}
}
}

/*
* Detects whether the event "eventName" is supported on a tag with name
* "nodeName". Based on code from
* http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
*/
me.isSupported = function (eventName, nodeName) {
var el = document.createElement(nodeName);
eventName = 'on' + eventName;
var isSupported = (eventName in el);
if (!isSupported) {
el.setAttribute(eventName, 'return;');
isSupported = typeof el[eventName] == 'function';
}
el = null;
return isSupported;
}


/* EventHelpers.init () */
function init(){
Expand Down
112 changes: 85 additions & 27 deletions shared/js/html5Widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
* This javascript library contains helper routines to assist with event
* handling consinstently among browsers
*
* html5Widgets.js v.1.0 by Zoltan Hawryluk
* html5Widgets.js v.1.1 by Zoltan Hawryluk
* latest version and documentation available at http://www.useragentman.com/
*
* Changelog:
* version 1.0: initial release
* version 1.1: implemented oninput method for form elements for unsupported browsers
* fix IE9 to ensure backspace and delete keys fire an oninput event.
*
* released under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*
Expand All @@ -18,10 +23,9 @@ var html5Widgets = new function(){

var delayEventTimeout = null;



me.inputNodes = new Array();
me.outputNodes = new Array();
me.formElements = null;
me.placeholderNodes = new Array();
me.dummyLink = document.createElement('input');
var quoteRe = /\"/g;
Expand All @@ -30,16 +34,27 @@ var html5Widgets = new function(){
var supportsNatively = new Object();

var isBadChrome = navigator.userAgent.indexOf('Chrome');

var valueRe = /this\.value/g;
var varRe = /([a-zA-Z][a-zA-Z0-9]*\.value)/g;
var isDebug;

var isIE9 = false;

/*@cc_on
@if (@_jscript_version == 9)
isIE9 = true;
@end
@*/



me.init = function(){

if (EventHelpers.hasPageLoadHappened(arguments)) {
return;
}


supportsNatively['oninput'] = EventHelpers.isSupported('input', 'form');

isDebug = CSSHelpers.isMemberOfClass(document.body, 'html5Widgets-debug')

Expand Down Expand Up @@ -108,6 +123,8 @@ var html5Widgets = new function(){
me.outputNodes.push(new OutputElement(outputEl))
}

me.formElements = document.getElementsByTagName('form');

}

function setOutputEvents(nodeName) {
Expand All @@ -118,6 +135,7 @@ var html5Widgets = new function(){
// first - set event to resolve output tags
EventHelpers.addEvent(formElement, 'change', me.resolveOutputs);
EventHelpers.addEvent(formElement, 'keyup', me.resolveOutputs);
EventHelpers.addEvent(formElement, 'cut', me.resolveOutputs);
}
}

Expand All @@ -131,7 +149,10 @@ var html5Widgets = new function(){
fdSliderController.removeOnLoadEvent();
}


var formElementTypes = ["input", "select", "textarea"];
for (var i=0; i<formElementTypes.length; i++) {
setOutputEvents(formElementTypes[i]);
}

var formElements = document.getElementsByTagName('input');

Expand Down Expand Up @@ -184,10 +205,7 @@ var html5Widgets = new function(){

}

var formElementTypes = ["input", "select", "te xtarea"];
for (var i=0; i<formElementTypes.length; i++) {
setOutputEvents(formElementTypes[i]);
}


if (window.fdSliderController) {
fdSliderController.redrawAll();
Expand Down Expand Up @@ -226,11 +244,45 @@ var html5Widgets = new function(){
EventHelpers.fireEvent(el, ev);
}

me.resolveOutputs = function () {
me.resolveOutputs = function (e) {

// This resolves the onforminput events on the output nodes
for (var i=0; i<me.outputNodes.length; i++) {
var outputNode = me.outputNodes[i];
outputNode.resolve();
}

// This resolves the oninput events on the form nodes
if (!supportsNatively['oninput']) {
for (var i=0; i<me.formElements.length; i++) {
var formNode = me.formElements[i];
var oninput = DOMHelpers.getAttributeValue(formNode, 'oninput');
if (oninput) {
eval(me.getValueFormula(oninput, formNode));
}
}
} else if (isIE9 && e) {
// must deal with buggy implementation - delete and backspace don't fire
// the oninput event
var input = EventHelpers.getEventTarget(e);
switch (e.type) {

case "keyup":
var key = EventHelpers.getKey(e);

switch (key) {
case 8:
case 46:
case 88:
EventHelpers.fireEvent(input.form, 'input');
}
break;
case "cut":
delayedFireEvent(input.form, 'input');
break;
}

}
}

me.hideInput = function (node) {
Expand All @@ -241,6 +293,17 @@ var html5Widgets = new function(){
node.style.visibility = 'hidden'
}

me.getValueFormula = function(expr, parentForm) {
var formula = expr
if (formula == null) {
return null;
}
formula = formula
.replace(valueRe, 'value')
.replace(varRe, 'document.forms["' + parentForm.id + '"].$1');
return formula;
}


function showError(err) {
if (isDebug) {
Expand All @@ -257,12 +320,13 @@ var html5Widgets = new function(){

function RangeElement(node){
var me = this;
var parentForm;

me.node = node;
me.sliderNode = null;

function init (){

parentForm = DOMHelpers.getAncestorByTagName(node, 'form');
var min = parseFloat(DOMHelpers.getAttributeValue(me.node, 'min'));
var max = parseFloat(DOMHelpers.getAttributeValue(me.node, 'max'));

Expand Down Expand Up @@ -349,9 +413,13 @@ var html5Widgets = new function(){
EventHelpers.addEvent(me.node, 'change', changeOriginalNodeEvent);
}

me.changeEvent = function (e){
delayedFireEvent(me.node, 'change');
me.changeEvent = function (e){
var oninput = DOMHelpers.getAttributeValue(parentForm, 'oninput');

if (oninput) {
eval(html5Widgets.getValueFormula(oninput, parentForm));
}
delayedFireEvent(me.node, 'change');
}

function changeOriginalNodeEvent(e) {
Expand Down Expand Up @@ -589,28 +657,18 @@ var html5Widgets = new function(){
var valueFormula;
var parentForm;

var valueRe = /this\.value/g;
var varRe = /([a-zA-Z][a-zA-Z0-9]*\.value)/g;


function init () {
parentForm = DOMHelpers.getAncestorByTagName(node, 'form');
if (!parentForm.id) {
parentForm.id = getNextDummyID();
}

valueFormula = getValueFormula();
valueFormula = html5Widgets.getValueFormula(DOMHelpers.getAttributeValue(me.node, 'onforminput'), parentForm);
}

function getValueFormula () {
var formula = DOMHelpers.getAttributeValue(me.node, 'onforminput');
if (formula == null) {
return null;
}
formula = formula
.replace(valueRe, 'value')
.replace(varRe, 'document.forms["' + parentForm.id + '"].$1');
return formula;
}


me.resolve = function () {
if (valueFormula == null) {
Expand Down
2 changes: 2 additions & 0 deletions tests/html5Widgets/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Changelog for this package:
version 1.0 - initial release (July 27, 2010)
version 1.0b - updated to deal with WebKit's half-implemented WebForms 2 Implementation (Sept 10, 2010)
version 1.1 - implemented oninput method for form elements for unsupported browsers
- fix IE9 to ensure backspace and delete keys fire an oninput event. (May 12, 2011)
1 change: 0 additions & 1 deletion tests/html5Widgets/autofocus.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

<link type="text/css" rel="stylesheet" href="css/form.css" />

Expand Down
5 changes: 3 additions & 2 deletions tests/html5Widgets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
<title>HTML5 Widgets</title>
<link rel="stylesheet" href="../../shared/css/useragentmanExample.css" type="text/css" media="all" />
</head>
Expand All @@ -21,7 +20,9 @@
<li><a href="placeholder.html"><code>placeholder</code> example</a></li>
<li><a href="range.html"><code>range</code> example</a></li>
<li><a href="datetime.html">the various <code>date</code> related widgets</a></li>
<li><a href="output.html"><code>output</code> tag example</a></li>
<li><a href="output.html"><code>output</code> tag with <code>onforminput</code> event</a></li>
<li><a href="outputWithOninput.html"><code>output</code> tag with <code>oninput</code> event</a></li>
<li><a href="outputWithBothOnforminputAndOninput.html"><code>output</code> tag with both <code>onforminput</code> and <code>oninput</code> events</a></li>
<li><a href="color.html"><code>color</code> example</a></li>
<li><a href="example.html">And now ... everything together.</a></li>
</ul>
Expand Down
3 changes: 1 addition & 2 deletions tests/html5Widgets/new_file.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
content="HTML Tidy, see www.w3.org" />
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible"
content="IE=EmulateIE8" />


<title>Untitled Document</title>
</head>
Expand Down
4 changes: 2 additions & 2 deletions tests/html5Widgets/output.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

<title>Example of the output tag.</title>

Expand All @@ -28,7 +27,8 @@
</head>
<body id="myExample" class="html5Widgets-debug">
<div id="exampleBlurb">
<p>The following is an example of using the HTML5 <code>output</code> tag to do
<p>The following is an example of using the HTML5 <code>output</code> tag with the
deprecated <code>onforminput</code> event to do
some calculations on the data within the form. <a href="#">Back to the User Agent Man HTML5 Forms article</a>.</p>
</div>

Expand Down
1 change: 0 additions & 1 deletion tests/html5Widgets/patternRequired-styleError.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

<link type="text/css" rel="stylesheet" href="css/form.css" />

Expand Down
1 change: 0 additions & 1 deletion tests/html5Widgets/patternRequired.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

<link type="text/css" rel="stylesheet" href="css/form.css" />

Expand Down
3 changes: 1 addition & 2 deletions tests/html5Widgets/patternRequiredWithVisibleIf.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />


<link type="text/css" rel="stylesheet" href="css/form.css" />
<link type="text/css" rel="stylesheet" href="../../shared/css/visibleIf.css" />

Expand Down
1 change: 0 additions & 1 deletion tests/html5Widgets/placeholder.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

<link type="text/css" rel="stylesheet" href="css/form.css" />

Expand Down
Loading

0 comments on commit db1ae81

Please sign in to comment.