A Portfolio and blog for Mustafa Kurtuldu

DT-phpAccordian, a simple Accordion menu

With PHP, JSON and jQuery

Updates

This code was written a long time ago, and may no longer works on my serve.

Finally posted this code to create a simple accordian with PHP, JSON and jQuery based on a dev test I did for LoveFILM. You can get the code from github or simply look at it below. I also posted it to gist too so you can see each file example and a working demo aswell!.

First up the PHP

I added comments in the code to explain whats what. WE add the JSON parser in the head for organising sake. Two files are parsed, one questions and one answers.

<head>
  <meta charset="utf-8" />
	<title>Simple Accordion with php, json & jQuery</title>
	<link rel="stylesheet" type="text/css" href="includes/css/styles.css">
	<?php
		// Requests to load and parse the json files. 
		$jsonQuestions= file_get_contents("includes/json/questions.json", true); 
		$decodedJQ = json_decode($jsonQuestions, true);
		$numberOfQuestions = sizeof($decodedJQ[questions]);
 
		$jsonAnswers = file_get_contents("includes/json/answers.json", true);
		$decodeJA = json_decode($jsonAnswers, true);
	?>
</head>

Now we run a really simple loop to go over each element in the JSON file. The first questions relates to the first answer yada yada… We also check to see if the current item in the loop is the first one as we want to add a open/expanded class to it for later use in jQuery.

<div id="wrapper">
 
<?php
	// Simple for loop that lists each question and each answer. 
	for ($i=0; $i < $numberOfQuestions; $i++) { 
		echo "<article class='faq_container'><section class='faq_question'><header class='faq_header'>";
 
		// This if state checks to see if the current item we are looping is first.
		// If it is we add a class selector .plus if not we add .minus
		// The .plus and .minus selectors are simply the - & + signs in the accordian. 
		// With jQuery we add and remove them according to the currently selected menu. 
		
		if ( $i==0 ) { 
			echo "<h1 class='plus'>";
			echo $decodedJQ[questions][$i];
			echo "</h1></header><div class='expanded'>";
		}else {
			echo "<h1 class='minus'>";
			echo $decodedJQ[questions][$i];
			echo "</h1></header><div>";
		}
		echo $decodeJA[answers][$i];
		echo "</div></section></article>";
	}
?>
 
</div>

JSON

Two files, one with 3 questions the other with three answers.

Questions:

{"questions":
  {
	"0":"I’ve registered, but how do I start getting rental discs sent out to me?",
	"1":"How do I order a title I want to rent?",
	"2":"How many discs can I have at home at any one time and how much does it cost?"
	}
}

Answers:

{"answers":
  {
	"0":"<p>The first thing we need is for you to tell us which titles you'd like to rent, otherwise we won't be able to send you anything as we won't know which of our 70,000 titles you want us to send to you.</p><p>The way you do this is simply by adding titles to your list - which is known as the \"My Rental List\". You can add a title to your list using the \"Rent\" or \"Add\" button displayed next to its name wherever you see the title displayed on our website. You can see this button in lots of places on our website after you've registered an account with us. For example it's next to all the titles on our home page after you've logged in, it's in the search results when looking for a title, and it's on the page you see when you've clicked on a title to read more about it.</p><p>Once you have created a list of titles, there is nothing more you need to do, we'll automatically select your first rentals from the list you've created and send them out to you on the next working day. We recommend having at least 10 titles on your list at all times, or there can be delays in sending your next rental. To save you from having to keep topping up the list regularly, feel free to add far more than 10 titles, the more the better!</p>","question_number":"0",
	
	"1":"<p>With our service, you don't need to process an \"order\" each time you want to rent a title.</p><p>We'll start sending you rentals shortly after you've registered and created a list of titles that you'd like to rent, which is called the My Rental List. You can add a title to your list using the \"Rent\" or \"Add\" button displayed next to its name wherever you see the title displayed on our website after you've signed in.</p><p>Once you have created a list of titles, there is nothing more you need to do, no 'order' as such needs to be made, we'll simply select your first rentals from the list you've created and send them out to you on the next working day. We recommend having at least 10 titles on your list at all times, or there can be delays in sending your next rental. To save you from having to keep topping up the list regularly, feel free to add far more than 10 titles, the more the better!</p><p>If you find that you'd like to see certain titles sooner than others then you can indicate this to us by setting those titles to be at High Priority, and the rest at Medium or Low Priority. We can't always promise we will always be able to send your highest priority titles as your next disc, but we will always do our very best to try whenever you tell us which ones they are with the priority buttons.</p>","question_number":"1",
 
	"2":"<p>The number of discs you can have at home at any one time depends on the package you take. Our service works on a subscription basis, and we send you either 1, 2, or 3 discs at a time from a list of DVDs you select. When you return a disc we send the next one.</p><p>You can see the full list of our current packages <a href=\"http://www.lovefilm.com/dvd-rental/\">here</a> (just click on \"Packages\")</p><p>If you want to change the package you're currently on, simply go to the Change Package page to go to the list of packages we currently offer and pick the right one for you.(Please note however that this is not available to customers who are currently enjoying either a free trial period or a gift subscription).</p>","question_number":"2"
	}
}

jQuery

I will at some point attempt to do this with pure JavaScript but for now here is some jQuery.

// jQuery
$(document).ready(function (){
  // if js is present we remove the no-script class from the body. 
	// no-script displays all of the menu items and prevents them from being hidden.
	$("body").removeClass("no-script").addClass("js");

	// The first item in our stack / accordian is expanded. First we want to target it.
	var openStack = $(".expanded");

	// Now we want to hide all the other stacks / accodian menu items
	$(".faq_question").find("div:not(.expanded)").hide();

	// A bit of bubble magic....
	// We place a click event on the each stack / accodian menu container
	$(".faq_question").click(function (e) {
		$container = $(this);
		$h1 = $container.find("h1");
		$div = $container.find("div");
		$plus = $(".plus");

		// This is to check what has been click
		var t = e.target; 

		// This gives us a true or false. What its check is to see if a H1 tag has been click, if so its true
		// if not then its false.
		var compare = t.tagName == $h1.get(0).tagName;

		// Now we check to see if the clicked item is a H1 and is NOT expanded. 
		if (compare && !$div.hasClass("expanded")) {
			// Then we remove the plus class to the currently expanded stack...
			$plus.removeClass("plus").addClass("minus");
			// ...and add it to the newly clicked menu heading...
			$h1.addClass("plus").removeClass("minus");

			//...then we close the currently opened stack...
			openStack.removeClass("expanded").slideUp();

			//...and open the newly clicked stack content...
			$div.slideDown().addClass("expanded");
			
			//...and finally we reset the variable so its set to the newly open/expanded/selected stack.
			openStack = $div;
		}
		return false;
	})
});