Inline Show/Hide toggle between 2 divs

Am trying to achieve a means of disclosure where the initial disclosure show trigger disappears when the disclosure happens, and reappears when the disclosure is closed using a trigger at the bottom of the disclosure area.

To get into the ballpark, I’m trying to get some javascript suggested by Walter Davis to work that would cause the disclosure div to show and then hide again on mouseover and mouseout over the disclosure show trigger. If I got this to work I figured I would probably be able to tweak it to disclose on a click and not only cause the disclosure div to appear but the trigger image’s own parent div to hide, and apply more or less the same code to then re-hide the disclosure div and re-show the disclosure trigger parent div.

The Freeway Talk thread I found this code in is:

I’ve tried various ways of inserted the javascript to no avail. I should note that Mr. Davis portrayed the code as a sketch of how you might go about doing something rather than the actual code you use.

www.peterlaundy.com/tests/showhidedivtoggletest.html


freewaytalk mailing list
email@hidden
Update your subscriptions at:

Try this script block before end Body

<script id="domloaded" type="text/javascript">
document.observe("dom:loaded", function() { $('InitiallyHidden').hide();});
document.observe("dom:loaded", function() {
	$('ShowButton').observe('click', function(evt){
$('InitiallyHidden').show();
$('InitiallyVisible').hide();
	});
$('HideButton').observe('click', function(evt){
$('InitiallyHidden').hide();
$('InitiallyVisible').show();
	});
});
</script>

This could be rewritten to be much more concise and use other methods.

Remove the display:none attribute from InitiallyHidden in Extended

D


freewaytalk mailing list
email@hidden
Update your subscriptions at:

And a link http://www.deltadesign.co/inlinetest/inline-hide.html

D


freewaytalk mailing list
email@hidden
Update your subscriptions at:

Thanks so much for the code and link: I was just writing you to tell you the code wasn’t working when you sent the link, which allowed to identify the problem.

For anyone who reads this in the future, in addition to adding the code DD suggests to insert before /body, you also need to insert the following before /head:

(DD: This code had been added by the Protaculous2 action I’d used as described in my initial post. When I deleted the action to delete the javascript code (which I needed to do to get your alternative javascript to work) it also deleted these links to the necessary code libraries)


freewaytalk mailing list
email@hidden
Update your subscriptions at:

I dont think that you even need the scriptaculous stuff - the prototype.js should do it.

D


freewaytalk mailing list
email@hidden
Update your subscriptions at:

And as if you hadn’t got enough here is a neater jQuery version - http://www.deltadesign.co/inlinetest/inline-hideJQ.html

This relies on you adding a class to each parent div (the ones you wish to hide/show) of parent (as well as the class of hidden (to the initially hidden one) which you would define in your stylesheet as display:none).

You also need to add the class of button to each of the images that you want to click to show/hide the parent divs.

Then include the following in before end Body

<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(document).ready(function(){
    $("img.button").click(function(){
        $("div.parent").toggleClass("hidden");
    });
});
</script>

D


freewaytalk mailing list
email@hidden
Update your subscriptions at:

Another refinement that you can try:

$(document).on('click', 'img.button', function(){
  $('div.parent').toggleClass('hidden');
});

The “on” function, which works exactly the same way in Prototype, lets you create a deferred observer that doesn’t need to be wrapped in a ready() handler. Another great thing about this is that you can define it once, and even if you update the DOM (maybe use Ajax to replace an element you were already listening to) the observer won’t stop working just because the actual element it was bound to has been replaced.

Walter

PS: In Prototype.js, this would be:

document.on('click', 'img.button', function(){
  $$('div.parent').invoke('toggleClass', 'hidden');
});

On Apr 9, 2016, at 8:31 PM, DeltaDave email@hidden wrote:

And as if you hadn’t got enough here is a neater jQuery version - http://www.deltadesign.co/inlinetest/inline-hideJQ.html

