Batfan
Batfan

Reputation: 8266

Jquery Sorting by Letter

I am using jquery to sort through a group of paragraph tags (kudos to Aaron Harun). It pulls the value "letter" (a letter) from the url string and displays only paragraphs that start with that letter. It hides all others and also consolidates the list so that there are no duplicates showing.

See the code:

var letter = '<?php  echo(strlen($_GET['letter']) == 1) ? $_GET['letter'] : ''; ?>'

function finish(){
    var found_first = [];
    jQuery('p').each(function(){     
    if(jQuery(this).text().substr(0,1).toUpperCase() == letter){
    if(found_first[jQuery(this).text()] != true){
        jQuery(this).addClass('current-series');
        found_first[jQuery(this).text()] = true;
    }else{
        jQuery(this).hide();
    }
    }
    else{ jQuery(this).hide();}
   })


}

Been working with this all day and I have 2 Questions on this:

  1. Is there a way to get it to ignore the word 'The', if it's first? For example, if a paragraph starts with 'The Amazing', I would like it to show up on the 'A' page, not the 'T' page, like it currently is.

  2. Is there a way to have a single page for (all) numbers? For example, the url to the page would be something similar to domain.com/index.php?letter=0 and this would show only the paragraph tags that start with a number, any number. I can currently do this with single numbers but, I would like 1 page for all numbers.

Upvotes: 1

Views: 902

Answers (1)

Mottie
Mottie

Reputation: 86413

Hiya! I ended up rewriting the script, but made a working demo for you :)

/* Return a unique array */
Array.prototype.getUnique = function(){
 var u = {}, a = [], i, l;
 for(i = 0, l = this.length; i < l; ++i){
  if(this[i] in u) continue;
  a.push(this[i]);
  u[this[i]] = 1;
 }
 return a;
}

/* Show paragraph containing first letter (or number if zero) */
function finish(letter){
 var t, txt, found = [];
 if (letter.match(/\d/)) { letter = "0"; } // set letter to zero if it is any number
 $('p').each(function(){
  // grab first 20 characters so we don't need to split the entire paragraph
  txt = $(this).text().substr(0,20).split(' ');
   if (txt[0].toLowerCase() == 'the') { txt.shift(); } // remove first element if it's "the"
  t = txt[0].match(/\d/) ? "0" : txt[0].substr(0,1).toLowerCase(); // set zero for digits or get first letter
  found.push(t); // Add letter/number to array
  if ((t == "0" && letter == "0") || t == letter.substr(0,1).toLowerCase()){ // show paragraph
   $(this).addClass('current-series').show();
  } else {
   $(this).hide();
  }
 })
 return found.getUnique().sort();
}

Update: Ok I finally understand what you mean by consolidated! YAY! You mean you only want the unique entries to show! I've updated the demo and I've also added a small script that grabs the letter variable from the URL, so you really don't need to use php for this:

Note in the demo, I had to remove the select list, but you can change the selected letter (for the demo only) by modifying this line:

 var letter = getletter() || '0';

Change the '0' to whatever letter you want to display (for the demo only). In the live version, it'll grab the letter from the URL automatically.

/* get letter from URL */
function getletter(){
 var p = (new RegExp("[\\?&]letter=([^&#]*)")).exec(window.location.href);
 return (p===null) ? "" : p[1];
}

/* Show paragraph containing first letter (or number if zero) */
function finish(){
 var t, txt, found = [];
 // get letter from url or set to zero if it doesn't exist
 var letter = getletter() || '0';
 // set letter to zero if it is any number
 if (letter.match(/\d/)) { letter = "0"; }
 $('p').each(function(){
  // grab first 20 characters so we don't need to split the entire paragraph
  txt = $(this).text().substr(0,20).split(' ');
  // remove first element if it's "the"
  if (txt[0].toLowerCase() == 'the') { txt.shift(); }
  t = txt[0].match(/\d/) ? "0" : txt[0].substr(0,1).toLowerCase(); // set zero for digits or get first letter
  // show paragraph if unique and matches letter
  if ((found[$(this).text()] != true) && ((t == "0" && letter == "0") || t == letter.substr(0,1).toLowerCase())){
   $(this).addClass('current-series').show();
   found[$(this).text()] = true;
  } else {
   $(this).hide();
  }
 })
}

Upvotes: 2

Related Questions