Action confirmation with JavaScript

Just a simple little trick for confirming with a user before they undertake an action on your web page. Sometimes you need to confirm things. You know, does the user of your site really want to delete that file FOREVER, or not. You can do it the hard way with a catch page to confirm, but the easier way is to use JavaScript.

Just like this:

	
<a href="irrevocable-action.php?doitnow=yes" onclick="return confirm('Are you really, really, really sure you want to do this?')">Do It!!</a>

When the user clicks the link, they will hit a pop up box, displaying the confirmation message and two buttons. If they click yes the link is followed and the action completed, otherwise they stay on the page and nothing happens.

Convert your website or web app to iOS app

I’ve been looking at web apps for iOS last weekend, as I was helping a friend with possibly porting his work as a native app. The solution provided by Apple is rather elegant, and very minimal in terms of work required. If your web app is HTML5 and CSS3 compliant, you’re good to go with about 15 minutes work. You’re able to have a web app run from the home screen of the iOS device, and appear to be native. The only flaw at this stage is that JavaScript is a bit laggy at times; this is primarily due to the fact that Apple has upgraded the JavaScript engine for Mobile Safari to the Nitro engine, while apps that run outside of Mobile Safari have not received access to the faster engine (read an unbiased explanation here). Anyways, what to do.

First, we need to hide the Safari components. We do this by adding the following inside the <head> tag of your normal web page/s:

<meta name="apple-mobile-web-app-capable" content="yes" />

Next, we need to hide the Status Bar. Again, by adding a single line to the <head> tag of your normal web page/s:

<meta name="apple-mobile-web-app-status-bar-style" content="black" />

There are three options for colors you can use here:

  • default – the status bar appears normal
  • black – the status bar has a black background
  • black-translucent – the status bar is black and translucent

If set to default or black, the web content is displayed below the status bar.
If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar.
The default value is default.

Now, the icon for your app. Presumably, you will want to use the same image as for your favicon, so at least you have the artwork ready to go. It just needs a little tweaking, and we’re away. You’ll need an icon which measures 57×57. You have two options for this, apple-touch-icon and apple-touch-icon-precomposed, depending on how you want Apple to handle your icon. The first option tells iOS that you’ve given it a generic icon to which it will add the standard app icon effects (rounded corners, drop shadow, and reflective shine); the second option tells iOS that you are giving it a fully kitted out icon with no need for adjustment. Bear in mind that the icon will always be placed on a black background, and be overlaid with a round-cornered “stencil”; so any transparent elements to the image will appear as black in the final displayed version.

Once this icon is created, place it in PNG format in the root document folder called apple-touch-icon.png or apple-touch-icon-precomposed.png. This specifies the icon for the entire website (every page on the website). Now you can link to it with a single line to the <head> tag of your normal web page/s:

<link rel="apple-touch-icon" href="/custom_icon.png"/>

or

<link rel="apple-touch-icon-precomposed" href="/custom_icon_precomposed.png"/>

For more information, check out Apple’s Web App tools, and also their discussion of meta-tags in iOS.

Create a list box in Excel to ensure valid data entry

I’ve been pulling together a spreadsheet for tracking and planning the expenses of my upcoming wedding and honeymoon. Having not used Excel for a while, I was a bit rusty. Anyway, what I wanted to do was have a simple list-box in a cell from which I could select ‘Yes’ or ‘No’ (I know, not earth-shattering at all).

So, I had a quick Google and found a plethora of tutorials on how to add a combo-box or a list-box; but, they all got way too messy and created a box that sat somewhere, and referenced a list of values before returning the index of that value, and then you could use that index to read the original list of values and select the correct one in order to use it. Phew, that was tiring just typing it!! Not a happy camper, but I knew there must be a simple way to have it “just work”.

I got there in the end, after some muddling around, and here’s the solution using Data Validation (this just does ‘Yes’ or ‘No’, but it’s easy to add more values):

  1. Select all the cells you want to have this validation applied to
  2. Go to Data | Data Validation
  3. On the Settings tab, select List from the Allow drop-down list
  4. In the Source text box, enter the valid values for the data, separated by commas (eg: Yes, No) [note: don't use quote marks]
  5. Select the In-cell Dropdown check box
  6. Click OK

Done!
When users move to one of the selected cells, Excel displays a drop-down arrow. Clicking the arrow reveals a list of valid options which users can select for that cell. If users attempt to type an entry that’s not on the list, Excel will display an error message.

simple random alpha char string variable in C#

Just a quick little code sample which creates a variable which generates a random alpha character string (upper and lower case). This can be very useful when you need to randomise a name, or create one or more temporary directories or files on the fly.

private const int _length = 15;
private static string RandomAlphaString {
	get {
		var ret = "";
		var random = new Random();
		while (ret.Length < _length)
			if (random.Next(1, 9) % 2 == 0)
				ret = ret + Convert.ToChar(random.Next(65, 90));
			else
				ret = ret + Convert.ToChar(random.Next(97, 122));
		return ret;
	}
}

Usage is to declare a var within your code, such as var randomName = RandomAlphaString; and this will be createda a string of length _length randomly using upper and lower case alpha characters (letters).

use CAB files in C# and .NET

An often overlooked element of working in C# and .NET is the ability to work with CAB files. These are very useful compressed files, which can help you immensely when you are deploying applications and need to move a large volume of files. They are EXTREMELY simple to use. Firstly, make sure you reference the library in your project (Microsoft.Deployment.Compression.Cab) and then you can easily use them in on a couple of lines. My example is actually overly verbose in the number of lines it uses in order to maintain clarity.

 
//Create cab files 
var pathToContainingFolder = @"C:\Desktop";
var cabFile = Path.Combine(pathToContainingFolder, + @"cabinet.cab");
var cabToPack = new CabInfo(cabFile);
var sourceDir = @"C:\Desktop\stuff";
cabToPack.Pack(sourceDir, true, Microsoft.Deployment.Compression.CompressionLevel.Min, null);

And there we have a compressed CAB file ready to use.

On the other end, extraction is equally straight-forward:

// extract the CAB file to the specified directory
var destDir = @"C:\Desktop\cabDemo";
EnsureDirectoryExists(destDir);
var cabToUnpack = new CabInfo(cabFile);
cabToUnpack.Unpack(destDir);

the above sample uses my little helper EnsureDirectoryExists(string dir):

private static void EnsureDirectoryExists(string dir) {	
	if (!Directory.Exists(dir)) {
		Directory.CreateDirectory(dir);
	}
}

copying or deleting everything in a directory (C#)

In C# we have the ability to move Directories or Files using System.IO.File.Move(sourceFile, destFile) and System.IO.Directory.Move(sourceDirPath, destDirPath) (making sure your paths use the string literal, ie var sourceDirPath = @"C:\Users\Public\public\test\"), however sadly there is no way to easily copy or delete entire directories (there is no Directory.Copy(fromDir, toDir) method available to us, only File.Copy(fromFile, toFile); and Directory.Delete(dir) only works for empty directories, so we need to empty them recursively!!). I have pulled together two methods to do this recursively.

The first is CopyAllDirectoriesAndFiles(string fromDirectory, string toDirectory), and also uses another method EnsureDirectoryExists(string dir):

private static void CopyAllDirectoriesAndFiles(string fromDirectory, string toDirectory) {
	if (Directory.Exists(fromDirectory)) {
		string[] files = Directory.GetFiles(fromDirectory);
		// make sure it exists
		EnsureDirectoryExists(toDirectory);
		// Copy the files and overwrite destination files if they already exist.
		foreach (string file in files) {
			var fileName = Path.GetFileName(file);
			var destFile = Path.Combine(toDirectory, fileName);
			File.Copy(file, destFile, true);
		}
		var di = new DirectoryInfo(fromDirectory);
		DirectoryInfo[] subDirs = di.GetDirectories();
		foreach (DirectoryInfo dirInfo in subDirs) {
			var directoryName = dirInfo.Name;
			var fromPath = Path.Combine(fromDirectory, directoryName);
			var toPath = Path.Combine(toDirectory, directoryName);
			EnsureDirectoryExists(toPath);
			// copy all files and folders across recursively
			CopyAllDirectoriesAndFiles(fromPath, toPath);
		}
	}
}

private static void EnsureDirectoryExists(string dir) {	
	if (!Directory.Exists(dir)) {
		Directory.CreateDirectory(dir);
	}
}

The second is DeleteAllDirectoriesAndFiles(string topDirectory):

private static void DeleteAllDirectoriesAndFiles(string topDirectory) {
	if (Directory.Exists(topDirectory)) {
		string[] files = Directory.GetFiles(topDirectory);
		foreach (string file in files) {
			File.Delete(file);
		}
		var di = new DirectoryInfo(topDirectory);
		DirectoryInfo[] subDirs = di.GetDirectories();
		foreach (DirectoryInfo dirInfo in subDirs) {
			var directoryName = dirInfo.Name;
			var fromPath = Path.Combine(topDirectory, directoryName);
			// delete all files and folders recursively
			DeleteAllDirectoriesAndFiles(fromPath);
		}
		// delete this folder
		Directory.Delete(topDirectory);
	}
}

Hopefully the inline comments are self-explanatory, if not, hit me up in the comments and I’ll provide you with more detail.

ensuring a Directory exists in C#

Often we need to ensure a Directory exists before we reference or use it. This is a little method that does this for you. Nothing complicated, but if you need to check that 2 or more directories exist, this will save you lines of code:

private static void EnsureDirectoryExists(string dir) {	
	if (!Directory.Exists(dir)) {
		Directory.CreateDirectory(dir);
	}
}

asp:DeclarativeCatalogPart WebPartsTemplate must have odd number of elements

I discovered an interesting anomaly today, working with ASP.NET and Web Parts, I had an issue whereby creating a CatalogZone caused the HTML generated from template to lose a whole lot of closing tags. This threw the whole page out the window as the CSS was stuffed. I did a LOT of Googling to no avail.

Finally I went into the tried and true method of trial and error; removing one element at a time until I found the problem bit. This was also anomalous as I have three pages with essentially the same code and only one breaks! I won’t bore you by going through every iteration and step I took, I’ll just bounce to the solution.

In their wisdom Microsoft has apparently made the template work for an odd number of elements, but an even number has a tantrum and is not composed correctly. It was only when I realised that that during my trial and error, the two working pages had 15 and 5 elements respectively, and the “broken” page had 6 elements; thinking this could not possibly be the issue, I checked and was astounded. The general response from my colleagues was “you’ve got to be f@$#en kidding me”. I swear, I’m not.

In summary, from an HTML point of view, this works:

<asp:CatalogZone ID="CatalogZone" runat="server">
	<ZoneTemplate>
		<asp:DeclarativeCatalogPart ID="DeclarativeCatalogPart" runat="server">
			<WebPartsTemplate>
				<tfr:stuff1 ID="stuff1" runat="server" />
				<tfr:stuff2 ID="stuff2" runat="server" />
				<tfr:stuff3 ID="stuff3" runat="server" />
			</WebPartsTemplate>
		</asp:DeclarativeCatalogPart>
		<asp:PageCatalogPart ID="PageCatalogPart" runat="server" />
	</ZoneTemplate>
</asp:CatalogZone>

and this doesn’t:

<asp:CatalogZone ID="CatalogZone" runat="server">
	<ZoneTemplate>
		<asp:DeclarativeCatalogPart ID="DeclarativeCatalogPart" runat="server">
			<WebPartsTemplate>
				<tfr:stuff1 ID="stuff1" runat="server" />
				<tfr:stuff2 ID="stuff2" runat="server" />
			</WebPartsTemplate>
		</asp:DeclarativeCatalogPart>
		<asp:PageCatalogPart ID="PageCatalogPart" runat="server" />
	</ZoneTemplate>
</asp:CatalogZone>

How to use a C# for loop

The for loop in C# is useful for iterating over arrays and for sequential processing. That is the statements within the code block of a for loop will execute a series of statements as long as a specific condition remains true. E.g.:

for(initialization; condition; increment) {
	statement/s
}

initialization :   Initialize the value of variable
condition :            Evaluate the condition based on the variable
increment :            Step taken for each execution of loop body

The for loop initializes the value before the first step. Then checks the condition against the current value of the variable and executes the statement/s inside the loop before incrementing.

int count = 4;
for(int i = 0; i < count; i++) {
	MessageBox.Show("The first number is: " + i);
}

This outputs:

The first number is: 0
The first number is: 1
The first number is: 2
The first number is: 3

The loop executes four times because we set the condition as being i is less than count, and i was initially 0.

All expressions in a for loop declaration are optional. The following creates an infinite loop:

for( ; ; ) {
	statement/s
}

in much the same way as simply using while(true) creates an infinite loop, e.g.:

while(true) {
	statement/s
}

Happy looping!

Preventing window close with JavaScript

Closing a browser window with JavaScript is easy, you just call window.close(); however catching the browser close event and preventing it is another kettle of fish. I’ve been working on this a bit on-and-off, and have managed to pull together what I think is a reasonable solution [NOTE: this does not work in Opera, as it uses the onunload() and onbeforeunload() events, which are not supported by Opera 11].

The solution I have come up with is pretty simple once you see it. I put the following code either in my JavaScript library included into the page, or I just place it at the top of the required page (in tags, of course):

function checkClose() {
    if (ok) {
        return "Have you saved your information?";
    }
}

var ok = true; // this is reset everytime a new page is loaded

function okToLeave() { // called if leaving the page is needed
    ok = false;
}

window.onbeforeunload = checkClose;
window.onunload = checkClose;

and in my links where I’m happy to leave the page without checking (i.e. on submitting a form):

I have also allowed for a cancel event, where I don’t want the checkClose() event called, but I still want to catch the close/departure:

What we have going on here is a standard JS being called whenever there is a page unloaded. This can be due to clicking a link, entering a new URL in the browser, or closing the window or tab. The JS call will be to checkClose(). If checking before exit is required, then the pop-up is activated. If the page-exiting event is not a problem, then the JS inserted within this event (onclick="okToLeave();") sets the checking variable (ok), which then causes the checkClose() function to do nothing, so the onunload events are not thwarted. In some circumstances (i.e. the Cancel button being clicked) we don’t want the onunload event called, but we do want to confirm departure; in these cases the extra JS inserted in the event (onclick="okToLeave(); return confirm('Confirm leaving this page.');") warns and confirms with the client user.

This approach is only necessary if you are trying to check for events not triggered within your own page (e.g. the window closing event), otherwise it is just overkill. If you only want to confirm when certain links are used, then insert the check within their use, i.e.:

<a href="otherpage.html" onclick="confirm('Do you really 
             want to leave this page?')" >this is a link</a>

I did like this comment I found on a forum regarding this concept though:

The question is not how but why??
If a user wants to close his browser, that’s his god-given right!

If you don’t want him to close it, make it so there’s something interesting in the window. (Naked women seem to do the trick for a lot of people)

Follow

Get every new post delivered to your Inbox.