This relies on you adding a class to each parent div (the ones you wish to hide/show) of parent (as well as the class of hidden (to the initially hidden one) which you would define in your stylesheet as display:none).

You also need to add the class of button to each of the images that you want to click to show/hide the parent divs.

Then include the following in before end Body

<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(document).ready(function(){
   $("img.button").click(function(){
       $("div.parent").toggleClass("hidden");
   });
});
</script>

D


freewaytalk mailing list
email@hidden
Update your subscriptions at:
Information for existing FreewayTalk / Groups.io users - Site Feedback - Softpress Talk


freewaytalk mailing list
email@hidden
Update your subscriptions at:
https://freewaytalk.softpress.com/person/options

Typo:

document.on('click', 'img.button', function(){
 $$('div.parent').invoke('toggleClassName', 'hidden');
});

On Apr 9, 2016, at 8:41 PM, Walter Lee Davis email@hidden wrote:

document.on('click', 'img.button', function(){
 $$('div.parent').invoke('toggleClass', 'hidden');
});

On Apr 9, 2016, at 8:31 PM, DeltaDave email@hidden wrote:

And as if you hadn’t got enough here is a neater jQuery version - http://www.deltadesign.co/inlinetest/inline-hideJQ.html

This relies on you adding a class to each parent div (the ones you wish to hide/show) of parent (as well as the class of hidden (to the initially hidden one) which you would define in your stylesheet as display:none).

You also need to add the class of button to each of the images that you want to click to show/hide the parent divs.

Then include the following in before end Body

<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(document).ready(function(){
  $("img.button").click(function(){
      $("div.parent").toggleClass("hidden");
  });
});
</script>

D


freewaytalk mailing list
email@hidden
Update your subscriptions at:
Information for existing FreewayTalk / Groups.io users - Site Feedback - Softpress Talk


freewaytalk mailing list
email@hidden
Update your subscriptions at:
https://freewaytalk.softpress.com/person/options

And here is Walter’s version - http://www.deltadesign.co/inlinetest/inline-hidePT.html

Preferred if you dont want to introduce another JS library to your page.

D


freewaytalk mailing list
email@hidden
Update your subscriptions at:

Thanks so much! So useful to see how to do it, then how to do it more and more elegantly.

Such a great community!


freewaytalk mailing list
email@hidden
Update your subscriptions at:

DeltaDave’s first suggestion

…does not treat the event as a strict toggle, a characteristic that could make it possible for showing and hiding the initially hidden div to have different behaviors.

It would be very nice if the initially hidden div appeared with a BlindDown effect and disappeared with a BlindUp effect. Does anyone know if there is code to replace or augment the .show() that shows “Initially Hidden” and the .hide() that again hides it to give these effects?


freewaytalk mailing list
email@hidden
Update your subscriptions at:

I’ve got the script working which is great but was wondering if it’s possible to implement multiple buttons and divs, I have ten buttons that would reveal 10 different divs?

Thanks


freewaytalk mailing list
email@hidden
Update your subscriptions at:

You can do almost anything you want with JavaScript. Can you post a link to your page, and include the other buttons/divs so we can see what you’re trying to accomplish?

One thing I recommend when you want to automate something like this is to follow a very strict naming convention, something like button_1 which triggers toggle_1. When you do that, you can make shortcuts in the JS code to write out a bunch of functions in one loop, or make a single function which can toggle N objects (where N can become a very large number without causing any pain).

Walter

On Apr 18, 2016, at 1:21 PM, Dave Dunning email@hidden wrote:

I’ve got the script working which is great but was wondering if it’s possible to implement multiple buttons and divs, I have ten buttons that would reveal 10 different divs?

Thanks


freewaytalk mailing list
email@hidden
Update your subscriptions at:
Information for existing FreewayTalk / Groups.io users - Site Feedback - Softpress Talk


freewaytalk mailing list
email@hidden
Update your subscriptions at:
https://freewaytalk.softpress.com/person/options

