I know this is a bug / behavior in Internet Explorer, but I was hoping that a fix could be put into Prototype to make it work. I''ve tried doing it myself based on some code I found, but I''m having problems getting it working so I need some help. The problem is that Internet Explorer will call functions that are attached to the same element and event type in random order instead of the order in which they were added. For example, if I register the following functions: Event.observe(window, ''load'', blah1); Event.observe(window, ''load'', blah2); Event.observe(window, ''load'', blah3); the functions can be called in any order in IE. So, a likely solution would be to call one function that calls all the other functions in order. So here was the code I found that someone suggested (the changed parts are commented out): Object.extend(Event, { ... observers: false, _observeAndCache: function(element, name, observer, useCapture) { if (!this.observers) this.observers = []; if (element.addEventListener) { this.observers.push([element, name, observer, useCapture]); element.addEventListener(name, observer, useCapture); } else if (element.attachEvent) { this.observers.push([element, name, observer, useCapture]); //element.attachEvent(''on'' + name, observer); element.attachEvent(''on'' + name, this._observeIE); } }, //Added _observeIE: function(e) { Event.observers.each( function(observer) { if (e.srcElement =observer[0]) observer[2].call(this, e); }.bind(this) ); }, ... stopObserving: function(element, name, observer, useCapture) { element = $(element); useCapture = useCapture || false; if (name == ''keypress'' && (navigator.appVersion.match(/Konqueror|Safari|KHTML/) || element.detachEvent)) name = ''keydown''; if (element.removeEventListener) { element.removeEventListener(name, observer, useCapture); } else if (element.detachEvent) { try { //element.detachEvent(''on'' + name, observer); element.detachEvent(''on'' + name, this._observeIE); } catch (e) {} } } }); The problem with this is... it never calls any of my functions. So I took a look at e.srcElement inside _observeIE with an alert, and it''s saying that''s e.srcElement is null. I don''t know why. So I thought, maybe window events have a null for their source element, but that wasn''t the case; it''s null for every event on every element. So hopefully someone has some suggestions. Thanks, Matt --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 1, 10:48 am, "Matt" <citrusmo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I know this is a bug / behavior in Internet Explorer, but I was hoping > that a fix could be put into Prototype to make it work. I''ve tried > doing it myself based on some code I found, but I''m having problems > getting it working so I need some help. > > The problem is that Internet Explorer will call functions that are > attached to the same element and event type in random order instead of > the order in which they were added.If you want a general purpose function to ensure handlers are called in the order they are added, you may like to read the following: <URL: http://groups.google.com.au/group/comp.lang.javascript/ browse_frm/thread/fbf6b4f6c9dc1806/9c129ca565b8ca97?lnk=gst&q=michael +winter+event+order&rnum=10#9c129ca565b8ca97 > The amount of code may seem daunting at first (about 120 lines), but the last 30 lines or so are to ensure a function.call method is available (the author is very thorough) and it''s been wrapped for posting. There are a couple of corrections later in the thread. -- Rob --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
If window.onload is the only case in which order matters to you, I suggest you use a simpler solution as follows: function addLoadEvent(func) { var oldonload = window.onload; if(typeof window.onload != ''function''){ window.onload = func; }else{ window.onload = function(){ oldonload(); func(); } } } In all other cases I think it should be possible to write your code to not depend on order easily enough. To make Event.observe handle this problem adds too much complexity and simply isn''t worth the trouble. Cheers, Colin Matt wrote:> I know this is a bug / behavior in Internet Explorer, but I was hoping > that a fix could be put into Prototype to make it work. I''ve tried > doing it myself based on some code I found, but I''m having problems > getting it working so I need some help. > > The problem is that Internet Explorer will call functions that are > attached to the same element and event type in random order instead of > the order in which they were added. For example, if I register the > following functions: > > Event.observe(window, ''load'', blah1); > Event.observe(window, ''load'', blah2); > Event.observe(window, ''load'', blah3); > > the functions can be called in any order in IE. So, a likely solution > would be to call one function that calls all the other functions in > order. So here was the code I found that someone suggested (the > changed parts are commented out): > > Object.extend(Event, { > ... > > observers: false, > > _observeAndCache: function(element, name, observer, useCapture) { > if (!this.observers) this.observers = []; > if (element.addEventListener) { > this.observers.push([element, name, observer, useCapture]); > element.addEventListener(name, observer, useCapture); > } else if (element.attachEvent) { > this.observers.push([element, name, observer, useCapture]); > //element.attachEvent(''on'' + name, observer); > element.attachEvent(''on'' + name, this._observeIE); > } > }, > > //Added > _observeIE: function(e) { > Event.observers.each( function(observer) { > if (e.srcElement => observer[0]) > observer[2].call(this, e); > }.bind(this) ); > }, > > ... > > stopObserving: function(element, name, observer, useCapture) { > element = $(element); > useCapture = useCapture || false; > > if (name == ''keypress'' && > (navigator.appVersion.match(/Konqueror|Safari|KHTML/) > || element.detachEvent)) > name = ''keydown''; > > if (element.removeEventListener) { > element.removeEventListener(name, observer, useCapture); > } else if (element.detachEvent) { > try { > //element.detachEvent(''on'' + name, observer); > element.detachEvent(''on'' + name, this._observeIE); > } catch (e) {} > } > } > }); > > The problem with this is... it never calls any of my functions. So I > took a look at e.srcElement inside _observeIE with an alert, and it''s > saying that''s e.srcElement is null. I don''t know why. So I thought, > maybe window events have a null for their source element, but that > wasn''t the case; it''s null for every event on every element. > > So hopefully someone has some suggestions. > > Thanks, > Matt > > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Not to sound rude or anything, but I''d really like to alter Prototypes Event methods to fix the problem. I don''t want to have to make special cases for everything I do or create/include a bunch of different classes/objects to get things to work. And order is important in my case because I use PHP classes that output their own Event.observe registrations, and the registrations I make in the scripts using those PHP classes depend on objects created by the former registrations. That probably didn''t make sense, but, nonetheless, order is important. In any case, I thought the point of Prototype was to create a library of cross-browser compatible utilities, and technically Event.observe does not produce the same results across browsers. I''d to note that the code that I posted had many flaws which I attempted to fix (ie. calling observers every time elements matched and detaching the observeIE method on a stopObserving call), but it still was producing odd behavior. In any case, if anybody has any other suggestions as to how I can alter the Event methods to make IE call the observers in order, I''d greatly appreciate it. Thanks, Matt --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Matt, in any event based language/system... it is considered best practice that if any 2 event handlers rely on the order of their execution, then they should be combined into a single handler (or one method calls the other). This is not a bug in any browser''s implementation of the W3C specs (which do not state that event handlers must fire in the order they were attached, as well it shouldn''t), it is a fundamental flaw in your application design (not to sound rude). Construct your handlers in such a way that order is not important, or chain them. On 2/1/07, Matt <citrusmoose-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > Not to sound rude or anything, but I''d really like to alter Prototypes > Event methods to fix the problem. I don''t want to have to make > special cases for everything I do or create/include a bunch of > different classes/objects to get things to work. And order is > important in my case because I use PHP classes that output their own > Event.observe registrations, and the registrations I make in the > scripts using those PHP classes depend on objects created by the > former registrations. That probably didn''t make sense, but, > nonetheless, order is important. In any case, I thought the point of > Prototype was to create a library of cross-browser compatible > utilities, and technically Event.observe does not produce the same > results across browsers. > > I''d to note that the code that I posted had many flaws which I > attempted to fix (ie. calling observers every time elements matched > and detaching the observeIE method on a stopObserving call), but it > still was producing odd behavior. In any case, if anybody has any > other suggestions as to how I can alter the Event methods to make IE > call the observers in order, I''d greatly appreciate it. > > Thanks, > Matt > > > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-920-955-1457 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 1, 12:28 pm, "Ryan Gahl" <ryan.g...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Matt, in any event based language/system... it is considered best practice > that if any 2 event handlers rely on the order of their execution, then they > should be combined into a single handler (or one method calls the other). > ...I understand your point, and I appreciate the comments. I guess handlers don''t really have to execute in order, but I assumed it would make sense if they did (especially since that''s the way FF does it :D) Anyway, of course, in most cases, I could wrap my functions into one, but my problem is that I don''t have access to one of the Event.observer registrations since it''s been wrapped up in output produced by PHP. My functions are dependent on that handler to be called first. And I don''t want to change the PHP because the PHP classes are suppose to abstract the implementation of the tool, and having to register a function outside the PHP that was created inside the PHP breaks that abstraction. Right now, I''m just setting a timeout on a function (that calls my functions in order) if the element that I''m dependent on doesn''t exist yet. It will continue to set an additional timeout every time it sees the element doesn''t exist. It seems hackish though. But right now that''s the only way that seems feasible / makes me happy :P Works like a charm though, so maybe I''ll just stick with that. Again, if you have a suggestion, I''d appreciate it. Thanks, Matt --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
> Anyway, of course, in most cases, I could wrap my functions into one, > but my problem is that I don''t have access to one of the > Event.observer registrations since it''s been wrapped up in output > produced by PHP. My functions are dependent on that handler to be > called first. And I don''t want to change the PHP because the PHP > classes are suppose to abstract the implementation of the tool, and > having to register a function outside the PHP that was created inside > the PHP breaks that abstraction. >Man that sounds confusing... What events are you observing exactly? I''m sure there has got to be a better way of doing what you are doing. Try posting a step by step explanation or sample code of what you are trying to accomplish and maybe we can suggest a better way for you. It might mean major changes on your existing code, but I''ve found that keeping all JS in JS files and only using PHP to serve the initial page and handle requests by processing *only* data is the way to go. The limited scope of eval''ing code returned by the server is very prone to error and increasing complexity, not to mention you can take advantage of browsers caching your JS files. My rule of thumb: unless I need raw data that is exclusive to the server, don''t make an Ajax request. For example, an HTML form is something that can be generated client-side. If you want to auto-fill the form, generate it and fill it with data that is retrieved from the server, don''t generate the form server-side if it uses complicated listeners etc... JSON and Builder.node are your friends :) Trust me, I just rewrote some old code that fetched a complex form from the server which had event handlers for various things, and the rewritten code which generates the form using javascript is so much cleaner and easier to understand and easier to debug. Colin --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Ok, sounds like you''ve got a little js on-demand action going on. I use the model a ton in my widget framework. The first thing I think you need to take care of is implementing a custom event model on the client (not for just DOM events, but allowing your classes to fire and subscribe to custom events as needed). Check out my EventPublisher class, which is a very lightweight, easy to use tool for this. Link to code here from my original on this list a year ago: http://wrath.rubyonrails.org/pipermail/rails-spinoffs/2006-February/002875.htmland link to short usage explanation here: http://lists.rubyonrails.org/pipermail/rails-spinoffs/2006-March/002885.html Then, I''d suggest just creating a globally accessible instance of the above class to act as an event dispatcher... var globalEventDispatcher = new EventPublisher(); Then you can do something like this at the end of your PHP generated function... globalEventDispatcher.fireEvent( "phpGeneratedJSExecuted", {someProperty: "someValue"} ); Then, in order to make your other functions execute after that php generated one, attach them to the event dispatcher (using the same event name)... globalEventDispatcher.attachEventHandler( "phpGeneratedJSExecuted", yourHandler ); Where "yourHandler" is a reference to a function that looks something like this: function someFunction(args) { // make sure this is the correct event for this function if (args.someProperty == "someValue") doSomething(); } On 2/1/07, Matt <citrusmoose-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > On Feb 1, 12:28 pm, "Ryan Gahl" <ryan.g...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Matt, in any event based language/system... it is considered best > practice > > that if any 2 event handlers rely on the order of their execution, then > they > > should be combined into a single handler (or one method calls the > other). > > ... > > I understand your point, and I appreciate the comments. I guess > handlers don''t really have to execute in order, but I assumed it would > make sense if they did (especially since that''s the way FF does it :D) > > Anyway, of course, in most cases, I could wrap my functions into one, > but my problem is that I don''t have access to one of the > Event.observer registrations since it''s been wrapped up in output > produced by PHP. My functions are dependent on that handler to be > called first. And I don''t want to change the PHP because the PHP > classes are suppose to abstract the implementation of the tool, and > having to register a function outside the PHP that was created inside > the PHP breaks that abstraction. > > Right now, I''m just setting a timeout on a function (that calls my > functions in order) if the element that I''m dependent on doesn''t exist > yet. It will continue to set an additional timeout every time it sees > the element doesn''t exist. It seems hackish though. But right now > that''s the only way that seems feasible / makes me happy :P Works > like a charm though, so maybe I''ll just stick with that. > > Again, if you have a suggestion, I''d appreciate it. > > Thanks, > Matt > > > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-920-955-1457 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 1, 2:45 pm, Colin Mollenhour <eliteii...-NPSFNn/7+NYVo650/ln6uw@public.gmane.org> wrote:> Man that sounds confusing... What events are you observing exactly? > > I''m sure there has got to be a better way of doing what you are doing. > Try posting a step by step explanation or sample code of what you are > trying to accomplish and maybe we can suggest a better way for you. > ...Yeah, I thought it might. I''ll try and explain it better. Basically, I''ve wrapped up LiveGrid Plus (Matt Brown''s enhancement of the Rico LiveGrid JS utility http://dowdybrown.com/dbprod/) into an abstract PHP class (PajaxTable). Any time the LiveGrid table is needed, all one needs to do is extend the PajaxTable and define a method in that extended class that will be used to fetch the data. For example, say I''ve created a class TestTable that extends PajaxTable: $table = new TestTable(''testGrid'', ''includes/PajaxFiller.php'', 15, 100); // Initialize table $table->setColors(''red'', ''white'', ''blue''); // Set odd, even, header, etc colors $table->addColumn(''Blah 1'', 200, true); // Add column to table (header, width, sortable) $table->addColumn(''Blah 2'', 100, true); $table->addColumn(''Blah 3'', 150, false); Then, after I''ve done that, I can simply call $table->printTable() in my HTML body and the JavaScript / HTML for the initial LiveGrid code will be printed out with the specified attributes that I set above. The JS that it prints out includes an Event.observe(window, ''load'', testGridOnLoad) and, of course, the testGridOnLoad function. Then, once the page loads, testGridOnLoad is called which creates the LiveGrid with JavaScript. Finally, LiveGrid code is used to fetch the data, but that''s got nothing to do with this. The problem is that my functions require that the LiveGrid already be created so that I can properly set widths and things based on the LiveGrid. This works fine in FF, but in IE, my other functions are getting called before testGridOnLoad. So my temp solution, like I said in my previous post, is setting a timeout function that goes to see if LiveGrid is created yet. Still confused? --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Yep, based on that, I''d say EventPublisher is perfect for you. Let me know if you have questions on how to implement it (if you decide it will work for your problem). On 2/1/07, Matt <citrusmoose-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > > On Feb 1, 2:45 pm, Colin Mollenhour <eliteii...-NPSFNn/7+NYVo650/ln6uw@public.gmane.org> wrote: > > Man that sounds confusing... What events are you observing exactly? > > > > I''m sure there has got to be a better way of doing what you are doing. > > Try posting a step by step explanation or sample code of what you are > > trying to accomplish and maybe we can suggest a better way for you. > > ... > > Yeah, I thought it might. I''ll try and explain it better. > > Basically, I''ve wrapped up LiveGrid Plus (Matt Brown''s enhancement of > the Rico LiveGrid JS utility http://dowdybrown.com/dbprod/) into an > abstract PHP class (PajaxTable). Any time the LiveGrid table is > needed, all one needs to do is extend the PajaxTable and define a > method in that extended class that will be used to fetch the data. For > example, say I''ve created a class TestTable that extends PajaxTable: > > $table = new TestTable(''testGrid'', ''includes/PajaxFiller.php'', 15, > 100); // Initialize table > $table->setColors(''red'', ''white'', ''blue''); // Set odd, even, header, > etc colors > $table->addColumn(''Blah 1'', 200, true); // Add column to table > (header, width, sortable) > $table->addColumn(''Blah 2'', 100, true); > $table->addColumn(''Blah 3'', 150, false); > > Then, after I''ve done that, I can simply call $table->printTable() in > my HTML body and the JavaScript / HTML for the initial LiveGrid code > will be printed out with the specified attributes that I set above. > The JS that it prints out includes an Event.observe(window, ''load'', > testGridOnLoad) and, of course, the testGridOnLoad function. Then, > once the page loads, testGridOnLoad is called which creates the > LiveGrid with JavaScript. Finally, LiveGrid code is used to fetch the > data, but that''s got nothing to do with this. > > The problem is that my functions require that the LiveGrid already be > created so that I can properly set widths and things based on the > LiveGrid. This works fine in FF, but in IE, my other functions are > getting called before testGridOnLoad. So my temp solution, like I > said in my previous post, is setting a timeout function that goes to > see if LiveGrid is created yet. > > Still confused? > > > > >-- Ryan Gahl Application Development Consultant Athena Group, Inc. Inquire: 1-920-955-1457 Blog: http://www.someElement.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 1, 4:14 pm, "Ryan Gahl" <ryan.g...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Yep, based on that, I''d say EventPublisher is perfect for you. Let me know > if you have questions on how to implement it (if you decide it will work for > your problem).Thanks, I''ll give it a whirl and let you know. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---