Truly understanding dynamic controls

Today while figuring out how to do something for a project, the solution that was chosen was to dynamically load a user control to the page.

After getting null reference errors and the control completely not rendered on the page, I found the solution to be this.

Control FeaturedProductUserControl = LoadControl(“FeaturedProduct.ascx”);
Controls.Add(FeaturedProductUserControl);

There is an article that I came across which is really good at explaining how this actually works, Truly understanding dynamic controls, definetely worth a read.

Browsers and their Javascript mouse events

Yesterday I came across this article at http://unixpapa.com/js/mouse.html, the author of the article documented all the different JavaScript events triggered by the same mouse event under different browsers, which is really really useful.

I’ve extracted only the events component here and combined them to a table, if you want to know about these events please visit the original article.

Browser Version

Windows Macintosh Linux
Internet Explorer 8.0.6001.18372 5.2
Firefox 3.0.5 (Gecko 1.9.0.5) 3.0 (Gecko 1.9) 3.0 (Gecko 1.9)
Safari 3.2.1 3.1.1
Opera 9.63 9.10 9.27
Konqueror 3.5.7
Chrome 1.0.154.43

Can default mouse actions be disabled?

Left Button Middle Button Right Button
Internet Explorer Yes Yes Yes
Safari Yes Yes Yes
Konqueror Yes Yes Yes
Firefox Yes Config file edit only Yes
Opera 7.23-7.54 Yes Only if user has enabled an obscure option
Other Opera Versions Yes No No
Netscape 4 Yes Config file edit only

Single Mouse Clicks

Left ↓ Left ↑ Right ↓ Right ↑ Middle ↓ Middle ↑
Internet Explorer mousedown mouseup click mousedown mouseup contextmenu mousedown mouseup click
Safari mousedown mouseup click mousedown mouseup contextmenu mousedown mouseup click
Konqueror mousedown mouseup click mousedown mouseup mousedown mouseup
Firefox mousedown mouseup click mousedown contextmenu mouseup mousedown mouseup
Opera < 8.0 mousedown mouseup click mousedown N/A mousedown N/A
Opera = 8.0 mousedown mouseup click mousedown mouseup mousedown mouseup
Netscape 4 mousedown mouseup click mousedown N/A mousedown No Data
Chorome 1.0 mousedown mouseup click mousedown mouseup contextmenu mousedown No Data
Chorome 0.2 mousedown mouseup click mousedown contextmenu mouseup mousedown No Data

Mouse Double Click, First Click

Left ↓ Left ↑ Right ↓ Right ↑ Middle ↓ Middle ↑
Internet Explorer mousedown mouseup click mousedown mouseup contextmenu mousedown mouseup click
Safari = 2.0 mousedown mouseup click mousedown mouseup contextmenu mousedown mouseup click
Safari 1.3 mousedown mouseup click mousedown mouseup mousedown mouseup click
Gecko = 1.7 (Firefox >1) mousedown mouseup click mousedown contextmenu mouseup mousedown mouseup
Opera = 9.10 mousedown mouseup click mousedown mouseup mousedown mouseup
Gecko 1.6 on Windows and Linux mousedown mouseup click mousedown contextmenu mouseup mousedown mouseup
Konqueror mousedown mouseup click mousedown mouseup mousedown mouseup
Opera = 8.0 < 9.10 mousedown mouseup click mousedown mouseup mousedown mouseup
Opera < 8.0 mousedown mouseup click mousedown N/A mousedown N/A
Netscape 4 mousedown mouseup click mousedown N/A mousedown N/A
Chrome 1.0 No Data No Data mousedown contextmenu mouseup mousedown No Data

Mouse Double Click, Second Click

Left ↓ Left ↑ Right ↓ Right ↑ Middle ↓ Middle ↑
Internet Explorer N/A mouseup dblclick mousedown mouseup contextmenu mousedown mouseup click
Safari = 2.0 mousedown mouseup click dblclick mousedown mouseup contextmenu mousedown mouseup click dblclick
Safari 1.3 mousedown mouseup dblclick mousedown mouseup mousedown mouseup click dblclick
Gecko = 1.7 (Firefox >1) mousedown mouseup click dblclick mousedown contextmenu mouseup mousedown mouseup
Opera = 9.10 mousedown mouseup click dblclick mousedown mouseup mousedown mouseup
Gecko 1.6 on Windows and Linux mousedown mouseup click dblclick mousedown contextmenu mousedown contextmenu mouseup mousedown mousedown mousedown
Konqueror mousedown mouseup dblclick mousedown mouseup mousedown mouseup
Opera = 8.0 < 9.10 dblclick click mouseup mousedown mouseup mousedown mouseup
Opera < 8.0 dblclick click mouseup mousedown N/A mousedown N/A
Netscape 4 mousedown mouseup click mousedown N/A mousedown N/A
Chrome 1.0 No Data No Data mousedown contextmenu mouseup mousedown No Data