It would be very nice if the initially hidden div appeared with a BlindDown effect and disappeared with a BlindUp effect.

Not using an initial state of display:none as this property isn’t animatable.

It could be rewritten to do this - a good place to start might be animate.css Redirecting to Animate.css

But it could get quite complicated. How much time/money do you want to invest for a bit of unnecessary Bling?

D


freewaytalk mailing list
email@hidden
Update your subscriptions at:
https://freewaytalk.softpress.com/person/options

I’ve got the script working which is great but was wondering if it’s possible to implement multiple buttons and divs, I have ten buttons that would reveal 10 different divs?

If you don’t currently have the javascript proficiency to execute Walt’s suggestion, and don’t have it in your plan to develop it, couldn’t you use
Delta Dave’s first solution above, since it did not use classes but instead used element names? I suspect you could use this code 10 times, each time changing name of div and image by one digit (i.e. “openbutton1”, “openbutton2”, etc.) of your elements and of the corresponding code. Freeway would do the numbering for you of the divs and images, and all you’d need to do is change the numbers in each version of the script.

But it could get quite complicated. How much time/money do you want to invest for a bit of unnecessary Bling?

DD: Thanks for the link to the github.

As to your time/money question, not a lot as I am only occasionally using js to push the envelope on Freeway to get it to do more user-centered things. I am finding that one of the situations I repeatedly find myself in is solving simultaneously for those who read to just get the gist of the story being told, and those who want to dig deeper, without bouncing them off of a page. So this entails read-mores, rotating disclosure triangles, etc. The read-more technique I’ve been using replaces the read-more message with a close message, both in the same position at the top of the disclosure. Putting the “close” at the top of the top of the message is inconvenient for the user if it has scrolled off the top of the page by the time the disclosure reaches its end. Hence my initial request here.

To push back against the bling characterization: Having implemented this new approach to solving the problem with a disclosure that is relatively long, I’ve found a confusion for the reader I am trying to address with the blind effect. When the user hits the close button, he is left down the page in unfamiliar territory. The two ways to orient the user that I imagined, were:

  1. The blind effect that would orient by showing the expansion and contraction of the disclosure
  2. On the closing of the disclosure, being returned to the scroll location at the top rather than below the bottom of the suddenly hidden disclosure.

My initial thought was that the former rather than the latter would be easier to achieve. Hence my follow up earlier today.


freewaytalk mailing list
email@hidden
Update your subscriptions at:
https://freewaytalk.softpress.com/person/options

On 18 Apr 2016, 9:35 pm, waltd wrote:

You can do almost anything you want with JavaScript. Can you post a link to your page, and include the other buttons/divs so we can see what you’re trying to accomplish?

One thing I recommend when you want to automate something like this is to follow a very strict naming convention, something like button_1 which triggers toggle_1. When you do that, you can make shortcuts in the JS code to write out a bunch of functions in one loop, or make a single function which can toggle N objects (where N can become a very large number without causing any pain).

Walter

On Apr 18, 2016, at 1:21 PM, Dave Dunning

Hi Walter, link to page is: http://www.stundesign.co.uk/bickhambarn/new/we-can-help.html

Currently I have it working with rollovers and Target Show/Hide Layers but was wondering if possible using the show/hide div toggle as I’d be able to size the divs to suit the content.

Dave


freewaytalk mailing list
email@hidden
Update your subscriptions at:
https://freewaytalk.softpress.com/person/options

I’ve had a quick look at this, and one thing that is going to make it more difficult to simplify is the manner in which you have constructed things. You have the InfoPanel providing the rounded corners and white background, and then inside that you have the InfoWrapper, and inside that the various CateringWrapper/CateringTitle9/CateringCopy9 elements. I fiddled a bit with the Safari Web Inspector, and got very confused how to make the whole thing disappear in one pop. Even if I hide every element inside the InfoPanel, you still see an empty white round-rect panel on screen.

