CSS Positions

A coworker asked me about CSS positions. I admit I’m no expert in this topic. However, I want to illustrate my brief understanding. Maybe you will find them helpful.

Position: static
Default, you don’t have to set it.

Position: relative
It’s like a ghost image. Setting the corresponding properties of top, left, right, or bottom will move this element out of the its original document location but it will not affect any surrounding elements. The surrounding elements will treat it as if its position never changed.

Position: absolute
Takes the element out of its normal document location. The corresponding properties of top, left, right, bottom will be based off its first parent element whose position is not static. Check out this example to get an idea. The parent element is bubbled all the way up until it finds the document window.

Position: fixed
Similar to the absolute position except its parent element is the browser window. I’ve tried using this many years ago and found that IE didn’t support it. It sounds like pre IE 8 never supported it properly. Because of this, I never found a great use for it.

If I confused you, the positions are explained in greater details here. I find it very well written.

jQuery read only elements

There is a business requirement on a project I have at work to only allow a certain number of properties editable at a certain stage of the domain object’s life cycle. And like always, the properties defined to be editable could change in the future.

I already have a page that allows the user to edit all properties of the domain object, I really do not wish to duplicate that code. Please note that if you set an input element on a form as disabled, the value associated with the element will NOT be submitted via form post, that certainly is NOT what I’m looking for. I want the values of the *read only* fields still be submitted by the form but I just don’t want the user to edit the values. So I looked into using the readonly attribute in HTML. It’s complete crap.

For faqs.org:

It’s important to understand that READONLY merely prevents the user from changing the value of the field, not from interacting with the field. In checkboxes, for example, you can check them on or off (thus setting the CHECKED state) but you don’t change the value of the field.

Basically it works half-hearted and most browsers (IE, FF) do not indicate (by default) that a field is readonly. So the users will probably be left wondering why they cannot edit the field.

I searched around for an alternative and found this wonderful jQuery plugin readonly. Even though I couldn’t get it to work right for my application, the idea behind it is genius. You basically put overlay layers on top of any input fields you wish to make read only. The plugin seems a bit outdated. Perhaps it doesn’t work well with the newer version of jQuery but the idea still works well. Therefore I implemented my own.

This implementation automatically makes all input fields read only unless the input field has the class excludeMeFromReadOnly. This is just my implementation for demonstration. I do not provide any support for this code. Use where you see fit.

CSS

.readOnlyOverlay {
	position: absolute;
	background-color: #666;
	opacity: 0.3;
	filter: alpha(opacity=30);
	padding: 0 !IMPORTANT;
	margin: 0 !IMPORTANT;
}

javascript function generateOverlay