Mouse button ID values in various browser

Internet Explorer Netscape 4 Gecko = 1.0

Safari 3

Opera = 8.0

Gecko 0.9 Opera < 8.0 Konqueror Safari 2
event.button LEFT

BUTTON

1* undefined 0 1 1 1 1
MIDDLE

BUTTON

4* undefined 1 2 3 4
RIGHT

BUTTON

2* undefined 2 3 2 2
event.which LEFT

BUTTON

undefined 1 1 1 1 1 1
MIDDLE

BUTTON

undefined 2 2 2 3 2
RIGHT

BUTTON

undefined 3 3 3 2 3

* for mousedown and mouseon only, zero for click, dblclick and contextmenu events.

Must Have Firefox Add-Ons for Web Development

Although I’ve tried very very hard to use Internet Explorer for web development, I just kept coming back to Firefox. I know I should use IE, especially IE6 since that’s where all the bugs happen to be found in, but it’s just not the same.

Over the years I’ve tried quite a few, and uninstalled quite a few Firefox add-ons, here are my favorite Firefox Add-Ons for web development.

Firebug

Allow you to modify the css of any html element on the fly, great for when you are doing css changes and don’t want to reload the entire page every time you make a css change.

firebug-css

Also it makes debugging JavasScript possible, you can put break points on the JavaScript file and pause it, evaluate the values of variables.

firebug-js
Add firebug at https://addons.mozilla.org/en-US/firefox/addon/1843

YSlow

It’s an add-on to Firebug, I’ve mentioned YSlow before on the article Improve your Ajax performance using YSlow and Firebug. It displays detailed information about page size, number of http calls, image size, Ajax call speed which is very useful.
yslow

You can find YSlow at https://addons.mozilla.org/en-US/firefox/addon/5369
ColorZilla

ColorZilla basically allows you to show css hex of the colours used on a web page, by using a eye dropper. This was the functionality in the first version I installed. In the newer version, a great functionality added is the ability to get the css colours used on a webpage analysed, and displayed. It shows you all the colours used in the page, where it’s used, and how many css classes use the colour. Here is the result from the word press admin system.

colorzilla

You can find ColorZilla at https://addons.mozilla.org/en-US/firefox/addon/271

Dust-me Selectors

This add-on will go through the current page’s exteral style sheets references and display all the css classes that are not used on the current page. This is really useful if you have a site that’s been changed for who knows how many times, and the css file has ended up with lots of redundant classes.

However there are two flaws in my opnion, one is it doesn’t scan inline css, and the other is it only checks if the class is used on the current page, so if you have a standard css for all pages, then there are bound to be css classes not used.

So it’s only useful if you have a external css file that is only used by the current page.

dust-me-selector

You can find Dust-me Selectors at https://addons.mozilla.org/en-US/firefox/addon/5392

Web Developer Tool Bar

Web developer tool bar, this is the original, I remember starting to use this is Firefox 1.0. It’s got heaps of functionality related to web development that makes it easy to clear cache, validate html, viewing images sources, finding brocken images and lots more. It’s a must have for any web developer in my opnion.

web-developer-toolbar

You can find Web Developer Toolbar at https://addons.mozilla.org/en-US/firefox/addon/60

View Source Chart

This add-on allows you to view the html source of the page, but in a chart format. Each different section is broken up into different colours so you can easily scan through the html to find the thing you are looking at, and where the tags start and end.

html-chart

You can find View Source Chart at https://addons.mozilla.org/en-US/firefox/addon/655
p.s: there isn’t a public version for Firefox 3.0 yet but I installed the beta and it seemed to work fine for what I needed

Pixel Perfect

This add-on allows  you to overlay an image over the html. It’s really handy in the html coding stage, you can overlay the design file over the html you’ve done and see if anything is out of alignment. It’s an add-on to Firebug so you will need to install Firebug before you can use this.

Pixel Perfect

You can find Pixel Perfect at https://addons.mozilla.org/en-US/firefox/addon/7943


Web Farm, Load Balancing and Sessions

I hadn’t really been exposed to web farm or load balancing much before. After having to use multiple web servers for one of my previous probject, I realised that the default session mode for the .Net project will no longer work in a multiple web server environment.

With load balancing, the request is directed to which ever server that is free.

