You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
982 lines
37 KiB
982 lines
37 KiB
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8"> |
|
<title>Test TextBox Validation Widgets</title> |
|
|
|
<style type="text/css"> |
|
@import "../../themes/claro/document.css"; |
|
@import "../css/dijitTests.css"; |
|
|
|
.testExample { |
|
background-color:#fbfbfb; |
|
padding:1em; |
|
margin-bottom:1em; |
|
border:1px solid #bfbfbf; |
|
} |
|
|
|
body .small { |
|
width: 3em; |
|
} |
|
body .medium { |
|
width: 10em; |
|
} |
|
body .long { |
|
width: 20em; |
|
} |
|
body .verylong { |
|
width: 90%; |
|
} |
|
|
|
.noticeMessage { |
|
color:#093669; |
|
font-size:0.95em; |
|
margin-left:0.5em; |
|
} |
|
|
|
.dojoTitlePaneLabel label { |
|
font-weight:bold; |
|
} |
|
#widget_q26 .dijitInputField { |
|
padding:10px !important; |
|
} |
|
|
|
.monospace .dijitTextBox { |
|
font-family: monospace; |
|
} |
|
|
|
.sans { |
|
font-family: sans-serif; |
|
} |
|
</style> |
|
|
|
<!-- required: the default dijit theme: --> |
|
<link id="themeStyles" rel="stylesheet" href="../../themes/claro/claro.css"/> |
|
|
|
<!-- |
|
required: dojo.js |
|
Note that the locale is hardcoded to english, for benefit of the robot/ValidationTextBox.html test |
|
(when running on a non-US computer). |
|
--> |
|
<script type="text/javascript" src="../../../dojo/dojo.js" |
|
data-dojo-config="isDebug: true, parseOnLoad: true, locale: 'en-us', extraLocale: ['de-de']"></script> |
|
|
|
<!-- only needed for alternate theme testing: --> |
|
<script type="text/javascript" src="../_testCommon.js"></script> |
|
|
|
<script type="text/javascript"> |
|
dojo.require("doh.runner"); |
|
|
|
dojo.require("dijit.form.TextBox"); |
|
dojo.require("dijit.form.ValidationTextBox"); |
|
dojo.require("dijit.form.NumberTextBox"); |
|
dojo.require("dijit.form.CurrencyTextBox"); |
|
|
|
dojo.require("dijit.Dialog"); |
|
dojo.require("dijit.form.Button"); |
|
dojo.require("dijit.tests.helpers"); // functions to help test |
|
|
|
dojo.require("dojo.currency"); |
|
dojo.require("dojo.parser"); // scan page for widgets and instantiate them |
|
|
|
// Add test=true to the URL to run unit tests. |
|
var test = /mode=test/i.test(window.location.href); |
|
|
|
function fixNbsp(val){ |
|
return typeof val == "string" ? val.replace(/\xA0/g, " ") : val; |
|
} |
|
|
|
dojo.ready(function(){ |
|
|
|
new dijit.form.TextBox({id: 'monospace1', "aria-label":"monospace1", disabled: true, value: 'M|M:monospace?'}, 'monospace1'); |
|
new dijit.form.TextBox({id: 'monospace2', "aria-label":"monospace2",disabled: true, value: 'M|M:monospace?'}).placeAt('widget_monospace1', 'after'); |
|
|
|
new dijit.form.TextBox({id: 'sans1', "aria-label":"sans1", disabled: true, value: 'sans1'}, 'sans1'); |
|
new dijit.form.TextBox({id: 'sans2', "aria-label":"sans2", disabled: true, value: 'sans2'}).placeAt('widget_sans1', 'after'); |
|
|
|
// See if we can make a widget in script and attach it to the DOM ourselves. |
|
var props = { |
|
name: "elevation", |
|
value: 3000, |
|
constraints: {min:-20000,max:20000,places:0,allowCruft:true}, |
|
promptMessage: "Enter a value between -20000 and +20000", |
|
required: true, |
|
style:{ textAlign: document.documentElement.dir == "rtl" ? "left" : "right" }, |
|
editOptions:{pattern:'#,##0'}, |
|
invalidMessage: "Invalid elevation.", |
|
onChange: function(val){dojo.byId('oc5').value = val; }, |
|
"class": "medium" |
|
}; |
|
(new dojo.declare("customNumberTextBox", dijit.form.NumberTextBox, props)({}, "q05")).startup(); |
|
|
|
props = { |
|
name: "ticket1651", |
|
id: "mname", |
|
templateString: null, // #11493 |
|
templatePath: dojo.moduleUrl('dijit.form.templates', 'TextBox.html'), |
|
value: null, |
|
"aria-labelledby":"l_ticket1651" |
|
}; |
|
(new dijit.form.TextBox(props, "ticket1651")).startup(); |
|
|
|
if(!test){ return; } |
|
|
|
// Test initial conditions |
|
doh.register("initial conditions", { |
|
name: "initial conditions", |
|
runTest: function(){ |
|
var form1 = dojo.byId("form1"); |
|
|
|
doh.is("Testing Testing", form1.firstname.value, "firstname"); |
|
doh.is("not fired yet!", dojo.byId("oc1").value, "firstname onchange"); |
|
|
|
doh.is("TESTING TESTING", form1.lastname.value, "lastname"); |
|
|
|
doh.is("", form1.age.value, "age"); |
|
doh.is("not fired yet!", dojo.byId("oc3").value, "age onchange"); |
|
|
|
doh.is("", form1.occupation.value, "occupation"); |
|
|
|
doh.is("3000", form1.elevation.value, "elevation"); |
|
doh.is("3,000", dojo.byId("q05").value, "elevation display value"); |
|
doh.is("not fired yet!", dojo.byId("oc5").value, "elevation onchange"); |
|
doh.t(!!dijit.byId("q05").constraints.allowCruft, "constructor constraints value"); |
|
|
|
doh.is("54775.53", form1.income1.value, "income1"); |
|
doh.is("$54,775.53", dojo.byId("q08").value, "income1 display value"); |
|
doh.is("not fired yet!", dojo.byId("oc8").value, "income1 onchange"); |
|
|
|
doh.is("54775.53", form1.income2.value, "income2"); |
|
doh.is("€54,775.53", dojo.byId("q08eur").value, "income2 display value"); |
|
doh.f(!!dijit.byId("q08eur").constraints.allowCruft, "constructor constraints value not proliferated"); |
|
|
|
doh.is("someTestString", form1.phone.value, "phone"); |
|
doh.is("", form1.password.value, "password"); |
|
doh.is("", form1.ticket1651.value, "ticket1651"); |
|
doh.is("cannot type here", form1.readOnly.value, "readonly"); |
|
doh.is("cannot type here", form1.disabled.value, "disabled"); |
|
} |
|
}); |
|
|
|
var watchHandle, onChangeHandle; |
|
|
|
function setTest(testName, textbox, setDict, watchExpected, unchangedExpected, isValid, onChangeExpected){ |
|
// summary: |
|
// Generate test to call set("value", ...) and check response |
|
// textbox: String |
|
// id of TextBox widget |
|
// setDict: Dictionary |
|
// Value to pass to textbox.set(), such as {value: "123"} or {displayedValue: "1,234"}. |
|
// watchExpected: Dictionary |
|
// Expected changes in state of TextBox, such as |
|
// {value: 1234, displayedValue: "1,234"} |
|
// Checks that watch() returns these values. |
|
// Also checks that textbox is actually displaying displayedValue |
|
// unchangedExpected: Dictionary |
|
// Attributes of textbox that shouldn't change/be reported by watch(), and their values |
|
// {value: 1234, displayedValue: "1,234"} |
|
// Checks that watch() returns these values. |
|
// Also checks that textbox is actually displaying displayedValue |
|
// isValid: Boolean |
|
// Checks return of textbox.isValid(). TODO: this should be watchable. |
|
// onChangeExpected: |
|
// Check that onChange reports this value |
|
|
|
|
|
return { |
|
name: testName, |
|
timeout: 1000, |
|
runTest: function(){ |
|
|
|
textbox = dijit.byId(textbox); |
|
|
|
// expectedState is a combination of the attributes that we expect to change |
|
// and the attributes that we expect not to change |
|
var expectedState = dojo.delegate(watchExpected, unchangedExpected); |
|
|
|
// save all notifications from watch() |
|
var watchActual = {}; |
|
watchHandle = textbox.watch(function(attr, oldVal, newVal){ |
|
console.log(textbox.id + ": " + attr + ": " + oldVal + " --> " + newVal); |
|
watchActual[attr] = fixNbsp(newVal); |
|
}); |
|
|
|
// and monitor onChange() calls too |
|
var onChangeActual; |
|
if(onChangeExpected){ |
|
onChangeHandle = textbox.on("change", function(newVal){ |
|
onChangeActual = fixNbsp(newVal); |
|
}); |
|
} |
|
|
|
// do the set |
|
textbox.set(setDict); |
|
|
|
doh.is(expectedState.displayedValue, fixNbsp(textbox.focusNode.value), "focusNode.value"); |
|
|
|
doh.is(isValid, textbox.isValid(), "isValid()"); |
|
|
|
var d = new doh.Deferred(); |
|
|
|
setTimeout(d.getTestCallback(function(){ |
|
// test that onChange() was called correctly |
|
if(onChangeExpected){ |
|
doh.is(onChangeExpected, onChangeActual, "onChange()"); |
|
} |
|
|
|
// check that watch() callbacks were called |
|
for(attr in watchExpected){ |
|
doh.t(attr in watchActual, "watch(" + attr + ") fired"); |
|
doh.is(watchExpected[attr], watchActual[attr], "watch(" + attr + ")"); |
|
doh.is(typeof watchExpected[attr], typeof watchActual[attr], "typeof watch(" + attr + ")") |
|
} |
|
|
|
// check that direct get(...) calls are also working, for both the attributes |
|
// that were supposed to change and the attributes that weren't supposed to change |
|
for(attr in expectedState){ |
|
doh.is(expectedState[attr], fixNbsp(textbox.get(attr)), "get(" + attr + ")"); |
|
doh.is(typeof expectedState[attr], typeof textbox.get(attr), "typeof get(" + attr + ")") |
|
} |
|
|
|
// check that watch() didn't report attributes as changed when they didn't change |
|
for(attr in unchangedExpected){ |
|
doh.f(attr in watchActual, attr + " shouldn't have been reported as changed by watch " + |
|
watchActual[attr]); |
|
} |
|
}), 50); |
|
|
|
return d; |
|
}, |
|
tearDown: function(){ |
|
watchHandle.unwatch(); |
|
watchHandle = null; |
|
if(onChangeHandle){ |
|
onChangeHandle.remove(); |
|
onChangeHandle = null; |
|
} |
|
} |
|
}; |
|
} |
|
|
|
doh.register("set('value')", [ |
|
// test valid and invalid settings of value |
|
setTest("valid_max", 'q03', {value: 120}, {value: 120, displayedValue: "120"}, {}, true), |
|
setTest("out_of_range_max",'q03', {value: 121}, {value: 121, displayedValue: "121", state: "Error"}, {}, false), |
|
setTest("valid_min", 'q03', {value: 0}, {value: 0, displayedValue: "0", state: ""}, {}, true), |
|
setTest("out_of_range_min", 'q03', {value: -1}, {value: -1, displayedValue: "-1", state: "Error"}, {}, false), |
|
setTest("invalid", 'q03', {value: 'two'}, {value: undefined, displayedValue: 'two'}, {}, false), |
|
setTest("null_required", 'q03', {required: true, value: null}, |
|
{required: true, value: NaN, displayedValue: ''}, {state: "Error"}, false), |
|
setTest("null_notrequired", 'q03', {required: false, value: null}, {}, {displayedValue: ''}, true), |
|
|
|
// test formatting of value vs. displayed value |
|
setTest("number format", 'q05', {value: 1234}, {value: 1234, displayedValue: "1,234"}, {}, true), |
|
setTest("currency format", 'q08', {value: 1234}, {value: 1234, displayedValue: "$1,234.00"}, {}, true) |
|
]); |
|
|
|
doh.register("set('displayedValue')", [ |
|
// test formatting of value vs. displayed value, in reverse |
|
setTest("number format", 'q05', {displayedValue: "4,321"}, {value: 4321, displayedValue: "4,321"}, {}, true), |
|
setTest("european currency format", 'q08eurde', {displayedValue: "4.321,98"}, |
|
{value: 4321.98, displayedValue: "4.321,98 €"}, {}, true) |
|
]); |
|
|
|
doh.register("font inheritance", [ |
|
{ |
|
name: "with srcNodeRef, style on .dijitTextBox", |
|
runTest: function(){ |
|
var d = new doh.Deferred(); |
|
setTimeout(d.getTestCallback(function(){ |
|
doh.is("monospace", dojo.style('monospace1', "fontFamily")); |
|
}), 0); |
|
return d; |
|
} |
|
}, |
|
{ |
|
name: "without srcNodeRef, style on .dijitTextBox", |
|
runTest: function(){ |
|
var d = new doh.Deferred(); |
|
setTimeout(d.getTestCallback(function(){ |
|
doh.is("monospace", dojo.style('monospace2', "fontFamily")); |
|
}), 0); |
|
return d; |
|
} |
|
}, |
|
{ |
|
name: "with srcNodeRef, style inherited", |
|
runTest: function(){ |
|
var d = new doh.Deferred(); |
|
setTimeout(d.getTestCallback(function(){ |
|
doh.is("sans-serif", dojo.style('sans1', "fontFamily")); |
|
}), 0); |
|
return d; |
|
} |
|
}, |
|
{ |
|
name: "without srcNodeRef, style inherited", |
|
runTest: function(){ |
|
var d = new doh.Deferred(); |
|
setTimeout(d.getTestCallback(function(){ |
|
doh.is("sans-serif", dojo.style('sans2', "fontFamily")); |
|
}), 0); |
|
return d; |
|
} |
|
} |
|
]); |
|
|
|
doh.register("pattern", [ |
|
{ |
|
name: "pattern markup", |
|
runTest: function(){ |
|
var w = dijit.byId('q22'); |
|
w.set('value', 'someTestString'); |
|
doh.is(true, w.isValid(false)); |
|
doh.f(!!w.focusNode.getAttribute('pattern'), "native pattern"); |
|
} |
|
}, |
|
{ |
|
name: "pattern string", |
|
runTest: function(){ |
|
var w = dijit.byId('q22'); |
|
w.set('value', 'someTestString'); |
|
w.set('pattern', "some[a-z]+"); // invalid |
|
doh.is(false, w.isValid(false), "invalid"); |
|
doh.is(false, w._isValidSubset(), "invalid partial"); |
|
w.set('value', 'some'); |
|
doh.is(true, w._isValidSubset(), "valid partial"); |
|
w.set('value', 'someTestString'); |
|
w.set('pattern', "someT[a-z]+S[a-z]+"); // valid |
|
doh.is(true, w.isValid(false), "valid"); |
|
doh.is(true, w._isValidSubset(), "valid partial 2"); |
|
doh.f(!!w.focusNode.getAttribute('pattern'), "native pattern"); |
|
} |
|
}, |
|
{ |
|
name: "pattern function", |
|
runTest: function(){ |
|
var w = dijit.byId('q22'); |
|
w.set('value', 'someTestString'); |
|
w.set('pattern', function(){ return "[a-z]+"; }); // invalid |
|
doh.is('Error', w.get('state')); |
|
doh.is(false, w.isValid(false), "invalid string"); |
|
w.set('pattern', function(){ return "[a-zTS]+"; }); // valid |
|
doh.is('', w.get('state')); |
|
doh.is(true, w.isValid(false), "valid string"); |
|
} |
|
} |
|
]); |
|
|
|
doh.register("#11889", [ |
|
{ |
|
name: "non-focused places:5", |
|
timeout: 2000, |
|
textbox: "q05", |
|
setUp: function(){ |
|
this.textbox = dijit.byId(this.textbox); |
|
this.textbox.set('constraints', { places: 5 }); |
|
this.textbox.set('editOptions', { places: "2,4" }); |
|
}, |
|
runTest: function(){ |
|
this.textbox.set('value', 1.625); |
|
doh.is(1.625, this.textbox.get('value'), 'numeric value is unchanged'); |
|
doh.is('1.62500', this.textbox.get('displayedValue'), 'formatted displayed value'); |
|
doh.t(this.textbox.isValid(false), 'nonfocused is valid'); |
|
} |
|
}, |
|
{ |
|
name: "focused places:2,4. blur to places:5", |
|
timeout: 2000, |
|
textbox: "q05", |
|
runTest: function(){ |
|
var d = new doh.Deferred(); |
|
var textbox = this.textbox; |
|
|
|
textbox = dijit.byId(this.textbox); |
|
textbox.set('constraints', { places: 5 }); |
|
textbox.set('editOptions', { places: "2,4" }); |
|
textbox.focus(); |
|
|
|
setTimeout(d.getTestErrback(function(){ // allow time for async focus on IE9+ |
|
textbox.set('value', 1.125); |
|
|
|
doh.is(1.125, textbox.get('value'), 'numeric value is unchanged'); |
|
doh.is('1.125', textbox.get('displayedValue'), 'formatted displayed value'); |
|
doh.t(textbox.isValid(true), 'focused is valid'); |
|
|
|
|
|
var handler = textbox.on("blur", function(){ |
|
handler.remove(); |
|
setTimeout(d.getTestCallback(function(){ |
|
doh.is(1.125, textbox.get('value'), 'numeric value is unchanged #2'); |
|
doh.is('1.12500', textbox.get('displayedValue'), 'formatted displayed value #2'); |
|
doh.t(textbox.isValid(false), 'nonfocused is valid #2'); |
|
}), 150); |
|
}); |
|
dojo.byId("q01").focus(); |
|
}), 0); |
|
|
|
return d; |
|
} |
|
} |
|
]); |
|
|
|
doh.register("validation in dialog", [ |
|
{ |
|
name: "showDialog", |
|
timeout: 5000, |
|
runTest: function() { |
|
// Show dialog, returning Deferred that fires when show dialog is finished. |
|
// Before showing, focus the open button, so that Dialog knows where to return focus to. |
|
|
|
var d = new doh.Deferred(); |
|
|
|
dijit.byId("dlgOpenBtn").focus(); |
|
|
|
// Focus on IE9+ is asynchronous, so wait for it to occur before showing Dialog. Otherwise, |
|
// when Dialog closes it restores focus somewhere strange. |
|
setTimeout(function () { |
|
dijit.byId("dlg").show().then(function () { |
|
d.resolve(true); |
|
}); |
|
}, 0); |
|
|
|
return d; |
|
} |
|
}, |
|
function enterInvalidValue(){ |
|
// Entering invalid value should make validation tooltip appear |
|
var d = new doh.Deferred(); |
|
dijit.byId("dlgNTB").set("value", "invalid"); |
|
dijit.byId("dlgNTB").focus(); |
|
setTimeout(d.getTestCallback(function(){ |
|
masterTT = dojo.global.dijit._masterTT; |
|
doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown"); |
|
}), 300); |
|
return d; |
|
}, |
|
{ |
|
name: "hideDialog", |
|
timeout: 5000, |
|
runTest: function () { |
|
// Hiding the dialog should make the validation tooltip disappear |
|
var d = new doh.Deferred(); |
|
dijit.byId("dlg").hide().then(function () { |
|
setTimeout(d.getTestCallback(function () { |
|
doh.t(isHidden(masterTT.domNode), "tooltip hidden"); |
|
}), 300); |
|
}); |
|
return d; |
|
} |
|
} |
|
]); |
|
|
|
doh.run(); |
|
}); |
|
</script> |
|
</head> |
|
|
|
<body class="claro" role="main"> |
|
<h1 class="testTitle">Dijit Validation Widgets</h1> |
|
<!-- to test form submission, you'll need to create an action handler similar to |
|
http://www.utexas.edu/teamweb/cgi-bin/generic.cgi --> |
|
<form id="form1" action="" name="example" method="GET"> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q01">First Name: </label> |
|
<span class="noticeMessage"> TextBox class, <b>tabIndex=2</b>, Attributes: {trim: true, propercase: true, intermediateChanges: true, style: 'width:700px', selectOnClick: true}, First letter of each word is upper case.</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q01" data-dojo-type="dijit/form/TextBox" |
|
name="firstname" value="testing testing" style="width:700px" tabIndex="2" |
|
data-dojo-props=' |
|
trim:true, |
|
selectOnClick:true, |
|
onFocus:function(){ console.log("user onfocus handler"); }, |
|
onBlur:function(){ console.log("user onblur handler"); }, |
|
onChange:function(v){ dojo.byId("oc1").value=v; }, |
|
intermediateChanges:true, |
|
propercase:true '/> |
|
<br><label for="oc1">onChange:</label><input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/> |
|
<input tabIndex="-1" type="button" onclick="dijit.byId('q01').set('disabled', true);" value="Disable"/> |
|
<input tabIndex="-1" type="button" onclick="dijit.byId('q01').set('disabled', false);" value="Enable"/> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q02">Last Name: </label> |
|
<span class="noticeMessage"> TextBox class, Attributes: {trim: true, uppercase: true, "class": 'verylong'}, all letters converted to upper case. </span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q02" data-dojo-type="dijit/form/TextBox" |
|
name="lastname" value="testing testing" class="verylong" |
|
data-dojo-props='trim:true, uppercase:true '/> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q03">Age: </label> |
|
<span class="noticeMessage"> NumberTextBox class, <b>tabIndex=1</b>, Attributes: {trim: true}, no initial value specified, tooltipPosition=[above, below]. Displays a prompt message if field is blank.</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q03" data-dojo-type="dijit/form/NumberTextBox" |
|
name="age" tabIndex="1" class="small" |
|
data-dojo-props=' |
|
promptMessage:"(optional) Enter an age between 0 and 120", |
|
maxLength:"3", |
|
constraints:{places:0,min:0,max:120}, |
|
onChange:function(val){ dojo.byId("oc3").value=""+val; }, |
|
tooltipPosition:["above", "below"] |
|
'/> |
|
<label for="oc3">onChange:</label><input id="oc3" size="14" disabled value="not fired yet!" autocomplete="off"/> |
|
<span style='white-space:nowrap;'> |
|
<button id="q03_valid" type=button onclick="dijit.byId('q03').set('value', 120);">set value to 120</button> |
|
<button id="q03_outofrange" type=button onclick="dijit.byId('q03').set('value', 121);">set value to 121</button> |
|
<button id="q03_invalid" type=button onclick="dijit.byId('q03').set('value', 'two');">set value to two</button> |
|
<button id="q03_null" type=button onclick="dijit.byId('q03').set('value', null);">set value to null</button> |
|
<button type=button onclick="dojo.byId('gv3').value=''+dijit.byId('q03').get('value');">get value</button> |
|
<input id="gv3" aria-label="get value 3" size="10" disabled value="" autocomplete="off"/> |
|
</span> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="fav">Favorite Number (1-100): </label> |
|
<span class="noticeMessage"> NumberTextBox class, Attributes: required=true, must be integer, no messages provided, no initial value specified, maxlength=3</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="fav" data-dojo-type="dijit/form/NumberTextBox" |
|
name="fav" class="small" required |
|
data-dojo-props='maxLength:"3",constraints:{places:0,min:1,max:100},pattern:"\\d+"'/> |
|
<button onclick="dijit.byId('fav').set('required', true); return false;">attr(required, true)</button> |
|
<button onclick="dijit.byId('fav').set('required', false); return false;">attr(required, false)</button> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q04">Occupation: </label> |
|
<span class="noticeMessage">ValidationTextBox class, |
|
Attributes: {lowercase: true, required: true, "class": verylong, style: font-size: 15pt;}. Displays a prompt message if field is blank.</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q04" data-dojo-type="dijit/form/ValidationTextBox" |
|
name="occupation" class="verylong" style="fontSize:15pt" required="true" |
|
data-dojo-props='lowercase:true, promptMessage:"Enter an occupation" '/> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q05">Elevation: </label> |
|
<span class="noticeMessage">IntegerTextBox class, |
|
Attributes: {required: true, min:-20000, max:+20000 }, displays a prompt message if field is blank, thousands separator remains during editing.</span> |
|
<span class="noticeMessage">Enter feet above sea level with a sign.</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q05" class="small"/> |
|
<label for="oc5">onChange:</label><input id="oc5" size="10" disabled value="not fired yet!" autocomplete="off"/> |
|
</div> |
|
<!-- |
|
<div class="dojoTitlePaneLabel"> |
|
<label for="attach-here">Population: </label> |
|
<span class="noticeMessage">IntegerTextBox class, |
|
Attributes: {trim: true, required: true, signed: false, separator: ","}. <br><b> This widget was added in script, not markup. </b> </span> |
|
</div> |
|
<div class="testExample" > |
|
<input id="attach-here" type="text" name="population" class="medium" value="1500000"/> |
|
</div> |
|
|
|
<script> |
|
// See if we can make a widget in script and attach it to the DOM ourselves. |
|
dojo.ready(function(){ |
|
var props = { |
|
name: "population", |
|
value: "1,500,000", |
|
trim: "true", |
|
required: "true", |
|
pattern: dojo.regexp.integer, |
|
constraints: {signed:false, separator: ","}, |
|
invalidMessage: "Invalid population. Enter a number." |
|
}; |
|
var w = new dijit.form.ValidationTextBox(props, "attach-here"); |
|
}); |
|
</script> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q06">Real Number: </label> |
|
<span class="noticeMessage">RealNumberTextBox class, |
|
Attributes: {trim: true, required: true}. Enter any sort of real number.</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q06" type="text" name="real1" class="medium" value="+0.1234" |
|
data-dojo-type="dijit/form/ValidationTextBox" |
|
pattern="dojo.regexp.realNumber" |
|
trim="true" |
|
required="true" |
|
invalidMessage="This is not a valid real number." /> |
|
</div> |
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q07">Exponential Notation: </label> |
|
<span class="noticeMessage">RealNumberTextBox class, |
|
Attributes: {exponent: true}. Enter a real number in exponential notation.</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q07" type="text" name="real2" class="medium" value="+0.12" |
|
data-dojo-type="dijit/form/ValidationTextBox" |
|
pattern="dojo.regexp.realNumber" |
|
trim="true" |
|
required="true" |
|
constraints="{exponent:true}" |
|
invalidMessage="Number must be in exponential notation. Example +5E-28" /> |
|
</div> |
|
--> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q08">Annual Income: </label> |
|
<span class="noticeMessage">CurrencyTextBox class, |
|
Attributes: {fractional: true}. Enter whole and cents. Currency symbol is optional. Cents are MANDATORY.</span> |
|
</div> |
|
|
|
<div class="testExample"> |
|
<input id="q08" data-dojo-type="dijit/form/CurrencyTextBox" |
|
name="income1" class="medium" value="54775.53" required |
|
data-dojo-props='constraints:{fractional:true}, |
|
currency:"USD", |
|
onChange:function(val){ dojo.byId("oc8").value = val; }, |
|
invalidMessage:"Invalid amount. Cents are MANDATORY." '/>USD |
|
<label for="oc8">onChange:</label><input id="oc8" size="15" disabled value="not fired yet!" autocomplete="off"/> |
|
</div> |
|
|
|
<div class="testExample"> |
|
<label for="q08eur">euro currency (local format) fractional part is optional:</label> |
|
<input id="q08eur" data-dojo-type="dijit/form/CurrencyTextBox" |
|
name="income2" class="medium" value="54775.53" required |
|
data-dojo-props='currency:"EUR", invalidMessage:"Invalid amount. Include cents." '/>EUR |
|
<button onclick="dijit.byId('q08eur').set('disabled',true); return false;">Disable</button> |
|
<button onclick="dijit.byId('q08eur').set('disabled',false); return false;">Enable</button> |
|
<button onclick="dijit.byId('q08eur').reset(); return false;">Reset</button> |
|
</div> |
|
|
|
<!-- |
|
It is unusual to override the lang properties on individual |
|
widgets. Usually it should be the user's default or set on |
|
a page basis by the server. This is for testing purposes |
|
--> |
|
<div class="testExample"> |
|
euro currency (fixed lang: de-de) programmatically created, fractional part is optional: <input id="q08eurde" class="medium"/>EUR |
|
</div> |
|
|
|
<script> |
|
// See if we can make a widget in script and attach it |
|
// to the DOM ourselves. |
|
dojo.ready(function(){ |
|
var example = dojo.currency.format(54775.53, {locale: 'de-de', currency: "EUR"}); |
|
var props = { |
|
name: "income3", |
|
value: 54775.53, |
|
lang: 'de-de', |
|
required: true, |
|
currency: "EUR", |
|
invalidMessage: "Invalid amount. Example: " + example, |
|
"aria-label": "income3 de-de" |
|
}; |
|
var w = new dijit.form.CurrencyTextBox(props, "q08eurde"); |
|
}); |
|
</script> |
|
|
|
<!-- |
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q08a">Annual Income: </label> |
|
<span class="noticeMessage">Old regexp currency textbox, |
|
Attributes: {fractional: true}. Enter dollars and cents.</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q08a" type="text" name="income3" class="medium" value="$54,775.53" |
|
data-dojo-type="dijit/form/ValidationTextBox" |
|
pattern="dojo.regexp.currency" |
|
trim="true" |
|
required="true" |
|
constraints="{fractional:true}" |
|
invalidMessage="Invalid amount. Include cents. Example: $12,000.00" /> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q09">IPv4 Address: </label> |
|
<span class="noticeMessage">IpAddressTextBox class, |
|
Attributes: {allowIPv6: false, allowHybrid: false}. Also Dotted Hex works, 0x18.0x11.0x9b.0x28</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q09" type="text" name="ipv4" class="medium" value="24.17.155.40" |
|
data-dojo-type="dijit/form/ValidationTextBox" |
|
pattern="dojo.regexp.ipAddress" |
|
trim="true" |
|
required="true" |
|
constraints="{allowIPv6:false,allowHybrid:false}" |
|
invalidMessage="Invalid IPv4 address."/> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q10"> IPv6 Address: </label> |
|
<span class="noticeMessage">IpAddressTextBox class, |
|
Attributes: {allowDottedDecimal: false, allowDottedHex: false}. |
|
Also hybrid works, x:x:x:x:x:x:d.d.d.d</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q10" type="text" name="ipv6" class="long" value="0000:0000:0000:0000:0000:0000:0000:0000" |
|
data-dojo-type="dijit/form/ValidationTextBox" |
|
pattern="dojo.regexp.ipAddress" |
|
trim="true" |
|
uppercase = "true" |
|
required="true" |
|
constraints="{allowDottedDecimal:false, allowDottedHex:false, allowDottedOctal:false}" |
|
invalidMessage="Invalid IPv6 address, please enter eight groups of four hexadecimal digits. x:x:x:x:x:x:x:x"/> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q11"> URL: </label> |
|
<span class="noticeMessage">UrlTextBox class, |
|
Attributes: {required: true, trim: true, scheme: true}. </span> |
|
</div> |
|
|
|
<div class="testExample"> |
|
<input id="q11" type="text" name="url" class="long" value="http://www.xyz.com/a/b/c?x=2#p3" |
|
data-dojo-type="dijit/form/ValidationTextBox" |
|
pattern="dojo.regexp.url" |
|
trim="true" |
|
required="true" |
|
constraints="{scheme:true}" |
|
invalidMessage="Invalid URL. Be sure to include the scheme, http://..." /> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q12"> Email Address </label> |
|
<span class="noticeMessage">EmailTextBox class, |
|
Attributes: {required: true, trim: true}. </span> |
|
</div> |
|
|
|
<div class="testExample"> |
|
<input id="q12" type="text" name="email" class="long" value="fred&barney@stonehenge.com" |
|
data-dojo-type="dijit/form/ValidationTextBox" |
|
pattern="dojo.regexp.emailAddress" |
|
trim="true" |
|
required="true" |
|
invalidMessage="Invalid Email Address." /> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q13"> Email Address List </label> |
|
<span class="noticeMessage">EmailListTextBox class, |
|
Attributes: {required: true, trim: true}. </span> |
|
</div> |
|
|
|
<div class="testExample"> |
|
<input id="q13" type="text" name="email" class="long" value="a@xyz.com; b@xyz.com; c@xyz.com; " |
|
data-dojo-type="dijit/form/ValidationTextBox" |
|
pattern="dojo.regexp.emailAddressList" |
|
trim="true" |
|
required="true" |
|
invalidMessage="Invalid Email Address List." /> |
|
</div> |
|
--> |
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q22">Regular Expression </label> |
|
<span class="noticeMessage">RegexpTextBox class, |
|
Attributes: {required: true} </span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q22" data-dojo-type="dijit/form/ValidationTextBox" |
|
name="phone" class="medium" value="someTestString" required |
|
data-dojo-props='pattern:"[\\w]+", invalidMessage:"Invalid Non-Space Text."'/> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q23"> Password </label> |
|
<span class="noticeMessage">(just a test that type attribute is obeyed) </span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q23" data-dojo-type="dijit/form/TextBox" type="password" name="password" class="medium"/> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label id="l_ticket1651">Trac ticket 1651: </label> |
|
<span class="noticeMessage">value: null should show up as empty</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="ticket1651" class="medium" value="not null"/> |
|
</div> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q24">initially readOnly TextBox</label> |
|
<span class="noticeMessage">a test that readOnly and disabled are understood for TextBox</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q24" data-dojo-type="dijit/form/TextBox" |
|
name="readOnly" class="medium" readOnly value="cannot type here" title="hint text"/> |
|
<input type="button" id="removereadonly" onclick="dijit.byId('q24').set('readOnly',false);" value="Remove readOnly" tabIndex="-1"/> |
|
<input type="button" onclick="dijit.byId('q24').set('readOnly',true);" value="Set readOnly" tabIndex="-1"/> |
|
<input type="button" id="removedisabled" onclick="dijit.byId('q24').set('disabled',false);" value="Remove disabled" tabIndex="-1"/> |
|
<input type="button" onclick="dijit.byId('q24').set('disabled',true);" value="Set disabled" tabIndex="-1"/> |
|
</div> |
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q25">initially disabled ValidationTextBox</label> |
|
<span class="noticeMessage">a test that disabled is understood for ValidationTextBox</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q25" data-dojo-type="dijit/form/ValidationTextBox" |
|
name="disabled" class="medium" disabled value="cannot type here"/> |
|
<input type="button" onclick="dijit.byId('q25').set('readOnly',false);" value="Remove readOnly" tabIndex="-1"/> |
|
<input type="button" onclick="dijit.byId('q25').set('readOnly',true);" value="Set readOnly" tabIndex="-1"/> |
|
<input type="button" onclick="dijit.byId('q25').set('disabled',false);" value="Remove disabled" tabIndex="-1"/> |
|
<input type="button" onclick="dijit.byId('q25').set('disabled',true);" value="Set disabled" tabIndex="-1"/> |
|
</div> |
|
|
|
<script> |
|
// so robot can get to it easily |
|
document.displayData=function(){ |
|
var f = document.getElementById("form1"); |
|
var s = ""; |
|
for(var i = 0; i < f.elements.length; i++){ |
|
var elem = f.elements[i]; |
|
if(elem.nodeName.toLowerCase() == "button" || elem.type=="submit" || elem.type=="button") { continue; } |
|
s += elem.name + ": " + elem.value + "\n"; |
|
} |
|
return s; |
|
} |
|
</script> |
|
|
|
<div> |
|
<button name="button" onclick="alert(document.displayData()); return false;" tabIndex="-1">view data</button> |
|
<input type="submit" name="submit" tabIndex="-1"/> |
|
</div> |
|
|
|
</form> |
|
<div class="dojoTitlePaneLabel"> |
|
<label for="q26">TextBox with placeholder</label> |
|
<span class="noticeMessage">a test that placeholder works for TextBox. 10px padding added for testing.</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="q26" data-dojo-type="dijit/form/TextBox" placeHolder="placeholder is here" name="placeHolder" value=""/> |
|
<button type="button" onclick="dijit.byId('q26').set('placeHolder', 'this is a very long placeholder that will overflow the input');"> |
|
set long placeholder |
|
</button> |
|
</div> |
|
<h2>Tooltip positioning</h2> |
|
<p> |
|
These buttons switch the positions searched to try to place the validation error tooltips. |
|
Note that setting tooltip positioning to "above" or "below" is dangerous if |
|
you have a node with a dropdown, but the drop down might overlap the tooltip. |
|
</p> |
|
<button onclick="dijit.Tooltip.defaultPosition=['above', 'below'];">above, below</button> |
|
<button onclick="dijit.Tooltip.defaultPosition=['after', 'before'];">after, before (default)</button> |
|
|
|
<div class="monospace"> |
|
<input id="monospace1"/> |
|
</div> |
|
<div class="sans"> |
|
<input id="sans1"/> |
|
</div> |
|
|
|
<h2>Validation tooltips inside of dialogs:</h2> |
|
<div dojoType="dijit.Dialog" id="dlg"> |
|
<label for="dlgNTB">NumberTextBox:</label> |
|
<div dojoType="dijit.form.NumberTextBox" id="dlgNTB"></div> |
|
</div> |
|
<button dojoType="dijit.form.Button" id="dlgOpenBtn" onclick="dijit.byId('dlg').show();">show dialog</button> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label id="l_ticket17923">Trac ticket 17923</label> |
|
<span class="noticeMessage">Partial numeric input should be validated with respect to the min/max constraints and available space</span> |
|
</div> |
|
|
|
<div class="testExample"> |
|
<input id="ticket17923" class="medium"/> |
|
<input type="button" id="ticket17923-maxLength5" value="maxLength: 5" tabIndex="-1"/> |
|
<input type="button" id="ticket17923-maxLength3" value="maxLength: 3" tabIndex="-1"/> |
|
<input type="button" id="ticket17923-min1:max15" value="min: 12, max: 142" tabIndex="-1"/> |
|
<input type="button" id="ticket17923-min-15:max15" value="min: -15, max: -5" tabIndex="-1"/> |
|
</div> |
|
<script> |
|
require(["dijit/form/NumberTextBox", "dojo/dom", "dojo/on", "dojo/_base/lang"], function(NumberTextBox, dom, on, lang){ |
|
|
|
var fld = new NumberTextBox({ |
|
name: "ticket17923", |
|
constraints: {pattern: '#000.#', min: 12, max: 142 }, |
|
maxLength: 5 |
|
}, "ticket17923"); |
|
|
|
on(dom.byId("ticket17923-maxLength5"), 'click', function(){ |
|
fld.set('maxLength', 5); |
|
}); |
|
|
|
on(dom.byId("ticket17923-maxLength3"), 'click', function(){ |
|
fld.set('maxLength', 3); |
|
}); |
|
|
|
on(dom.byId("ticket17923-min1:max15"), 'click', function(){ |
|
fld.set('constraints', lang.mixin({}, fld.get('constraints'), {min: 12, max: 142})); |
|
}); |
|
|
|
on(dom.byId("ticket17923-min-15:max15"), 'click', function(){ |
|
fld.set('constraints', lang.mixin({}, fld.get('constraints'), {min: -15, max: -5})); |
|
}); |
|
|
|
fld.startup(); |
|
}); |
|
</script> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label id="l_ticket17955">Trac ticket 17955</label> |
|
<span class="noticeMessage">Ensure setting the formattedValue does not alter the entered value on blur</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="ticket17955" class="medium"/> |
|
</div> |
|
<script> |
|
require(["dijit/form/NumberTextBox"], function(NumberTextBox){ |
|
|
|
var fld = new NumberTextBox({ |
|
name: "ticket17955", |
|
constraints: {pattern: '000.#', min: 12, max: 142 }, |
|
placeHolder: "Number Pattern 000.#", |
|
maxLength: 5 |
|
}, "ticket17955"); |
|
fld.startup(); |
|
}); |
|
</script> |
|
<div class="dojoTitlePaneLabel"> |
|
<label id="l_ticket18260">Trac ticket 18260</label> |
|
<span class="noticeMessage">Make sure rounding works with different locale's</span> |
|
</div> |
|
|
|
<div class="testExample"> |
|
<input id="ticket18260" class="medium"/> |
|
</div> |
|
<script> |
|
require(["dijit/form/NumberTextBox"], function(NumberTextBox){ |
|
|
|
var fld = new NumberTextBox({ |
|
name: "ticket18260", |
|
lang: 'de-de', |
|
value: 12.4, |
|
constraints: {pattern: '000.#', min: 12, max: 142 }, |
|
maxLength: 5 |
|
}, "ticket18260"); |
|
fld.startup(); |
|
}); |
|
</script> |
|
|
|
<div class="dojoTitlePaneLabel"> |
|
<label id="l_ticket18367">Trac ticket 18367</label> |
|
<span class="noticeMessage">Make sure precision ranges work as expected</span> |
|
</div> |
|
<div class="testExample"> |
|
<input id="ticket18367" class="medium"/> |
|
</div> |
|
<script> |
|
require(["dijit/form/NumberTextBox"], function(NumberTextBox){ |
|
|
|
var fld = new NumberTextBox({ |
|
name: "ticket18367", |
|
value: 8.0153234, |
|
constraints: { min: 1, max: 10 , places: "0,5"}, |
|
maxLength: 5 |
|
}, "ticket18367"); |
|
fld.startup(); |
|
}); |
|
</script> |
|
|
|
</body> |
|
</html>
|
|
|