function generateOverlay(element) {
	var dimension = getDimensions($(element));
	//console.log('top=' + dimension.top + ' left=' + dimension.left +' width='+ dimension.width + ' height=' + dimension.height);

	// disassociate corresponding label attributes so the value of the element cannot be changed by clicking on the labels
	var id = $(element).attr('id');
	var label = $('label[for="'+id+'"]');
	$(label).removeAttr('for');

	// set my tabindex to -1 so tabs will ignore me
	$(element).attr('tabIndex', -1);
	$(label).attr('tabIndex', -1);

	// create a div overlay
	var overlay = $('</pre>
<div class="readOnlyOverlay"></div>
<pre>
').appendTo('body');
	$(overlay).css('top', dimension.top).css('left', dimension.left).css('width', dimension.width).css('height', dimension.height);
}

javascript function getDimensions

function getDimensions(element){
	var ret = {};

	// The multiple acquisitions of the CSS styles are required to cover any border and padding the elements may have.
	// The Ternary (parseInt(...) || 0) statements fix a bug in IE6 where it returns NaN,
	//  which doesn't play nicely when adding to numbers...
	ret.width = $(element).width()
	  + (parseInt($(element).css('borderLeftWidth')) || 0)
	  + (parseInt($(element).css('borderRightWidth')) || 0)
	  + (parseInt($(element).css('padding-left')) || 0)
	  + (parseInt($(element).css('padding-right')) || 0);
	ret.height = $(element).height()
	  + (parseInt($(element).css('borderTopWidth')) || 0)
	  + (parseInt($(element).css('borderBottomWidth')) || 0)
	  + (parseInt($(element).css('padding-bottom')) || 0)
	  + (parseInt($(element).css('padding-bottom')) || 0);
	var offsets = $(element).offset();
	ret.left = offsets.left;
	ret.top = offsets.top;

	return ret;
}

jQuery selector

// select all input,select elements. I'd wrap my form in a div.
$('div#formContent input, div#formContent select, div#formContent textarea').each(function(i, element) {
	// if the element doesn't have the class named excludeMeFromReadOnly, overlay it to make it look like it's read only
	if(!$(element).hasClass('excludeMeFromReadOnly')) {
		generateOverlay($(element));
	}
});

Please note, the plugin contains a lot more logic including IE hacks etc. Fortunately for me, I really don’t care about IE prior to version 8 in my particular scenario. Therefore I don’t need all of those hacks.

—>Example code (example at jsFiddle)<—

QUnit – test your javascript

After over ten years of javascript programming, I’m finally seriously considering writing at least unit tests for my javascript. Since I’m such a big fan of jQuery, QUnit seems like the obvious choice.

It’s sad but better late than never.

The truth is, in my opinion, the fact that javascript test frameworks do not yet maturely work with many of the continuous integration software deters programmers from using them. What’s the point of unit testing if they don’t automatically get run? Based on my research, JSUnit is the only one that integrates with ANT innately. But JSUnit is more of an abandomware now so people are looking for alternatives.

QUnit + CI topics

>> Run my test suite <<

QUnit simple example:

HTML:

<!DOCTYPE html>
<html>
<head>
	<title>Test Suite</title>
	<script src="http://code.jquery.com/jquery-latest.js"></script>
	<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
	<script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
	<!-- Your source files go here -->
	<script type="text/javascript" src="functions.js"></script>

	<!-- Your tests files go here -->
	<script type="text/javascript" src="isEvenTest.js"></script>
	<script type="text/javascript" src="startsWithTest.js"></script>

</head>
<body>
	<h1 id="qunit-header">QUnit example</h1>
	<h2 id="qunit-banner"></h2>
	<div id="qunit-testrunner-toolbar"></div>
	<h2 id="qunit-userAgent"></h2>
	<ol id="qunit-tests"></ol>

	<!-- Any HTML you may require for your tests to work properly -->
	<div id="qunit-fixture">test markup, will be hidden</div>
</body>
</html>

Source javascript file:

function isEven(val) {
	return val % 2 === 0;
}

function startsWith(data, startsWithStr) {
	data = jQuery.trim(data);
	startsWithStr = jQuery.trim(startsWithStr);
	if(data) {
		return data.toUpperCase().lastIndexOf(startsWithStr.toUpperCase(), 0) === 0;
	} else if(data === startsWithStr) {
		return true;
	} else {
		return false;
	}
}

Sample test file:

$(document).ready(function(){

	module("startsWithTest");

	test('startsWith', function() { 
		ok(startsWith("ll-925", "ll-"), 'Starts with ll-'); 
		ok(!startsWith("ll-925", "xl-"), 'Does not start with xl-'); 
		ok(!startsWith("", "xx-"), 'Does not start with xx-'); 
		ok(startsWith(" xx-sdgj ", "xx-"), 'Trimming test: starts with xx-'); 
		ok(startsWith(" xx-sdgj", " xx- "), 'Trimming test 2: starts with xx-'); 
		ok(startsWith("", " "), 'Empty string starts with empty string'); 
		ok(startsWith("Mn-u59", "mN-"), 'Non case sensitive test'); 
//		raises(startsWith(foo, " "), 'Undefined test 1');  // undefined is obviously not considered a normal exception
	}) 

});

>> git repo for the source <<

Additional resources:

Use modal windows for delete confirmations please

While reviewing an existing project at work, I notice it has many delete confirmation pages. In my opinion, delete confirmation PAGES should really just retire from the face of the earth. Seriously, why do we need to create a http request & html for the mere purpose of asking

“Are you sure you wish to delete blah?”

Yes, I’m sure | No, go back

Often the URLs for delete confirmation pages are consisted of

some.host/someApplication/deleteConfirmation?toDelete=some+description&id=some+id

Delete confirmation should be an UI client side behavior to prevent the user from accidentally clicking on a delete link/button and forcing a backend change to the data that was not intended.

Preconditions

The delete actions are hyperlinks. There are many examples with delete actions as form submissions. My example expects the delete actions to be links such as delete.php?id=#. I believe this is a more challenging situation than a form submission. I will share my solution. I think ideally it will be nice for the jQuery UI dialog to return a boolean javascript variable but since it currently does not (and I’m not sure it ever will), I’m using window.location to load the delete action link.

View the example of the page without any jQuery

Please have some general knowledge regarding jQuery selectors. I will not go into details how that works.

Assume you have a way of using jQuery selectors to uniquely bind an onclick event to each delete link. For simplicity purpose, in my example, all of my delete links will have the css class deleteConfirmation.

jQuery UI example of a delete confirmation modal window
I will be using links from Google CDN in my example.

Step 1
Create a div with an unique id in your html markup. It doesn’t matter where it exists in your markup, it just need to exist. We will create the jQuery UI dialog off it.

<div id="jQueryDeleteConfirmationModalWindow"></div>

Step 2
When the DOM is loaded, create your jQuery UI dialog and have its autoOpen property set to false. This allows us to reuse this dialog for all delete confirmations.

// create the jQuery modal window and set autoOpen to false
$("#jQueryDeleteConfirmationModalWindow").dialog({
	title: "Delete Confirmation",
	autoOpen: false,	// set this to false so we can manually open it
	dialogClass: "jQueryDeleteConfirmationModalWindow",
	closeOnEscape: false,
	draggable: false,
	width: 460,
	height: 260,
	modal: true,
	buttons: {
			"Yes, I'm sure": function() {
				$( this ).dialog( "close" );
			},
			Cancel: function() {
				$( this ).dialog( "close" );
			}
		},
	resizable: false,
	open: function() {
		// scrollbar fix for IE
		$('body').css('overflow','hidden');
	},
	close: function() {
		// reset overflow
		$('body').css('overflow','auto');
	}
}); // end of dialog

Step 3
Bind the onclick events to the delete action links via the css class deleteConfirmation.

$('a.deleteConfirmation').click(function() {
	var name = $(this).parent().parent().children('td.name').html(); // a.delete -> td -> tr -> td.name
	name = jQuery.trim(name);
	$("#jQueryDeleteConfirmationModalWindow").html('Are you sure you wish to delete ' + name + '?');
	$("#jQueryDeleteConfirmationModalWindow").dialog('open');
	return false;
});

Notice I also made it so my confirmation message will contain an unique description via the inner html property of another table cell of the same table row?

Step 4
If the user clicks on “Yes, I’m sure”, we want to execute the delete action. Therefore, my solution is to create a global variable that contains the value of the hyperlink the user clicked on and then set it to the window.location if the “Yes, I’m sure” is clicked on the modal window.

As the first line inside of the script tag, add

var deleteTheSelectedUrl = '';

In the button “Yes, I’m sure”, after dialog close, add

if('' != jQuery.trim(deleteTheSelectedUrl)) {
	window.location = deleteTheSelectedUrl;
}

In the onclick event binding, add as the first line

deleteTheSelectedUrl = $(this).attr('href');

View the final example

github repo

itext page number (page x of y)

I was looking for a complete example of how to dynamically generate the page numbers when you create the pdf using iText and I couldn’t find one. This is based on the example in the iText in Action book but I added my “refactoring” if you will.

I hope this helps someone. If not, it will definitely help myself in the future :)

public abstract class BaseReportBuilder extends PdfPageEventHelper {
	protected BaseFont baseFont;
	private PdfTemplate totalPages;
	private float footerTextSize = 8f;
	private int pageNumberAlignment = Element.ALIGN_CENTER;

	public BaseReportBuilder() {
		super();
		baseFont = load("fonts", "tahoma.ttf");
	}

	private BaseFont load(String location, String fontname) {
		try {
			InputStream is = getClass().getClassLoader().getResourceAsStream(location + System.getProperty("file.separator") + fontname);

			ByteArrayOutputStream out = new ByteArrayOutputStream();
			byte buf[] = new byte[1024];

			while (true) {
				int size = is.read(buf);
				if (size < 0)
					break;
				out.write(buf, 0, size);
			}
			is.close();
			buf = out.toByteArray();
			return BaseFont.createFont(fontname, BaseFont.CP1252, true, true, buf, null);
		} catch (Exception ex) {
			return null;
		}
	}

	@Override
	public void onOpenDocument(PdfWriter writer, Document document) {
		totalPages = writer.getDirectContent().createTemplate(100, 100);
		totalPages.setBoundingBox(new Rectangle(-20, -20, 100, 100));
	}

	@Override
	public void onEndPage(PdfWriter writer, Document document) {
		PdfContentByte cb = writer.getDirectContent();
		cb.saveState();
		String text = String.format("Page %s of ", writer.getPageNumber());

		float textBase = document.bottom() - 20;
		float textSize = baseFont.getWidthPoint(text, footerTextSize);
		
		cb.beginText();
		cb.setFontAndSize(baseFont, footerTextSize);
		if(Element.ALIGN_CENTER == pageNumberAlignment) {
			cb.setTextMatrix((document.right() / 2), textBase);
			cb.showText(text);
			cb.endText();
			cb.addTemplate(totalPages, (document.right() / 2) + textSize, textBase);
		} else if(Element.ALIGN_LEFT == pageNumberAlignment) {
			cb.setTextMatrix(document.left(), textBase);
			cb.showText(text);
			cb.endText();
			cb.addTemplate(totalPages, document.left() + textSize, textBase);
		} else {
			float adjust = baseFont.getWidthPoint("0", footerTextSize);
			cb.setTextMatrix(document.right() - textSize - adjust, textBase);
			cb.showText(text);
			cb.endText();
			cb.addTemplate(totalPages, document.right() - adjust, textBase);
		}
		cb.restoreState();
	}

