Life, the Universe and the Internet

My ramblings about making a living on the internet and life in general

Archive for the ‘AJAX’


ASP.Net Ajax SelectedIndexChanged Bug With RadioButtonList and AJAX Update Panels

Today I discovered a little bug when using AJAX update panels with radio button lists to update the panel. Here as my scenario:

I had a gridview inside an AJAX update panel and I had a radio button list on my page with two options (Active and Inactive). My goal was to update the content of the gridview depending on the option selected from the radio button list. Here is the code for my radio button list:

        <asp:RadioButtonList ID="rblStatus" runat="server" AutoPostBack="True" RepeatDirection="Horizontal">
            <asp:ListItem>Active</asp:ListItem>
            <asp:ListItem Selected="True" >Inactive</asp:ListItem>
        </asp:RadioButtonList>

And here is how my update panel looked:

        <asp:UpdatePanel ID="updMainGrid" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
        <asp:GridView ID="gridView1" runat="server" Width="100%" AutoGenerateColumns="False" >
            <Gridview setup.....................>
        </asp:GridView>
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="rblStatus" EventName="SelectedIndexChanged" />
        </Triggers>
        </asp:UpdatePanel>

The code behind for the SelectedIndexChanged event of the radio button list simply rebound the gridview depending on the option selected at the radio button. To my surprise this didn’t work, the first time I click “Active” it would work but after that it would not run the SelectedIndexChanged code again. However if I took the AJAX panel away it worked perfectly. Eventually I traced the problem down to the “Selected=”True”” option in the radio button. As soon as you have this on any of the options the AJAX panel breaks.

So now that I have the bug, how do I make sure that a default option is selected when the page first loads? I tried setting the property in the code behind and this still causes the same problem. Eventually I found a little piece of javascript that worked. Here is the script I used:

<script language="JavaScript" type="text/javascript">
document.getElementById('<Control Name>').checked = true; </script>

To use this simply change <Control Name> to the name of your radio button list control.

Z-Index The Vital CSS Property For AJAX Development

When I first started using AJAX I soon came across a problem that had me stumped for a while. The problem was that some of the AJAX tools like hover menus, popup windows, calendars etc were appearing behind other controls on the page so that they would either be only partially displayed or not even displayed at all.

Now a lot of you reading probably already know the simple fix for this, but just in case there are some out there like me who got stuck at this point I hope this little tip can help.

There is a little property in CSS called Z-Index and to use the official description the z-index property sets the stack order of an element. An element with greater stack order is always in front of another element with lower stack order.

What this means is that the higher the Z-Index number of an element on the page the higher it will appear in the stack, so if you think of your page as a three dimensional element, the item with the highest Z-Index will be on the top of the pile of elements.

By default if you don’t specify your Z-Index for any css element then they all have a default of 0 and they will be stacked in the default order. So if you have a relatively simple requirement where you only need to ensure one item is always on top, all you need is this in the elements CSS properties:


.myelement
{
Z-Index: 1;
}

As long as no other elements have the same or higher Z-Index your element should appear at the top of the stack. Conversely you can also set a negative Z-Index number if you want to ensure an element is pushed lower down the stack.

For the official page on Z-Index go here.

How To Stop Losing The Focus With An ASP.Net AJAX Panel

I had a recent problem when working with ajax update panels on an asp.net application. I basically had a panel with lots of drop down boxes and text boxes inside it. Whenever a drop down was changed or a value was entered in a textbox, the whole panel would be recalculated as it contained totals and sub totals based on the contents of these boxes.

The problem I had was that I had to include all of the controls inside the update panel otherwise I would have ended up with 20-30 update panels on the page, a situation that I really wanted to avoid. Because the controls were inside the panel every partial postback I was losing the focus as effectively even though you don’t see it, the panel is destroyed and rebuilt every time.

So it became impossible for a user to just tab through the form updating values, as the focus was reset with every field, not an ideal user friendly situation.

So after much research I discovered that you can actually force focus to an individual control using the script manager control in the server side code. The code to do this is pretty simple, and would be something like:

Me.ScriptManager1.SetFocus(Textbox1)

Where scriptmanager1 is the name of your script manager control and textbox1 is the name of the control you want to set the focus too.

Now this is fine if you always know which control should have the focus, however if you have a lot of controls being processed inside one update panel you might not know which control to focus on next. Thankfully I found a neat little javascript on this blog http://couldbedone.blogspot.com/2007/08/restoring-lost-focus-in-update-panel.html That you can include with your script manager on any page, the javascipt will take care of all your focus problems for any update panels you have on your page. I’ll include the full script code below, don’t ask me to explain how it works, I’m just happy that it does and hope it will be of some use to you.

// JScript File

var lastFocusedControlId = "";

function focusHandler(e)

{

document.activeElement = e.originalTarget;

}

function appInit()

{

if (typeof(window.addEventListener) !== "undefined")

{

window.addEventListener("focus", focusHandler, true);

}

Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(pageLoadingHandler);

Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedHandler);

}

function pageLoadingHandler(sender, args)

{

lastFocusedControlId = typeof(document.activeElement) === "undefined"

? "" : document.activeElement.id;}function focusControl(targetControl)

{

if (Sys.Browser.agent === Sys.Browser.InternetExplorer)

{

var focusTarget = targetControl;

if (focusTarget && (typeof(focusTarget.contentEditable) !== "undefined"))

{

oldContentEditableSetting = focusTarget.contentEditable;

focusTarget.contentEditable = false;

}

else

{

focusTarget = null;

}

targetControl.focus();

if (focusTarget)

{

focusTarget.contentEditable = oldContentEditableSetting;

}

}

else

{

targetControl.focus();

}

}

function pageLoadedHandler(sender, args)

{

if (typeof(lastFocusedControlId) !== "undefined" && lastFocusedControlId != "")

{

var newFocused = $get(lastFocusedControlId);

if (newFocused)

{

focusControl(newFocused);

}

}

}

Sys.Application.add_init(appInit);