Monday, September 6, 2010

Sitecore Fetch Squad

Automated crawler fetching websites and blogs from Sitecore content

My first jQuery plug-in - Element Expander

Crawled: On January - 21 - 2009 Source

I wanted to have a go at writing a jQuery plug-in. I also wanted to shrink the screen space that some of my blogs took up. So I wanted plug-in that allowed me to shrink a blog entry with a link at the bottom to expand the blog to see the full article.

To download the plug-in click ExperimentsInCode.jQuery.ExpandableElement.js (3.45 kb)

The result was a tool that allowed me to shrink any element to a set size that can then can be expanded, for example:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam ipsum elit, elementum at, luctus a, scelerisque et, leo. Phasellus purus velit, dictum eget, aliquam in, varius nec, dui. Vestibulum gravida tempus velit. Nullam elementum consectetur nisi. Nulla dapibus, nunc sit amet semper feugiat, leo tortor commodo elit, sit amet congue est ipsum at augue. Quisque in tellus. Nam tellus diam, tincidunt eu, pellentesque at, ultrices et, urna. Donec pretium tempus nunc. Etiam ligula urna, eleifend quis, gravida eu, dictum ut, purus. Phasellus et nibh id arcu vestibulum scelerisque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam hendrerit facilisis dui. Aenean odio pede, bibendum eu, interdum nec, vehicula sed, nibh. Cras a orci vitae mi consequat elementum. Fusce porta pede et sapien. Maecenas interdum posuere libero. Quisque risus purus, gravida quis, tempus quis, tempus ac, nunc. Maecenas posuere congue quam. Phasellus varius.

The code to get this to work is pretty simple:

$j('#expanderExample1').expandable({
length:50
});

The plugin allows the following parameters to be passed:

Name Description Default
length The length/height that the element should be. Elements that are 110% bigger than this length will be shrunk. For example if I have two elements, element A has a height of 500px and element B has a height of 180px. If I set the length to 200px then element A will be shrunk but element B will not. The system adds 10% to the length value when deciding if it should shrink and element, so for example an element of 210px high would not be shrunk despite being large than 200px. 300px
moreText The link text displayed to expand the element more
lessText The link displayed to shrink the element less
animateOver This is the animation to play when the user hovers over the expandable element. The animation is applied to the link text. The animation is included to draw the user to the link. The default will double the size of the link text. The function that is called must accept a single parameter, this is the link object.
		    function(obj) {
			    $(obj).animate({
			        fontSize: "2em"
			    });
			}
			
animateOff This animation is played when the user moves their mouse off an area that can be expanded. The default is to shrink the text back to it’s original size. The function that is called must accept a single parameter, this is the link object.
            function(obj) {
			    $(obj).animate({
			        fontSize: "1em"
			    });
			}
			

To change the default animation we just need to pass in the animationOn and animationOff functions:

In facilisis turpis. Pellentesque eget elit id turpis consequat luctus. Phasellus nibh. Sed eu libero a tellus luctus adipiscing. Ut vel urna. Duis ipsum massa, suscipit vitae, vulputate sed, bibendum in, elit. Donec in pede ut velit ultricies faucibus. Fusce vel nunc eget urna semper sodales. Nullam at risus in urna dictum eleifend. Sed nec nisi. Maecenas vitae erat. Donec non sapien. In accumsan cursus libero. Nulla facilisi. Fusce nisi eros, feugiat at, tristique ac, mattis eu, libero. Maecenas sem mi, ultricies eu, cursus ac, egestas quis, erat. In sed nisl. Vestibulum eleifend ornare metus. Etiam faucibus pulvinar lectus.

The code to get this animation to work is:

$j(function(){
    $j('#expanderExample2').expandable({
        length: 50,
        animateOver: function(obj) {
            $j('#expanderExample2 ~ div > .expandable_link').css("position", "relative");
            obj.animate({
                "fontSize": "2em",
                "left": "+=50px"
            });
        },
        animateOff: function(obj) {
            obj.animate({
                "fontSize": "1em",
                "left": "10px"
            });
        }
    });
});

The most important line is:

 $j('#expanderExample2 ~ div > .expandable_link').css("position", "relative");

This needs to be added before the animation is played so that the move left command will work. If you don’t set the position value the text stays where it is. I have to select a sibling and then the link because the expander code creates a container item around the element that needs to be expanded and then adds a link as a child of the new container. This diagram shows you how the elements end up:

    Container
        |-> Your Element
        |-> More Link Container
            |-> More Link

There are still some bits that I am not happy with. In particular having to pass a parameter into the animateOver and animateOff functions. I would prefer to use $(this) within the function but I can’t work out how to make it work. I am calling the animations with the following:

        $(link).stop();
        $(link).each(options.animateOver($(link)));
    

It would be nice to do something like:

        $(link).stop();
        $(link).each(options.animateOver());
    

The function would then assume that $(this) would be the link object.

One important part of the code which I had to work on when I started to write the post was the effect of nested expandable elements. Nesting caused the whole thing to fall over, so I added the following code to ensure on the correct link was selected. This to me doesn’t seem like the best solution but it works:

        //this ensures that nested expanders don't clash
        var linkAry = $(".expandable_link", newContainer);
        var link = null;
        for (var i = 0; i < linkAry.length; i++) {
            if ($($($(linkAry[i]).parent().get(0)).parent().get(0)).html() == $(newContainer).html()) {
                link = $(linkAry[i]);
            }
        }
    

I have plans to expand on this basic functionality; maybe make it so that you can expand both the width and height.Sometimes it also produces excess white space but that is for later, for now I should go and have breakfast.


Mike’s Blog

Comments are closed.