On your first login to the site, the FormsAuthentication will generate the authentication session. The default session mode of “inProc” will store the session reference on the server. On the next visit the the same site, if the other web server were more free, your request will get redirected to the other web server, at that point the session variable generated previously authentication won’t work.  and you will get error similar to this in the Event Log.

Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that configuration specifies the same validationKey and validation algorithm.

Basically the session variable that was previously generated was referencing one machine, now that you are directed to another web server, the machine reference to is no long the same one.

In order to over come this issue, you will need to use either State Server or SQL Server session mode, which is a configuration in the config file.

I found a really good article on this topic, WEB farm – Load Balancing in Asp.net.  This article goes through everything step by step, and gives really clear explanations on the different methods and how to implement them.

Throw that shoe at Bush (Flash Game)

Since the incident last week in Iraq, where a Journalist throw his shoe at US’s President Bush, the video has been viewed millions of times on YouTube.

Now there is a flash game about it, only after a few days, and it’s got massive traffic, with the top country playing it the US.

Check it out at http://www.sockandawe.com/.

Selecting Top X records per group SQL Server 2005

Selecting top x number of records per group is something I needed to implement recently, using the build in functions of SQL Server 2005, it can be done quite easily.

Selecting top x records per group basically divides the data into groups based on  a particular field, and then order the records only in that group based on the criteria. Because each row’s details are needed, not a summary of some data in the table, you can’t use group by.  An example of this is get the top 10  scores of all test results based on subjects.

In order to get the record, the thing to use is the Partition By statement combined with the Row_Number Over.

For example, I have a blog table BlogPosts which stores blog posts, with this structure.

Columns BlogTitle BlogCategory BlogCommentNo
SQL Post SQL 3
JQuery Post 1 JQuery 1
JQuery Post 10 JQuery 10
JQuery Post 5 JQuery 5
JQuery Post 6 JQuery 6
JQuery Post 8 JQuery 8
JQuery Post 9 JQuery 9

I want to know which posts had the most number of comments, in each category, the following shows the steps to take.

Step1, generate a column that represent the position of the item based on the number of comments

SELECT  BlogTitle,   BlogCategory,BlogCommentNo
ROW_NUMBER() OVER (PARTITION BY BlogCategory ORDER BY BlogCommentNo DES) Position
FROM
BlogPosts

The PartitionBy will divid the records based on the BlogCategory field, with the order by the BlogCommentNo field, the Row_Number() Over will then assign a number based on that criteria, with the name of position. This will give you the position of the particular role, based on the number of comments it’s got, in the category it is related to.

After I run the above script, the following data is returned. So now I’ve got the data in the order I want it to return, I just need to modify the script to return only the top 5.

Columns BlogTitle BlogCategory BlogCommentNo
SQL Post SQL 3
JQuery Post 10 JQuery 10
JQuery Post 9 JQuery 9
JQuery Post 8 JQuery 8
JQuery Post 6 JQuery 6
JQuery Post 5 JQuery 5
JQuery Post 1 JQuery 1

Step2, select the top X records

Using previous query as a sub query,  using the Position column as the order of the post in the category, I can then select the top 5 records from it.

Select * From

(SELECT  BlogTitle,   BlogCategory,BlogCommentNo
ROW_NUMBER() OVER (PARTITION BY BlogCategory ORDER BY BlogCommentNo DES) Position
FROM
BlogPosts) results
Where
Position <6

This will get the top 5 results based on the position column.

This is all  you need to get the Top X records per group.

Columns BlogTitle BlogCategory BlogCommentNo
SQL Post SQL 3
JQuery Post 10 JQuery 10
JQuery Post 9 JQuery 9
JQuery Post 8 JQuery 8
JQuery Post 6 JQuery 6
JQuery Post 5 JQuery 5

You can also modify this script to do other things related to grouping of data.

Update top X number of records based on a group

Say I want to Update all top 5 posts with the most comments to have 0 number of comments for some bizarre reason.

Update BlogPosts

Set BlogCommentNo = 0
From

(Select * From

(SELECT  BlogTitle,   BlogCategory,BlogCommentNo
ROW_NUMBER() OVER (PARTITION BY BlogCategory ORDER BY BlogCommentNo DES) Position
FROM
BlogPosts) results
Where
Position <6) setzero
Where BlogPost.BlogTitle = setZero.BlogTitle

The where clause will need to match against the primary key field from the table to the subQuery, in this example I’ve just used the BlogTitle, assuming that it’s the primary key field.

Or I can modify the script so instead of selecting the top X records, it selects all records except the top X.

Here I only want to select blog posts that are not in the top 5 comments.

Select * From

(SELECT  BlogTitle,   BlogCategory,BlogCommentNo
ROW_NUMBER() OVER (PARTITION BY BlogCategory ORDER BY BlogCommentNo DES) Position
FROM
BlogPosts) results
Where
Position >5