I’ve said this before, and I will probably say it a few more times: it is considerably simpler* to create a highly-styled page using code alone than using a WYSIWYG tool like Freeway, which cannot read your mind or understand your design intent. Freeway is an impossibly wonderful sketching tool, and in the hands of someone who understands the shortcuts it takes, a capable production tool as well. But you will end up with code that is difficult to modify or extend without having a deep understanding of how it “thinks” about a page layout.

Imagine this code instead:

<div id="catering_panel" class="info-panel hidden">
  <h2>CATERING</h2>
  <p>You can use your own caterers, ... etc ... </p>
  <p><a href="#helpanchor"><img src="cateringuparrow.png"></a></p>
</div>

Which then uses this CSS:

.info-panel {
  border-radius: 9px;
  font-family: Lato, sans-serif;
  font-size: 16px;
  font-weight: 400;
  color: #999;
  text-align: center;
  padding: 20px 40px;
  overflow: hidden;
  background-color: #fff;
}

.info-panel h2 {
  color: #393939;
  font-family: Montserrat, sans-serif;
  font-size: 18px;
}

.hidden {
  display: none;
}

That should be invisible and occupy no space on the page, so the rest of the contents appear snug to the bottom of the toggle-icons. When you hover over an icon, your script would remove the hidden classname, and the panel would appear and take up space, moving the rest of the page out of the way so it could be read. All of the panels would sit in your page code one right after the other. Since they are hidden, they don’t occupy any space visually, and only one of them is ever shown at a time.

Imagine if the catering button had the ID catering_button and the classname info-button. Then the following Prototype JS would do the switcheroo:

// assuming you would add this with Protaculous 2, which will write the correct
// dom:loaded listener wrapper around this code

// first, hide the info panels if they aren't already
$$('.info-panel').invoke('addClassName', 'hidden');

// next, set an observer function to show the correct panel
// naming is important, we use one function for everything!
document.on('mouseenter', '.info-button', function(evt, elm){
  // get the first part of the button ID to know which panel to display
  var panel = elm.readAttribute('id').split('_').first();
  // hide all the panels again
  $$('.info-panel').invoke('addClassName', 'hidden');
  // show the chosen one
  $(panel + '_panel').removeClassName('hidden');
});

That’s really it.

Make sure that all of the other buttons and panels match name-wise, and there’s nothing extra to write. Simpler HTML means simpler JS. The result is more maintainable and easier to read than ten copies of one function that differ by a few characters each, or a towering stack of nested DIVs.

Walter

*By simpler, here, I mean elegant and simplified code to produce complex-looking results. Not necessarily easier, but very definitely easier to extend later.

On Apr 19, 2016, at 4:42 AM, Dave Dunning email@hidden wrote:

On 18 Apr 2016, 9:35 pm, waltd wrote:

You can do almost anything you want with JavaScript. Can you post a link to your page, and include the other buttons/divs so we can see what you’re trying to accomplish?

One thing I recommend when you want to automate something like this is to follow a very strict naming convention, something like button_1 which triggers toggle_1. When you do that, you can make shortcuts in the JS code to write out a bunch of functions in one loop, or make a single function which can toggle N objects (where N can become a very large number without causing any pain).

Walter

On Apr 18, 2016, at 1:21 PM, Dave Dunning

Hi Walter, link to page is: http://www.stundesign.co.uk/bickhambarn/new/we-can-help.html

Currently I have it working with rollovers and Target Show/Hide Layers but was wondering if possible using the show/hide div toggle as I’d be able to size the divs to suit the content.

Dave


freewaytalk mailing list
email@hidden
Update your subscriptions at:
Information for existing FreewayTalk / Groups.io users - Site Feedback - Softpress Talk


freewaytalk mailing list
email@hidden
Update your subscriptions at:
https://freewaytalk.softpress.com/person/options

On 19 Apr 2016, 11:04 pm, waltd wrote:

