Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    Jun 2003
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts

    An object's properties are not accessible by its methods

    I've got a bit of weirdness about an object's properties not being visible to any of its methods. The intention is to override IE's handling of keystrokes for <select> dropdowns so that it behaves more like Mozilla (so the code that follows is IE-specific); FYI, IE's behaviour is to take you to the first element in the selection whose first character matches the key you just hit, while Mozilla retains a memory of the last few keys you hit (so that you can type more than just one character of the selection). In the sample list below, hitting "JS" would in IE find you selecting "superguy", while in Mozilla you'd select "jsmith".

    You'll note that the entire object has four (user-defined) properties and a method. The method itself is the actual event handler, while the properties supply the object with the "more than one thing at a time" memory that it needs to perform.

    I have non-OO code that does work - it uses global variables instead of properties, the search function has to have the <select> object passed to it as a parameter, and the handler is specified in an "onkeyup" attribute, but it's otherwise the same code. I can fall back on that in a pinch, but I want to be using this behaviour multiple times on multiple pages, and encapsulating seems desirable.

    Code:
    <script type="text/javascript" language="javascript">
    
    function TypistDropdown(select, usevalue)
    {	this.select = select; // The <select> element this binds to.
    	this.usevalue = usevalue || false; // Search value or text?
    	this.elapsed = (new Date()).valueOf(); // # of milliseconds since last keystroke
    	this.buffer = ''; // The most recent keystrokes in this dropdown
    };
    
    TypistDropdown.prototype.search = function()
    {	var key = String.fromCharCode(event.keyCode);
    	if(key<'A' || key>'Z') return false; // Nothing to do with us (XXX other character ranges?)
    	var right_now = (new Date()).valueOf();
    	if(right_now-this.elapsed > 500) // milliseconds (XXX configurable?)
    		this.buffer = ''; // Been so long - flush the buffer
    	this.buffer += key; // Add this keystroke to the buffer
    	this.elapsed = right_now; // Reset the timer
    	var buffer_length = this.buffer.length;
    	var select_length = this.select.options.length;
    	var option;
    	for(var i=0; i<select_length; i++)
    	{	option = this.select.options[j];
    		option = this.usevalue ? option.value : option.text;
    		option = option.substr(0,buffer_length).toUpperCase();
    		if(option==this.buffer) // We have a match
    		{	this.select.selectedIndex = j;
    			break;
    		}
    	}
    document.getElementById('mybuffer').innerHTML = this.buffer;
    	return true;
    };
    
    </script>
    .......
    <SELECT name='username' id="username" size="4">
        <OPTION value="alienface">alienface</option>
        <OPTION value="barry">barry</option>
        <OPTION value="fredh">fredh</option>
        <OPTION value="fredt">fredt</option>
        <OPTION value="jblair">jblair</option>
        <OPTION value="jsmith">jsmith</option>
        <OPTION value="ppolly">ppolly</option>
        <OPTION value="superguy">superguy</option>
        <OPTION value="ttt">ttt</option>
    </select>
    <script type="text/javascript" language="javascript">
    var username_handler = new TypistDropdown(document.getElementById('username'));
    document.getElementById('username').onkeyup = username_handler.search;
    </script><span id='mybuffer'></span>
    To make things clear right now, the event handling itself appears to work - that is to say, key gets the value it should, and so forth. Problems begin the moment I start using the object's properties (select, usevalue and the rest). They are all (according to judicious alert()s dotted about) undefined. I've tried various alternate idioms ("this.buffer=''; this.search = function(){...}", etc.) but all fail in the same way: "right_now-this.elapsed" is meaningless because "this.elapsed" is undefined (and before you ask, yes I did check to see what this.buffer and other properties contained, including a few ("this.foo") created for the purpose; they were all undefined in the scope of the search method).

    Judging from other Javascript code I've read all about the place, I really can't see what's so different about my code that makes it not work. STFW, RTFM, UTSL - I can't see the difference. If I've missed a thread in my searching that does deal with this, I'd appreciate it being pointed out. Ditto if I'm missing some much more elegant solution.

    Oh yeah, mybuffer is a debugging instrument - its function should be obvious (don't see why having it would make a difference: and, surprisingly, taking it out doesn't magically make things work). (Anyone suspect I'm getting just a little peeved?)
    Last edited by Floyd; 06-13-2003 at 07:01 AM.

  • #2
    Regular Coder
    Join Date
    Jun 2002
    Location
    Atlanta, GA.
    Posts
    313
    Thanks
    0
    Thanked 0 Times in 0 Posts
    document.getElementById('username').onkeyup = username_handler.search

    When the onkeyup event handler is fired the "this" object is the select object not your object.

    You may be able to do this
    Code:
    function TypistDropdown(select, usevalue)
    {
    	select.selObj = this;
    
    	this.select = select; // The <select> element this binds to.
    	this.usevalue = usevalue || false; // Search value or text?
    	this.elapsed = (new Date()).valueOf(); // # of milliseconds since last keystroke
    	this.buffer = ''; // The most recent keystrokes in this dropdown
    };
    and then reference YOUR object by
    Code:
    TypistDropdown.prototype.search = function()
    {	var key = String.fromCharCode(event.keyCode);
    ...
    ...
    var selObj = this.selObj;
    alert(selObj.buffer);
    alert(selObj.useval);

  • #3
    Senior Coder
    Join Date
    Aug 2002
    Posts
    3,467
    Thanks
    0
    Thanked 0 Times in 0 Posts
    If you really want to encapsulate this for IE-only, why not make a DHTML behavior for it instead?

    http://msdn.microsoft.com/workshop/a...s/overview.asp

    I can show you how to make one if you need help.
    My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
    “Minds are like parachutes. They don't work unless they are open”
    “Maturity is simply knowing when to not be immature”

  • #4
    Regular Coder
    Join Date
    Apr 2003
    Location
    Atlanta, GA
    Posts
    487
    Thanks
    0
    Thanked 0 Times in 0 Posts
    don't forget about Opera - does it natively support type-ahead combos? what with IE's lack of update for the past two years, and none ever again available without a new OS or a subscription to MSN, in addition to its lack of good CSS, DOM, mime-type, etc., support, I get the feeling it'll kind of fall by the wayside amongst any in the know who still explore new browsers.

  • #5
    New to the CF scene
    Join Date
    Jun 2003
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    RoyW: thanks for that - didn't quite realise that "this" in an event handler refers to the object firing the event even if the handler is a method of another object (is there no better way to access the object's own properties?). It didn't work for a couple of minutes - but if you look at the code you'll see why .

    beetle: I will have a look at using DHTML behaviours when I review this. Thanks for the suggestion - I didn't know about the things (coming from an open standards environment). It will be a bonus if it simplifies the task of avoiding everything except IE whining about Javascript errors (if I don't check, Mozilla spits the dummy about "event" not being defined).

    Choopernickel: To be honest I have no idea what the default behaviour for Opera is - dunno if the behaviour is even OS-sensitive or not in Moz and IE. In the present environment the number of browsers reporting themselves to be Opera however is currently running at 0% and looks unlikely to change.

    To be blunt, the Powers That Be specify I have to write this for Internet Explorer, and they're the ones signing my paychecks. I still use Mozilla as a test platform though, because it has much better debugging facilities and I want to at least make a token effort at standards compliance - this just happened to be a situation where that approadch didn't work. At least I got to say "But Mozilla already does this..." again

  • #6
    Senior Coder
    Join Date
    Aug 2002
    Posts
    3,467
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Originally posted by Floyd
    It will be a bonus if it simplifies the task of avoiding everything except IE whining about Javascript errors
    Boy does it ever! And it's seamless to apply - perhaps the best part.

    Code:
    <style tyle="text/css">
    select {
        behavior: url(js/type_ahead.htc);
    }
    </style>
    Then type_ahead.htc
    Code:
    <public:component>
    // HTC code here
    </public:component>
    That's it. No initialization scripting - just attach the behavior to the element via CSS (the crux of the whole thing). And since behaviors introduce their own scope, you don't even need to use OO js, although there's nothing wrong with it.

    My Site | fValidate | My Brainbench | MSDN | Gecko | xBrowser DOM | PHP | Ars | PVP
    “Minds are like parachutes. They don't work unless they are open”
    “Maturity is simply knowing when to not be immature”


  •  

    LinkBacks (?)

    1. 05-22-2014, 04:44 PM

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •