Overwriting the Browser Confirm pop up using jQuery

The browser’s default confirm function is a synchronous blocking function that usually pops up a dialog box causing a web page to stop executing code and wait for user input. In most browsers, the user is allowed to select “OK” or “Cancel” and developers usually have very little control over the confirm box other than the message displayed.

This can lead to some problems when the confirm box blends into the website such as in the case with Chrome 35.0 or when you simply want more control over the button options.

You can overwrite the default confirm function such as in the following snippet of code which combines jQuery UI and Bootstrap to create a nice looking confirm box that is easier to read.

It is important to note that you will still run into a problem if you attempt to write code that blocks until the user presses a button. For that reason, the code will fall back to the old confirm function if you don’t give it a function to call when you press the OK or the Cancel button.

<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</head>
<body>
<div id="wrap">
<div class="container">
<div class="row">
<div class="col-sm-12">

<h1>Overwrite the Browser's Default Confirm Box</h1>

<div id="status"></div>

<div>
	<a href="#" class="btn btn-default" onclick="confirm('Are you sure that you want to continue?', confirm_function1, cancel_function1); return false;">Click to confirm</a>
</div>

<div>
	<a href="#" class="btn btn-default" onclick="if (confirm('Are you sure that you want to continue?')) { confirm_function1(); } else { cancel_function1() }; return false;">Click to confirm using default confirm box</a>
</div>

<script type="text/javascript">
function confirm_function1() {
	$('#status').html('Pressed OK');
}

function cancel_function1() {
	$('#status').html('Pressed Cancel');
}

/**
 * Replace the jQuery UI buttons styles in the confirm box with Bootstrap styles
 *
 * @param string id: The jQuery object to update
 * @param string buttonClass: The button class to the give the button
 * @return void
 */
function updateConfirmBoxButton(id, buttonClass) {
	var disableJqueryUICss = function() { 
		$(id)
			.removeClass("ui-state-hover")
			.removeClass("ui-state-focus")
			.removeClass("ui-state-active"); 
	};

	$(id)
		.prop("class", buttonClass)
		.mouseover(disableJqueryUICss)
		.mousedown(disableJqueryUICss)
		.focus(disableJqueryUICss)
		.focusout(disableJqueryUICss);
}

// Adjust how the confirm box is rendered
window.default_confirm = window.confirm; // Save the old confirm box function in case we need to fallback to it

/**
 * Create a new confirm box function
 *
 * @param string message: The message to display
 * @param function confirm_function: The function to execute when the user presses the 'confirm' button
 * @param function cancel_function: The function to execute when the user presses the 'cancel' button
 * @return object: If confirm_function or cancel_function are null then return the value returned by the old confirm box function Else return the new confirm box object
 */
window.confirm = function(message, confirm_function, cancel_function){
	// Fall back to the old default confirm box if we don't have both a confirm and cancel function
	if (confirm_function == null || cancel_function == null) {
		return window.default_confirm(message);
	}

	// Create the new confirm box
	var confirmBox = document.createElement("div");
	$(confirmBox)
		.html(message)
		.dialog({
			dialogClass: "confirmBox",
			buttons: {
				"OK": {
					id: "OK",
					text: "OK",
					click: function() {
						confirm_function();
						$(this).remove();
					}
				},
				"Cancel": {
					id: "Cancel",
					text: "Cancel",
					click: function() {
						cancel_function();
						$(this).remove();
					}
				}
			},
			close: function() {
				$(this).remove();
			},
			draggable: false,
			modal: true,
			resizable: false,
			width: 'auto'
		});
		
	//
	// Adjust the dialog box we just created
	//
	
	// Update the background so it is higher contrast
	$(".confirmBox.ui-widget-content").css("background", "#fff");
	
	// Update the background so it is higher contrast and the buttons are centered
	$(".confirmBox .ui-dialog-buttonpane").css("background", "#fff").css("border-width", "0").css("padding", "0");
	$(".confirmBox .ui-dialog-buttonset").css("text-align", "center").css("float", "none");
	
	// Hide the Titlebar
	$(".confirmBox .ui-dialog-titlebar").hide();
	
	// Update the confirm box buttons
	updateConfirmBoxButton(".confirmBox .ui-dialog-buttonset #OK", "btn btn-success");
	updateConfirmBoxButton(".confirmBox .ui-dialog-buttonset #Cancel", "btn btn-danger");

	return confirmBox;
};

</script>
</div>
</div>
</div>
</div>
</body>
</html>

Simple Cache Class in C#

A simple class that caches Hashtables within a Session object in C#.

using System;
using System.Web;
using System.Web.SessionState;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

public class Cache
{
	/**
	 * Delete the cache item from the cache by key
	 * 
	 * @param string CacheKey: The data to delete
	 * @return bool: Indicates the cache key was deleted
	 **/
	public static bool Delete(string CacheKey)
	{
		HttpContext.Current.Session[CacheKey] = null;
		return true;
	}

	/**
	 * Get the cache item by key
	 * 
	 * @param string CacheKey: The data to retrieve
	 * @return Hashtable: The data retrieved
	 **/
	public static Hashtable Get(string CacheKey)
	{
		if (HttpContext.Current.Session[CacheKey] != null)
		{
			Cache.Item item = (Cache.Item)HttpContext.Current.Session[CacheKey];
			if (item.Expiration >= DateTime.Now)
			{
				return item.Data;
			}
		}

		return null;
	}

	/**
	 * Set a cache item
	 * 
	 * @param string CacheKey: The key to set for the item
	 * @param Hashtable Data: The data to set
	 * @param int NumSecondsAlive: The number of seconds to set the cache for (defaults to 5 seconds)
	 * @return Hashtable: The data retrieved
	 **/
	public static bool Set(string CacheKey, Hashtable Data = null, int NumSecondsAlive = 5)
	{
		Cache.Delete(CacheKey);
		HttpContext.Current.Session[CacheKey] = new Cache.Item(Data, NumSecondsAlive);

		return true;
	}

	/**
	 * 
	 * Start Item Class
	 * 
	 **/
	private class Item
	{
		public Hashtable Data = null;
		public DateTime Expiration = new DateTime();

		public Item(Hashtable Data, int NumSecondsAlive)
		{
			this.Data = Data;
			this.Expiration = DateTime.Now.AddSeconds(NumSecondsAlive);
		}
	} // End Item Class
} // End Cache Class

You may want to consider performance and efficiency when implementing this on an actual site.

Caching the results of a PDO Query in Memcache

This is a quick example of code that will prepare a PDO statement and cache the results in Memcache.

It is easiest to use the two following sets of instructions to set up a LAMP environment that will handle the PHP, PDO, and Memcache packages that the code uses:

  1. How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu
  2. How To Install and Use Memcache on Ubuntu 12.04

Code

<?php
function db_connect() {
	global $memcache, $db;

	// Connect to the Memcache server
	$memcache = new Memcache();
	$memcache->pconnect('localhost', 11211);

	// Connect to the Database using PDO
	$host = "localhost";
	$dbname = "test";
	$user = "test";
	$pass = "test";

	try {
		$db = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
	} catch (PDOException $e) {
		die($e->getMessage());		
	}
}

function db_fetch_all($sql, $params = array(), $use_cache = true) {
	global $memcache, $db, $cache_expiration;

	$result = false;
	if ($use_cache) {
		// Generate a key for the cache
		$cache_key = md5($sql . serialize($params));
		$result = $memcache->get($cache_key);
	}

	if (!$result) {
		// Cache Miss: Prepare the sql and recache it
		$sth = $db->prepare($sql);
		
		// This handles ? within a sql query
		// i.e. "SELECT id FROM example WHERE name = ?";
		$i = 0;
		foreach ($params as $param) {
		    $sth->bindParam(++$i, $param);
		}

		// This handles :params within queries
		// "SELECT id FROM example WHERE name = :name";
		foreach ($params as $key => $value) {
		    // keys must be in the form :key within the query
		    $sth->bindParam($key, $value);
		}

		$sth->execute();
		$result = $sth->fetch(); // Fetch the entire result into an array
		
		// Cache expires in 10 seconds
                $cache_key = md5($sql . serialize($params));
		$cache_expiration = 10;
		$memcache->set($cache_key, serialize($result), MEMCACHE_COMPRESSED, $cache_expiration);

		echo "used mysql";
	} else {
		// Cache Hit
		echo "used memcache";
	}

	return $result;
}

echo "Time: " . time() . "<br />";
if (class_exists("Memcache")) {
	db_connect();

	// The query only works with ? as variables in the prepared statement
	$query = "SELECT id FROM example WHERE name = ?";
	$result = db_fetch_all($query, array("new_data"));
} else {
	echo "Memcache not installed :(";
}
?>