Thursday, December 30, 2004

Style Sheet Tweak Favelet

Style Sheet Tweak Favelet (JavaScript bookmark/favourite) is very useful for tweaking CSS on a page. The Favelet Suite is also very good (has list of favelets that can be run from host web site)

Saturday, December 25, 2004

Mozilla Update update

Mozilla Update has been updated. It looks a lot better than before and has new functionality. You can search and subscribe to an RSS feed to alert you of new/updated extensions.

Thursday, December 23, 2004

Bookmarklets for Firefox

Jesse Ruderman bookmarklets (SquareFree site author, does the Burning Edge the Firefox nightly build blog, user styles, JavaScript shell and JavaScript Environment)

Wednesday, December 22, 2004

Spread Firefox eCard Gallery

Send a Firefox/Thunderbird eCard using the Spread Firefox eCard Gallery.

Saving Session Variables

ASPAlliance Article: Session Variables - Saving with XML

Abstract
When developing web sites there are many times that session state has to be saved between pages. Here is a way to store all of your session variables in a single string and give access to all variables across all pages.

Cross Browser Modal Dialog Box

EggHeadCafe article: Cross Browser Modal Dialog Box. A model dialog box is one that maintains focus when you click on the window that opens it - i.e. you have to choose an option before you can continue using the site.

Tuesday, December 21, 2004

Image Manipulation: The GIMP 2.2 / Paint.NET 2.0

The GIMP 2.2 is now out. Download for Windows: http://gimp-win.sf.net/. The GIMP is a tool for working with and manipulating images and is open source. Not the most intuitive tool but very powerful, and is extended via plugins. Since the GIF patent expired you can generate GIF images (not available in version 2.0 and earlier). The file open/save dialog is a lot better in this version than the last version (2.0) and contains an image preview. Works on many platforms.

A good free tool for working with graphics. If you already have Photoshop or another professional package, then this may not offer any more over it. Help is a community project - not the same quality as what you may get with a commercial product, but covers the basics.

Total download size (with all optional components - help and animation): 20775kb (20.3MB) - GTK+ 2.4 runtime (3292kb), GIMP (7165kb), GIMP Help (9569kb), GIMP Animation Package (749kb)

Paint.NET 2.0 (developed by Washington State University with Microsoft mentorship) is also out. A Paintbrush replacement tool, requires .NET Framework and Windows XP. 7.71mb download (28.7mb with Framework).

Use Paint.NET for basic manipulation of bitmap images and GIMP for more complex work.

ASP.NET Smart Navigation

Smart Navigation (i.e. maintaining scroll position) only works in Internet Explorer. Luckily there is a way to get it to work in other browsers as well. Coding Horror: The Antidote to ASP.NET Smart Navigation, Part Deux

Web Developer Extension 0.9.1

The web developer extension for Firefox has been updated to version 0.9.1. It has a few bug fixes over 0.9.

Friday, December 17, 2004

Mastering ASP.NET Databinding

CodeProject Article: Mastering ASP.NET DataBinding

The goal of this tutorial is to shed light on some of the more common and frequently asked questions about the capabilities of databinding.

NVU Extension - htmlHeader Toolbar

First extension I have seen for NVU: htmlHeader Toolbar for N|Vu 0.6.

Thursday, December 16, 2004

SUM on bit columns (SQL)

When using SUM on a field ('bitcolumn') with the data type 'bit', you may not get the expected result - i.e. you would expect it to return the count of all the rows that have this field set to true (1).

SELECT SUM(bitcolumn)

However, it returns an error: The sum or average aggregate operation cannot take a bit data type as an argument.

You can however, use CAST to convert 'bit' to 'int', and perform SUM on the result.

SELECT SUM(CAST(bitcolumn As int))

This can however result in NULL returned as a value, when you want 0 instead. To always get a number as the result, you can also use COUNT combined with CAST and NULLIF. The key is that COUNT does not include any rows with NULL set on the field you are querying. CAST converts to 'int' and NULLIF converts the 0's to NULL's. COUNT therefor only includes the row count you want (where the field value is 1).

SELECT COUNT(CAST(NULLIF (bitcolumn, 0) AS int))

DataBinding Expressions in ASP.NET

OdeToCode article: Digging Into Data Binding Expressions. 'This article will demonstrate some techniques beyond simple DataBinder.Eval calls in ASP.NET data binding expressions.'. Includes usage of a method written in your code-behind, or casting (converting from one type to another, C# only).

Generic Url Creator

Generic Url Creator (GUC) is a Firefox extension that creates a URL from the text you select (i.e. use to lookup definitions, or perform a search). You can edit the list via the use of regular expressions.

Wednesday, December 15, 2004

Firefox Extension: Scrapbook

A useful Firefox extension that allows you to save web pages (or snippets from a web page). You can also search the snippets as well. ScrapBook Homepage. Good for when you find some code on a web site and want to quickly save it.

Firefox Theme Design

How to make a theme for Firefox. cheeaunblog - First steps in theme design. The author of this post created the Phoenity Theme.

Firefox v Internet Explorer

CNET has a feature where you can vote for which is the best browser: Sunday Smackdown: Mozilla Firefox 1.0 vs. Internet Explorer 6. Obviously you vote for Firefox (it already has 90% of the votes)

Tuesday, December 14, 2004

Tweaking Firefox

A guide to tweaking the various features in Firefox: Firefox Tweak Guide. Written before Firefox 1.0 came out, but still relevant.

Edit: Another way of speeding up Firefox would be to try one of Moox's custom builds. There is also a list of freeware on that site as well.

Future of CSS

Daniel Glazman (NVU developer) has written a post on what he thinks of the current state of CSS and what should happen in the future: Calling for a new CSS revolution. An interesting read.

What would the web be like now if Microsoft continued to work on Internet Explorer? I'm sure it would have been a lot better (less hacks for CSS in IE, better looking sites). Instead, Longhorn/Smart Clients is part of their future strategy and could go any way (new hardware and OS would be required, but you would be tied to Windows and would therefor be more expensive). Richer applications, but to the detriment of competition (i.e. Novell/IBM/Sun - who are investing in Linux and thin-clients) and the environment (old PC's going into landfills).

Monday, December 13, 2004

Dynamic Creation of Validation Controls (ASP.NET)

MSDN Article on creating validation controls dynamically via an XML file.

Useful Utilities - Zeraha.org

A few useful utilities from zeraha.org:

  • nPad - source viewer/editor with syntax highlighting
  • NetGraph - real-time network monitor
  • CodeBank - code snippet database with syntax highlighting
  • ImageScaler - quality image scaling/rotation
  • XMLPad - XML Editor
  • IconInjector - replace icon in exe/dll file (via command line)
  • MovieBank - movie database
  • MemBoost - defrag memory in Win 95/98
  • nSMS - send SMS via email (requires email-to-SMS gateway)

Friday, December 10, 2004

Google Suggest

Google has a beta feature that offers suggestions as you type: http://www.google.com/webhp?complete=1. Works the same way as typing a name into the To box when composing an email in GMail. What is good about it is that it does it so quickly (considering the amount of data they hold) and lists how many matches to each suggestion.