I’ve had a quick look at this, and one thing that is going to make it more difficult to simplify is the manner in which you have constructed things. You have the InfoPanel providing the rounded corners and white background, and then inside that you have the InfoWrapper, and inside that the various CateringWrapper/CateringTitle9/CateringCopy9 elements. I fiddled a bit with the Safari Web Inspector, and got very confused how to make the whole thing disappear in one pop. Even if I hide every element inside the InfoPanel, you still see an empty white round-rect panel on screen.

I’ve said this before, and I will probably say it a few more times: it is considerably simpler* to create a highly-styled page using code alone than using a WYSIWYG tool like Freeway, which cannot read your mind or understand your design intent. Freeway is an impossibly wonderful sketching tool, and in the hands of someone who understands the shortcuts it takes, a capable production tool as well. But you will end up with code that is difficult to modify or extend without having a deep understanding of how it “thinks” about a page layout.

Imagine this code instead:


Which then uses this CSS:

.info-panel {
  border-radius: 9px;
  font-family: Lato, sans-serif;
  font-size: 16px;
  font-weight: 400;
  color: #999;
  text-align: center;
  padding: 20px 40px;
  overflow: hidden;
  background-color: #fff;
}

.info-panel h2 {
  color: #393939;
  font-family: Montserrat, sans-serif;
  font-size: 18px;
}

.hidden {
  display: none;
}

That should be invisible and occupy no space on the page, so the rest of the contents appear snug to the bottom of the toggle-icons. When you hover over an icon, your script would remove the hidden classname, and the panel would appear and take up space, moving the rest of the page out of the way so it could be read. All of the panels would sit in your page code one right after the other. Since they are hidden, they don’t occupy any space visually, and only one of them is ever shown at a time.

Imagine if the catering button had the ID catering_button and the classname info-button. Then the following Prototype JS would do the switcheroo:

// assuming you would add this with Protaculous 2, which will write the correct
// dom:loaded listener wrapper around this code

// first, hide the info panels if they aren't already
$$('.info-panel').invoke('addClassName', 'hidden');

// next, set an observer function to show the correct panel
// naming is important, we use one function for everything!
document.on('mouseenter', '.info-button', function(evt, elm){
  // get the first part of the button ID to know which panel to display
  var panel = elm.readAttribute('id').split('_').first();
  // hide all the panels again
  $$('.info-panel').invoke('addClassName', 'hidden');
  // show the chosen one
  $(panel + '_panel').removeClassName('hidden');
});

That’s really it.

Make sure that all of the other buttons and panels match name-wise, and there’s nothing extra to write. Simpler HTML means simpler JS. The result is more maintainable and easier to read than ten copies of one function that differ by a few characters each, or a towering stack of nested DIVs.

Walter

*By simpler, here, I mean elegant and simplified code to produce complex-looking results. Not necessarily easier, but very definitely easier to extend later.

On Apr 19, 2016, at 4:42 AM, Dave Dunning

Hi Walter noted all your comments and thanks for the advice. I can understand your confusion re the different panels! I’d set it up that way failing better knowledge! What I’d like to achieve is an initially visible ‘catering’ panel div, then when the ‘cutlery’ button is clicked the ‘catering’ div disappears to be replaced by the ‘cutlery’ div and so on.

I hear you re simplicity though and I guess it may be best to just have all the information set out on the page and the viewer just scrolls down through it, maybe I’m falling foul of form over function!

I’ll try out both later options later.

Thanks
Dave


freewaytalk mailing list
email@hidden
Update your subscriptions at:
https://freewaytalk.softpress.com/person/options

If you change this line:

$$('.info-panel').invoke('addClassName', 'hidden');

to this:

$$('.info-panel').invoke('addClassName', 'hidden').first().removeClassName('hidden');

…then the first panel will be open at page load.

Walter


freewaytalk mailing list
email@hidden
Update your subscriptions at: