Expanding and Collapsing Large Fields, DataView Style

Okay, got a fun one today. I was asked by someone who had a list if the description column could be collapsed and expanded. Currently if you have a list with a description field and put the description field on a view, you're left with a large verbose scrolling piece of ugliness. After a few vanilla latte's and some dead brain cells I came up with what I thought was a pretty good solution (without having to resort to writing a custom Web Part). Here's the solution.

  1. First create the list or decide what list you're using. It can be any list but the reason we're doing this is because we want to show a description field or something that would have a lengthy bit of text.
  2. Create a new Web Part page and put the list on it with the view you want to use.
  3. Now load up the page in FrontPage 2003
  4. Right click on the list and choose "Convert to XSLT..." to convert it into a DataView
  5. Somewhere down in the page source for the DataView there's the XSLT code to display the Description field you want this to work on. In my example I have a field called Description so you'll see something like this:

    <!--Description-->

    <TD Class="{$IDAEAF1I}">

    <xsl:value-of disable-output-escaping="yes" select="ddwrt:AutoNewLine(string(@Description))"/>

    </TD>


  6. Now we want to change the output to show our collapsed or expanded text. This is done by surrounding the XSL tag with some regular HTML and a reference to some JavaScript (yes, horrors of horrors) that we'll add to the page later. So change your XSLT code to your liking but it'll be something like this:

    <!--Description-->

    <TD Class="{$IDAEAF1I}" width="200px" bgcolor="#ffff00">

        <a title="Show/Hide" href="javascript: void(0);" onclick="toggle(this);">

            <div>

                <xsl:value-of disable-output-escaping="yes" select="ddwrt:AutoNewLine(string(@Description))"/>

            </div>

        </a>

    </TD>


    In the example above, I've done a few things: Fixed the width of the TD surrounding the Description field to 200 pixels; Given it a yellow background so it stands out; and added the reference to our JavaScript function called "toggle" in the OnClick event of the new link surrounding our XSL output.
  7. Now we'll add a simple piece of JavaScript (yeah, you knew this was coming) to the page through a Content Editor Web Part. Add it to the page then in the Source View add this JavaScript:

    <script language="javascript">

    var isCollapsed = false;

    var fullText = "";

    function trimText(text, size)

    {

        var tmp = "";

        tmp = text.substring(0, size);

        tmp += "...";

        return tmp;

    }

    function toggle(link)

    {

        if (isCollapsed == true)

        {

            link.innerHTML = fullText;

            isCollapsed = false;

        }

        else

        {

            fullText = link.innerHTML;

            link.innerHTML = trimText(fullText, 60);

            isCollapsed = true;

        }

    }

    </script>


    This will get a copy of the Description field and save it (for restoring later) and trim the text down by the amount you specify (I've put in 60 here but adjust as you see fit).

That's it. Here's what the DataView Web Part looks expanded:

And here it is collapsed after clicking on the Description:

Simple and easy. Hope that helps.

4 Comments

  • Surely putting the Javascript into a content editor webpart leaves it rather vulnerable? I'd certainly be nervous about leaving that lying around for people to fiddle with.



    Would it not be better to have a custom ows.js registered with all of your templates by editing the default templates (with the appreciation that this needs to be done _before_ site creation)?

  • Am I wrong or are your javascript variables unique for the whole page ?

    How can this be working when there are many lines in your list ? How can your variables save state for every lines ?

  • FatEric, do you mean the saving state between postbacks? Going by the javascript above you'd certainly lose any toggling after a postback.



    It's good practise to prefix any global javascript variable names (even if you put them in a custom ows.js with your company name or something easily-identifiable that is unlikely to be duplicated elsewhere to avoid duplications of function names...

  • This is a DVWP on a list so the only postbacks you have are if you use the sorting or filtering features. Yes, it does reset the JavaScript but the goal that was asked here was to do something simple to reduce the clutter when you do have lots of items on the screen. You can default all the collapsed values to true so it starts in that state.



    As to Erics comment about the variables, they're in a separate web part and through various magic you can toggle multiple items independantly. Again, this was a short excercise which solved the problem. There are certainly more robust ways to do this (including writing a full blown web part).



    Thanks for your comments.

Comments have been disabled for this content.