In this post I'll show you how to use SharePoint's content query web part to build an expanding and collapsing question and answer list on a web page.
I'll assume that you already have a SharePoint list populated with questions and answers. My list for this demo has the question in the Title field and the answer in the Description field, but you can use any columns from any list, you'll just have to do some tweaking, which I'll discuss later.
So, diving right in... we need to modify the xsl style sheet files that control the output of the content query web part. There are three of these: ItemStyle.xsl, Header.xsl and ContentQueryMain.xsl. All three of these files are in your site's style library. To get there click Site Actions -> View All Site Content then click on the library "<Your Site Name> Global Styles"; the xsl files are in the XSL Style Sheets folder:
ItemStyle.xsl contains several pre-defined item templates, one of which will be applied to every item shown in your content query web part. We'll be creating a new item style template which will render each question and answer using a pair of div tags. Get a local copy of ItemStyle.xsl by pulling down the file's context menu, clicking Send To -> Download a Copy.
Open the file in your favorite xml editor and insert the following code before the closing </xsl:stylesheet> tag:
<xsl:template name="QuestionAndAnswer" match="Row[@Style='QuestionAndAnswer']" mode="itemstyle">
<xsl:variable name="QuestionDivId">cbq_q_<xsl:value-of select="@ID" /></xsl:variable>
<xsl:variable name="AnswerDivId">cbq_a_<xsl:value-of select="@ID" /></xsl:variable>
<xsl:variable name="DisplayTitle">
<xsl:value-of select="@Title" />
</xsl:variable>
<div class="cbq-item">
<div class="cbq-question" id="{$QuestionDivId}">
<span onclick="toggleQAAnswer('{$AnswerDivId}');"><xsl:value-of select="$DisplayTitle"/></span>
</div>
<div class="cbq-answer" id="{$AnswerDivId}">
<xsl:value-of select="@Description" disable-output-escaping="yes" />
</div>
</div>
</xsl:template>
There are a few things worth noting in the code above: First, note the template name "QuestionAndAnswer" and the matching row style filter. These tie into the content query web part when you choose the item style in the appearance section. Secondly, note how we're generating a unique div id for each item using the item's ID field from the SharePoint list. This will work for most cases, but you will have to come up with something more creative for generating ids if you plan on having more than one of these Q/A web parts on the page at a time, otherwise the expanding and collapsing won't work as expected.
Lastly, note the CSS class names on the divs and the onclick event in the questions span tag. These handle the expanding and collapsing and tie into the CSS and javascript we'll add shortly.
Save your changes and upload and check-in your new ItemStyle.xsl.
Now on to the CSS. Typically I include a site specific css file and link it in via the master page. Whatever your case, add the following CSS classes to your site's stylesheet:
.cbq-question
{
margin:5px 0px;
font-weight:bold;
color:#042453;
}
.cbq-question span
{
cursor:pointer;
}
.cbq-answer {
margin:10px 10px 10px 20px;
font-style:italic;
color:#585880;
display:none;
}
Obviously, you'll want to tweak colors and such to match your site, but the main takeaways from this css code are the display:none attribute on the answer style and the cursor:pointer on the span tag inside the question div. These hide the answer by default and make the question look clickable.
The last code change we need to make is to add the javascript to make the expanding and collapsing work. Again, I typically include a site specific .js file with these types of scripts. Add the following to yours:
// toggles an answer div from visible to hidden or hidden to visible
function toggleQAAnswer(answerDivId)
{
var answerDiv = document.getElementById(answerDivId);
if ( answerDiv != null)
{
var currentDisp = answerDiv.style.display
var disp = ( ( currentDisp == "" || currentDisp == "none" ) ? "block" : "none" );
answerDiv.style.display = disp;
}
}
As you can see this script simply accepts the div id for the answer div and toggles the display property appropriately. Save and check-in your changes.
Now all that's left to do is to add a content query web part to our page and set it up to use the new QuestionAndAnswer style:
Open your page and add a Content Query Web Part:

In the query section of the settings, choose the list that holds your questions and answers:

In the Styles section, set the item style to our new QuestionAndAnswer style:

With all that done, your page should look something like the following:
That's it! If you think about it, there are literally tons of ways to apply this type of customization to the content query web part, be creative!
-ed
More Resources