Event Reference Problem

M

MC

This is a simple date picker. On changing the month or year, it should focus
on the next element. It does not do that because I am not referencing the
element correctly. See the line: this.dtDay.focus(); -->Problem this.dtDay
equals undefined

Resolution?
Thanks,
MC
PS, full text is included in case anyone wants to use it, or abuse it.

com.my.js.Month =
['January','February','March','April','May','June','July','August','September','October','November','December'];
com.my.js.DatePicker = function(startYr, endYr) {
this.dt = document.createElement("div");
this.dtMonth = document.createElement("select");
for (var i=0; i<com.aisus.js.Month.length; i++)
this.dtMonth.options = new Option(com.aisus.js.Month,i);
this.dtDay = document.createElement("select");
for (var i=0; i<32; i++)
this.dtDay.options = new Option(''+(i+1),(i+1));
this.dtYear = document.createElement("select");
this.dtYear.options[0] = new Option('',0);
for (var i=0; (startYr+i)<=(endYr); i++)
this.dtYear.options[i+1] = new Option(''+(endYr-i),(endYr-i));

this.dt.appendChild(this.dtMonth);
this.dt.appendChild(this.dtDay);
this.dt.appendChild(this.dtYear);

this.dtMonth.onchange = function(){
this.dtDay.focus(); -->Problem this.dtDay equals undefined
}
this.dtDay.onchange = function(){
this.dtYear.focus(); -->Problem this.dtYear equals undefined
}
};
com.my.js.DatePicker.prototype = {
getDiv: function() {return this.dt;},
getMonth: function() {return this.dtMonth.value;},
getDay: function() {return this.dtDay.value;},
getYear: function() {return this.dtYear.value;},
getMMDDYYYY: function() {
var s = '';
if (this.getMonth() < 9) s += '0';
s += ''+(parseInt(this.getMonth(), 10) + 1);
if (this.getDay() < 10) s += '0';
s += this.getDay();
s += this.getYear();
return s;
}
};

//Sample Usage
//var e = document.getElementById('someHtmlElementId');
//var datePicker = new com.aisus.js.DatePicker(1900,2011);
//e.appendChild(datePicker.getDiv());
 
J

Jukka K. Korpela

this.dtMonth.onchange = function(){
this.dtDay.focus(); -->Problem this.dtDay equals undefined

The problem appears to be that "this" is context-dependent, local to
function where it appears. To refer to the "this" of the outer function,
define a local variable there:

var that = this;

and use that.dtDay.
 
T

Thomas 'PointedEars' Lahn

Jukka said:
The problem appears to be that "this" is context-dependent,

Yes, undoubtedly.
local to function where it appears.

No. We have been over this[tm].
To refer to the "this" of the outer function, define a local variable
there:

var that = this;

and use that.dtDay.

Other ways to resolve this[tm], including

this.dtMonth.onchange = (function(that) {
return function() {
that.dtDay.focus();
};
}(this));

and a/the Function.prototype.bind() method (standard built-in since
ECMAScript Ed. 5 ca. 1.5 years ago¹) have been suggested here ad nauseam².

It is of course a Very Bad Idea[tm], and can easily fail as browser vendors
have acknowledged the accessibility problem, to try moving the input focus
in an event listener.

For example, if I had selected the day and tried to select another control,
if these countermeasures were not in place, another control than the one I
wanted to focus would be focused by the script. This would disregard WCAG
2.0, Guideline "3.2 Predictable: Make Web pages appear and operate in
predictable ways.", in particular "3.2.2 On Input: Changing the setting of
any user interface component does not automatically cause a change of
context unless the user has been advised of the behavior before using the
component. (Level A)"³.


PointedEars
___________
¹ <http://www.ecma-international.org/publications/standards/Ecma-262.htm>,
links to <http://www.ecma-international.org/publications/files/ECMA-
ST/ECMA-262.pdf> (2.4 MiB PDF document)
² Admittedly, they are not easy to find in archives as `this' is a rather
common word in English. However, the problem comes up so often here that
one can easily know about it (and its solutions) when reading the
newsgroup for a while before posting (as recommended by the FAQâ´ and
various Usenet tutorials).
³ <http://www.w3.org/TR/WCAG20/#consistent-behavior>
â´ <http://www.jibbering.com/faq/#posting>
 
M

MC

this.dtMonth.onchange = (function(that) {
return function() {
that.dtDay.focus();
};
}(this));

This, (no pun intented) worked like a charm. I'm curious as to how the bind
would look? For my user base, they will all be Chrome 11+ users so cross
browser is not an issue.

Thank you,
MC
 
L

Lasse Reichstein Nielsen

(Please retain attributions on your quotes)
This, (no pun intented) worked like a charm. I'm curious as to how the bind
would look? For my user base, they will all be Chrome 11+ users so cross
browser is not an issue.

this.dtMonth.onchange = function() { this.dtDay.focus(); }.bind(this);

The bind function isn't any better than the above code (it's just a more
complex way of doing the same thing, because bind also does other things
than binding the this-value), so I wouldn't necessarily prefer it.

You can also omit the binding completely, because the dtDay control
is in the same form as the dtMonth control, so you can access dtDay
through that.
I would use addEventListener instead off setting the onchange property,
though.

this.elements['dtMonth'].addEventListener("change", function(evt) {
this.form.elements['dtDay'].focus();
}, false);

Best of luck.
/L
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
, Thu, 16 Jun 2011 14:30:40, MC <mica@[removethis].invalid> posted:
This is a simple date picker.
for (var i=0; i<32; i++)
this.dtDay.options = new Option(''+(i+1),(i+1));

this.dt.appendChild(this.dtMonth);
this.dt.appendChild(this.dtDay);
this.dt.appendChild(this.dtYear);

That enables selection of an invalid date in Feb Apr Jun Sep Nov. So
you probably need a date validator. Most of those used on the web are
bloated and inefficient; most of the rest are one of those.

It would be nicer to present the right number of days for the selected
year and month. Since fields are most naturally used left-to-right,
that means using ISO 8601 dates.

Test how long it takes to use a date picker in comparison with the tome
taken to type in a numeric date.
 
M

MC

We currently use an input text field for date. We are switching because our
users, some of whom can barely turn on a computer, find select fields easier
to use. Using selects cuts some of the validations out and makes it a little
easier for us as well. We are entirely based in the USA so we are mmddyyyy
based, but this could easily satisfy the yyyymmdd of the ISO 8601 and it
would make for a more logical validation. I did add an isValid() function
btw :)

The goal behind this is to create some simple non-humongus library widgets
that are reliable and reusable.

Appreciate the input!
MC
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,701
Latest member
XavierQ83

Latest Threads

Top