Tag: Web Development

Add keyboard shortcuts to your web app

Keyboard shortcuts are common place in desktop apps, to such an extent that you would probably be surprised if holding ctrl+s didn't save a document, or if holding ctrl+n didn't do some kind of new action. But with website's its a lot less common. The bigger email providers all now provide the support, but for the sites produced smaller companies out there it's still not the norm. Actually adding the support for it though is actually quite straight forward.

In this example I'm going to use jQuery but it's just as easy in everyday JavaScript.

1var isCtrl = false;
2
3$(document).keyup(function (e) {
4 if(e.which == 17) isCtrl=false;
5}).keydown(function (e) {
6 if(e.which == 17) isCtrl=true;
7 if(e.which == 83 && isCtrl == true) {
8 alert("Hello World");
9 return false;
10 }
11});

What is happening here is relatively straight forward. When you hold a key down, JavaScript will pick up an event that says which key was pressed by it's number. However what it can't do is pick up a combination, so if you do a ctrl+s what you get is two events (one for the ctrl and one for the s). So on every keydown if it's a ctrl we set the variable isCtrl to true, then on the next keydown we know it's a combination. The keyup detects the end of the ctrl being held down and sets the variable back to false.

The return false, when we've detected a ctrl+s is also very important as what this will do is stop the browser from carrying out any shortcuts it may have had for that combination.

So there we have it, in around 10 lines of code you can add some functionality to your web app, that seems really advanced but is actually really really simple.

.NET Charts (Pleasing clients by giving them a graph to look at)

Irrespective of if your working on some kind of company extranet or the admin side of a public facing site, one thing that will make you're clients go ooooooo and love your work is the inclusion of a funky looking chart. It may not serve any amazing purpose, but as there looking through all the boring text area's and buttons that actually make up the functionality of the site, the inclusion of nice looking chart is going to make them go "oooo that's nice" and like you even more. For those of us working in .NET, thanks' to an update from Microsoft at the end of 2008 it's also something that've very quick an easy to do. Better yet the update was free so the only cost is the time you take to implement it. 

First off if you want to use the chart's and you haven't downloaded them then that's what you need to do. The chart's shipped after .NET 3.5 so there a separate install, .NET 4 however has them included by default. 

Using the Chart Control

Like I said adding a chart to a page is a quick and easy thing to do. Once you have the Visual Studio add on installed you can also drag and drop everything into place. However I'm going to go into a bit more detail. 

To start your going to need a data source. In this example I'm using a SQL Data Source object for ease of use, in a production environment I heavily recommend against using them as there going to make your code a completely unmanageable mess, instead I would use something like a Entity Data Source. My chart is going to be showing a graph of mobile phone handset popularity so my SQL is simply just returning a table of phone names and how many people use them. 

Code so far: 

1<asp:SqlDataSource ID="ChartDB" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" SelectCommand="SELECT [Name], [People] FROM [PhonePopularity]">
2</asp:SqlDataSource> 

Next we need to add a chart, the easiest way to do this is to just drag a chart object onto the page from the toolbox, however if you do want to type it yourself it's not particularly complex. 

First you will need to register the assembly on the page.. 

1 <%@ Register assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="System.Web.UI.DataVisualization.Charting" tagprefix="asp" %> 

And then add the chart like so...

1<asp:Chart ID="Chart1" runat="server" DataSourceID="ChartDB" Height="400px" Width="400px">
2 </asp:Chart>

Now we're ready to start customizing what type of chart we're going to have and what data it should show from our data source.

To actually show a chart there's two bits of information you have to describe, area's and series'. The first area's is used to define an area for a chart to appear, one interesting thing about the chart control is you aren't limited to just one area. In fact in this example I'm going to have to chart's one showing a pie chart of phone popularity that will quickly show what kind of share each phone has, and then a second bar chart making it more clear the actual numbers people have of each phone. Area's also let you set properties on what the chart is actually going to look like as well. In this instance I'm going to set for both charts to be 3D.

The second bit of information is the Series. This is where you're actually specifying what data is going to be shown in which area and what kind of chart it is (e.g. Pie, Column, Donut etc). My completed code then looks like this...

1<asp:Chart ID="Chart1" runat="server" DataSourceID="ChartDB" Height="400px" Width="400px">
2
3<series>
4
5<asp:Series ChartArea="ChartArea1" ChartType="Pie" Name="Series1" XValueMember="Name" YValueMembers="People">
6</asp:Series>
7<asp:Series ChartArea="ChartArea2" Name="Series2" XValueMember="Name" YValueMembers="People">
8</asp:Series>
9
10</series>
11<chartareas>
12
13<asp:ChartArea AlignmentOrientation="Horizontal" Name="ChartArea1">
14
15<Area3DStyle Enable3D="True" />
16
17</asp:ChartArea>
18<asp:ChartArea Name="ChartArea2">
19
20<area3dstyle enable3d="True" />
21
22</asp:ChartArea>
23
24</chartareas>
25
26</asp:Chart>