	@Override
	public void onCloseDocument(PdfWriter writer, Document document) {
		totalPages.beginText();
		totalPages.setFontAndSize(baseFont, footerTextSize);
		totalPages.setTextMatrix(0, 0);
		totalPages.showText(String.valueOf(writer.getPageNumber() - 1));
		totalPages.endText();
	}

	public void setPageNumberAlignment(int pageNumberAlignment) {
		this.pageNumberAlignment = pageNumberAlignment;
	}
}

public class PageNumberReportBuilder extends BaseReportBuilder {
	public ByteArrayOutputStream buildPage() {
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		Document document = new Document(PageSize.LETTER);
		
		try {
			PdfWriter writer = PdfWriter.getInstance(document, stream);
			writer.setPageEvent(this);
			document.open();
			// add your document stuff
		} catch(DocumentException e) {
			throw new RuntimeException(e);
		}
		
		document.close();
		return stream;
	}
}

Download the complete code example (eclipse project) along with jUnit tests where you can actually generate the PDF file.

Java instaniate an abstract class… sort of…

At work I had to create some test data for a junit test. The function I’m testing expects a super abstract class to be passed in and I need to test the same function for bunch of child classes. I wish I could just pass in the parent class but since it’s abstract I cannot instantiate it. I wonder if there is a way using reflection so I can instantiate the class?? Since I could not find a way, I used the following:

public void testSomeFunction() throws Exception {
	ParentData data1 = populate(ChildDataOne.class);
	//..test..

	ParentData data2 = populate(ChildDataTwo.class);
	//..test..
}

private static ParentData populate(Class clazz) throws Exception {
	ParentData data = clazz.newInstance();
	data.setProperty1("1");
	data.setProperty2("2");
	data.setProperty3("3");
	data.setProperty4("4");
	data.setProperty5("5");
	return data;
}

jQuery session timeout countdown with jQueryUI dialog

Very nice jQuery session timeout countdown example with the use of the jQuery idleTimer plugin.

Here’s my example with the jQueryUI dialog as the warning.

