, nested DOM nodes, etc)
+ //
function addClasses() {
- var str, firstChar, firstWord, spl, $this, hasPrefixes = (opts.prefixes.length > 0); $($list).children().each(function() {
- $this = $(this), firstChar = '', str = $.trim($this.text()).toLowerCase(); if (str != '') {
- if (hasPrefixes) { spl = str.split(' '); if ((spl.length > 1) && ($.inArray(spl[0], opts.prefixes) > -1)) { firstChar = spl[1].charAt(0); addLetterClass(firstChar, $this, true); } }
- firstChar = str.charAt(0); addLetterClass(firstChar, $this);
- }
+ var str, firstChar, firstWord, spl, $this, hasPrefixes = (opts.prefixes.length > 0);
+ var letters = [' '];
+ var specials = ['.', '/', '?'];
+ function remember (letters, letter) {
+ if (letters.indexOf (letter) === -1 && specials.indexOf (letter) === -1 && isNaN(letter)) {
+ letters.push (letter);
+ }
+ }
+ $($list).children().each(function() {
+ $this = $(this), firstChar = '', str = $.trim($this.text()).toLowerCase();
+ if (str !== '') {
+ if (hasPrefixes) {
+ spl = str.split(' ');
+ if ((spl.length > 1) && ($.inArray(spl[0], opts.prefixes) > -1)) {
+ firstChar = spl[1].charAt(0);
+ remember (letters, firstChar);
+ addLetterClass(firstChar, $this, true, letters);
+ }
+ }
+ firstChar = str.charAt(0);
+ remember (letters, firstChar);
+ addLetterClass(firstChar, $this, false, letters);
+ }
});
+ letters = letters.sort ();
+ letters [0] = '_';
+ letters.push ('-');
+ return letters;
+ }
+
+ function addLetterClass(firstChar, $el, isPrefix, letters) {
+ // Deployed with SRF 1.9 to recognize the data-sortkey
+ var sortKey = String( $el.data( 'sortkey' ) );
+ if ( sortKey !== 'undefined' ){
+ firstChar = sortKey.toLowerCase();
+ } else {
+ if (!isNaN(firstChar)) {
+ firstChar = '_'; // use '_' if the first char is a number
+ } else if (letters.indexOf (firstChar) === -1) {
+ firstChar = '-'; // not a special symbol, so considered "other"
+ }
+ }
+
+ $el.addClass('ln-' + firstChar);
+
+ if (counts[firstChar] === undefined) counts[firstChar] = 0;
+ counts[firstChar]++;
+ if (!isPrefix) allCount++;
}
- function addLetterClass(firstChar, $el, isPrefix) { if (/\W/.test(firstChar)) firstChar = '-'; if (!isNaN(firstChar)) firstChar = '_'; $el.addClass('ln-' + firstChar); if (counts[firstChar] == undefined) counts[firstChar] = 0; counts[firstChar]++; if (!isPrefix) allCount++; }
- function addDisabledClass() { for (var i = 0; i < letters.length; i++) { if (counts[letters[i]] == undefined) $('.' + letters[i], $letters).addClass('ln-disabled'); } }
- function addNoMatchLI() { $list.append('
' + opts.noMatchText + ''); }
- function getLetterCount(el) { if ($(el).hasClass('all')) return allCount; else { var count = counts[$(el).attr('class').split(' ')[0]]; return (count != undefined) ? count : 0; } }
+
+ function addDisabledClass(letters) {
+ for (var i = 0; i < letters.length; i++) {
+ if (counts[letters[i]] === undefined) $('.' + letters[i], $letters).addClass('ln-disabled');
+ }
+ }
+
+ function addNoMatchLI() {
+ $list.append('
' + opts.noMatchText + '');
+ }
+
+ function getLetterCount(el) {
+ if ($(el).hasClass('all')) return allCount;
+ else {
+ var count = counts[$(el).attr('class').split(' ')[0]];
+ return (count !== undefined) ? count : 0; // some letters may not have a count in the hash
+ }
+ }
+
function bindHandlers() {
- if (opts.showCounts) { $wrapper.mouseover(function() { setLetterCountTop(); }); }
- if (opts.showCounts) { $('a', $letters).mouseover(function() { var left = $(this).position().left; var width = ($(this).outerWidth({ margin: true }) - 1) + 'px'; var count = getLetterCount(this); $letterCount.css({ left: left, width: width }).text(count).show(); }); $('a', $letters).mouseout(function() { $letterCount.hide(); }); }
+
+ // sets the top position of the count div in case something above it on the page has resized
+ //
+ if (opts.showCounts) {
+ $wrapper.mouseover(function() {
+ setLetterCountTop();
+ });
+ }
+
+ // mouseover for each letter: shows the count above the letter
+ //
+ if (opts.showCounts) {
+ $('a', $letters).mouseover(function() {
+ var left = $(this).position().left;
+ var width = ($(this).outerWidth({ margin: true }) - 1) + 'px'; // the -1 is to tweak the width a bit due to a seeming inaccuracy in jquery ui/dimensions outerWidth (same result in FF2 and IE6/7)
+ var count = getLetterCount(this);
+ $letterCount.css({ left: left, width: width }).text(count).show(); // set left position and width of letter count, set count text and show it
+ });
+
+ // mouseout for each letter: hide the count
+ //
+ $('a', $letters).mouseout(function() {
+ $letterCount.hide();
+ });
+ }
+
+ // click handler for letters: shows/hides relevant LI's
+ //
$('a', $letters).click(function() {
- $('a.ln-selected', $letters).removeClass('ln-selected'); var letter = $(this).attr('class').split(' ')[0]; if (letter == 'all') { $list.children().show(); $list.children('.ln-no-match').hide(); isAll = true; } else {
- if (isAll) { $list.children().hide(); isAll = false; } else if (prevLetter != '') $list.children('.ln-' + prevLetter).hide(); var count = getLetterCount(this); if (count > 0) { $list.children('.ln-no-match').hide(); $list.children('.ln-' + letter).show(); }
- else $list.children('.ln-no-match').show(); prevLetter = letter;
+ $('a.ln-selected', $letters).removeClass('ln-selected');
+
+ var letter = $(this).attr('class').split(' ')[0];
+
+ if (letter == 'all') {
+ $list.children().show();
+ $list.children('.ln-no-match').hide();
+ isAll = true;
+ } else {
+ if (isAll) {
+ $list.children().hide();
+ isAll = false;
+ } else if (prevLetter !== '') $list.children('.ln-' + prevLetter).hide();
+
+ var count = getLetterCount(this);
+ if (count > 0) {
+ $list.children('.ln-no-match').hide(); // in case it's showing
+ $list.children('.ln-' + letter).show();
+ }
+ else $list.children('.ln-no-match').show();
+
+ prevLetter = letter;
}
- if ($.cookie && (opts.cookieName != null)) $.cookie(opts.cookieName, letter); $(this).addClass('ln-selected'); $(this).blur(); if (!firstClick && (opts.onClick != null)) opts.onClick(letter); else firstClick = false; return false;
+
+ if ($.cookie && (opts.cookieName !== null)) $.cookie(opts.cookieName, letter);
+
+
+ $(this).addClass('ln-selected');
+ $(this).blur();
+ if (!firstClick && (opts.onClick !== null)) opts.onClick(letter);
+ else firstClick = false;
+ return false;
});
}
- function createLettersHtml() {
- var html = []; for (var i = 1; i < letters.length; i++) { if (html.length == 0) html.push('
ALL0-9'); html.push('
' + ((letters[i] == '-') ? '...' : letters[i].toUpperCase()) + ''); }
- return '
' + html.join('') + '
' + ((opts.showCounts) ? '
0
' : '');
+
+ // creates the HTML for the letter links
+ //
+ function createLettersHtml(letters) {
+ var html = [];
+ for (var i = 1; i < letters.length; i++) {
+ if (html.length === 0) html.push('
ALL0-9');
+ html.push('
' + ((letters[i] == '-') ? '...' : letters[i].toUpperCase()) + '');
+ }
+ return '
' + html.join('') + '
' + ((opts.showCounts) ? '
0
' : ''); // the styling for ln-letter-count is to give us a starting point for the element, which will be repositioned when made visible (ie, should not need to be styled by the user)
}
+
init();
});
- }; $.fn.listnav.defaults = { initLetter: '', includeAll: true, incudeOther: false, includeNums: true, flagDisabled: true, noMatchText: 'No matching entries', showCounts: true, cookieName: null, onClick: null, prefixes: [] };
+ };
+
+ $.fn.listnav.defaults = {
+ initLetter: '',
+ includeAll: true,
+ incudeOther: false,
+ includeNums: true,
+ flagDisabled: true,
+ noMatchText: 'No matching entries',
+ showCounts: true,
+ cookieName: null,
+ onClick: null,
+ prefixes: []
+ };
})(jQuery);