My blog has moved

I won’t be making any updates to this blog anymore. I finally setup my own domain for my blog and I will be updating my blog there.

The url is http://www.techy-talk.com

Now I can play around with plug-ins, change themes and all sorts of things. Yay!!.

Comparing Gmail Tasks and Remember the Milk Gmail Widget

Today I read Gmail added a Tasks module from TechCrunch, finally. It’s not part of standard Gmail yet, you have to turn it on in the Labs section of your Gmail account. Go to Settings -> Labs and find Tasks.

Before this was released I used the Remember the Milk Widget in Gmail for my tasks list, so I wanted to see which one is better and whether I should switch to Gmail Tasks.

After comparing them,  I think it depends on what you need from you task list on which one to use. For me I will keep using Remember the Milk, the main reason is it displays on the main Gmail page so it’s easy for me to see.

Remember the Milk is a website for tasks and reminders, and has existed for quite a while now, but I didn’t bother signing up to it before. I didn’t really want to use another website for my task list. Only recently I discovered that there is a Widget for it to integrate with Gmail. So I installed it on my Gmail straight away.

Here is a screen shot of the Gmail Task.

google-task

and Remember the Milk Widget

remember-the-milk

I compared them on a few things

Login

Remember the Milk

Requires a seperate login since it’s a seperate website, it does however have the remember me option so you don’t have to login again. This I think works on a cookie bases so if you access your Gmail at different locations you will have to login again.

Gmail Tasks
Intergrated with Gmail, so no login required.

I like: Gmail, cause I don’t have to login

Adding a task

Remember the Milk

Click on the add tasks button at the bottom, and a textbox will appear to add a task, only task title can be added, other details will  have to be added in later.

Gmail Tasks
Type into the empty list and a text box will appear.
I like: Gmail, cause I don’t have to click on a extra button

Viewing Tasks

Remember the Milk

The widget gets added to the left hand side column, below your contact lists and labels, it does make the page a bit long so I close my contacts lists panel to get the page shorter.

Gmail Tasks

You will have to click on a Tasks menu item on the left hand side, it’s a link and took me a few seconds to find where it is after I first enabled Tasks

I like: Remember the Milk, the widget is always displayed, so it really does remind me of my tasks to do, since I am on Gmail most of the time. Gmail tasks on the other hand, you kind of have to remember you’ve got tasks to do, to click on the Tasks link and check it.

Task Details

Remember the Milk
There is a lot of details you can add for each task, task name, details, which day it is due, priority, time estimation.

Gmail Tasks
I can add a title, due date, and then the details

I like:Remember the Milk, even though I only use the title, it’s got heaps more options if I ever needed to expand on my tasks list, I can.

Extras

There is a few things only Remember the Milk has

  • Postpone a task, so you can do it the next day.
  • Tasks are displayed in categories on date.
  • Only show tasks with a due date or all tasks.

And there is a few thing that only Gmail Tasks has

  • Grag and drop to re-order tasks.
  • Tips section for newbies.
  • You can add multiple lists.

At the end I am still using Remember the Milk, the main reason was because for the Gmail Tasks, I had to click on a Tasks link and pop up a window, and I know I will forget to click that link within a few days, and completely forget about the Tasks feature.

Maybe I am just a bit lazy.

Social Media and ROI

Social media seems to be getting a lot of attention lately, and today I came across an article from Social Media Today on the measurement of ROI.

The article is http://www.socialmediatoday.com/SMC/57710

The article mentions how you would actually measure ROI based on various social networks like Linke-In, Twitter and others.

Create Public Accessible Function in JQuery Plug-in

Sometimes you need to access certain functions within a plug-in outside of the plugin. In my example, the JQuery Plug-in creates a list of items, and writes them out as li objects. But if the user selectes some other option in another drop down list, the items stored in the plug-in had to be cleared. This requires access to objects that were declared in the plug-in, as well as other setting variables.

To do this, here the plug-in name is listSelector, and in it is a public function called clearItems.

(function($) {
$.fn.listSelector= function(options) {

…..

$.fn.listSelector.clearItems=function(){

}

…..

declaring the function in the format of $.fn.pluginname.functionname=function(){} makes the function accessiable outside the plugin it self.

In the actual page where the plugin is created, you would have the following code to access the function.

$(“.list”).listSelector(options);

$(“.dropdown”).change($.fn.listSelector.clearItems());

On the change event of the drop down list with class of drop down, the function of the plug-in will be called.

To access public functions, in the plug-in it self, the same syntax will need to be followed. i.e $.fn.listSelector.clearItems()

This article here is a very good read at understanding the basics of creating a plug-in.