www.webdeveloper.com
Results 1 to 7 of 7

Thread: 'this' is invalid in event handler

  1. #1
    Join Date
    Jun 2007
    Posts
    4

    'this' is invalid in event handler

    Hi all,

    Very new to web development so I apologize for bad terminology or dumb mistakes. BTW I'm using the Microsoft AJAX extensions.

    I've create a "class" in javascript using the prototype style. I've attached it to a div that has an image in it using the $create macro. I instantiate multiple instances (2, so far) of this control and everything seems to be working fine. Then, I created a very simple custom event using the EventHandlerList per some samples that I've seen. In this same class I've implemented a handler for this event down in the prototype section of the class definition. I have multiple instances of this class and I need one class to "notify" the other instances about this event. If I step through the code the event is raised and the handler code is initiated as expected. The problem is that references to "this" in the event handler function are basically empty. None of the properties for that class are available. I'm doing plenty of other things with instances of this class and all of the data is there. Any ideas? I've also tried using the "propertyChanged" event and I get exactly the same results. Be glad to share more details if it would help.

    Thanks,
    Dave

  2. #2
    Join Date
    Mar 2007
    Location
    localhost
    Posts
    2,344
    Post the code you have...
    Yes, I know I'm about as subtle as being hit by a bus..(\\.\ Aug08)
    Yep... I say it like I see it, even if it is like a baseball bat in the nutz... (\\.\ Aug08)
    I want to leave this world the same way I came into it, Screaming, Incontinent & No memory!
    I laughed that hard I burst my colostomy bag... (\\.\ May03)
    Life for some is like a car accident... Mine is like a motorway pile up...

    Problems with Vista? :: Getting Cryptic wid it. :: The 'C' word! :: Whois?

  3. #3
    Join Date
    Jun 2007
    Posts
    4

    Reply: Some code for this issue

    Here's some of the code I'm having trouble with. Sorry about the long post but I'm not sure how much of the code might be relevant:

    Notes:

    At this point this app lets the user drag and drop rectangular "devices" on sections that are configured sort of like a rack mount system.

    The event in question is fired in the drop method in the section.js.
    The event is received by the onDevDroppedSomewhere handler. The event data seems to be OK but any references to "this" in the handler seem to be invalid or empty.

    I'm new at this but I'm expecting that this handler is in an instance (1 of 2) of a section class and that I should be able to reference and update properties of this instance of the class.

    I really appreciate any advice on this.
    Thanks,
    Dave

    default.aspx:

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">

    <head runat="server">
    <title>DpWeb2</title>
    </head>

    <body>
    <form id="form1" runat="server">

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    <Scripts>
    <asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewScript.js"/>
    <asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewDragDrop.js"/>
    </Scripts>
    </asp:ScriptManager>

    <script language="javascript" type="text/javascript" src="ScriptLibrary\section.js"></script>
    <script language="javascript" type="text/javascript" src="ScriptLibrary\device.js"></script>

    <img id="imgFeeder" src="Images/feeder.jpg" alt="" />
    <img id="imgStarter" src="Images/starter.jpg" alt="" />

    <div id="sectionZone1" class="dropzone">
    <img src="Images/section.jpg" alt="" />
    </div>

    <div id="sectionZone2" class="dropzone">
    <img src="Images/section.jpg" alt="" />
    </div>

    <script type="text/javascript">
    <!--
    Sys.Application.add_init(pageInit);
    function pageInit(sender, e)
    {
    // create a section and a couple of devices
    $create(DPUIWeb.Section,{}, {}, {}, $get('sectionZone1'));
    $create(DPUIWeb.Section,{}, {}, {}, $get('sectionZone2'));

    $create(DPUIWeb.Device, {}, {}, {}, $get('imgFeeder'));
    Sys.UI.DomElement.setLocation($get('imgFeeder'), 50,50);

    $create(DPUIWeb.Device, {}, {}, {}, $get('imgStarter'));
    Sys.UI.DomElement.setLocation($get('imgStarter'), 50,200);
    }

    Sys.Application.add_load(myPageLoad);
    function myPageLoad()
    {
    var section1 = sectionZone1.control;
    section1.set_sid('0001');
    section1.set_width(20);
    section1.set_baseXOffset(400);
    section1.set_baseYOffset(50);
    section1.add_devDroppedSomewhere(section1.onDevDroppedSomewhere);

    var section2 = sectionZone2.control;
    section2.set_sid('0002');
    section2.set_width(20);
    section2.set_baseXOffset(600);
    section2.set_baseYOffset(50);
    section2.add_devDroppedSomewhere(section2.onDevDroppedSomewhere);

    $get('imgFeeder').control.set_sid('0010');
    $get('imgFeeder').control.set_height(12);
    $get('imgFeeder').control.set_sectionSid('0000');

    $get('imgStarter').control.set_sid('0011');
    $get('imgStarter').control.set_height(18);
    $get('imgStarter').control.set_sectionSid('0000');
    }

    /-->
    </script>
    </form>
    </body>
    </html>


    section.js:
    // JScript File
    Type.registerNamespace('DPUIWeb');

    // prototype: constructor
    DPUIWeb.Section = function(element)
    {
    DPUIWeb.Section.initializeBase(this, [element]);
    this._sid = '0000';
    this._height = 0;
    this._width = 0;
    this._devices;
    this._baseYOffset = 0;
    this._baseXOffset = 0;
    this._dropLocation = 0;
    this._events = new Sys.EventHandlerList();
    }

    // prototype: members
    DPUIWeb.Section.prototype =
    {
    initialize : function()
    {
    DPUIWeb.Section.callBaseMethod(this, 'initialize');
    Sys.Preview.UI.DragDropManager.registerDropTarget(this);

    // create an array to hold the sid of the device in each cell
    this._devices = new Array();
    for (var ndx=1; ndx<=24; ndx++)
    {
    Array.insert(this._devices, ndx, '0000');
    }

    this._baseXOffset = Sys.UI.DomElement.getLocation(this.get_element()).x;
    },

    dispose : function()
    {
    Sys.Preview.UI.DragDropManager.unregisterDropTarget(this);
    DPUIWeb.Section.callBaseMethod(this, 'dispose');
    },

    // methods to support the EventHandlerList
    get_events : function()
    {
    return this._events;
    },

    add_devDroppedSomewhere : function(handler)
    {
    this.get_events().addHandler('devDroppedSomewhere', handler);
    },

    remove_devDroppedSomewhere : function(handler)
    {
    this.get_events().removehandler('devDroppedSomewhere', handler);
    },

    _raiseEvent : function(eventName, eventArgs)
    {
    var handler = this.get_events().getHandler(eventName);
    if (handler)
    {
    if (!eventArgs)
    {
    eventArgs = Sys.EventArgs.Empty;
    }
    handler(this, eventArgs);
    }
    },

    onDevDroppedSomewhere : function(sender, e)
    {
    Sys.Debug.trace(e + ' dropped something on section ' + this._get_sid());
    // while(Array.remove(this._devices, sender.get_devJustDropped()))
    // {
    // }
    },

    // methods required by IDropTarget interface
    get_dropTargetElement : function()
    {
    return this.get_element();
    },

    canDrop : function(dragMode, dataType, dragData)
    {
    // make sure it's a device
    if (dataType != '__device')
    return false;

    // get the current y offset
    this._dropLocation = Sys.UI.DomElement.getLocation(dragData.control._dragVisual);
    return this._isCellEmpty(this._dropLocation.y, dragData.control.get_height(), dragData.control.get_sid());
    },

    drop : function(dragMode, dataType, dragData)
    {
    // notify other sections that the device was just dropped on this section
    // in case they need to remove it from their section.
    this._raiseEvent('devDroppedSomewhere', dragData.control.get_sid());
    // update the devices list for this section
    var firstCellNo = this._getCellNo(this._dropLocation.y);
    var devHeight = dragData.control.get_height()/3;
    var lastCellNo = firstCellNo + devHeight - 1;

    for (ndx = firstCellNo; ndx <=lastCellNo; ndx++)
    {
    Array.insert(this._devices, ndx, dragData.control.get_sid());
    }

    // update the poistion and sectionSid for the dropped device
    Sys.UI.DomElement.setLocation(dragData, this._baseXOffset, 50 + 30 * (firstCellNo - 1));
    dragData.control.set_sectionSid(this._sid);
    },

    onDragEnterTarget : function(dragMode, dataType, dragData)
    {
    },

    onDragInTarget : function(dragMode, dataType, dragData)
    {
    },

    onDragLeaveTarget : function(dragMode, dataType, dragData)
    {
    },

    _isCellEmpty : function(yOffset, devHeight, devSid)
    {
    var cellNo = this._getCellNo(yOffset);

    // first make sure the base cell is empty
    if (this._devices[cellNo] != '0000' && this._devices[cellNo] != devSid)
    return false;

    // see if there are enough empty cells
    var devHeightInCells = devHeight / 3;
    for (ndx = cellNo; ndx < cellNo + devHeightInCells; ndx++)
    {
    if (this._devices[ndx] != '0000' && this._devices[cellNo] != devSid)
    return false;
    }


    return true;
    },

    _getCellNo : function(yOffset)
    {
    if (yOffset < this._baseYOffset)
    return 0;
    return (Math.floor((yOffset - this._baseYOffset) / 30)) + 1;
    },

    // properties:
    get_sid : function()
    {
    return this._sid;
    },

    . . . other get/sets omitted for brevity ..

    }


    DPUIWeb.Section.registerClass('DPUIWeb.Section', Sys.UI.Control, Sys.Preview.UI.IDropTarget);

    // Notify ScriptManager that this is the end of the script.
    if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

  4. #4
    Join Date
    Mar 2007
    Location
    localhost
    Posts
    2,344
    If its too long then put the file in a post as an attachment OR post the URL to the example as it helps to see the fully rendered pages as well as helps with troubleshooting.

    The prototype your using, is it a library you have written or is it one that you have found on the net?
    Yes, I know I'm about as subtle as being hit by a bus..(\\.\ Aug08)
    Yep... I say it like I see it, even if it is like a baseball bat in the nutz... (\\.\ Aug08)
    I want to leave this world the same way I came into it, Screaming, Incontinent & No memory!
    I laughed that hard I burst my colostomy bag... (\\.\ May03)
    Life for some is like a car accident... Mine is like a motorway pile up...

    Problems with Vista? :: Getting Cryptic wid it. :: The 'C' word! :: Whois?

  5. #5
    Join Date
    Jun 2007
    Posts
    4

    full code for this issue

    Really appreciate you taking time to look at this.

    I've attached a file called DPWeb2.zip. I'm using Vista ultimate, Visual Studio 2005 Team Suite, ASP.NET AJAX extensions 1.0 and the ASP.NET AJAX May CTP. The javascript is not from a library but some is loosely based on some sample code in a new book called ASP.NET AJAX in Action by Manning.

    When you drag and drop a "device" on a "section" it fires an event that is to notify other sections that a device has been dropped on this section and to remove it from your section if that's where it came from. As I said the section event handler seems to get the event but then all references to 'this' in the event handler do not know anything about the section member variables defined in the constructor.

    Thanks for any help
    Attached Files Attached Files

  6. #6
    Join Date
    Mar 2007
    Location
    localhost
    Posts
    2,344
    this is a funny beast.

    this refers to the thing its attached to and not "this" in general eg an external variable.

    Code:
    a = {
      id:[],
      f:function(){
        this.push(f);
      }
    }
    this refers to "a" it is saying a.id.push(f);

    when you get to handlers, eg,
    Code:
    ajax.onreadystatechange = readystatehandler;
    and then in the readystatehandler function you refer to "this", this as a property doesnt exist because ajax.onreadystatechange isnt a variable but a method.
    so you may want to pass the value of the object your working with to the event handler to attach the correct event trigger to the desired object.
    Code:
    ajax.onreadystatechange = readystatehandler(ajax);
    in this case passes the ajaz object to the function so that in the function you make for easier access to that objects methods and properties.

    I had a similar experience trying to find the name of an anonymous function, seems that "this" has some latent limitations.

    This is the possible reason for the problem, I cant see anything that wrong with the .js but IM only skimming it because theirs allot of code but so far it looks ok.
    Yes, I know I'm about as subtle as being hit by a bus..(\\.\ Aug08)
    Yep... I say it like I see it, even if it is like a baseball bat in the nutz... (\\.\ Aug08)
    I want to leave this world the same way I came into it, Screaming, Incontinent & No memory!
    I laughed that hard I burst my colostomy bag... (\\.\ May03)
    Life for some is like a car accident... Mine is like a motorway pile up...

    Problems with Vista? :: Getting Cryptic wid it. :: The 'C' word! :: Whois?

  7. #7
    Join Date
    Mar 2007
    Location
    localhost
    Posts
    2,344
    Typo:
    Code:
    a = {
      id:[],
      f:function(d){
        this.id.push(d);
      }
    }
    Yes, I know I'm about as subtle as being hit by a bus..(\\.\ Aug08)
    Yep... I say it like I see it, even if it is like a baseball bat in the nutz... (\\.\ Aug08)
    I want to leave this world the same way I came into it, Screaming, Incontinent & No memory!
    I laughed that hard I burst my colostomy bag... (\\.\ May03)
    Life for some is like a car accident... Mine is like a motorway pile up...

    Problems with Vista? :: Getting Cryptic wid it. :: The 'C' word! :: Whois?

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

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



Recent Articles