_jQuery Accordion with 8 Lines of Code

Ok.  Maybe more than 8 lines of code but very little.  I have been working with another agency (that will rename nameless) on a mobile web site for a client of ours.  The agency provided the HTML/CSS/Images and Script for our technology team to implement.  We hook up all the back end and call it a day.

The section that came into question was an ‘accordion’ style UI for a set of FAQ’s and other content.  When I first loaded up their pages, everything worked fine.  Upon further inspection of their code I noticed a lot of JavaScript libraries that were not needed.  They included jQuery AND Prototype along with some effects and accordion scripts.  (Prototype alone is almost 100kb in file size and the other scripts were 42kb.  That still does not include the 70kb for jQuery)  I thought to myself, this is a mobile site…why have extra scripts if not needed.  To make matters even more funny, we are supporting Mobile Safari (iOS), Mobile Chrome (Android) and the BlackBerry Browser (RIM), it does not work in BlackBerry at all.  Forget enabling or disabling JavaScript it just does not work.  Even the elements are hidden.

So it got me thinking about the old saying, “if you want something done right you have to do it yourself”.  So I did.

I removed all the libraries except for jQuery and made all of the elements visible by default.  Basically if a user does not have JavaScript enabled then they can see everything.

Here is my HTML

<div>
     <a href="#">Really Great Information</a>
     <div class="accordion_content">
          Content that will expand
     </div>
     <a href="#">Really Great Information</a>
     <div class="accordion_content">
         Content that will expand again
     </div> 
</div>

Styles and other HTML can be wrapped around it. You can change the paragraph tags to div’s if needed but that is the structure you need more or less.

Now for the JavaScript.

Make sure you embed jQuery (I did from Google)

$('.accordion_content').hide();
//If JavaScript is not enabled, all content containers stay open, which is nice.

//Next, bind the click event to all of the targets, in this case all 'a' elements in the 'accordion_toggle' class
$('.accordion_toggle a').click(function(e){
     //code to come
});
//Within the click function we need to first check if the element being clicked is set as the 'current' which means open.  If it is, we need to remove the class 'current' and close the content container.
if($(this).parent().hasClass('current')) {
     $(this).parent()
          .removeClass('current')
          .next('.accordion_content').slideUp();
} else {
...
}

Then hide all open content containers:

If the element does not have the ‘current’ class then we need to first remove the ‘old’ ‘current’, close the ‘old’ ‘current’ and open and set the new ‘current’.

$(document).find('.current')
     .removeClass('current')
     .next('.accordion_content').slideUp();

$(this).parent()
     .addClass('current')
     .next('.accordion_content').slideDown();

Done.

Here is the final:

$(function() {
     $('.accordion_content').hide();
     $('.accordion_toggle a').click(function(e){
          if($(this).parent().hasClass('current')) {
               $(this).parent()
                   .removeClass('current')
                   .next('.accordion_content').slideUp();
          } else {
               $(document).find('.current')
                    .removeClass('current')
                    .next('.accordion_content').slideUp();
              $(this).parent()
                    .addClass('current')
                    .next('.accordion_content').slideDown();
          }
          e.preventDefault();
      });
});

Depending on how you format the code and what you count as a ‘line’ it can be about 8 lines :)

Demo here – View in Mobile Browser.  Desktop browser will work as well.  Works on iOS, Android, BlackBerry.

Mar
10
2011

_Android Activity Not Launching MapActivity

I have decided to play around with Android and started out using the Google API for Maps.  My goal is to create an app that has a tab view that you can tab through some info and on the tabs there will be a button to launch the Google Map to show the location of the point of interest and show where you are and provide directions.  I have the tab view working great but when I try to fire off an event for the MapActivity that is where it fails.

If I create my own MapActivity project it works fine, but when I include the class in my tab project it fails.

Here is what I have:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.location_tab);
...
Button btnMap = (Button) findViewById(R.id.btnMapview);
btnMap.setOnClickListener(mMapListener);
...
}

And my Listener

private OnClickListener mMapListener = new OnClickListener() {
        public void onClick(View v) {
        	Intent mapIntent = new Intent(getApplicationContext(),LocationMap.class);
        	startActivity(mapIntent);
        }
 };

And here is my Map Class:

public class LocationMap extends MapActivity {

	MapView mapView;
    MapController mc;
    GeoPoint p;

	@Override
	protected boolean isRouteDisplayed() {
	    return false;
	}

    /** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mapView = (MapView) findViewById(R.id.myMapView);
        mapView.setBuiltInZoomControls(true);

        mc = mapView.getController();
        String coordinates[] = {"40.750386", "-73.976773"};
        double lat = Double.parseDouble(coordinates[0]);
        double lng = Double.parseDouble(coordinates[1]);

        p = new GeoPoint(
            (int) (lat * 1E6),
            (int) (lng * 1E6));

        mc.animateTo(p);
        mc.setZoom(17);
        mapView.invalidate();

	}
}

I get a force close each time I click the button. I have swapped out my LocationMap.class with a standard activity class and that works fine. I have put my LocationMap class in it’s own project and that works fine as well, but together…no dice.

Any thoughts?  Here is my StackOverflow post

May
05
2010