Depending on your data this should give you something like this...

This is just a simple example of what you can do, but if you download the Chart Samples Project and have a look through there is no end to the possibilities with everything from different styles of charts to adding ajax functionality even with the ability to click of different parts of the carts to trigger events.

System.Lazy

Lazy loading isn't a new concept, it's a pattern that been around for a while to improve the performance of your apps by only loading objects when they are going to be used. For example if you have an object that contains a property of a list of customers then you only really need to populate it when you access the property not when the object was initially created, as it may never be used. At the same time though you don't want to be going off to the database every time access the property. So the simple solution is to have another private variable that stores if the customers property is populated or not and then check that in the property's get to determine if the data needs to be loaded or not.

Well now in .NET 4, lazy loading has been built into the framework with System.Lazy. Instead of the above all you need to do now is write something like this...

Lazy<Customers> _customers = new Lazy<Customers>();

What this will do is create you a customers object but only run the constructor when you actually access the objects Value property which will be of type Customers. e.g.

_customers.Value.CustomerData 

It's that simple, but can get even better. The constructor may not be the only thing you want to run when you access the property the first time. In this case you would write something like...

_customers = new Lazy<Customers>(() =>
        {
            // Write any other initialization stuff in here
            return new Customers();
        });

I must point out though while as great as this is, it does have some limitations so you probably won't want to use it in all scenarios.

For more information check out the Lazy initialization page on MSDN

Browser Testing IE Versions

Anyone in Web development knows that they should be testing their products on all browsers including different versions, which presents a problem when your only using the one PC. Programs like Multiple IE aren't great and often you can find yourself trying to fix a problem that doesn't actually exist on the proper version.

The best solution is the have virtual machines running on your own machine, but these take time to set up and most developers tend to have little time to spare as it is. Well thankfully if you want to test Internet Explorer you don't have to set the virtual machine up yourself, just head to the following address and you can download one from Microsoft's site. Save the address as you will have to keep downloading it every 3 months due to them building in a time bomb as it is essentially a free OS.

http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&displaylang=en

The second option also from Microsoft is Super Preview that is planned to be part of their Expression package. Currently it's only at the Beta stage but it if you enter an address it will give you a side by side comparison of a page in IE 6/7/8, plus its free. The full version when it's ready is meant to have support for all the popular browsers (but then you will have to pay for it to). However it is also limited to just being a preview so as far as testing all your JavaScript functions goes, you still need your virtual machines for that.

Doloto

Doloto

Meant for Web 2.0 Apps that use a lot of JavaScript, Doloto will speed up the download time of all the JavaScript by basically removing anything that isn't initially needed and replacing it with stubs. It will then download in the background or wait until it is first called. The result, a seemingly much faster Web App for the user.

For more info have a look at the Doloto page on Microsoft's Research site or head over to the download page on MSDN.

Introduction to Real Time Search

The Real Time Search this article relates to is a dll that comes included in the Web Client Software Factory one of Microsoft's patterns and practices downloads. What it can do and what this example will demonstrate is adding the ability cause a post back that will refresh an update panel as the users types into a search box. This can give a great effect and make a web app really user friendly in scenarios like searching photo's, emails or any general list.

First late me state though that this is in no way the most optimal way program. In most scenarios you could built a better result using something like JSON as their will be a lot less data transfer, which is also a general reason to avoid update panels. However this is also very quick and very easy to implement, not to mention if you've ever used update panels before you already know 90% of what's needed. This can also only work in situations where you have a good search that is going to return the result quickly, rather than leaving the user sitting there trying to work out why nothing's happening and where the search button has gone.

Implementing Real Time Search

For this example I will be filtering a table from a DB based on the search criteria and refreshing a Grid View with the results. I will be using a normal C# Web Site project with the Adventure Works sample DB from Microsoft. DB connection will be done using LINQ to EntityFramework, however there is no need to use this it is just my preference for the example.

First off set up you're website and db and make sure both are working with no problems. As results will be displayed in an Update Panel, get one of these along with a script manager added to your page, so it looks something like this:

1<form id="form1" runat="server">
2<div>
3<asp:ScriptManager ID="ScriptManager1" runat="server">
4</asp:ScriptManager>
5<asp:UpdatePanel ID="UpdatePanel1" runat="server">
6<ContentTemplate></ContentTemplate>
7</asp:UpdatePanel>
8</div>
9</form>

Next let's get the search working in the normal method, so I'm going to create my Entity Model and add a textbox and gridview to show the results. Again you can connect and show your results however you want. You should now have something like this in your aspx file:

1<form id="form1" runat="server">
2<div>
3<asp:ScriptManager ID="ScriptManager1" runat="server">
4</asp:ScriptManager>
5
6<asp:TextBox ID="txtSearch" runat="server" OnTextChanged="TextChanged" Text=""></asp:TextBox>
7
8<asp:UpdatePanel ID="UpdatePanel1" runat="server">
9<ContentTemplate>
10
11<asp:LinqDataSource ID="LinqDataSource1" runat="server" onselecting="LinqDataSource1_Selecting">
12</asp:LinqDataSource>
13
14<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="LinqDataSource1">
15<Columns>
16<asp:BoundField DataField="ProductID" HeaderText="ProductID"
17ReadOnly="True" SortExpression="ProductID" />
18<asp:BoundField DataField="Name" HeaderText="Name"
19ReadOnly="True" SortExpression="Name" />
20<asp:BoundField DataField="ProductNumber" HeaderText="ProductNumber" ReadOnly="True" SortExpression="ProductNumber" />
21<asp:BoundField DataField="Color" HeaderText="Color"
22ReadOnly="True" SortExpression="Color" />
23<asp:BoundField DataField="SafetyStockLevel" HeaderText="SafetyStockLevel"
24ReadOnly="True" SortExpression="SafetyStockLevel" />
25<asp:BoundField DataField="ReorderPoint" HeaderText="ReorderPoint"
26ReadOnly="True" SortExpression="ReorderPoint" />
27</Columns>
28</asp:GridView>
29</ContentTemplate>
30
31</asp:UpdatePanel>
32</div>
33</form>

And this in your code behind:

1protected void LinqDataSource1_Selecting(object sender, LinqDataSourceSelectEventArgs e)
2{
3Model.AdventureWorks2008Entities AdventureWorkds = new Model.AdventureWorks2008Entities();
4var products = from p in AdventureWorkds.Product
5where p.Name.Contains(txtSearch.Text)
6select p;
7e.Result = products;
8}

Next its time to add the Real Time Search. Make sure you have the dll downloaded (you may need to compile the download to get it) and add it to your bin folder. Add the following to your page in the relevant places:

1<%@ Register Assembly="RealTimeSearch" Namespace="RealTimeSearch" TagPrefix="cc1" %>
2
3<cc1:RealTimeSearchMonitor ID="RealTimeSearchMonitor1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
4<ControlsToMonitor>
5<cc1:ControlMonitorParameter EventName="TextChanged" TargetID="txtSearch" />
6</ControlsToMonitor>
7</cc1:RealTimeSearchMonitor>

Important things to notice here are the AssociatedUpdatePanelId which tells the control what it has to refresh and the controls to monitor section which sets what the control to watch is called and the event name that will be fired when the post back is created. You will now need to corresponding control in your code behind like so:

1protected void TextChanged(object sender, EventArgs e)
2{
3GridView1.DataBind();
4}

Run the site and  you should find that the grid view now updates as you type (all be it with a slight delay).

To improve you can add other controls like update progress to show something happening which will help with any delays in displaying the results.

How to search inside Stored Procedures?

A common problem faced by many developers when it comes to databases and SQL Server is how to search the text inside a stored procedure.

In many systems particularly older Classic ASP solutions, functional code has been moved from the actual application to stored procedures inside the database. This is usually because it will either run faster here, or because it was just a lot easier to perform the necessary task using TSQL. Following this though comes the problem of how you can search what's in all those stored procedures, especially when you're getting into the hundreds of them. Let's say there was a Users table that contained fields for an address, but that now needs to be moved to a table of its own, you would need to search all the code for things accessing those table columns but SQL Server Management Studio certainly doesn't provide any search box's with the power to do this.

Never fear though syscomments is here. Syscomments contains the original text from amongst other things all the Stored Procedures in the DB s all you need to do is search that for what you're looking for:

1Select OBJECT_NAME(id), [text]
2From syscomments
3Where [text] like '%Create%'

The function OBJECT_NAME will also help you by converting the id number in the result set into the actual name of the stored procedure (or view, function etc). If you wanted to limit the result to just stored procedures you can add the following line to the where clause:

1AND OBJECTPROPERTY(id, 'IsProcedure') = 1

Refreshing an UpdatePanel using JavaScript

Update panels provide a really easy way to add partial page refresh's to a web page in order to give a more user friendly experience that's more like a common desktop App. By default a button within that update panel will cause a post back and so long as no elements outside of the update panel are affected in the post back only it will refresh. However what do you do if you need to refresh a panel based on something outside of the update panel. One option is just to place a hidden button within the Update Panel and trigger that to post back, however this appears a little hacky. The solution is to use JavaScript and the _doPostBack method.

The following bit of code is all you really need:

1<script type="text/javascript">
2function refreshUpdatePannel(param) {
3var prm = Sys.WebForms.PageRequestManager.getInstance();
4prm._doPostBack('<%=UpdatePanel1.ClientID %>', param);
5prm.add_endRequest(refreshUpdatePanelComplete);
6}
7
8
9function refreshUpdatePanelComplete() {
10//add code here for when the update pannel is refreshed
11}
12</script>

All you need to add is something to call the function.

The second parameter is optional and provides a way of passing some information back to the server to let it know what has just happened on the page.

When the update panel has finished refreshing the refreshUpdatePanelComplete function will fire so more JavaScript can be added if needed e.g. To reset whatever just happened on the page that caused the initial postback.