Showing posts with label elements. Show all posts
Showing posts with label elements. Show all posts

Monday, March 26, 2012

Prevent child elements from firing parent element onclick event

This question does not appear to be directly related to the Ajax Client framework. However, I am asking it here because a) there is actually heavy use of Ajax in the real life issue, but it is not necessary to explain this to illustrate the problem and b) it is JavaScript related, and where better to find an answer to such a question than on this forum, with so many hardcore JavaScript experts visiting?

So, I hope you'll forgive the apparently off-topic nature of this post.

I have made the rows of a Gridview clickable. I have a hidden 'Select' button in each row, and in the code behind RowDataBound event I steal the JavaScript from this button and apply it as an 'onclick' attribute for the entire row.

In the resulting HTML, there is a TR element generated for each Gridview row. This TR element has the 'onclick' attribute, containing the necessary JavaScript to do a row 'Select' postback. If I now click anywhere in the TR element (i.e. anywhere in the Gridview row), the 'onclick' event is fired and a 'Select' postback occurs.

This is exactly what I want to happen, except for one instance. One of the Gridview row Cells (which corresponds to a TD element in the resulting markup) contains an <asp:HyperLink> control. When the user clicks on this HyperLink, a new window opens as it should. However, the 'onclick' event for the entire row also fires and the Gridview row ends up being selected.

As the <A HREF> element resulting from the HyperLink control is within the TR element which has the 'Select' onclick attribute, this onclick event is fired. I want to know how I can stop this.

To put it succinctly:
- I have a TR element with an 'onclick' attribute.
- I have an <A HREF> within the DOM hierarchy descending from the TR element.
- How can I stop the TR element 'onclick' attribute firing when I click on the <A HREF> link?

I've tried setting the 'onclick' event of the <A HREF> element to nothing, but it makes no difference.

A solution I have found is to replace the HyperLink control with a LinkButton control. I give the LinkButton an 'onclick' attribute which does a 'window.open' with the appropriate link. So the resulting behaviour is just like the HyperLink. But using a LinkButton involves a postback (albeit a dummy postback which does nothing at all other than reload the page), which wastes server resources and bandwidth. I could whack the LinkButton into an UpdatePanel to minimise this, but it still seems like overkill to me. And it would mean an UpdatePanel for each Gridview row, which is a lot of extra script for so simple a purpose.

So... any thoughts on this would be very much appreciated.

Thanks...

You should just be able to cancel the "bubble" event... seehttp://www.quirksmode.org/js/events_order.html

The code you want is in the section"Turning it off":

if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();

-Damien


Thank you very much. That is exactly the information I was looking for. I have to say, the more I find out about JavaScript the more impressed I am with it.

As well as solving the issue I had that is a very interesting read and I've bookmarked it for future reference.

Thanks again for your help, much obliged...

Saturday, March 24, 2012

Problem getting elements by ID inside <Content> of AccordionPane

Dear All,

I've got problem on changing the content inside a <div> element inside the Content part of AccordionPane. The code is below:

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

<script type="text/javascript">

function test1(){

var table = document.createElement('TABLE');
table.setAttribute('border',0);
table.setAttribute('id','sliderTable');

var tBody = document.createElement('TBODY');
table.appendChild(tBody);

var row = document.createElement('TR');

var cell = document.createElement('TD');

cell.style.backgroundColor = "#CCCCCC" ;
cell.style.width = 10+ "px";
cell.style.height = 5+ "px";

row.appendChild(cell);

tBody.appendChild(row);
}
document.getElementById('colorTable').appendChild(table);

document.getElementById('colorTable').style.display='';

}

</script>

<asp:ScriptManager id="ScriptManager1" runat="server" />

<ajaxToolkit:Accordion ID="Accordion1" .....>

<Panes>

<ajaxTookit:AccordionPane...>

<Header>Color</Header>

<Content><div id='colorTable' style="display:none"></div><Content>

</ajaxToolkit:AccordionPane>

......

</Panes>

</ajaxToolkit:Accordion>

</asp:Content>

When I run the code it said there is a javascript error "Object Required". It is the script cannot locate the 'colorTable' element? And what way can I locate the element?

Thanks!!

Stard

Hello,

As you propably discoveredSmile:

function test1(){

var table = document.createElement('TABLE');
table.setAttribute('border',0);
table.setAttribute('id','sliderTable');

var tBody = document.createElement('TBODY');
table.appendChild(tBody);

var row = document.createElement('TR');

var cell = document.createElement('TD');

cell.style.backgroundColor = "#CCCCCC" ;
cell.style.width = 10+ "px";
cell.style.height = 5+ "px";

row.appendChild(cell);

tBody.appendChild(row);
} <----- syntax error
document.getElementById('colorTable').appendChild(table);

document.getElementById('colorTable').style.display='';

}

has syntax error, there is an unnecessary } /or your copy/paste was not successful/


Hi stmarti,

sorry I've got typo error in my post :) Since I just type the main structures of my code and my original one haven't got this typo error.

Btw I searched some other forum and got some solutions like document.getElementById('<%colorTable.ClientID%>') because I am working with a content page under a master page. But I get "colorTable do not have the ClientID property" error.

Any idea on this?

Many thanks.

Stard


Hi,

I have some comments maybe it helps:

a) the correct syntax is <%= colorTable.ClientID %> or <%# colorTable.ClientID %>

but I think it is unnecessary, because your div isnot a server side control so it's id won't be altered! This is only necessary when you have:

<div id='colorTable' style="display:none"runat="server" ></div>

b) The really big problem is style="display:none"andthe empty div.

Why? Because with this style yourempty div will not ever rendered in the browser(!!!) and not even part of the DOM tree! Just check this.

Try instead of: strip style="display:none" or change it style="visibility: hidden;" or use a span instead of div as a placeholder or put some content in the div. Try all these to understand how your browser render empty or display:none divs.



Hi,

Small update, start here: change your div to

<div id='colorTable' style="display: none;"> </div>

and document.getElementById( 'colorTable' ) should worksSmile