var idleTime = 2000; // number of miliseconds until the user is considered idle
var initialSessionTimeoutMessage = 'Your session will expire in <span id="sessionTimeoutCountdown"></span> seconds.<br /><br />Click on <b>OK</b> to continue your session.';
var sessionTimeoutCountdownId = 'sessionTimeoutCountdown';
var redirectAfter = 10; // number of seconds to wait before redirecting the user
var redirectTo = ' http://regretless.com/2010/02/14/jquery-session-timeout-countdown/'; // URL to relocate the user to once they have timed out
var keepAliveURL = 'keepAlive.php'; // URL to call to keep the session alive
var expiredMessage = 'Your session has expired.  You are being logged out for security reasons.'; // message to show user when the countdown reaches 0
var running = false; // var to check if the countdown is running
var timer; // reference to the setInterval timer so it can be stopped
$(document).ready(function() {
	// create the warning window and set autoOpen to false
	var sessionTimeoutWarningDialog = $("#sessionTimeoutWarning");
	$(sessionTimeoutWarningDialog).html(initialSessionTimeoutMessage);
	$(sessionTimeoutWarningDialog).dialog({
		title: 'Session Expiration Warning',
		autoOpen: false,	// set this to false so we can manually open it
		closeOnEscape: false,
		draggable: false,
		width: 460,
		minHeight: 50,
		modal: true,
		beforeclose: function() { // bind to beforeclose so if the user clicks on the "X" or escape to close the dialog, it will work too
			// stop the timer
			clearInterval(timer);

			// stop countdown
			running = false;

			// ajax call to keep the server-side session alive
			$.ajax({
			  url: keepAliveURL,
			  async: false
			});
		},
		buttons: {
			OK: function() {
				// close dialog
				$(this).dialog('close');
			}
		},
		resizable: false,
		open: function() {
			// scrollbar fix for IE
			$('body').css('overflow','hidden');
		},
		close: function() {
			// reset overflow
			$('body').css('overflow','auto');
		}
	}); // end of dialog


	// start the idle timer
	$.idleTimer(idleTime);

	// bind to idleTimer's idle.idleTimer event
	$(document).bind("idle.idleTimer", function(){
		// if the user is idle and a countdown isn't already running
		if($.data(document,'idleTimer') === 'idle' &amp;&amp; !running){
			var counter = redirectAfter;
			running = true;

			// intialisze timer
			$('#'+sessionTimeoutCountdownId).html(redirectAfter);
			// open dialog
			$(sessionTimeoutWarningDialog).dialog('open');

			// create a timer that runs every second
			timer = setInterval(function(){
				counter -= 1;

				// if the counter is 0, redirect the user
				if(counter === 0) {
					$(sessionTimeoutWarningDialog).html(expiredMessage);
					$(sessionTimeoutWarningDialog).dialog('disable');
					window.location = redirectTo;
				} else {
					$('#'+sessionTimeoutCountdownId).html(counter);
				};
			}, 1000);
		};
	});

});

Here’s my example with the jQueryUI dialog as the warning.

Creative overlay/popup with jQuery

While doing a presentation on jQuery at work today, I went over a particular example I put together earlier today. I thought I’d share it with you here.

In the past, we have used popups for editing values inside of a input box. The most well known example I can think of is smilies on a forum script.

There are shortcuts to insert smilies on the right side of the your textarea. Then if you want more, you click on the more link. A popup window shows up, in the new window, you may click on any of the smiley to insert the shortcut into the textarea where your post is.

There is nothing wrong with the old way. It’s working fine but I believe there is a better way to handle this kind of scenario.

Take a look at this example. (More complete example)

When you click on “Edit Input”, a layer slides out and then if you click on anywhere else on the page to indicate you are done with that input field, the layer goes away. On the layer that slides out, you may display more smiley shortcuts.

Benefits of the new way:

  1. You are not making another http request
  2. You are not opening another window so you don’t have to worry about popup blockers
  3. You don’t have to worry about the parent window child window crap in javascript
  4. The layer is on the same page as your regular input, it’s a lot easier to access its content
  5. Your code is probably is easier to understand.

HTML:

<div class="editing"><span id="trigger">Edit Input</span>
<div id="toolWrapper">Some kind of editing tool</div>
</div>

Very simple. Just an input box with a layer next to it. Within the layer is a trigger link (you may use an nice image icon if you wish).

CSS:

#trigger {
	cursor: pointer;
}
#toolWrapper {
	position:absolute;
	z-index:100;
	top:20px;
	left:20px;
	background:#eee;
	border:1px solid #111;
	display:none;
	-moz-border-radius: 6px;
	-webkit-border-radius: 6px;
	width:250px;
	padding-right:20px;
	height:200px;
}
div.editing {
	position: relative;
	display: inline;
}

The CSS utilizes the positioning trick. The outer wrapper (div.editing) is relatively positioned so the insider layer (#toolWrapper) may be positioned absolute to the outer one.

jQuery:

$(function() {
	$("#trigger").click(function() {
		$('#toolWrapper').toggle(function() {
			$(document).click(function(event) {
				if (!($(event.target).is('#toolWrapper') || $(event.target).parents('#toolWrapper').length || $(event.target).is('#trigger'))) {
					$('#toolWrapper').hide(500);
				}
			});
		});
	});
});

Uses the new toggle(showOrHide) method – the logic depends on where you click on the page. I will let you digest it yourself. Read the jQuery api if you need :)

Now take a look the time editor I wrote for work. It uses the slider widget from jQuery UI. I will not go over the javascript used. Feel free to view source if you are curious.

jQuery just got a new forum!! WOOHOO. I never liked discussion groups anyway. Forum is much more preference community format for me.