I''m trying to prevent double ajax requests when I have nested onclick handlers. I have a table with clickable column headings (for sorting by that column). I have onclick handlers on both the <th> and the <a> link so that clicking anywhere on the table heading should work. <th onclick="window.location.href=''http://foo?sort=foo'';"> <a href="http://foo?sort=foo"> sort by foo </a> </th> I use the following to prevent a click on the <a> to bubble to the <th>. This seems to work, at least in firefox. var myrules = { // Disable bubble up to the <tr> that might have an onclick event ''#matrix a'' : function(e){ e.onclick = function(e){ if (!e) var e = window.event; e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); } } }; Behaviour.register(myrules); Now, I added Ajax.Updater like below, but now when I click on a link I get two ajax requests. <th onclick="new Ajax.Updater(''tableTable'', ''http://url?sort=foo'' ); return false;"> <a href="http://url?sort=foo" onclick="new Ajax.Updater(''tableTable'', ''http://url?sort=foo''} ); return false;"> sort by foo </a> </th> Any suggestions how to prevent the double-request? Thanks, -- Bill Moseley moseley-kv6DSSSScSo@public.gmane.org
Not sure if it''ll do what you want, but see my changes below:> var myrules = { > // Disable bubble up to the <tr> that might have an onclickevent> ''#matrix a'' : function(e){ > e.onclick = function(e){Event.stop(e); return false;> } > } > }; > > Behaviour.register(myrules); >...> > <th onclick="function(e) { new Ajax.Updater(''tableTable'',''http://url?sort=foo'' ); Event.stop(e);> return false; }"> > <a href="http://url?sort=foo" onclick="function(e) { newAjax.Updater(''tableTable'',> ''http://url?sort=foo''} ); Event.stop(e); return false; }"> > sort by foo > </a> > </th>Mostly, I just changed to Event.stop() from prototype which should kill propagation for you. And you have to return false for browsers like IE. But, since you need to take the event as an argument to pass it to Event.stop, I changed your onclick slightly. I didn''t test this at all, but I think it should do what you want. Greg
Just don''t put a click handler on the <a> -----Original Message----- From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Gregory Hill Sent: Monday, January 16, 2006 1:18 PM To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: RE: [Rails-spinoffs] Preventing bubble Not sure if it''ll do what you want, but see my changes below:> var myrules = { > // Disable bubble up to the <tr> that might have an onclickevent> ''#matrix a'' : function(e){ > e.onclick = function(e){Event.stop(e); return false;> } > } > }; > > Behaviour.register(myrules); >...> > <th onclick="function(e) { new Ajax.Updater(''tableTable'',''http://url?sort=foo'' ); Event.stop(e);> return false; }"> > <a href="http://url?sort=foo" onclick="function(e) { newAjax.Updater(''tableTable'',> ''http://url?sort=foo''} ); Event.stop(e); return false; }"> > sort by foo > </a> > </th>Mostly, I just changed to Event.stop() from prototype which should kill propagation for you. And you have to return false for browsers like IE. But, since you need to take the event as an argument to pass it to Event.stop, I changed your onclick slightly. I didn''t test this at all, but I think it should do what you want. Greg _______________________________________________ Rails-spinoffs mailing list Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs The information transmitted in this electronic mail is intended only for the person or entity to which it is addressed and may contain confidential, proprietary, and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from all computers.
What I mean is... don''t use an <a>, just put text in the <th> is that''s truely the element you want to handle clicks for. -----Original Message----- From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Ryan Gahl Sent: Monday, January 16, 2006 1:42 PM To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: RE: [Rails-spinoffs] Preventing bubble Just don''t put a click handler on the <a> -----Original Message----- From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Gregory Hill Sent: Monday, January 16, 2006 1:18 PM To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: RE: [Rails-spinoffs] Preventing bubble Not sure if it''ll do what you want, but see my changes below:> var myrules = { > // Disable bubble up to the <tr> that might have an onclickevent> ''#matrix a'' : function(e){ > e.onclick = function(e){Event.stop(e); return false;> } > } > }; > > Behaviour.register(myrules); >...> > <th onclick="function(e) { new Ajax.Updater(''tableTable'',''http://url?sort=foo'' ); Event.stop(e);> return false; }"> > <a href="http://url?sort=foo" onclick="function(e) { newAjax.Updater(''tableTable'',> ''http://url?sort=foo''} ); Event.stop(e); return false; }"> > sort by foo > </a> > </th>Mostly, I just changed to Event.stop() from prototype which should kill propagation for you. And you have to return false for browsers like IE. But, since you need to take the event as an argument to pass it to Event.stop, I changed your onclick slightly. I didn''t test this at all, but I think it should do what you want. Greg _______________________________________________ Rails-spinoffs mailing list Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs The information transmitted in this electronic mail is intended only for the person or entity to which it is addressed and may contain confidential, proprietary, and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from all computers. _______________________________________________ Rails-spinoffs mailing list Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
On Mon, Jan 16, 2006 at 12:18:14PM -0700, Gregory Hill wrote:> Not sure if it''ll do what you want, but see my changes below:I wasn''t sure with your line wrapping, but this is what I tried now, but it''s still doing double requests: Sorry for the long lines: <th onclick="new Ajax.Updater(''tableTable'', ''http://bumby:3000/admin/location?o=name'', { requestHeaders: [''X-Ajax-Updater'', ''ajax_table''] } ); Event.stop(e); return false;"> <a href="http://bumby:3000/admin/location?o=name" onclick="new Ajax.Updater(''tableTable'', ''http://bumby:3000/admin/location?o=name'', { requestHeaders: [''X-Ajax-Updater'', ''ajax_table''] } ); return false;"> Location </a> </th> And then also: var myrules = { // Disable bubble up to the <tr> that might have an onclick event ''#matrix a'' : function(e){ e.onclick = function(e){ Event.stop(e); return false; /* above replaces below */ if (!e) var e = window.event; e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); } } }; Behaviour.register(myrules); There''s other odd things happening. When I first load the page clicking on the <a> links nothing happens, and I have to first click either on the <th> area or on some link on the page ( like the ajax updater for "page next", for example). Another thing it''s been bugging me is I have a spinner "busy" icon that shows up during the ajax request. But it only shows up sometimes -- even on long requests. For some reason its display prop isn''t being enabled. No javascript errors according to Firefox, either. Thanks, -- Bill Moseley moseley-kv6DSSSScSo@public.gmane.org
On Mon, Jan 16, 2006 at 01:43:35PM -0600, Ryan Gahl wrote:> What I mean is... don''t use an <a>, just put text in the <th> is that''s > truely the element you want to handle clicks for.I want the fallback if there''s no javascript, though. -- Bill Moseley moseley-kv6DSSSScSo@public.gmane.org
Not to thread hijack, but wondering if anyone else noticed this w/ Behavior? If the page is still loading and you trigger an action, the Behavior may not trigger. Is this a problem shared by all Behavior users, or something I did wrong?
On Mon, Jan 16, 2006 at 11:50:26AM -0800, Bill Moseley wrote:> There''s other odd things happening. When I first load the page > clicking on the <a> links nothing happens, and I have to first click > either on the <th> area or on some link on the page ( like the ajax > updater for "page next", for example).Well duh!, as they say. I''ve got an inline onclick handler on the <a> tag and I also have Behaviour setup to add an onclick handler to those <a> tags -- which replaces the inline ones. I suppose I could (should) assign unique ids to every link where I need Ajax.Updater and use behaviour to do both the Event.stop and the Ajax.Updater for each id -- just to get the javascript out of the html. BTW, seems like doing: Ajax.Updater(); Event.stop(e); return false; actually somehow returns true because the browser is making both the ajax and non-ajax request. Where just: Ajax.Updater(); return false; works ok (and when I don''t have onclick on the <tr> ). Maybe I need to learn more about event order to understand why this isn''t working. -- Bill Moseley moseley-kv6DSSSScSo@public.gmane.org
It would be better if you''d use something like: <script type="text/javascript"> Event.observe(''element_id'', ''click'', function (e) { Ajax.Updater(); Event.stop(e); return false; }); </script> And drop your inline event handlers. It''s a pain dealing with stopping events on inline handlers. Anyway, in the code I sent, I put the ''function (e) { Ajax.Updater(); Event.stop(e); return false; }'' in the inline handler. I''m not sure if that actually works as I''ve always attached events separately if I needed any access to the event object itself, but I thought it was worth a try. When you sent the code back, you had not included the ''function (e)'' part, which may be why you are getting problems. The variable ''e'' would not be defined otherwise, or is defined in another scope and probably not referring to what you think it is. Greg> -----Original Message----- > From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org[mailto:rails-spinoffs-> bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Bill Moseley > Sent: Monday, January 16, 2006 9:16 PM > To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > Subject: Re: [Rails-spinoffs] Preventing bubble > > On Mon, Jan 16, 2006 at 11:50:26AM -0800, Bill Moseley wrote: > > There''s other odd things happening. When I first load the page > > clicking on the <a> links nothing happens, and I have to first click > > either on the <th> area or on some link on the page ( like the ajax > > updater for "page next", for example). > > Well duh!, as they say. > > I''ve got an inline onclick handler on the <a> tag and I also have > Behaviour setup to add an onclick handler to those <a> tags -- which > replaces the inline ones. > > I suppose I could (should) assign unique ids to every link where I > need Ajax.Updater and use behaviour to do both the Event.stop and the > Ajax.Updater for each id -- just to get the javascript out of the > html. > > BTW, seems like doing: > > Ajax.Updater(); Event.stop(e); return false; > > actually somehow returns true because the browser is making both theajax> and > non-ajax request. > > Where just: > > Ajax.Updater(); return false; > > works ok (and when I don''t have onclick on the <tr> ). > > Maybe I need to learn more about event order to understand why this > isn''t working. > > -- > Bill Moseley > moseley-kv6DSSSScSo@public.gmane.org > > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
On Tue, Jan 17, 2006 at 08:30:52AM -0700, Gregory Hill wrote:> <script type="text/javascript"> > Event.observe(''element_id'', ''click'', function (e) { Ajax.Updater(); > Event.stop(e); return false; }); > </script> >Geeze, I can''t even get something simple working. I can get the example for Event.observe to work without any problem, but I can''t see to assign by id. This example works: <script> Event.observe(window, ''load'', showMessage, false); function showMessage() { alert(''Page loaded.''); } </script> This generates "element has no properties" in prototype.js in line 1479 <script type="text/javascript"> function sayHello() { alert( ''Hello Message'' ); } Event.observe( ''updater1'', ''click'', sayHello, false); </script> And the element with that id is: <a href="http://localhost:3000/workshop/classes?o=name&p=7" id="updater1">Workshop</a> Here''s the try with Ajax.Updater: <script type="text/javascript"> Event.observe( ''updater6'', ''click'', function(e) { Ajax.Updater(''updater6'', ''http://localhost:3000/workshop/classes?o=class_time&p=7'', { method: ''get'', requestHeaders: [''X-Ajax-Updater'', ''ajax_table''] }); Event.stop(e); return false; }, false ); Event.observe( ''updater7'', ''click'', function(e) { Ajax.Updater(''updater7'', ''http://localhost:3000/workshop/classes?o=class_time&p=7'', { method: ''get'', requestHeaders: [''X-Ajax-Updater'', ''ajax_table''] }); Event.stop(e); return false; }, false ); </script> Then the links look like this: <th id="updater6"> <a href="http://localhost:3000/workshop/classes?o=class_time&p=4" id="updater7"> Date and Time </a> </th>> And drop your inline event handlers. It''s a pain dealing with stopping > events on inline handlers.The problem with prototype and all these nice javascript libraries is that it makes it easy for someone like me to use them. ;) I didn''t realize that the inline handlers were any different than what you have above. I thought they all assigned to the same event. -- Bill Moseley moseley-kv6DSSSScSo@public.gmane.org
> This generates "element has no properties" in prototype.js in > line 1479 > > <script type="text/javascript"> > > function sayHello() { > alert( ''Hello Message'' ); > } > > Event.observe( ''updater1'', ''click'', sayHello, false); > > </script> > > And the element with that id is: > > <a href="http://localhost:3000/workshop/classes?o=name&p=7" > id="updater1">Workshop</a>Is the element farther down the page than the javascript? HTML is rendered in the order it is output. If you try to get an element that has yet to be rendered, it does not exist.> The problem with prototype and all these nice javascript libraries is > that it makes it easy for someone like me to use them. ;)Not to knock you too hard, but yeah, it is. Then again, we all were newbies at some point, so if it came out 5 years earlier, I''d be the one asking the questions. I actually shyed away from javascript for a couple years until Prototype and Scriptaculous came out and made it fun again.> I didn''t realize that the inline handlers were any different than what > you have above. I thought they all assigned to the same event.Well, it''s in how browsers deal with them. Library functions like Event.stop() deal with the browser inconsistencies internally, so you don''t have to worry about them. Event handling has always been one of the major differences in browsers. Standards-based browsers pass the event object to the event handling function (hence the function (e) {...}, where e is the event object), IE stores the last-fired event in window.event. IE and Mozilla have different ways of attaching events in javascript, as well (IE = element.onclick = function, Mozilla element.addEventListener(''click'', function)). It gets even worse when trying to determine where the mouse was when the event fired and what element fired the event. Just use the prototype functions and all will be well, but remember to have the javascript that attaches the events be called AFTER the element has been rendered. Did you get all that? Greg
On Tue, Jan 17, 2006 at 03:16:04PM -0700, Gregory Hill wrote:> Is the element farther down the page than the javascript? HTML is > rendered in the order it is output. If you try to get an element that > has yet to be rendered, it does not exist.No comment. ;) It was the "new" that I had left off, too. But I think I have another problem. The link I click on happens to be included in the HTML returned from the Ajax request. I expect that''s not going to work very well, unless I reset the event handler after the ajax completes. Plus, it seems to add the new content instead of replacing the old content. Very ugly. So I went back to the inline onclick handlers. Looks like I''m going to have skip using an onclick on the link''s enclosing <td> or <tr>. In your examples you had function(e) {} in the onclick handler: <th onclick="function(e) { new Ajax.Updater(''tableTable'', ''http://url?sort=foo'' ); Event.stop(e); return false; }"> How does that function get called? Needs "new" in front, right? I thought perhaps this would also work, but nothing happens: onclick="( function(e) { new Ajax.Updater(), .. })()"; Anyway, I can''t seem to get Event.stop(e) to work on the onclick handler, only the last of these is working. "new function(e) {new Ajax.Updater(''$table_id'', ''$link'', { method: ''get'', requestHeaders: [''X-Ajax-Updater'', ''ajax_table''] } ); Event.stop(e); return false;}" "new function(e) {new Ajax.Updater(''$table_id'', ''$link'', { method: ''get'', requestHeaders: [''X-Ajax-Updater'', ''ajax_table''] } ); Event.stop(e); return false;}; return false;" "new Ajax.Updater(''$table_id'', ''$link'', { method: ''get'', requestHeaders: [''X-Ajax-Updater'', ''ajax_table''] } ); Event.stop(e); return false;" "new Ajax.Updater(''$table_id'', ''$link'', { method: ''get'', requestHeaders: [''X-Ajax-Updater'', ''ajax_table''] } ); return false;" Seems like whenever I use Event.stop(e) then both the ajax request and the normal href http requests happen. So it seems like Event.stop(e) must be causing the onclick handler to return true, which then causes the href to fire. This stuff can eat time! -- Bill Moseley moseley-kv6DSSSScSo@public.gmane.org