octalforty

Hello. octalforty is the canvas for Yassir Yahya to share his views on user interface & user experience on the web. It's made in Malaysia too!

Posted on 9th June 2010 by admin

Renaming jQuery UI Tabs With Validation

octal­forty shows you how to make your jQuery UI Tabs rename­able. We’ll also look into how to val­i­date the user input before sav­ing the new tab name.

Recently, one of our projects requires me to use jQuery UI Tabs for its user inter­face. One of the prob­lem was, to fig­ure a way for the user to rename the tab and val­i­date the input at the same time. Most of the site’s client-side val­i­da­tion is through jQuery Val­i­date plu­gin, so that should be straight-forward.

Want to see the it in action? Why not play around with the online demo or down­load the source files.

The markup

First off, let’s start by includ­ing jQuery, jQuery UI and jQuery live­query plu­gin. For this demo, I’ll point the files to Google CDN when­ever pos­si­ble, and start with the jQuery UI Tabs default func­tion­al­ity demo markup.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>jQuery UI Tabs - Default functionality</title>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js"></script>
	<script type="text/javascript" src="js/jquery.livequery.js"></script>
	<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>

	<link type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/themes/smoothness/jquery-ui.css" rel="stylesheet" />
</head>
	<body>
		<div id="demo">
			<div id="tabs">
				<ul id="tabs-nav">
					<li><a href="#tabs-1"><span>Nunc tincidunt</span></a></li>
					<li><a href="#tabs-2"><span>Proin dolor</span></a></li>
					<li><a href="#tabs-3"><span>Aenean lacinia</span></a></li>
				</ul>
				<div id="tabs-1">
					<!-- Content for the first tab will be here -->
				</div>
				<div id="tabs-2">
					<!-- Content for the second tab will be here -->
				</div>
				<div id="tabs-3">
					<!-- Content for the third tab will be here -->
				</div>
			</div><!-- /#tabs -->
		</div><!-- /.demo -->
		<script type="text/javascript"></script>
	</body>
</html>

The JavaScript

We’ll be includ­ing most of the scripts inside the <script> tag on line 32. We’ll split the whole inter­ac­tion to few phases so that we can see clearly what we should do. The happy path should be some­thing like:

  1. Click on the tab name to edit.
  2. Dis­play input text with the tab name filled in by default.
  3. If the name is changed, save it. Oth­er­wise, revert to the old name.

We’ll also limit the abil­ity to rename a tab to just the cur­rently selected tab only.

Step 1: Click Tab Name To Edit.

For this, we’ll be tak­ing advan­tage of Live­Query to bind the click events to the selected tab’s span.

$(function() {
	// Initialize tabs with the default options
	$("#tabs").tabs();
	// Bind "click" event to the span, so that it calls the renameTab function
	$("li.ui-tabs-selected span").livequery("click", function(){
		renameTab(this);
	});
});
Step 2: Display input text with the tab name as default value

Now we need to cre­ate a func­tion to han­dle the “click”, and inject the form. We’ll also save the cur­rent tab name in a vari­able, and bind the save and can­cel buttons.

function renameTab(obj) {
	var  obj = $(obj),
		oldName = $(obj).html(),
		editMode = '<div class="editable"><form id="rename_tab_form"><input type="text" id="new_tab_name" value="' + oldName + '" name="new_tab_name" maxlength="20" /><button id="saveRename" class="btn"><span>Save</span></button><button id="cancelRename" class="btn"><span>Cancel</span></button></form></div>',
		form = $("#rename_tab_form");
	// Inject the form after the span, and then remove the span from DOM
	obj.after(editMode).remove();
	//We might not need this now, but it will be useful later when we add in validation
	$("div.editable", "#tabs-nav").closest("a").addClass("editing");
	$("#new_tab_name").bind("focus", function() {
		this.select();
	}).focus();

	$("#saveRename").bind("click", function() {
		$("#rename_tab_form").submit();
		return false;
	});

	$("#cancelRename").bind("click", function() {
		replaceName( false, this, oldName );
		return false;
	});
	$("body").bind("click", function(e) {
		var target = e.target.id;
		if ( target != 'cancelRename' ) {
			replaceName(false, $("#cancelRename"), oldName);
		}
		return false;
	});

	$("#rename_tab_form").bind("submit", function(e) {
		replaceName( true, $("#cancelRename"), $("#new_tab_name").val() );
		e.preventDefault();
		return false;
	});
}
Save or cancel?

Now that we’ve the form shown to the user and prop­erly bind them to an event, they could either save it, or can­cel it by click­ing the can­cel but­ton or any­where within the page. We write a func­tion to han­dle these request and han­dle them prop­erly. I’ve also included a check if the name is empty, it will be named as “Unti­tled” instead. But this could be removed based on your val­i­da­tion cri­te­ria later on.

// replaceName (boolean, object, value)
function replaceName(action, obj, val) {
	var name = '';

	if (action) { // If action is "true", we save the data
		// You could use the .ajax() method to save the data as you see fit
	} else {
		name = val;
	}

	if ( val == '' ) {
		val = 'Untitled';
	}

	$(obj).parents("div.editable").after('<span>'+ val +'</span>').remove();
	$("li.ui-tabs-selected span","#tabs-nav").closest("a").removeClass("editing");
	$("#saveRename, #cancelRename, body").unbind();

}

%

One Response to Renaming jQuery UI Tabs With Validation

great writeup — more to come?

or