0

I am wanting to use Collapsible DIVs to show and hide content from the user.

I found this jQuery code to do the expand and collapse: http://webcloud.se/code/jQuery-Collapse/

However the content is already loaded in the divs (its just hidden from view).

So I then found this: http://www.raymondcamden.com/index.cfm/2011/4/5/Collapsible-content-and-Ajax-loading-with-jQuery-Mobile

Which loads the content into the opening div but also unloads it when it closes!

However its all mixed in with jQuery mobile and so it styled. I want to be able to style the divs myself. also the first example uses nice bounce or fade effects to bring the content into view.

The reason for doing this is I want to show the user different content such as images or flash files but I don't want everything to load into the page on page load, this would be too much stuff.

So how can I use the first jQuery Collapse example but with loading external pages in?

russian box
  • 167
  • 4
  • 10
  • This question isn't very specific, or clear, but I'll try to do the best I can in understanding what you're after. It sounds like you want to use `ajax` to make a sever call and replace the collapsed `div` with the ajax response string. – Ryan Jun 16 '12 at 02:44
  • I'm wanting to use this: http://webcloud.se/code/jQuery-Collapse/ but have content from different pages load into the area. like this does: http://www.coldfusionjedi.com/demos/april52011/test.cfm but with the styling and extra options (such as animations) that the first link (jQuery-Collapse) gives you. does that help? – russian box Jun 16 '12 at 02:49
  • You may find this helpful: http://stackoverflow.com/a/27139899/1922144 – davidcondrey Nov 26 '14 at 01:35

3 Answers3

1

I liked the question so I spent a little time making something close to a plugin:

//only run the event handler for collapsible widgets with the "data-url" attribute
$(document).delegate('.ui-collapsible[data-url] > .ui-collapsible-heading', 'click', function () {

    //cache the collapsible content area for later use
    var $this = $(this).siblings('.ui-collapsible-content');

    //check if this widget has been initialized yet
    if (typeof $this.data('state') === 'undefined') {

        //initialize this widget

        //update icon to gear to show loading (best icon in the set...)
        $this.siblings('.ui-collapsible-heading').find('.ui-icon').removeClass('ui-icon-plus').addClass('ui-icon-gear')

        //create AJAX request for data, in this case I'm using JSONP for cross-domain abilities
        $.ajax({

            //use the URL specified as a data-attribute on the widget
            url           : $this.closest('.ui-collapsible').data('url'),
            type          : 'get',
            dataType      : 'jsonp',
            success       : function (response) {

                //get the height of the new content so we can animate it into view later
                var $testEle   = $('<div style="position:absolute;left:-9999px;">' + response.copy + '</div>');
                $('body').append($testEle);
                var calcHeight = $testEle.height();

                //remove the test element
                $testEle.remove();

                //get data to store for this widget, also set state
                $this.data({
                    state         : 'expanded',
                    height        : calcHeight,
                    paddingTop    : 10,
                    paddingBottom : 10

                //add the new content to the widget and update it's css to get ready for being animated into view
                }).html('<p>' + response.copy + '</p>').css({
                    height        : 0,
                    opacity       : 0,
                    paddingTop    : 0,
                    paddingBottom : 0,
                    overflow      : 'hidden',
                    display       : 'block'

                //now animate the new content into view
                }).animate({
                    height        : calcHeight,
                    opacity       : 1,
                    paddingTop    : $this.data('paddingTop'),
                    paddingBottom : $this.data('paddingBottom')
                }, 500);

                //re-update icon to minus
                $this.siblings('.ui-collapsible-heading').find('.ui-icon').addClass('ui-icon-minus').removeClass('ui-icon-gear')
            },

            //don't forget to handle errors, in this case I'm just outputting the textual message that jQuery outputs for AJAX errors
            error         : function (a, b, c) { console.log(b); }
        });
    } else {

        //the widget has already been initialized, so now decide whether to open or close it
        if ($this.data('state') === 'expanded') {

            //update state and animate out of view
            $this.data('state', 'collapsed').animate({
                height        : 0,
                opacity       : 0,
                paddingTop    : 0,
                paddingBottom : 0
            }, 500);
        } else {

            //update state and animate into view
            $this.data('state', 'expanded').animate({
                height        : $this.data('height'),
                opacity       : 1,
                paddingTop    : $this.data('paddingTop'),
                paddingBottom : $this.data('paddingBottom')
            }, 500);
        }
    }

    //always return false to handle opening/closing the widget by ourselves
    return false;
});​

The collapsible HTML looks like this:

<div data-role="collapsible" data-url="http://www.my-domain.com/jsonp.php">
    <h3>Click Me</h3>
    <p></p>
</div>

Here is a demo: http://jsfiddle.net/YQ43B/6/

Note that for the demo I found the best way to make the initial animation smooth was to add this CSS:

.ui-mobile .ui-page .ui-collapsible .ui-collapsible-content {
    padding-top    : 0;
    padding-bottom : 0;
}​

The default padding added by jQuery Mobile is 10px for both top and bottom paddings, I added those values as data-attributes to each widget to maintain the defaults.

Note that this code can be slightly tweaked to show other types of content, I used JSONP simply because you can use it on JSFiddle.

Jasper
  • 75,717
  • 14
  • 151
  • 146
  • I'm trying it out now, but no matter what I do the text keeps getting cut off. even when I copy the code straight from the jsfiddle :S however this does seem to be the right type of thing, i think my biggest issue will be styling it so it doesn't have any of the mobile css styling. – russian box Jun 16 '12 at 20:47
0

Here is an example that I made :

         $(document).ready(function () {
               $('.accordian_body').hide();
                 });


         $('.accordian_head').click(function () {
            $(this).next().animate(
        { 'height': 'toggle' }, 'fast'
        );

Then in HTML

   <div class="accordian_head"></div>
   <div class="accordian_body"></div>

in CSS you can style the head and body however you like , to add in code behind -

   <asp:Literal ID="lit1" runat="server" />


    foreach(DataRow dr in DataTable.Rows)
     {
         lit1.Text = lit1.Text + "<div class=\"accordian_head\">" Whatever you want... "</div><div class=\"accordian_body\">" Whatever in body "</div>
      }
Scott Selby
  • 9,420
  • 12
  • 57
  • 96
  • I think you missed out a }) at the end of the first bit of code. I tried implementing this in a jsfiddle but i couldn't get it to work. I'm a beginner with this type of thing, so I might not be implementing this right. – russian box Jun 16 '12 at 03:33
  • There's no Ajax here, the content is just being preloaded into the divs. – LukeGT Jun 16 '12 at 03:38
  • if you want this to work in jsfiddle - you have to put something in the _head and _body div's , I was just making an example because you said you wanted to fill them dynamically - so I provided asp:Literal to fill them from code behind – Scott Selby Jun 16 '12 at 03:42
  • well I can pre-load the content with the first link example, that's not what I want to do because its loading too much stuff. I want to let the user say when to load in the content. as maybe they wont want to. @Scott, oh I see. I was wondering about the asp stuff. yeah its going to be a php page so it does need jquery and ajax. Thanks for trying – russian box Jun 16 '12 at 03:43
0

Check this link it's in php and shows how to load external link to DIV Ajax can load only internal pages and doesn't work across domains.

laspalmos
  • 149
  • 1
  • 3
  • 20
  • The page I want to link is within my domain, one is full of pictures and another has flash files. i want it to load when a user clicks not when the page is made. My page is already php and loading values in for this. – russian box Jun 16 '12 at 03:40