The good thing with Google is that new features they add are browser friendly (i.e. work in Firefox, Safari, Mozilla and Opera - so don't just test against Internet Explorer). It looks like they probably use web services extensively via JavaScript and XMLHttpRequest (Mozilla/Firefox/Opera/Safari) or Microsoft.XMLHTTP/Msxml2.XMLHTTP (Internet Explorer).

Thursday, December 09, 2004

Reusable Page Class Library (ASP.NET)

Code Project has a 4-part series on creating a web page class library that can be implemented in your web application:

Free eBook on SharpDevelop (.NET)

There is a free eBook (i.e. PDF document) available on SharpDevelop. While SharpDevelop does not do ASP.NET, it has a decent code editor with syntax highlighting and code-completion. So useful for building libraries (i.e. a data access layer or common function library) for use within a web application. It also does not have version control (had CVS support in the past, but that was dropped).

With enough demand (and hopefully more developers), SharpDevelop may get ASP.NET and source control in the future - which are essential if it really wants to compete with Visual Studio. At the moment the only decent tool for ASP.NET development is Visual Studio (which is sometimes out of people's budget, especially if they work for non-profit or budget sensitive organisations) - and that likes to reformat your code. Dreamweaver does ASP.NET - but no support for code-behind or code-completion (except for tags - even then, only the ones part of ASP.NET, not custom ones).

More information/download: Dissecting a C# Application: Inside SharpDevelop

Reporting websites that do not work in Firefox/Mozilla

There is a tool available for reporting sites that have issues with Firefox (and other Mozilla based browsers) - telling user to use Internet Explorer, blocking access, or with rendering/dhtml problems. There is a web-based form and an extension available to do this.

More information/screenshots: gemal.dk - New Reporter Tool.

Wednesday, December 08, 2004

Programmer's Fonts

A collection of fonts, that are useful when programming (i.e. readable, with l/I/1 and 0/O distinguishable). Sheldon and ProFont are good choices.

Edit (17 Dec 2004): ProgrammerFonts Wiki

Free .NET Charting Control (ASP.NET)

ASP.NET.4GuysFromRolla.com: A Look at WebCharts, a Free .NET Charting Control. Useful for generating web charts dynamically.

Monday, December 06, 2004

Tips and Tricks (SQL)

A few tips and tricks for SQL Server - via bersileus@SQLJunkies - Tips & Tricks.

  • Rounding by halves
  • Comma seperated list in WHERE clause
  • Simple paging
  • Case-sensitive comparison
  • Call stored procedure on other server

Sunday, December 05, 2004

Developing Validator Controls (ASP.NET)

MSDN Article - Developing a Validator Control. There are also alternatives to ASP.NET's built in validation controls that function the same but work in other browsers - DOM-Compliant Validator Controls (also available on Glavs Homepage at ASPAlliance.com) The site seems to have a CSS bug that makes it display incorrectly in Firefox/Mozilla. There is a feedback form for contacting the WebMaster (fix is to remove the height: 33px; line in the div.abstract class in the stylesheet aspalliance.css).

The validation controls in the next version of ASP.NET should work in browsers other than IE.

Friday, December 03, 2004

Multiple search terms (SQL)

When searching for data in a column, you may want to perform an OR AND or exact term on a user supplied string. When you use LIKE, the column needs to contain the whole text string, which is not always what you want. One way round this is to use a stored procedure as outline by Jeff Smith (Dr. Cross Join) a member of SQLTeam.com - Search Logic For Multiple Search Terms

NVU 0.6 (WYSIWYG html editor)

NVU 0.6, the free WYSIWYG html editor is now available for download. Still a long way to go before it is near Dreamweaver in terms of functionality. Has a few bugs as well (reformats code, does not work well with server side (ASP,PHP) code, adds DOCTYPE declaration (which you can't change) even when you don't want one (i.e. when editing an include file, or a template file used within a CMS), no XHTML support). Hopefully 1.0 will be a lot better (but will probably be a lot better by 2.0)

Site manager has improved, but could be better (i.e. context-menu, handling of other file types - cannot open ASP/ASP.NET files with it, no ability to add association (or use built in Windows associations). Perhaps it could be better if there were more working on the project (Daniel Glazman seems to be the only one (that I know of) actively working on it)?

XML Form Generator (ASP.NET)

This sample application creates an XML form that can create an XML file that contains data users entered into the form. It also has an example of how to display that data (via XSL)

Thursday, December 02, 2004

Web File Manager (ASP.NET)

The Code Project - Web File Manager - ASP.NET. By the same author who wrote User Friendly ASP.NET Exception Handling

A basic web based file manager that performs common functions on files/folders:

  • Copy/Move
  • Delete
  • Rename
  • Upload

Wednesday, December 01, 2004

Convert ArrayList to String (C#, VB.NET)

A function (with overloads, for char or string deliminator) for converting an ArrayList to a string (with defined deliminator). When calling with ArrayListToString(MyArrayList), default deliminator is ,.

C#

public string ArrayListToString(System.Collections.ArrayList ar)
{
 return ArrayListToString(ar, ',');
}
public string ArrayListToString(System.Collections.ArrayList ar, char delim)
{
 return ArrayListToString(ar, delim.ToString());
}
public string ArrayListToString(System.Collections.ArrayList ar, string delim)
{
 return string.Join(delim, (string []) ar.ToArray(typeof(string)));
}

VB.NET

Public Overloads Function ArrayListToString(ByVal ar As System.Collections.ArrayList) As String
 Return ArrayListToString(ar, ","C)
End Function

Public Overloads Function ArrayListToString(ByVal ar As System.Collections.ArrayList, ByVal delim As Char) As String
 Return ArrayListToString(ar, delim.ToString)
End Function

Public Overloads Function ArrayListToString(ByVal ar As System.Collections.ArrayList, ByVal delim As String) As String
 Return String.Join(delim, CType(ar.ToArray(GetType(String)), String()))
End Function

DetailsView control for ASP.NET 1.x, NAnt

The DetailsView control is a new control that will be in the next version of ASP.NET (Whidbey). This has been backported to ASP.NET 1.x as a custom control. NAnt is a tool for building .NET applications (get source, configure, compile, test, create documention and package for deployment). Building Web Applications with NAnt (ASP.NET)

Tuesday, November 30, 2004

Netscape to merge Firefox and IE

This sounds like it could be a very good browser. Could please both those that want ActiveX support and a standards compliant browser. Although these may be mutually exclusive (as the browser will give a choice between using Netscape rendering (Gecko) or Internet Explorer rendering (Trident)).

BetaNews Article | CNet News Article | MozillaZine News Article | Screenshots

Edit: IE rendering engine code name, MozillaZine articles

Monday, November 29, 2004

Basic Excel Spreadsheet Generation (ASP/ASP.NET)

The 'correct' way to generate Excel spreadsheets is through the use of Office Web Components. However, due to the licensing (see MSKB Article) you cannot use them on a public internet site (as a client license for Office is needed for each user retrieving the document).

However, this can be overcome due to the fact that Excel recognises HTML code. You can therefore output HTML that can be opened in Excel:

First of all, set the content type and response header to make the browser handle it as an Excel spreadsheet.

ASP VBScript:

<%@Language="VBScript"%>
<%
	Response.ContentType="application/vnd.ms-excel"
	Response.AddHeader "content-disposition", "attachment; filename=ExcelFileName"
%>

ASP JScript:

<%@Language="JScript"%>
<%
	Response.ContentType="application/vnd.ms-excel";
	Response.AddHeader("content-disposition", "attachment; filename=ExcelFileName");
%>

ASP.NET VB

<%@ Page Language="VB" %>
<script runat="server">
	Sub Page_Load (Sender As Object, E As EventArgs)
		Response.ContentType="application/vnd.ms-excel"
		Response.AddHeader("content-disposition", "attachment; filename=ExcelFileName")
	End Sub
</script>

ASP.NET C#

<%@ Page Language="C#" %>
<script runat="server">
	void Page_Load(Object Sender, EventArgs E)
	{
		Response.ContentType="application/vnd.ms-excel";
		Response.AddHeader("content-disposition", "attachment; filename=ExcelFileName");
	}
</script>

Start the html document and set the summary details (i.e. the information you see when you view the document properties: File - Properties in Excel). xmlns:o and xmlns:x are required for the summary information to be recognised by Excel. &#13;&#10; represents a line break (only valid in o:Description)

<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
<head>
<title>Title</title>
<!--[if gte mso 9]><xml>
 <o:DocumentProperties>
  <o:Subject>Subject</o:Subject>
  <o:Author>Author</o:Author>
  <o:Keywords>Keyword1, Keyword 2</o:Keywords>
  <o:Description>Comment Line 1&#13;&#10;Comment Line 2</o:Description>
  <o:Category>Category</o:Category>
  <o:Manager>Manager Name</o:Manager>
  <o:Company>Company Name</o:Company>
</o:DocumentProperties>
</xml><![endif]-->

You can also set the name of the worksheet (this code is also required if you want to see the grid lines in the sheet) and also protect the contents by setting x:ProtectContents to True (i.e. you will have to unprotect the sheet (Tools - Protection - Unprotect Sheet) before you can edit):

<!--[if gte mso 9]><xml>
 <x:ExcelWorkbook>
  <x:ExcelWorksheets>
   <x:ExcelWorksheet>
    <x:Name>Worksheet Name</x:Name>
    <x:WorksheetOptions>
     <x:ProtectContents>False</x:ProtectContents>
    </x:WorksheetOptions>
   </x:ExcelWorksheet>
  </x:ExcelWorksheets>
 </x:ExcelWorkbook>
</xml><![endif]--> 

Next add the CSS (this is important as you want line breaks to be part of the same cell, otherwise the text after the line break will go on a new row):

<style>
<!--
 br {mso-data-placement:same-cell;}
-->
</style>

Close the head tag and then output the table (static, or done dynamically using repeater (i.e. loop through recordset object in ASP, or bind to DataTable in ASP.NET)):

</head>
<body>
	<table border="1">
		<tr><th>Head 1</th><th>Head 2</th></tr>
		<tr><td>Data 1</td><td>Data 2</td></tr>
		<tr><td>Data 3<br>Should be<br>In same cell</td><td>Data 4</td></tr>
	</table>
</body>
</html>

Tuesday, November 23, 2004

Find As You Type in Firefox

Find As You Type is one of the most useful features of Firefox. This article: Get the Most Out of Firefox: Cut Through Pages With Find As You Type provides an example of how to use it. Very useful for pages with lots of text or links (like in the example shown).

User Agent Switcher Extension

The User Agent Switcher extension for Firefox has been updated. This is useful on some sites which check to see if you are using Internet Explorer, and if not, block you from using the site. You then use this to make the site think you are using IE and thus give you access.

Web Developer Extension

A new version of the Web Developer Extension for Firefox is available for download. Lots of new features in this version.

Thursday, November 18, 2004

Portable Firefox / Thunderbird

There are portable versions (unofficial packages) of the Firefox browser and Thunderbird email client available. Useful for running your favourite browser/email client on a removable drive (like a USB pen drive). I wonder if there will be official versions (i.e. released by Mozilla) in the future, rather than by a third party (which may not be updated in the future, but probably will)?

Sunday, November 14, 2004

British Firefox, Extensions Mirror

There is a download for Firefox for those users in the UK (rather than the default US English Version). It can be downloaded from: http://download.mozilla.org/?product=firefox&os=win&lang=en-GB. Found via: http://www.mozilla.org/products/firefox/all.html. You can also set your homepage to Google UK, with Firefox branding: http://www.google.co.uk/firefox?client=firefox-a&rls=org.mozilla:en-GB:official

As well as the official extensions site (https://update.mozilla.org/extensions/?application=firefox), there is also a site with many more extensions listed and available for download: http://www.extensionsmirror.nl/index.php?showforum=2

You will have to add www.extensionsmirror.nl to the list of sites that are allowed to install software. To do so, find an extension you want (i.e. ConQuery), click Install then click Edit Options in the notification bar and then click Allow, OK. Click Install again and the extension will install. You will not have to do this for any additional extensions on the site. As always, exit (via File - Exit, not the cross in the top right) then reopen the browser to use the extension.

Tuesday, November 09, 2004

Firefox 1.0

Firefox 1.0 is finally out. Is this the start of the new web, will it take 10% market share and will Microsoft take notice and update Internet Explorer (not just for Longhorn)? Only time will tell.

Monday, November 08, 2004

DHTML Calendar, WYSIWYG Editing in your Web Browser

A very useful DHTML calendar that can be in a popup window or appear near a button/link that you click. Appearance can be changed via CSS, and you can even navigate the calendar using the keyboard.

HTMLArea is also a very good tool as it allows you to do rich text editing within the browser (Internet Explorer and Firefox/Mozilla Browser). It relies on the browsers built in capabilities. There is also a plugin that generates standards compliant XHTML/CSS called XStandard. It generates compliant, accessible code without resorting to heavy use of JavaScript to clean up the code generated by Internet Explorer's built in editor (which is what HTMLArea is based on for IE).

Wednesday, November 03, 2004

Set Form Enctype (ASP.NET)

This UserControl sets the EncType of the server side form on an ASP.NET page. Useful if you have another UserControl that uploads a file, as it prevents the need to change the parent page EncType (to "multipart/form-data").

Code:

<%@ Control Language="C#" %>
<script runat="server">
public string EncType = "";

void Page_Load(object sender, EventArgs e)
{
	SetEncType(EncType);
}

protected void SetEncType(string EncType)
{
	// continue if enctype is valid
	if(EncType=="text/plain" || EncType=="multipart/form-data" || EncType=="application/x-www-form-urlencoded") {
		Control container = this.Parent;
		while( container.GetType() != typeof(UserControl) && container.GetType() != typeof(HtmlForm) && container.GetType() != typeof(Page) ) {
			container = container.Parent;
		}
		HtmlForm form = container as HtmlForm;
		if ( form != null) {
			form.Enctype = EncType;
		}
	}
}
</script>

Example use:

Register tag: <%@ Register TagPrefix="Form" TagName="EncType" Src="formenc.ascx" %>. Add at start of UserControl page: <Form:EncType EncType="multipart/form-data" runat="server" />

Monday, November 01, 2004

A9 Toolbar

You can now search A9.com using the A9 Toolbar for Firefox. Quite a good search engine (searches books and images as well as web pages). If registered with Amazon.com (or co.uk and I assume other country specific Amazon sites) you get advanced features (bookmarks, diary, search history).

Friday, October 29, 2004

ASP VBScript Business Object (MyGeneration)

New template for MyGeneration that generates a vbscript class that allows you to connect to an ADODB database
v 1.0 read only, can supply SQL select statement (if not supplied, selects all rows)
i.e.

Public tb
Set tb = new MyTable
Response.Write("<ul>")
Do 
	Response.Write("<li>" & tb.MyColumn & "</li>")
Loop While tb.MoveNext
Response.Write("</ul>")
Set tb = Nothing

Also my 100th post. First one was July 25th 2003, First Weblog - Toolbars

Tuesday, October 26, 2004

ASP.NET SQL Server DataGrid (MyGeneration)

Created a new template for MyGeneration that creates a page with a DataGrid. The DataGrid source is a SQL Server database. Get it from: ASP.NET SQL Server DataGrid

Sunday, October 24, 2004

Countdown (JavaScript)

This script counts down from a specified number of minutes.

<html>
<head>
<title>Countdown</title>
<script type="text/javascript">
// how many minutes
var mins = 30;

// how many seconds (don't change this)
var secs = mins * 60;
function countdown() {
	setTimeout('Decrement()',1000);
}
function Decrement() {
	if (document.getElementById) {
		minutes = document.getElementById("minutes");
		seconds = document.getElementById("seconds");
		// if less than a minute remaining
		if (seconds < 59) {
			seconds.value = secs;
		} else {
			minutes.value = getminutes();
			seconds.value = getseconds();
		}
		secs--;
		setTimeout('Decrement()',1000);
	}
}
function getminutes() {
	// minutes is seconds divided by 60, rounded down
	mins = Math.floor(secs / 60);
	return mins;
}
function getseconds() {
	// take mins remaining (as seconds) away from total seconds remaining
	return secs-Math.round(mins *60);
}
</script>
</head>
<body onload="countdown();">
	Countdown: <input id="minutes" type="text" style="width: 22px;"> minutes <input id="seconds" type="text" style="width: 22px"> seconds remaining.
</body>
</html>

Thursday, October 21, 2004

Client Side Validation in ASP.NET 2.0

Looks like the next version of ASP.NET (Whidbey) will be able to do Client Side Validation for browsers other that Internet Explorer. It shows that when making suggestions on the beta of the next version of Visual Studio, they are taken seriously. Looks like the next version of .NET will be very good for web developers. XHTML output and validation that works client side with multiple web browsers. There will also be an asp:Menu control (i.e. drop down menus (File, Edit, View, Help etc) much like those in many Windows apps) that works for other browsers as well.

Tuesday, October 19, 2004

fireFTP - FTP in Firefox

Firefox now has an extension that is a basic FTP client, known as fireFTP. So you can use Firefox for your web and FTP needs. Use with MozEdit and the Web Developer Toolbar and you can work on and upload web pages without leaving Firefox.

Edit: MozEdit and Web Developer Toolbar.

Monday, October 18, 2004

S5: A Simple Standards-Based Slide Show System (HTML/CSS/JavaScript)

S5: A Simple Standards-Based Slide Show System. This is a way of doing a slideshow using just one page and accessible (and easy to understand) markup. Can be navigated via keyboard or mouse, printer friendly (printed page can have extra information on it), and degrades gracefully for older browsers.

Defending the Fox

Defending the Fox (a site that lists sites that don't support Firefox) now is at version 2 and has a new Url: http://www.defendingthefox.com/. Not many links on at the moment, and a few pages are still under construction (Web Standards, HTML Guide, CSS Guide, Forums). Colour scheme could be improved though, as well as the submitted sites page (which does not have page navigation or search). Has potential though.

Friday, October 15, 2004

Fade in/out transition (JavaScript/HTML/CSS)

Internet Explorer has a DirectX filter that enables you to do a fading transition on images (opaque to transparent or vice-versa), known as BlendTrans. However, filters are Windows IE only features. There is a workaround though, that enables you to do the same using JavaScript, and it is outlined here: Cross-browser BlendTrans Filter JavaScript

Thursday, October 14, 2004

Google Desktop Search

Google Desktop Search is a new tool that allows you to search email (Outlook, Outlook Express), AOL Instant Messenger, Internet Explorer history (unfortunately not Firefox, but they may add it as it is mentioned in their help center) and documents on your computer (Text, Word, Excel, PowerPoint). Interesting how they can do that using just a 400k download. You can still search documents using Firefox though.

Hope they add support for different products in the future (Firefox for web pages, Thunderbird for Email).

If Microsoft did a tool as well, I wonder if search would just be limited to Microsoft products (while everyone else searches Microsoft and non-Microsoft software/documents)? If so, they may not dominate desktop search.

Tuesday, October 12, 2004

Around the World in Seven Days

Around the World in Seven Days - the 3rd Firefox browser campaign, for spreading Firefox. They want 1,000 Firefox related photos (something you have done to help spread the word - i.e. handing out flyers, distributing CD's, car stickers, posters etc) submitted after 7 days. Check out the Mozilla store for Mozilla/Firefox related things (T-Shirts, CD's, stickers)

Update: Photo's needed are not computer related (you or someone you know at a desktop/laptop PC) - they are ways of spreading Firefox, in the Office, street, College etc.

Friday, October 08, 2004

Code Project Articles (ASP.NET)

ASP.NET currently does not output valid XHTML (ASP.NET 2.0/Whidbey will though). But there is a C# class (via The Code Project site) that can be used which outputs valid XHTML. It intercepts the code before it is sent to the client - so you may get a performance hit (which will probably only be a problem if you get lots of visitors to the page)

There is another article on The Code Project, User Friendly ASP.NET Exception Handling that improves on the default unhandled exception handler in several ways. It enables you to email exceptions to the site administrators, log to a file, log to the event log or display to the end user (with the same colour scheme as the default one, but it provides more information).

Firefox Extensions for Web Developers

One of the best features of Firefox is that it can easily be improved by using extensions. Talked about it before in February - Firefox Extensions (for Firefox 0.8). No developer extensions (that I can find) since then (new features added to existing ones, updated due to version changes, added to Mozilla Update), but that may simply be because the current ones do what most developers want. Here are the useful ones to web developers:

  • Web Developer Extension, by Chris Pederick, the best one so far
  • IE View - for those rare times when you need to open a page in Internet Explorer, or for testing purposes
  • LiveHTTPHeaders - for viewing HTTP Headers you send/receive to/from websites
  • EditCSS - editing CSS live on a website in your side bar (you can do this with the Web Developer Extension as well).
  • User Agent Switcher, also by Chris Pederick. To make some sites think you are using a different browser.
  • JavaScript Debugger, AKA Venkman - for debugging JavaScript errors.
  • Web Panel Enhancer - allows you to do various things in the sidebar, like open link, current page, or show source code

There is also a tutorial available on creating extensions for Firefox.

Sunday, October 03, 2004

Ben Goodger, Firefox Developer Interview

Neowin has done an interview with Ben Goodger, concerning Firefox 1.0PR and the future. Perhaps Firefox will take a chunk out of IE's market share (even if it is only 1%/2%)?

Wednesday, September 29, 2004

ASP.NET.4GuysFromRolla.com: Dynamic Web Controls, Postbacks, and View State

Useful article on how to handle controls that are dynamically added to ASP.NET pages: ASP.NET.4GuysFromRolla.com: Dynamic Web Controls, Postbacks, and View State

Tuesday, September 28, 2004

Defending The Fox / Spread Firefox

Defending The Fox is a site that lists websites that do not support Firefox (those that suggest users to 'upgrade' to IE 5 or later. This was found on the Spread Firefox site (a site to get people to move to the Firefox browser). They succesfully achieved 2 million downloads in 10 days (very good considering the target was 1 million). Now they want 10,000 new users in 10 days.

Friday, September 24, 2004

.NET Command Prompt

This batch file allows you to do various .NET related tasks. This is useful when running under a limited user account. To do the advanced tasks you need to know the local machine administrator password. Features include:

  • Goto .NET SDK, .NET bin folder
  • Show .NET help file
  • Start Web Browser
  • Administrate folders (i.e. set permissions)
  • Administrate the computer
  • List .NET related files

DotNetCommand.cmd

@echo off
rem .NET SDK bin directory
set NetSDKBin=%NetSamplePath%bin
rem .NET bin directory
set DotNetBin=%windir%\Microsoft.NET\Framework\v1.1.4322
set PATH=%DotNetBin%;%NetSDKBin%;%PATH%
color 1f
rem goto directory as supplied (i.e. via dragging onto batch file)
cd %1
rem register doskey
doskey /insert
rem go to .NET SDK bin directory
doskey sdkdir=cd "%%NetSamplePath%%"
rem go to .NET bin directory
doskey netbin=cd "%%DotNetBin%%"
rem start Web Browser, homepage set to Google
doskey webbrowser=start http://www.google.com
rem .NET help file
doskey dotnethelp="%%ProgramFiles%%\Common Files\Microsoft Shared\Help\dexplore.exe" /helpcol ms-help://ms.netframeworksdkv1.1
rem open Windows Explorer as admin
doskey adminc=runas /u:Administrator /env "%%ProgramFiles%%\Internet Explorer\iexplore.exe c:\\"
rem open Computer Management as admin
doskey compman=runas /u:Administrator "mmc %%windir%%\system32\compmgmt.msc"
rem list c# files
doskey listcs=dir *.cs /q /p
rem list vb files
doskey listvb=dir *.vb /q /p
rem list web files
doskey listweb=dir *.as*x /q /p
rem list assembly files (dll)
doskey listdll=dir *.dll /q /p
cls
echo To goto .NET SDK directory, type: sdkdir
echo ----------------------------------------
echo To goto .NET bin directory, type: netbin
echo ----------------------------------------
echo To start Default Web Browser, type: webbrowser
echo ----------------------------------------------
echo To show .NET help file, type: dotnethelp
echo ----------------------------------------
echo To administrate folders (i.e. set permissions), type: adminc
echo  (type Control Panel in the Address bar to open the Control Panel)
echo -------------------------------------------------------------------
echo To administrate the computer, type: compman
echo -------------------------------------------
echo You can also list files and their owner
echo  (listcs, listvb, listweb, listdll)
echo ---------------------------------------
cmd.exe /e:on /f:on /k Title .NET 1.1 Command Prompt

Edit: Added ability to list .NET related files

Client-Side Validation (ASP.NET)

There is a way of getting ASP.NET to output JavaScript that works in other browsers, and it is detailed in this 4Guys article: Client-Side Validation in Downlevel Browsers. Also vote for the following bug at MSDN Labs so ASP.NET 2.0 outputs cross-browser JavaScript: Client Side Validation.

Wednesday, September 22, 2004

Entity Spaces (.NET)

Entity Spaces will become the successor to dOOdads. These are (will be in the case of Entity Spaces) .NET architectures and provide a data access layer to allow developers to interact (add, update, delete records) with any database system (Access, SQL Server, Oracle, Firebird) without needing to code for the underlying database (i.e. SQL Parameters). With these you can change your database backend without needing to change all your code (except the data access classes, which can be generated via a simply UI).

Follow the progress in Mike Griffin's Blog.

Edit (27 Sep 04): blog link update

Url Manipulation v2 (C#)

Made some improvements to the previous UrlQuery class (July 22nd, 2004). It now has a shorter way of assigning QueryString parameters:

MyQuery = new UrlQuery();
// add another parameter (or replace existing one)
MyQuery["myparam"] = "myval";
Trace.Write(MyQuery["myparam"]); // returns 'myval'
// remove parameter
MyQuery["myparam"] = null; // or string.Empty
Trace.Write(MyQuery["myparam"]); // returns ''

UrlQuery class code:

public class UrlQuery
{
	/// <summary>
	/// Base on current page
	/// </summary>
	public UrlQuery()
	{
		this.url = HttpContext.Current.Request.Url.AbsolutePath;
	}
	/// <summary>
	/// Base on other page
	/// </summary>
	/// <param name="value">The url of the page to reference, i.e.: '/path/to/folder/page.aspx?param1=1&param2=2'</param>
	public UrlQuery(string value)
	{
		int q = value.IndexOf('?');
		if (q != -1)
		{
			this.url = value.Substring(0, q);
			this.queryString = NameValueCollection(value);
		}
		else
		{
			this.url = value;
		}
	}
	/// <summary>
	/// Get and set Url parameters
	/// </summary>
	public string this[string param]
	{
		get
		{
			return this.Get(param);
		}
		set
		{
			this.Set(param,value);
		}
	}

	private string url;
	/// <summary>
	/// The Url of the page, without QueryString
	/// </summary>
	/// <value>/path/to/folder/page.aspx</value>
	public string Url
	{
		get
		{
			return this.url;
		}
	}
	/// <summary>
	/// Returns the virtual folder the page is in
	/// </summary>
	/// <value>/path/to/folder/</value>
	public string VirtualFolder
	{
		get
		{
			return this.Url.Substring(0, Url.LastIndexOf("/") + 1);
		}
	}
	/// <summary>
	/// The AbsoluteUri
	/// </summary>
	/// <value>page.aspx?param1=1&param2=2</value>
	public string AbsoluteUri
	{
		get
		{
			return this.Url + this.Get();
		}
	}
	private NameValueCollection queryString;
	/// <summary>
	/// Get the QueryString for the page
	/// </summary>
	public NameValueCollection QueryString
	{
		get
		{
			if (this.queryString != null)
			{
				return this.queryString;
			}
			else
			{
				this.queryString = new NameValueCollection(HttpContext.Current.Request.QueryString);
				return this.queryString;
			}
		}
	}
	/// <summary>
	/// Get the QueryString
	/// </summary>
	/// <returns>String in the format ?param1=1&param2=2</returns>
	public string Get()
	{
		string query = "";
		if (this.QueryString.Count != 0)
		{
			query = "?";
			for (int i = 0; i <= this.QueryString.Count - 1; i++)
			{
				if (i != 0)
				{
					query += "&";
				}
				query += this.QueryString.GetKey(i) + "=" + this.QueryString.Get(i);
			}
		}
		return query;
	}
	/// <summary>
	/// Get parameter from QueryString
	/// </summary>
	/// <param name="param">Parameter to get</param>
	/// <returns>Parameter Value</returns>
	public string Get(string param)
	{
		return this.QueryString[param];
	}
	/// <summary>
	/// Set QueryString parameter
	/// </summary>
	/// <param name="param">Parameter to set</param>
	/// <param name="value">Value of parameter</param>
	public void Set(string param, string value)
	{
		if (param != string.Empty)
		{
			if (value == string.Empty || value == null)
			{
				this.QueryString.Remove(param);
			}
			else
			{
				this.QueryString[param] = value;
			}
		}
	}
	/// <summary>
	/// Convert QueryString string to NameValueCollection
	/// http://groups.google.co.uk/groups?hl=en&lr=&ie=UTF-8&safe=off&selm=uyMZ2oaZDHA.652%40tk2msftngp13.phx.gbl
	/// </summary>
	public static NameValueCollection NameValueCollection(string qs)
	{
		NameValueCollection nvc = new NameValueCollection();
		//strip string data before the question mark
		qs = qs.IndexOf('?') > 0 ? qs.Remove(0, qs.IndexOf('?') + 1) : qs;
		Array sqarr = qs.Split("&".ToCharArray());
		for (int i = 0; i < sqarr.Length; i++)
		{
			string[] pairs = sqarr.GetValue(i).ToString().Split("=".ToCharArray());
			nvc.Add(pairs[0], pairs[1]);
		}
		return nvc;
	}
	/// <summary>
	/// Copies a form paramater to the QueryString
	/// </summary>
	/// <param name="param">Form Parameter</param>
	public void FormToQuery(string param)
	{

		this.Set(param, HttpContext.Current.Request.Form[param]);
	}
}

Tuesday, September 21, 2004

Get Firefox

Best web browser at the moment.

Get Firefox!

Tuesday, September 14, 2004

SharpDevelop 1.0 (.NET)

SharpDevelop version 1.0 is now finally out. While it doesn't do ASP.NET, it is useful for compiling .NET libraries (i.e. dll files, can be used for both Windows and Web Forms).

Wednesday, September 08, 2004

Building Web Applications with NAnt (ASP.NET)

NAnt allows you to build web applications from solution files when you do not have Visual Studio installed (or even when you do). To do so you need to install NAnt into a new directory (e.g. C:\NAnt\). After doing this add C:\NAnt\bin\ to your PATH (via System Properties, Advanced, Environment Variables, System Variables). Also add the path to the vbc/csc compilers (if not already there - C:\WINNT\Microsoft.NET\Framework\v1.1.4322\;C:\NAnt\bin\). To then compile the solution, add WebProjectName.build to the same folder as the solution (i.e. C:\Inetpub\wwwroot\WebProjectName\) and add the following to it:

<project name="WebProjectName">
	<property name="nant.settings.currentframework" value="net-1.1"/>
	<property name="Host" value="http://localhost" />
	<property name="Path" value="c:\inetpub\wwwroot" />
	<property name="WebProjectName.Host" value="${Host}/WebProjectName/WebProjectName.vbproj" />
	<property name="WebProjectName.Path" value="${Path}\WebProjectName\WebProjectName.vbproj" />
	<solution solutionfile="WebProjectName.sln" configuration="Release" >
		<webmap>
			<map url="${WebProjectName.Host}" path="${WebProjectName.Path}" />
		</webmap>
	</solution>
</project>

After saving the file, navigate to the folder using the command prompt
Start
Run
cmd
cd C:\Inetpub\wwwroot\WebProjectName\
nant.

To make things easier, you can add a Command Prompt Here (instructions, alternative download) shortcut to Windows Explorer.

Monday, September 06, 2004

Internet Explorer Hacks (CSS)

The following shows how you can hide/show CSS for certain versions of Internet Explorer (works when page is in standards mode - i.e. DOCTYPE at top of page):

mytag {
	/* all browsers */
	property: value;
	/* IE only browsers */
	_property: value;
	/* ignored by IE 5, works in IE 5.5/6 */
	property /**/: value;
	/* ignored by IE 5.5, works in IE 5/6 */
	property/**/: value;
	/* ignored by IE 6, works in IE 5/5.5 */
	property: /**/value;
	/* all browsers */
	property2: value;
	/* voice-family hack - any code after 'voice-family' not recognised by IE5/5.5 */
	voice-family: "\"}\"";
	voice-family: inherit;
	property2: newvalue;
}

CSS Filters also lists many filters for delivering certain CSS to different browsers.

Edit: CSS Filters link, more IE filtering methods - so you can serve different CSS to IE 5 / 5.5 and 6

Thursday, September 02, 2004

Generate SQL Server Views (MyGeneration) pt2

Added another template that generates a related table view (i.e. via INNER JOIN statement). Select primary/foreign table and which columns are to be in the view. Same link as before - Generate SQL Server Views.

Wednesday, September 01, 2004

Generate SQL Server Views (MyGeneration)

Added a new MyGeneration template archive that contains a template that generates views from your tables (SQL Server) - Generate SQL Server Views.

Returns NULL's if blank string and column allows NULL's. Also breaks down dates into component parts (i.e. Month, Day, Year) and to other formats:

  • Short Date (mon dd yyyy)
  • Short Time (hh:mm)
  • US Date (mm/dd/yyyy)
  • ANSII Date (yyyy.mm.dd)
  • UK Date (dd/mm/yyyy)
  • German Date (dd.mm.yyyy)
  • Italian Date (dd-mm-yyyy)

Example Output:

USE [news]
GO

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
         WHERE TABLE_NAME = 'vw_News')
   DROP VIEW vw_News
GO

CREATE VIEW [vw_News]
AS
SELECT
		[ID] AS [NewsID],
		NULLIF ([Title], '') AS [News Title],
		NULLIF ([Url], '') AS [News Url],
		[Added] AS [Date Added],
		CONVERT ( char(11) , [Added] , 113) AS [Date Added_ShortDate],
		CONVERT ( char(5) , [Added] , 108) AS [Date Added_ShortTime],
		CONVERT ( char(10) , [Added] , 101) AS [Date Added_USDate],
		CONVERT ( char(10) , [Added] , 102) AS [Date Added_ANSIIDate],
		CONVERT ( char(10) , [Added] , 103) AS [Date Added_UKDate],
		CONVERT ( char(10) , [Added] , 104) AS [Date Added_GermanDate],
		CONVERT ( char(10) , [Added] , 105) AS [Date Added_ItalianDate],
		{ fn DAYNAME ([Added])  } AS [Date Added_DayName],
		DAY ( [Added] ) AS [Date Added_Day],
		{ fn MONTHNAME ([Added])  } AS [Date Added_MonthName],
		MONTH ( [Added] ) AS [Date Added_Month],
		YEAR ( [Added] ) AS [Date Added_Year]
FROM [news]
GO
PRINT 'View Creation: vw_News Succeeded'
GO

Thursday, August 26, 2004

Replace content in database table (SQL)

You may have rows in your database that contains <br>, which you want to replace with line breaks (this may be the case if you are using Server.HtmlEncode to encode your output, which you didn't previously do). This can simply be done using the replace function (note the line break):

UPDATE [table]
SET
  [column]= REPLACE([column], '<br>', '
')
WHERE
  [column] LIKE '%<br>%'
Also, if you wish to convert < and > to their html encoded equivalents:
UPDATE [table]
SET
  [column]= REPLACE([column], '<', '&lt;')
WHERE
  [column] LIKE '%<%'
UPDATE [table]
SET
  [column]= REPLACE([column], '>', '&gt;')
WHERE
  [column] LIKE '%>%'
Or to do the reverse:
UPDATE [table]
SET
  [column]= REPLACE([column], '&lt;', '<')
WHERE
  [column] LIKE '%&lt;%'
UPDATE [table]
SET
  [column]= REPLACE([column], '&gt;', '>')
WHERE
  [column] LIKE '%&gt;%'
Tested this in the Query Analyzer so not sure if it would work on web pages. To make sure nothing goes wrong (unlikely though), backup your data first.

Friday, August 13, 2004

Popup Window Countdown (JavaScript)

This code opens a new popup window that contains a timer that counts down, then closes the window when it reaches 0. Will not work if user has a popup blocker blocking the page.

<html>
<head>
<title>Popup Timer</title>
<script language="JavaScript" type="text/JavaScript">

// popup window var
var popup;

// At what number shall the countdown counter start?
CounterStart = 10;
 
// This function CustomAction() can be modified to do 
// whatever you want done every second.
 
function CustomAction() {
	popup.document.timer.timeleft.value = CounterStart;
} // end of function CustomAction()

// end of JavaScript customization


function Decrement() {
	CounterStart--;
	CustomAction();
	if(CounterStart <= 0) { popup.close(); alert('Timer reached 0'); }
	else { setTimeout('Decrement()',1000); }
}
 
function StartTheCounter() {
	openPopup(120,100);
	setTimeout('Decrement()',1000);
}

function openPopup(w,h){
	// new window title
	var contents = '<html><head><title>Counter Window<\/title>';
	// resize window once image has loaded
	contents += '<script type="text\/javascript">window.onload = init;';
	// centre the popup window
	contents += 'function init() {window.moveTo((screen.width-'+w+')/2,(screen.height-'+h+')/2)}';
	contents += '<\/script>';
	contents += '<\/head><body>';
	contents += '<form name="timer">'
	contents += '<input name="timeleft" type="text" size="4" readonly="" value="'+CounterStart+'" /> seconds!';
	contents += '</form>';
	contents += '<\/body><\/html>';
	// open popup window
	popup = window.open('about:blank','popup','location=no,menubar=no,scrollbars=no,status=no,toolbar=no,width='+w+',height='+h);
	popup.document.open();
	popup.document.write(contents);
	popup.document.close();
}
// -->
</script>
</head>
<body onload="StartTheCounter();">
Popup Window Timer
</body>
</html>

Wednesday, August 11, 2004

Prevent User Control Code from running (ASP.NET)

You can prevent code within a user control (ascx file) from running if it is invisible on the containing page. To do so, just check base.Visible (C#) or MyBase.Visible (VB). For example:

C#

private void Page_Load(object sender, EventArgs e)
{
	if (base.Visible) {
		// run code
	}
}

VB

Private Sub Page_Load(sender As Object, e As EventArgs)
	If MyBase.Visible Then
		' run code
	End If
End Sub

Tuesday, August 10, 2004

Recursive File List Control (ASP.NET)

This control lists files and folders within a given directory. It shows only the root directories and files, but if you click a folder in the list, your get the sub folders and files.

Control code (filelist.ascx)

<%@ Control Language="C#" %>
<%@ Import Namespace="System.Collections" %>
<script runat="server">

private void Page_Load(object sender, EventArgs e)
{
	// add file types
	fileTypes.Add("doc");
	fileTypes.Add("rtf");
	fileTypes.Add("xls");
	fileTypes.Add("pdf");
	walkFolders(VirtualFolder);
	lnkReset.NavigateUrl = Url;
}
public string VirtualFolder = "/";
private ArrayList fileTypes = new ArrayList();
private ArrayList folders;
private ArrayList Folders {
	get {
		if (folders==null) {
			if (PathInfo!=null) {
				folders = new ArrayList(PathInfo.Split(';'));
			} else {
				folders = new ArrayList();
			}
		}
		return folders;
	}
	set {
		folders = value;
	}
}
private string Url {
	get {
		return HttpContext.Current.Request.Path;
	}
}

private string PathInfo
{
	get {
		return HttpContext.Current.Request.QueryString["show"];
	}
}
private string BuildQuery
{
	get {
		string strList = string.Empty;
		for(int i=0; i<Folders.Count; i++)
		{
			strList += Server.UrlEncode(Folders[i].ToString()) + ";";
		}
		if (strList!=string.Empty) {
			strList = "?show=" + strList.Substring(0, strList.LastIndexOf(';'));
		}
		return strList;
	}
}
private bool InQuery(string s)
{
	for(int i=0; i<Folders.Count; i++)
	{
		if(Folders[i].ToString() == s) {
			return true;
		}
	}
	return false;
}
private bool AllowedFileType(string fileExt)
{
	for(int i=0; i<fileTypes.Count; i++)
	{
		if(fileTypes[i].ToString() == fileExt.ToLower()) {
			return true;
		}
	}
	return false;
}
// based on code from http://groups.google.com/groups?selm=uUvzKryuDHA.540%40tk2msftngp13.phx.gbl&rnum=3
private void walkFolders(string rootPath)
{
	// Open the list
	FileList.Text += "<ul>";
	string mappedRoot = Server.MapPath(rootPath);
	try {
		// Iterate through each folder
		foreach (string folder in System.IO.Directory.GetDirectories(mappedRoot))
		{
			string virtfolder = folder.Replace(mappedRoot, string.Empty);
			string subFolder = rootPath + virtfolder + "/";
			string strList = string.Empty;
			if (InQuery(subFolder)) {
				Folders.Remove(subFolder);
				strList = BuildQuery;
				Folders.Add(subFolder);
			} else {
				Folders.Add(subFolder);
				strList = BuildQuery;
				Folders.Remove(subFolder);
			}
			string b = "<li> Folder: <a href=\"" + Url + strList + "\">" + Server.HtmlEncode(virtfolder) + "</a>";
			FileList.Text += b;
			if (InQuery(subFolder)) {
				// Walk through this folder
				FileList.Text += Environment.NewLine;
				walkFolders(subFolder);
			}
			FileList.Text += "</li>" + Environment.NewLine;
		}	
	} catch (System.Exception ex) {
		Trace.Write(ex.Source + " : " + ex.HelpLink + " : " + ex.Message);
	}
	try {
		// Iterate through the files in this folder
		foreach (string file in System.IO.Directory.GetFiles(mappedRoot))
		{
			string fileName = file.Replace(mappedRoot, string.Empty);
			if (!AllowedFileType(getExt(fileName))) continue;
			// Remove path and prefix with LI
			string b = "<li> File: " + "<a href=\"" + rootPath + fileName + "\">" + Server.HtmlEncode(removeExt(fileName)) + "</a></li>";
			// Put the fileName in the textbox
			FileList.Text += b + Environment.NewLine;
		}
	} catch (System.Exception ex) {
		Trace.Write(ex.Source + " : " + ex.HelpLink + " : " + ex.Message);
	}
	// Close the list
	FileList.Text += "</ul>" + Environment.NewLine;
}

private string removeExt(string fileName)
{
	return fileName.Substring(0,fileName.LastIndexOf('.'));
}

private string getExt(string fileName)
{
	int dot = fileName.LastIndexOf('.') + 1;
	return fileName.Substring(dot, fileName.Length - dot);
}
</script>
<asp:HyperLink id="lnkReset" runat="server" Text="Reset List" />
<asp:Literal EnableViewState="False" runat="server" id="FileList" />

Page code (filelist.aspx)

<%@ Page Language="C#" Trace="False" ContentType="text/html" ResponseEncoding="iso-8859-1" %>
<%@ Register TagPrefix="Files" TagName="List" Src="filelist.ascx" %>
<html>
<head>
<title>File listing</title>
</head>
<body>
<form runat="server">
	<Files:List runat="server" VirtualFolder="/virtualdir/" />
</form>
</body>
</html>

Wednesday, August 04, 2004

Internet Explorer Toolbar Fix

When Internet Explorer has several toolbars installed, the context menu items do not reflect the correct toolbar - i.e. Google and Yahoo toolbars are both showing and you wish to hide the Google one. So you click 'Google' in the menu - but the Yahoo one disappears instead. This bug has been around for a long time. However, it can be fixed by tweaking the registry (found at http://www.mvps.org/winhelp2002/ietips.htm#Odd). Here is the fix (create blank text file called ResetBrowserToolbar.reg, and then double-click the newly created file)

REGEDIT4

[HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar\WebBrowser]
"ITBarLayout"=-

Friday, July 30, 2004

Styling forms (CSS)

A good article on styling forms using CSS can be found at aplus. A pity that not all browsers are not as good at CSS as they could be, if they were you could design forms without using tables.

ASP.NET Custom Controls

Excentrics World has a lot of free .NET Custom Controls for use on your ASP.NET pages. They are as follows:

  • Accordion Panel
  • Bread Crumb Trail
  • Calendar Popup
  • Collapsable Panel
  • Empty DataGrid
  • Faq Repeater
  • Masked Textbox
  • Multi-Text List Controls
  • Numeric Box
  • Ordered Listbox
  • Time Picker

The source code is available for purchase (as download does not contain it).

Developing ASP.NET Server Controls on MSDN is a good article on creating custom controls.

The Regulator (Regular Expression Tool)

The Regulator is a tool for regular expressions. It integrates with RegExLib.com (regular expression library), by offering the ability to search it and submit your own regular expressions. You can also compile it to a .NET assembly or generate VB.NET/C# code so you can use throughout multiple projects.

Thursday, July 22, 2004

Url Manipulation (C#)

Edit (25-Mar-2005): Newer version here: Url Manipulation v2 (C#).

This class enables you to manipulate and get the QueryString of a page. It also returns the current page's AbsoluteUri (i.e. /path/to/myfile.aspx?param=test), base Url (i.e. /path/to/myfile.aspx) and virtual folder (i.e. /path/to/)

Use:

UrlQuery MyQuery;
private void Page_Load(object sender, EventArgs e) {
 MyQuery = new UrlQuery("/path/to/myfile.aspx?param=test");
 // or to get the current page use:
 // MyQuery = new UrlQuery()
 Trace.Write(MyQuery.Url); // returns '/path/to/file.aspx'
 Trace.Write(MyQuery.VirtualFolder); // returns '/path/to/'
 Trace.Write(MyQuery.Get()); // returns '?param=test'
 // change query
 MyQuery.Set("param2","value2");
 Trace.Write(MyQuery.Get()); // returns '?param=test¶m2=value2'
 // remove 'param' paramater
 MyQuery.Set("param",null);
 Trace.Write(MyQuery.Get("param2")); // returns 'value2'
 Trace.Write(MyQuery.AbsoluteUri);
 // go to new page
 Trace.Write(MyQuery.VirtualFolder + "file2.aspx" + MyQuery.Get()); // returns '/path/to/file2.aspx?param2=value2'
}

The class 'MyQuery' is based on:

public class UrlQuery
{
 /// <summary>
 /// Base on current page
 /// </summary>
 public UrlQuery()
 {
  url = HttpContext.Current.Request.Url.AbsolutePath;
 }
 /// <summary>
 /// Base on other page
 /// </summary>
 /// <param name="value">The url of the page to reference, i.e.: '/path/to/folder/page.aspx?param1=1&param2=2'</param>
 public UrlQuery(string value)
 {
  int q = value.IndexOf('?');
  if (q != -1)
  {
   url = value.Substring(0, q);
   queryString = NameValueCollection(value);
  }
  else
  {
   url = value;
  }
 }

 private string url;
 /// <summary>
 /// The Url of the page, without QueryString
 /// </summary>
 /// <value>/path/to/folder/page.aspx</value>
 public string Url
 {
  get
  {
   return url;
  }
 }
 /// <summary>
 /// Returns the virtual folder the page is in
 /// </summary>
 /// <value>/path/to/folder/</value>
 public string VirtualFolder
 {
  get
  {
   return Url.Substring(0, Url.LastIndexOf("/") + 1);
  }
 }
 /// <summary>
 /// The AbsoluteUri
 /// </summary>
 /// <value>page.aspx?param1=1¶m2=2</value>
 public string AbsoluteUri
 {
  get
  {
   return Url + Get();
  }
 }
 private NameValueCollection queryString;
 /// <summary>
 /// Get the QueryString for the page
 /// </summary>
 public NameValueCollection QueryString
 {
  get
  {
   if (queryString != null)
   {
    return queryString;
   }
   else
   {
    queryString = new NameValueCollection(HttpContext.Current.Request.QueryString);
    return queryString;
   }
  }
 }
 /// <summary>
 /// Get the QueryString
 /// </summary>
 /// <returns>String in the format ?param1=1&param2=2</returns>
 public string Get()
 {
  string query = "";
  if (QueryString.Count != 0)
  {
   query = "?";
   for (int i = 0; i <= QueryString.Count - 1; i++)
   {
    if (i != 0)
    {
     query += "&";
    }
    query += QueryString.GetKey(i) + "=" + QueryString.Get(i);
   }
  }
  return query;
 }
 /// <summary>
 /// Get parameter from QueryString
 /// </summary>
 /// <param name="param">Parameter to get</param>
 /// <returns>Parameter Value</returns>
 public string Get(string param)
 {
  return QueryString[param];
 }
 /// <summary>
 /// Set QueryString parameter
 /// </summary>
 /// <param name="param">Parameter to set</param>
 /// <param name="value">Value of parameter</param>
 public void Set(string param, string value)
 {
  if (param != string.Empty)
  {
   if (value == string.Empty || value == null)
   {
    QueryString.Remove(param);
   }
   else
   {
    QueryString[param] = value;
   }
  }
 }
 /// <summary>
 /// Convert QueryString string to NameValueCollection
 /// http://groups.google.co.uk/groups?hl=en&lr=&ie=UTF-8&safe=off&selm=uyMZ2oaZDHA.652%40tk2msftngp13.phx.gbl
 /// </summary>
 public static NameValueCollection NameValueCollection(string qs)
 {
  NameValueCollection nvc = new NameValueCollection();
  //strip string data before the question mark
  qs = qs.IndexOf('?') > 0 ? qs.Remove(0, qs.IndexOf('?') + 1) : qs;
  Array sqarr = qs.Split("&".ToCharArray());
  for (int i = 0; i < sqarr.Length; i++)
  {
   string[] pairs = sqarr.GetValue(i).ToString().Split("=".ToCharArray());
   nvc.Add(pairs[0], pairs[1]);
  }
  return nvc;
 }
 /// <summary>
 /// Copies a form paramater to the QueryString
 /// </summary>
 /// <param name="param">Form Parameter</param>
 public void FormToQuery(string param)
 {

  this.Set(param, HttpContext.Current.Request.Form[param]);
 }
}

Edit (25-Jul-2004): can pass on page url as a parameter (leave blank for current page)

Edit (27-Jul-2004): can copy a form elements value to the QueryString on postback. i.e.

void Button1_Click(object sender, EventArgs e)
{
 // transfer form parameter to query
 MyQuery.FormToQuery("mytextbox");
 Trace.Write(MyQuery.Get());
}

Tags: , ,

Wednesday, July 21, 2004

Programmers Notepad

A new build of programmers notepad is available - PN2 version 0.5.5 (herbie). Looks quite good and can only get better. Quite a few changes and bug fixes since 0.5 (the last development release) - including 'magic folders' within a project (a magic folder lists the files/folders contained within a directory on your computer). Read the release notes, or download from SourceForge.

I'm sure PN2 will be very good when the stable build is released.

Site Feed

Site feed available via Feedburner: http://feeds.feedburner.com/WebDeveloperBlog

Tuesday, July 20, 2004

Programmers Fonts

These fonts are quite good for when you work with source code and want a nice readable font:

Sunday, July 04, 2004

New MyGeneration Template Library

MyGeneration now has a new template library where you can add your own templates. Hopefully there will be many quality templates put on the site. Several of my templates have gone on (user sbc).

Sunday, June 27, 2004

JavaScript: Open Image Links in Popup

The following script makes all links to images open in a popup window. No inline JavaScript required. Modern browser required (i.e. IE5+, NS 6+, Mozilla Firefox). Save into scripts directory and include on page by adding into page <head> tags:

example.html

<html>
<head>
<title>Popup Image Example</title>
<script type="text/javascript" src="scripts/imagepop.js"></script>
</head>
<body>
<p><a href="images/foo.gif" title="Foo Title" width="120" height="300">Foo</a>
| <a href="images/bar.jpg" width="140" height="280">Bar</a>
| <a href="page.html">Baz</a></p>
</body>
</html>

scripts/imagepop.js

function imagepop(url,title) {
	// new window title
	var contents = '<html><head><title>' + ((title)?title:'Image Popup') + '<\/title>';
	// resize window once image has loaded
	contents += '<script type="text\/javascript">window.onload = resize;';
	contents += 'function resize() {';
	contents += 'w=document.images[0].width+25;';
	contents += 'h=document.images[0].height+25;';
	contents += 'window.resizeTo(w,h);';
	// centre the popup window
	contents += 'window.moveTo((screen.width-w)/2,(screen.height-h)/2)}';
	contents += '<\/script>';
	// remove padding and margin using css
	contents += '<style type="text\/css">body{margin:0;padding:0;text-align:center}img{display:block;margin:auto}<\/style>';
	// add image to page
	contents += '<\/head><body><img src="' + url + '">';
	contents += '<\/body><\/html>';
	// open popup window
	imgpop = window.open('about:blank','imgpop','location=no,menubar=no,scrollbars=no,status=no,toolbar=no');
	imgpop.document.open();
	imgpop.document.write(contents);
	imgpop.document.close();
	return false;
}
function checklinks() {
	if(document.getElementsByTagName) {
		// list of image types that are recognised as images
		types = new Array('.jpg','jpeg','.gif','.png','.bmp');
		// get anchor links
		a = document.getElementsByTagName('a');
		// loop through list of anchors
		for (var i=0;i<a.length;i++) {
			// loop through image types
			for (var j=0;j<types.length;j++) {
				/* make sure it links to an image by checking where the extension appears in the string
				   Example 1 (image): http://localhost/image.jpg
				   length of href string is 26, index of .jpg is 22
				   so 26 - 22 = 4 (same length as '.jpg') so linking to an image
				   Example 2 (not image): http://localhost/image.jpg/folder/
				   length of href string is 34, index of .jpg is 22
				   so 34 - 22 = 12 (not the same length as '.jpg') so leave alone
				*/
				if ((a[i].href.length - a[i].href.indexOf(types[j])) == types[j].length){
					// attach onclick event to call the function to open a popup window
					a[i].onclick = function () {
						// pass on href link and title
						return imagepop(this.href,this.title);
					}
				}
			}
		}
	}
}
window.onload = checklinks;

Friday, June 25, 2004

CSS: min-width and min-height with Internet Explorer

Combining the underscore hack with the ability of IE to evaluate expressions in CSS, you can set the minimum/maximum width and minimum height of an HTML element using CSS:

div.content {
	background: #eee;
	/* minimum height */
	min-height: 400px;
	/* auto height for compliant browsers */
	height: auto;
	/* min-height for IE browsers */
	_height: 400px;
	/* minimum width */
	min-width:300px;
	/* IE Dynamic Expression to set the width */
	width:expression(document.body.clientWidth < 300 ? "300px" : "100%" );
	/* maximum width */
	max-width:600px;
	/* IE Dynamic Expression to set the width */
	width:expression(document.body.clientWidth > 600 ? "600px" : "100%" );
}

This makes sure that the DIV element this is applied to is at least 400px high and 300px wide and at most 600px wide. This is a combination of Imposing Minimum Width With CSS and The Underscore Hack.

Saturday, June 12, 2004

Browser Capabilities Project

The Browser Capabilities Project is a site where you can get an updated Browscap.ini file that is used for getting the capabilities of the browser that the site visitor is using - so you can check to see if a certain feature is supported - JavaScript, VBScript, Cookies, Tables etc.

The above does not work with ASP.NET, but there is a way to do it by editing your machine.config or web.config files. Details

Underscore Hack (CSS)

A useful hack for serving up CSS that only Internet Explorer for Windows can interpret (i.e. to fix various bugs). Other browsers simply ignore the property. Useful for working round the position:fixed and min-height issues, as well as any others that require CSS that is only interpreted on Windows IE.

ASP.NET Poll Web Control

A useful ASP.NET web control for adding polls to an ASP.NET driven site. Free to use, supports SQL and Access databases. Fairly customisable and the API is documented.

Wednesday, June 02, 2004

MyGeneration SharpDevelop Project Template (C# version)

C# version of my previous template for MyGeneration. Save in the same directory as generated C# dOOdads entities. Set namespace to same one that was used to generate the dOOdads entities. Also MyGeneration.dOOdads.dll has to be placed in the bin\Release subfolder - i.e. My Documents\SharpDevelop Projects\My Project\bin\Release

Interface Code:

Dim cmbDatabases
Dim lstTables

Sub setup()

	If Not input.Contains("lstTables") Or Not input.Contains("txtPath") Then

		ui.Title = "Generate C# SharpDevelop Project"
		ui.Width  = 330
		ui.Height = 450

		' Grab default output path
		Dim sOutputPath
		sOutputPath = ""
		If input.Contains("defaultOutputPath") Then 
			sOutputPath = input.Item("defaultOutputPath")
		End If

		ui.AddLabel "lblPath", "Output file path: ",  "Select the output path."
		ui.AddTextBox "txtPath", sOutputPath, "Select the Output Path."
		ui.AddFilePicker "btnPath", "Select Path", "Select the Output Path.", "txtPath", true
		
		ui.AddLabel "lblNamespace", "Namespace: ",  "Provide your objects namespace."
		ui.AddTextBox "txtNamespace", "Your.Namespace", "Provide your objects namespace."

		' List Databases in a ComboBox
		ui.AddLabel "lblDatabases", "Select a database:", "Select a database in the dropdown below."
		Set cmbDatabases = ui.AddComboBox("cmbDatabase", "Select a database.")

		' List Tables in a listbox
		ui.AddLabel "lblTables", "Select tables:", "Select tables from the listbox below."
		Set lstTables = ui.AddListBox ("lstTables", "Select tables:")
		lstTables.Height = 150

		' Attach the onchange event to the cmbDatabases control.
		setupDatabaseDropdown cmbDatabases
		cmbDatabases.AttachEvent "onchange", "cmbDatabases_onchange"
		
		ui.ShowGUI = true
	Else 
		ui.ShowGUI = false
	End if

End Sub

Sub setupDatabaseDropdown(cmbDatabases)
	cmbDatabases.BindData MyMeta.Databases

	If Not MyMeta.DefaultDatabase Is Nothing Then
		cmbDatabases.SelectedValue = MyMeta.DefaultDatabase.Name
		bindTables cmbDatabases.SelectedValue
	End If
End Sub

Sub bindTables(sDatabase)
	Set db = MyMeta.Databases.Item(sDatabase)
	lstTables.BindData(db.Tables)
End Sub

' Event Handler
Sub cmbDatabases_onchange(control)
	Set cmbDatabases = ui.item("cmbDatabase")
	bindTables cmbDatabases.SelectedText
End Sub

Template Code:

<%
'------------------------------------------------------------------------------
' SharpDevelopC#.vbgen
' Last Updated: 2 June 2004
' Author: Sam Collett
' Creates SharpDevelop project file. Save to same directory as generated business entities
' Place MyGeneration.dOOdads.dll to bin\Release sub folder
'
'------------------------------------------------------------------------------

Dim objTable
Dim objColumn
Dim intLp
Dim bInFirst
Dim tableNames
Dim tableName
Dim namespace
Dim buffer
' Grab the namespace
namespace = input.Item("txtNamespace")
Dim databaseName
databaseName  = input.Item("cmbDatabase")
Set database = MyMeta.Databases.Item(databaseName)

Set tableNames = input.Item("lstTables")
%>
<Project name="<%=database.Alias%>" standardNamespace="<%=namespace%>" description="" newfilesearch="None" enableviewstate="True" version="1.1" projecttype="C#">
	<Contents>
  <%
' Loop through tables in db
For intLp = 0 To tableNames.Count - 1
	tableName = tableNames(intLp)
	Set objTable = database.Tables.Item(tableName)
	If objTable.Name = tableName Then
%>
		<File name=".\<%=objTable.Alias%>.cs" subtype="Code" buildaction="Compile" dependson="" data="" /><%
	End If
Next
%>
		<File name=".\AssemblyInfo.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
	</Contents>
	<References>
		<Reference type="Assembly" refto=".\bin\Release\MyGeneration.dOOdads.dll" localcopy="True" />
	</References>
	<DeploymentInformation target="" script="" strategy="File" />
	<Configuration runwithwarnings="True" name="Release">
		<CodeGeneration includedebuginformation="False" optimize="True" generateoverflowchecks="False" rootnamespace="" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" imports="" />
		<VBDOC outputfile="" enablevbdoc="False" filestoparse="" commentprefix="" />
		<Execution consolepause="True" commandlineparameters="" />
		<Output directory=".\bin\Release" assembly="<%=database.Alias%>" executeScript="" executeBeforeBuild="" executeAfterBuild="" />
	</Configuration>
	<Configurations active="Debug">
		<Configuration runwithwarnings="False" name="Debug">
			<CodeGeneration includedebuginformation="True" optimize="True" generateoverflowchecks="True" rootnamespace="" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" imports="" />
			<VBDOC outputfile="" enablevbdoc="False" filestoparse="" commentprefix="" />
			<Execution consolepause="True" commandlineparameters="" />
			<Output directory=".\bin\Debug" assembly="<%=database.Alias%>" executeScript="" executeBeforeBuild="" executeAfterBuild="" />
		</Configuration>
		<Configuration runwithwarnings="True" name="Release">
			<CodeGeneration includedebuginformation="False" optimize="True" generateoverflowchecks="False" rootnamespace="" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" imports="" />
			<VBDOC outputfile="" enablevbdoc="False" filestoparse="" commentprefix="" />
			<Execution consolepause="True" commandlineparameters="" />
			<Output directory=".\bin\Release" assembly="<%=database.Alias%>" executeScript="" executeBeforeBuild="" executeAfterBuild="" />
		</Configuration>
	</Configurations>
</Project>
<% 
' save project file
SaveOutput database.Alias, "prjx"
' assembly file %>
using System;
using System.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.

// Review the values of the assembly attributes

[assembly: AssemblyTitle("<%=database.Alias%>")]
[assembly: AssemblyDescription("C# Class Library")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
// Version information for an assembly consists of the following four values:

//      Major Version
//      Minor Version 
//      Build Number
//      Revision

// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:

[assembly: AssemblyVersion("1.0.*")]
<%
SaveOutput "AssemblyInfo", "cs"
' this function saves the output to disk
Function SaveOutput(filename, ext)
	' Save the output file for this Table
	Dim filepath
	filepath = input.item("txtPath")
	' length of file path
	Dim length
	' position of last 	Dim pos
	' get length from input
	length = Len(filepath)
	' get position of last 	pos = InStrRev(filepath, "\")
	' if last \ is not at the end of the file path, it needs adding
	If Not pos = length Then
		' append \ to path
		filepath = filepath & "\"
	End If
	' filename is generated from table alias, removing invalid filename characters
	filename = filepath & filename & "." & ext
	' save output to file
	output.save filename, false
	buffer = buffer & output.text
	output.clear
End Function

output.write buffer

 %>

<%

Function TrimSpaces(str)

	Dim tname
	Dim name
	Dim char
	Dim l

	name = ""
	tname = str
	l = Len(tname)

	For j = 1 To l
		char = Mid(tname, j, 1)
		If Not char = " " Then
			name = name & char
		End If
	Next

	TrimSpaces = name
End Function
%>

Friday, May 28, 2004

Neowin Interview : Ben Goodger from the Mozilla Foundation

An interview with the chief Mozilla Firefox developer. Looks like 0.9 will be very good when it comes out. I wonder if a lot of people will switch when version 1.0 comes out? The future may be looking good for Mozilla. Will Internet Explorer be improved and the competition be renewed like in the Netscape days?

Tuesday, May 25, 2004

ASP.NET DataGrid Template

My MyGeneration template, ASP.NET DataGrid has been added to the Template Library at the MyGeneration website.

Friday, May 21, 2004

Microsoft SQL Web Data Administrator

A way to access your SQL Server MSDE Database via the Web: Microsoft SQL Web Data Administrator. There is also a third party tool that works a bit like Enterprise Manager called ASP.Net Enterprise Manager. Both are probably best only used on development databases rather than production ones, but can be useful if you wish to administrate when you don't have Enterprise Manager installed - i.e. so you can admin the server on any PC.

Thursday, May 20, 2004

MyGeneration SharpDevelop Project Template

Template for MyGeneration that generates a project file for SharpDevelop, to be placed in the same directory as the generated dOOdads business entities. Also MyGeneration.dOOdads.dll has to be placed in the bin\Release subfolder - i.e. My Documents\SharpDevelop Projects\My Project\bin\Release

Interface Code:

Dim cmbDatabases
Dim lstTables

Sub setup()

 If Not input.Contains("lstTables") Or Not input.Contains("txtPath") Then

  ui.Title = "Generate SharpDevelop Project"
  ui.Width  = 330
  ui.Height = 400

  ' Grab default output path
  Dim sOutputPath
  sOutputPath = ""
  If input.Contains("defaultOutputPath") Then 
   sOutputPath = input.Item("defaultOutputPath")
  End If

  ui.AddLabel "lblPath", "Output file path: ",  "Select the output path."
  ui.AddTextBox "txtPath", sOutputPath, "Select the Output Path."
  ui.AddFilePicker "btnPath", "Select Path", "Select the Output Path.", "txtPath", true

  ' List Databases in a ComboBox
  ui.AddLabel "lblDatabases", "Select a database:", "Select a database in the dropdown below."
  Set cmbDatabases = ui.AddComboBox("cmbDatabase", "Select a database.")

  ' List Tables in a listbox
  ui.AddLabel "lblTables", "Select tables:", "Select tables from the listbox below."
  Set lstTables = ui.AddListBox ("lstTables", "Select tables:")
  lstTables.Height = 150

  ' Attach the onchange event to the cmbDatabases control.
  setupDatabaseDropdown cmbDatabases
  cmbDatabases.AttachEvent "onchange", "cmbDatabases_onchange"
  
  ui.ShowGUI = true
 Else 
  ui.ShowGUI = false
 End if

End Sub

Sub setupDatabaseDropdown(cmbDatabases)
 cmbDatabases.BindData MyMeta.Databases

 If Not MyMeta.DefaultDatabase Is Nothing Then
  cmbDatabases.SelectedValue = MyMeta.DefaultDatabase.Name
  bindTables cmbDatabases.SelectedValue
 End If
End Sub

Sub bindTables(sDatabase)
 Set db = MyMeta.Databases.Item(sDatabase)
 lstTables.BindData(db.Tables)
End Sub

' Event Handler
Sub cmbDatabases_onchange(control)
 Set cmbDatabases = ui.item("cmbDatabase")
 bindTables cmbDatabases.SelectedText
End Sub

Template Code:

<%
'------------------------------------------------------------------------------
' SharpDevelop.vbgen
' Last Updated: 13 May 2004
' Author: Sam Collett
' Creates SharpDevelop project file. Save to same directory as generated business entities
' Place MyGeneration.dOOdads.dll to bin\Release sub folder
'
'------------------------------------------------------------------------------

Dim objTable
Dim objColumn
Dim intLp
Dim bInFirst
Dim tableNames
Dim tableName
Dim buffer

Dim databaseName 
databaseName  = input.Item("cmbDatabase")
Set database = MyMeta.Databases.Item(databaseName)

Set tableNames = input.Item("lstTables")
%>
<Project name="<%=database.Alias%>" standardNamespace="<%=TrimSpaces(database.Alias)%>" description="" newfilesearch="OnLoadAutoInsert" enableviewstate="True" version="1.1" projecttype="VBNET">
 <Contents><%
' Loop through tables in db
For intLp = 0 To tableNames.Count - 1
 tableName = tableNames(intLp)
 Set objTable = database.Tables.Item(tableName)
 If objTable.Name = tableName Then
%>
  <File name=".\<%=objTable.Alias%>.vb" subtype="Code" buildaction="Compile" dependson="" data="" /><%
 End If
Next
%>
  <File name=".\AssemblyInfo.vb" subtype="Code" buildaction="Compile" dependson="" data="" />
 </Contents>
 <References>
  <Reference type="Assembly" refto=".\bin\Release\MyGeneration.dOOdads.dll" localcopy="True" />
 </References>
 <DeploymentInformation target="" script="" strategy="File" />
 <Configuration runwithwarnings="True" name="Release">
  <CodeGeneration includedebuginformation="False" optimize="True" generateoverflowchecks="False" rootnamespace="" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" imports="" />
  <VBDOC outputfile="" enablevbdoc="False" filestoparse="" commentprefix="" />
  <Execution consolepause="True" commandlineparameters="" />
  <Output directory=".\bin\Release" assembly="<%=database.Alias%>" executeScript="" executeBeforeBuild="" executeAfterBuild="" />
 </Configuration>
 <Configurations active="Debug">
  <Configuration runwithwarnings="False" name="Debug">
   <CodeGeneration includedebuginformation="True" optimize="True" generateoverflowchecks="True" rootnamespace="" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" imports="" />
   <VBDOC outputfile="" enablevbdoc="False" filestoparse="" commentprefix="" />
   <Execution consolepause="True" commandlineparameters="" />
   <Output directory=".\bin\Debug" assembly="<%=database.Alias%>" executeScript="" executeBeforeBuild="" executeAfterBuild="" />
  </Configuration>
  <Configuration runwithwarnings="True" name="Release">
   <CodeGeneration includedebuginformation="False" optimize="True" generateoverflowchecks="False" rootnamespace="" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" imports="" />
   <VBDOC outputfile="" enablevbdoc="False" filestoparse="" commentprefix="" />
   <Execution consolepause="True" commandlineparameters="" />
   <Output directory=".\bin\Release" assembly="<%=database.Alias%>" executeScript="" executeBeforeBuild="" executeAfterBuild="" />
  </Configuration>
 </Configurations>
</Project>
<% 
' save project file
SaveOutput database.Alias, "prjx"
' assembly file %>
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices

' General Information about an assembly is controlled through the following 
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.

' Review the values of the assembly attributes

<Assembly: AssemblyTitle("<%=database.Alias%>")> 
<Assembly: AssemblyDescription("VB.NET Class Library")> 
<Assembly: AssemblyCompany("")> 
<Assembly: AssemblyProduct("")> 
<Assembly: AssemblyCopyright("")> 
<Assembly: AssemblyTrademark("")> 
' Version information for an assembly consists of the following four values:
'
'      Major Version
'      Minor Version 
'      Build Number
'      Revision
'
' You can specify all the values or you can default the Build and Revision Numbers 
' by using the '*' as shown below:

<Assembly: AssemblyVersion("1.0.*")> 
<%
SaveOutput "AssemblyInfo", "vb"
' this function saves the output to disk
Function SaveOutput(filename, ext)
 ' Save the output file for this Table
 Dim filepath
 filepath = input.item("txtPath")
 ' length of file path
 Dim length
 ' position of last  Dim pos
 ' get length from input
 length = Len(filepath)
 ' get position of last  pos = InStrRev(filepath, "\")
 ' if last \ is not at the end of the file path, it needs adding
 If Not pos = length Then
  ' append \ to path
  filepath = filepath & "\"
 End If
 ' filename is generated from table alias, removing invalid filename characters
 filename = filepath & filename & "." & ext
 ' save output to file
 output.save filename, false
 buffer = buffer & output.text
 output.clear
End Function

output.write buffer

 %>

<%

Function TrimSpaces(str)

 Dim tname
 Dim name
 Dim char
 Dim l

 name = ""
 tname = str
 l = Len(tname)

 For j = 1 To l
  char = Mid(tname, j, 1)
  If Not char = " " Then
   name = name & char
  End If
 Next

 TrimSpaces = name
End Function
%>

Wednesday, May 19, 2004

SnippetCompiler / SharpDevelop

SnippetCompiler App - a useful application for compiling .NET code snippets, can import VS.NET projects. Has Intellisense and snippets can be exported to RTF or HTML format. Easier than using the command prompt for compiling.

SharpDevelop is a useful Open Source IDE for .NET, so allows you develop without Visual Studio. Unfortunately it is not so good a doing AS.NET projects and is more focused on WinForms development. Currently in Beta 1 status.

FileZilla / Notepad2

Very good tools I have been using for a while. FileZilla is a excellent FTP client which is Open Source. The current version (2.2.6) is for Windows only (may work on Linux via Wine though). Apparently there will be no more development done on this version, but a version 3 is in the works - it should work cross platform when it is release. Progress can be followed on the Development Forum on the site.

Notepad2 is a very good Notepad replacement and offers features like syntax highlighting, regular expression search, brace matching, auto indenting and more. The replace Notepad batch file script I posted earlier can be used to replace Notepad with this program. There is another batch file that can do this, but it cannot be use as a generic replacement program for notepad. Here is another method to do it - for XP only. Also mentioned on the PowerToys WebLog.

Tuesday, April 20, 2004

Let Them Eat Cake: A List Apart

Let Them Eat Cake: A List Apart - this is an article on making your web pages both accessible AND usable. For it to work you must have a well structured page, with links to various parts of the page at the top. Add in a bit of CSS and DOM compliant JavaScript and your done.

The good thing is it works with JavaScript disabled. The code is kept entirely separate from the content so you can have the page in XHTML Strict mode (no inline CSS or JavaScript, the example uses XHTML Strict). There is very little JavaScript involved. For those with older browser (IE4, Netscape 4), the user will just get the basic page - but as very few people use these browsers, most visitors will get the best experience.

Replace Notepad (Windows XP/2000 and later)

Edit - 30-Mar-2005: Fixed issues if backup version of notepad was in another folder, or SP2 was applied (C:\I386 or %windir%\ServicePackFiles\i386\)

The following batch script will allow you to replace notepad with a text edtor of your choice (will replace it for all users). Drag the file you wish to replace it with onto the batch script to do the replacement. You will probably get a warning about replacing a critical system file - you can ignore this. For it to work you need admin rights. To restore notepad, just double-click on the batch file. The use of this script is AT YOUR OWN RISK.

@echo off
REM This will replace Windows notepad with the program of your choice
REM The use of this script is AT YOUR OWN RISK.
REM filename to backup to
SET backupto=oldnotepad.exe
REM get file from parameter supplied
SET file=%1
REM if backup file exists, end the script
IF EXIST %windir%\system32\dllcache\%backupto% GOTO alreadyreplaced
REM If you do not specify a parameter, end the script
REM brackets are needed as spaces are ignored
IF (%file%) == () GOTO nofile
REM If source file does not exist, the replacement can not be made
IF NOT EXIST %file% GOTO nofile
attrib -r -h -s %windir%\system32\dllcache
ren %windir%\system32\dllcache\notepad.exe %backupto%
attrib +r +h +s %windir%\system32\dllcache
del %windir%\notepad.exe
copy /Y %file% %windir%\notepad.exe
del %windir%\system32\notepad.exe
copy /Y %file% %windir%\system32\notepad.exe
REM other folders that may contain notepad
IF EXIST C:\I386\notepad.exe ren C:\I386\notepad.exe %backupto%
IF EXIST %windir%\ServicePackFiles\i386\notepad.exe ren %windir%\ServicePackFiles\i386\notepad.exe %backupto%
GOTO end
:alreadyreplaced
attrib -r -h -s %windir%\system32\dllcache
ren %windir%\system32\dllcache\%backupto% notepad.exe
attrib +r +h +s %windir%\system32\dllcache
REM deleting the other notepad files will cause WFP to replace with the one in the dll cache
del %windir%\system32\notepad.exe
del %windir%\notepad.exe
REM other folders that may contain notepad
IF EXIST C:\I386\%backupto% ren C:\I386\%backupto% notepad.exe
IF EXIST %windir%\ServicePackFiles\i386\%backupto% ren %windir%\ServicePackFiles\i386\%backupto% notepad.exe
echo ------------------------------------------------------
echo  Notepad has already been replaced, original restored
echo ------------------------------------------------------
GOTO end
:nofile
echo ----------------------------------------------------
echo  You did not specify a file, or file does not exist
echo ----------------------------------------------------
:end

Tested on Windows XP - but should work on 2000. May not work on Windows 95/98/ME.


Tags: ,