Life, the Universe and the Internet

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

Archive for the ‘Programming’


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.

Having More Than Two Sections In An ASP.Net Repeater Control

If you’re familiar with the ASP.Net repeater control then you will know that when laying out the repeater contents you can have individual style for alternating rows so far example every other row could have a different background. But what if you wanted more sophisticated options, say for example you wanted to do a news style repeater with the first item having a photo and an in depth story, then next five having a picture and summary and the remaining items having just a headline.

Well I found a great tip on how you can do this with a single repeater. The way to do it is to set up panels inside your repeaters item template, as the example below:

<asp:Repeater id="myRepeater" runat="server">

<ItemTemplate>

<asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# (Container.ItemIndex  = 0) %>' >
<div>

My First Item Controls

</div>
</asp:PlaceHolder>

<asp:PlaceHolder ID="PlaceHolder2" runat="server" Visible='<%# (Container.ItemIndex >=1) and (Container.ItemIndex <5) %>' >
<div class="underlined">

My Next Five Item Controls

</div>
</asp:PlaceHolder>

<asp:PlaceHolder ID="PlaceHolder3" runat="server" Visible='<%# (Container.ItemIndex >= 5) %>' >
<div

The Reminder Of My Items Controls

</div>
</asp:PlaceHolder>

</ItemTemplate>

</asp:Repeater>

So you set up a panel for each of the individual styles that you require and then the Visible property of the panel is derived from where we are currently in the list of items. Nice and easy, requires no complex code behind tricks and works like a charm.

Hope this will be of help to someone out there, it certainly was to me.

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);

ASP.NET 2 Generating a Client Side Message Box from a Server Side Event or Function

One of the big problems with an asp.net application over say a windows application is that when you really want to bring something to the users attention, it can be difficult to pop up a modal dialog box to tell the user what is going on. You cannot use the generic messagebox function because on a server side event this will pop up a message on the server which is not very useful.

So there are of course ways around this problem, by using javascript on button click events etc, but what if you want to display a messagebox from some server side code that is not initiated from a user action such as a button click. Well as it turns out and I recently discovered this is very easy to do with asp.net 2, by using the CientScript.RegisterStartupScript event. Below is an example.

Private Sub SomeSubRoutine()

   If SomeVariable <> SomethingElse Then

      Dim strMessage As String
      strMessage = "Warning, this process generated an error"
      Page.ClientScript.RegisterStartupScript(Me.GetType(), _
        "alert", "<script>alert('" + strMessage + "');</script>")

   End If

End Sub

So there you go, pretty simple really. Now any server side process on a web page can generate a message box for the user if you require it. You don’t necessarily need to declare the fill Page.ClientScript.RegisterStartupScript, on an aspx page you can get away with just ClientScript.RegisterStartupScript. But if you use the full name it will work anywhere including user controls.

Hope this is of some help to someone out there.

SQL Server 2005: Selecting Records From One Table That Do Not Exist In Another

This week I learned a handy little piece of sequel, which even though you probably already now about, I thought I would share it as I had not seen it before.

The Scenario

Say you had two tables, for example a customer table and an orders table. The tables were structured so that whenever an order was placed it was related to a particular customer through the ID. Pretty straightforward so far right? Well now say you wanted a list of all customers that have never had an order placed against them, so therefore no records will exist in the orders table.

Now I was going to approach this by doing all sorts of complicated outer joins, but then someone should be a much neater solution, it is the NOT IN clause which I had not come across before. So you basically say show me all records where table1’s ID is NOT IN table2. Below is an example using the tables I already mentioned.

SELECT cu.CustomerName,
Cu.CustomerID
FROM dbo.Customers cu
WHERE Cu.CustomerID NOT IN
(SELECT CustomerID FROM dbo.Orders)

Pretty simple eh, and works like a charm. Hope this will be as helpful to someone out there as it was to me.