jquery.tabPane()

Posted by stephen on February 26th, 2009

Everyone enjoys a good set of tabbed panes. I wrote jquery.tabPane to give us a simple way to do that, because this particular site is using Adobe Contribute as the CMS. Basically, you create some links to anchors, then tell this function what the containing elements for those are.

Usage

jQuery.tabPane(tabPaneSettings, callback);

Example

This isn’t so much of an example as a clarified description. If you want to see a sample, go here. It also has some HTML and CSS selectors you can use as a base, if you’d like.

Let’s say you have a list of anchor links, and several divs with content. You can point the tabPane settings at the containers of the links to those anchors (tabs), and the containers of those anchors (pane). The display/hide functionaly is handled for you, and you can style it any way you want.

Here you have it:

var paneSettings = {
	tabContainers:"div.pane-buttons li",
	contentContainers:"div.pane-content div.content-pane"
};
j.tabPane(paneSettings);

Getting an element’s html, not just the innerHTML

Posted by stephen on January 13th, 2009

The original content of this post involved a little function I wrote called “getNodeHtml”, which basically wrapped a given HTML element with a parent node, got the innerHTML of that temporary parent node, reset the DOM to its previous state, then returned the HTML string. I also used jQuery in the function, which seemed unnecessary to me.

Today I saw that IE has an outerHTML property, which does exactly what I need. I generally avoid giving IE credit, but they get a chocolaty kudos bar for this one.

The Array.indexOf() function I have gave me the idea to extend the prototype of the HTMLElement object so I could have it at my fingertips, and use the same property call in FF and IE (amoung others). After spending some time trying to add a “get outerHTML” property to the HTMLElement object, I found some useful info on Javascript Getters and Setters that pointed me in the right direction. The result…
if(document.__defineGetter__ && !HTMLElement.outerHTML){
HTMLElement.prototype.__defineGetter__(”outerHTML”, function(){
var parent = this.parentNode;
var span = document.createElement(”span”);
span.appendChild(this);
var HTML = span.innerHTML;
parent.appendChild(this);
delete span;
return HTML;
});
}

The __define[SG]etter__ methods do not exist in IE, so I’m still curious how to add a getter/setter to an existing prototype there. We could just create functions like value(’test’, ’set’) / value(null, ‘get’) or setValue(’test’) / getValue(), but bleh…those are methods, not properties.

********************UPDATE************************

I have found that manipulating the DOM momentarily to get the outerHTML of an element can cause some problems when you’re doing alot of DOM manipulation simultaneously. Instead, the following method builds the HTML of the current element by looping through its attributes - much more reliable!

if (document.__defineGetter__ && !HTMLElement.outerHTML) {
    HTMLElement.prototype.__defineGetter__("outerHTML", function(){
        var emptyTags = {
		   "img":   true,
		   "br":    true,
		   "input": true,
		   "meta":  true,
		   "link":  true,
		   "param": true,
		   "hr":    true
		};

		var attrs = this.attributes,
		tagName = this.tagName.toLowerCase(),
		str = "<" + tagName;
		for (var a = 0; a < attrs.length; a++)
		  str += " " + attrs[a].name + "=\"" + attrs[a].value + "\"";

		if (emptyTags[tagName])
		  return str + "/>";

		return str + ">" + this.innerHTML + "";

    });
}

jQuery.navActives - Navigation Highlighting

Posted by stephen on October 26th, 2008

Nav highlighting can be a little tricky. It usually gets tricky when there is more than one level of secondary nav.

How do we know to hide or show sublinks, and how do we know when to highlight an associated “Overview” link? Or, what if your page is not in the left nav links, but you still want to highlight its parent? The list of caveats grows as you try to answer those questions, so I set out to make something that applies to these squirrely situations, instead of having to write a custom function each time.

jQuery.navActives scans through a specified list of links and finds the clostest matches to a given url (generally the current address - window.location.href).

Usage

j("#yourlinkcontainer a").navActive(options, callback(this, activeLinks, highestMatch));

The call back function is passed 3 parameters. The jQuery object calling the callback (this), an array of the matching links (activeLinks), and the highest match rigidity found (highestMatch).

Like my other plugins, we need to pass it some settings. Here’s an example of what I use for some primary navigation:
var mainNavHighlight = {
matchUrl:currentPageUrl,
alterElements: [{element:"each", className:"active"}],
rigidity:[1]
};
j(”div#siteHeader a”).navActives(mainNavHighlight);

Notice the rigidity. That is basically the number of items past the main URL to compare. That is one reason I have the Home Page in a “/home/” directory.

It is important that you organize ALL sections and sub sections in their own folder. Here’s a complex example of a navigation list that has parent and sub lists:

var sideNavHighlight = {
matchUrl:currentPageUrl,
alterElements: [{element:"each", className:"current"},
{element:"each.parents('ul:first').parent().children('a')", className:"current"},
{element:"each.siblings('ul:first').find('a:first')", className:"current"}],
rigidity:[1,2,3]
};
j(”div#sideNav a”).navActives(sideNavHighlight, showActiveSubs);
function showActiveSubs(i, list, high){
jQuery.map(list, function(n){
if(n.rigidity>=2){
jQuery(n.link).parents(”ul”).css(”display”,”block”);
}
});
}

Notice the alterElements setting, the rigidity, and the showActiveSubs function that uses the list of matched URLs returned by navActives.

jQuery.selectorInspector - Modular CSS With Indentation

Posted by stephen on October 26th, 2008

This tool allows you to select a block of HTML, then customize CSS selectors for each of the child elements. The resulting block of CSS is considered “modular”, in that the corresponding HTML must follow a particular structure. Yes, this is already the basic concept behind CSS selectors, but stylesheet selectors tend to be much more vague and unorganized. This allows you to control and recognize the scope of styles much more easily.

This tool also makes use of jQuery.paneSizer.

jQuery.paneSizer

Posted by stephen on October 26th, 2008

This plugin was created to be used with jQuery.selectorInspector. The following example has not been simplified to showcase paneSizer.

This tool could use considerable improvement  on following the mouse, but I was having some glitches using the UI resizables from jQuery.

jQuery.selecteSizer - a fix for IE cutting off select dropdowns

Posted by stephen on October 23rd, 2008

You may have seen this before…you have select dropdowns that are set to a certain width in accordance to the design. Anyone using IE will click the dropdown, and if any of the option items are wider than the select element’s width, they’re cutoff. This can be extremely hindering where you have a select dropdown of products or resources that all begin with the same ~20 characters. Some people just want to see the full option, too.

I’ve only found one, semi-elegant solution, and that is resizing the select container to “width:auto” on the focus event, and setting it back to its original size on the blur (unfocus) event. You also need to toggle the position to absolute and set its position so it shows up in the correct spot.

I created jQuery.selecteSizer to do this automatically on all specified selects.

Example Usage

if(j.browser.msie){
j("select").selecteSizer();
}

jQuery.meshtml

Posted by stephen on October 14th, 2008

With tables being viewed as improper, overly-complicated structural markup, it surprises me sometimes how many divs and whatnots are required to achieve certain effects. It’s not efficient for us to create 6 divs for every container we want with rounded corners, when one or two would do for a rectangle. Even two divs can be somewhat complicated for clients unfamiliar with html, and we all know they still want to add pretty content.

jQuery.meshtml will replace or insert-into any element with a block of html (e.g. your complicated container markup). Here’s a quick sample:


var baseHtml = "<div>{$mesh}</div>";
var meshSettings = {base:baseHtml, replace:true};
j('.container-box').meshtml(meshSettings);

With replace set to true, the targeted elements will be replaced. Otherwise it will insert your block of html inside of the target elements.

What makes this more useful than the built in replaceWith, wrap, wrapInner and other methods is that our markup can be much more complicated, and we define exactly where we want the variable(s). By default, the variable name is “mesh”. Notice “{$mesh}” in baseHtml above. We can also define multiple variable names and what elements/content those reference. The keyword for the current element being inspected is “each”. See a more complex example of using meshtml below:

Note that you can use my getNodeHtml function so that you aren’t stuck with moving the innerHTML of the elements around. View the source of the complex example to see how.

jQuery function/plugin base

Posted by stephen on October 13th, 2008

A great article on creating your own jQuery plugins/functions.
http://www.learningjquery.com/2007/10/a-plugin-development-pattern

Here’s a quick sample. Serves well as a base…

jQuery.fn.functionName = function(options, callback){
var settings = {
setting: "a",
callback: null
};
if (options) {
jQuery.extend(settings, options);
}
var jQueryParent = this;
var objIdx = 0;
this.each(function(){
jQueryChild = jQuery(this);
//put all your goodies here
//execute the callbacks
if (settings.callback != null) {
settings.callback(this);
}
objIdx++;
});
if (callback != null) {
callback(jQueryParent);
}
return jQuery(this);
}

jQuery hover() and unbind()

Posted by stephen on October 13th, 2008

Quick tip on jQuery hover event. There is a gotcha you may also run into, which is similar to one I’ve found in Actionscript 3.0…obj.hover(function(){}) works as expected in Firefox and IE. Binding the mouseover event seems to get different results in FF and IE.

I was unable to unbind the hover event with obj.unbind(”hover”) and obj.unbind(”mouseover”), so I did some searching around and came across this post. Apparently, the hover() method binds to the mouseenter and mouseleave events, so I just needed to unbind those. Oddly, I haven’t seen those events anywhere in the jQuery event docs, along with several other properties and methods. I’m not sure where an actual complete reference is if their site doesn’t even have it…


Copyright © 2007 Stephen Rushing. All rights reserved.