Jquery slide down within a group

Hi

I have 4 buttons that when clicked reveal the appropriate div eleemnt

Here is my example:
http://dev.openwaterdesign.com/

I want to toggle the "+" symbols and obviously the div
I cant get it to work as it should - any ideas?

Jquery is:
$(".template1 .icon-reveal").click(function() {
  $el = $(this).attr('class').split(' ')[1];
  $(this).addClass("active");
 
   
  $(".plus").each(function() {
    if($(this).html()=="-") {
      $(".plus").html("+");
    }
  });
  $("#"+$el).slideToggle();

  if($(this).children(".plus").html()=="+") {
    $(this).children(".plus").html("-");
  } else {
    $(this).children(".plus").html("+");
  }


});
coolispaulAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

APoPhySptCommented:
I did not completelly understand what it is you are trying to achieve, could you give any more examples or further explain?

cheers
0
coolispaulAuthor Commented:
the 4 big buttons  with the plus symbols, when clicked reveal content

(the first 2 work...)

so content slides down. When clicked again i want it to slide up. If another button is clicked i want all to reset and the clicked one to reveal appropriate content..

Thanks
0
APoPhySptCommented:
well, I wrote this on notepadd++ so I did not have a chance to test it, but I think it should be something along the lines of:

<script>

function hideAll()
{
	-- $('#' + revealed1).slideUp(0);
	-- $('#' + revealed2).slideUp(0);
	-- $('#' + revealed3).slideUp(0);
	-- $('#' + revealed4).slideUp(0);

	$(".revealed").each(function() {
		$(this).slideUp(0);
	});
}

function toogleContainer(container)
{
	-- get the current text of the container '-' or '+'
	var text = $('.' + container).html();
	
	if(text == '-')
	{
		$('#' + container).slideUp(300);
		$('.' + container).html('+');
	}	
	else if(text == '+')
	{
		hideAll();
		
		$('#' + container).slideDown(300);
		$('.' + container).html('-');
	}		
}

$(document).ready(function () {
    
    $("#revealed1").on("click", function () {
        toogleContainer('revealed1');
    });
	
	$("#revealed2").on("click", function () {
        toogleContainer('revealed2');
    });
	
	$("#revealed3").on("click", function () {
        toogleContainer('revealed3');
    });
	
	$("#revealed4").on("click", function () {
        toogleContainer('revealed4');
    });

});

</script>

Open in new window

0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

Julian HansenCommented:
Ok first up your 3rd and 4th panels don't work because they have the same id as the second panel

Secondly - I would change your markup of your <a> to this

  <a class="icon-reveal" data-id="revealed1">I'm New Here<br/><span class="plus">+</span></a>
  <a class="icon-reveal greenicon" data-id="revealed2">Who We Are<br/><span class="plus">+</span></a>
  <a class="icon-reveal redicon" data-id="revealed3">Get Involved<br/><span class="plus">+</span></a>
  <a class="icon-reveal orangeicon" data-id="revealed4" style="margin-right:0">Together: Medway &amp; Beyond<br/><span class="plus">+</span></a>

Open in new window

The main difference is the use of the HTML5 custom data attribute - in this case I have called it id (data-id) and put the id of the corresponding panel that must slide when that <a> is clicked.

Finally the JQuery
<script type="text/javascript">
$(function() {
    $('a.icon-reveal').click(function(e) {
        //
        // prevent default click behaviour on the <a>
        //

        e.preventDefault();

        //
        // check if the panel is already open - if it is
        // then it will be closed in the following loop
        // and the final open code can be skipped
        //

        var open = $(this).hasClass('open');


        //
        // for each open panel (should only be 1) but
        // will find open panels that are not linked to the
        // <a> clicked. We find open panels by the 'open'
        // class that is assigned to the element when the panel
        // is opened
        //

        $('a.icon-reveal.open').each(function () {
 
            //
            // Find the <span> and set the html to a '+'
            // we know it is a '+' because we are closing 
            // panels in this loop
            //

            $(this).find('span').html('+');

           
            //
            // Slide the corresponding panel up as part
            // of the close. Instead of parsing the class
            // we get the id straight from the data-id attribute
            // using the JQuery .data() method
            //

 
            $('#' + $(this).data('id')).slideUp();

            //
            // Remove the 'open' class we use to identify open
            // panels
            //

            $(this).removeClass('open');
        });

        //
        // Now, if we are opening the panel i.e. if it was closed
        // when clicked then ....
        // 

        if (!open) {

            // 
            // Add the open class to mark it as open
            // Change the html to a minus sign
            //

            $(this).addClass('open').find('span').html('-');

            //
            // And finally open the corresponding panel
            // using the data-id attribute to find the correct
            // panel
            //

            $('#' + $(this).data('id')).slideDown();
        }
    });
});
</script> 

Open in new window


Don't forget to fix the id's on your <div>'s
  <div class="revealed" id="revealed1">
    <h2>I'm New Here</h2>
  </div>

  <div class="revealed" id="revealed2">
    <h2>Who We Are</h2>
  </div>

  <div class="revealed" id="revealed3">
    <h2>Get Involved</h2>
  </div>

  <div class="revealed" id="revealed4">
    <h2>Together</h2>
  </div>

Open in new window

0
coolispaulAuthor Commented:
thanks julianH that works great and thanks for explaining how it works - all understood.

just one thing, when you have one already open and you click another you kind of get o flicking (obviously because there is a slide up and slide down at same time) - would a fade work better in this scenario and how could this be done?

Thanks
0
Julian HansenCommented:
The issue is that the slidUp code runs asynchronously so the slideUp and slideDown are bumping into each other.

There are two ways to solve this

1 move the slide down code into the complete function of the slideUp
   var el = $(this);
  ...
 .slideUp('fast', function() {
     if (!open) {
         el.addClass('open').find('span').html('-');
         $('#' + el.data('id')).slideDown();
     }
 });

Open in new window

Not very elegant - although you should not have a condition where the loop goes round more than once - you would probably (for completeness) need to code for the eventuallity which means adding more flags and checks to see that the open has not happened before running it again.

2. Change the slideUp to a hide
<script type="text/javascript">
$(function() {
    $('a.icon-reveal').click(function(e) {
        e.preventDefault();
        var open = $(this).hasClass('open');
        $('a.icon-reveal.open').each(function () {
            $(this).find('span').html('+');
            $('#' + $(this).data('id')).hide();
            $(this).removeClass('open');
        });
        if (!open) {
            $(this).addClass('open').find('span').html('-');
            $('#' + $(this).data('id')).slideDown();
        }
    });
});
</script> 

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
COBOLdinosaurCommented:
If you want it to work reliably, you probably want to validate  and fix the errors, plus I suggest you do not use label that way. It has a very narrow and specific use.

The way you are using it could break a page if a future browser release does not recognize it in an invalid context.

Cd&
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
jQuery

From novice to tech pro — start learning today.