Collapsing / hiding figures in R markdown - r

In my rmarkdown document, I am able to show and hide code with the following - which creates a convenient button on the righthand side of the document before each block of code:
output:
html_document:
code_folding: hide
Is there a similarly convenient method to hide tables or figures? If so, please provide a reference as I have not been able to find any. Otherwise a workaround would be appreciated, thank you!

I have not been able to get the above solution (or others I found) to work consistently, but using the in-line html (Bootstrap example/solution) I found at W3schools.com works well in Rmarkdown.
I use it to show a simple plot in html output in the example below. It should work with any chunk output:
<button class="btn btn-primary" data-toggle="collapse" data-target="#BlockName"> Show/Hide </button>
<div id="BlockName" class="collapse">
```{r}
plot(mtcars$disp, mtcars$mpg)
```
</div>
note: If you use this on multiple sections, each one needs a unique id (ie replace BlockName with a unique id for each section to be collapsed.)

If you add this to the end of your .Rmd file
<script>
$( "input.hideshow" ).each( function ( index, button ) {
button.value = 'Hide Output';
$( button ).click( function () {
var target = this.nextSibling ? this : this.parentNode;
target = target.nextSibling.nextSibling.nextSibling.nextSibling;
if ( target.style.display == 'block' || target.style.display == '' ) {
target.style.display = 'none';
this.value = 'Show Output';
} else {
target.style.display = 'block';
this.value = 'Hide Output';
}
} );
} );
</script>
and then this before each chunk you want to have a toggle:
<input type=button class=hideshow></input>
(adapted from here: https://groups.google.com/forum/#!topic/knitr/d37E0mP3w6k)
Note: this will work if you show the code - if you are hiding the code (with echo = FALSE), change
target = target.nextSibling.nextSibling.nextSibling.nextSibling;
to
target = target.nextSibling.nextSibling;
Note 2: if you want to use the code_folding option, change
target = target.nextSibling.nextSibling.nextSibling.nextSibling;
to
target = target.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling;

I was able to get Lucy's code working for me, but I also think it's more useful and cleaner to have the outputs hidden by default. It's a very simple addition. Just execute jquery that clicks all the "Hide Output" buttons upon rendering. My code looks like this:
<script>
$( "input.hideshow" ).each( function ( index, button ) {
button.value = 'Hide Output';
$( button ).click( function () {
var target = this.nextSibling ? this : this.parentNode;
target = target.nextSibling.nextSibling;
if ( target.style.display == 'block' || target.style.display == '' ) {
target.style.display = 'none';
this.value = 'Show Output';
} else {
target.style.display = 'block';
this.value = 'Hide Output';
}
} );
} );
$("input.hideshow").click()
</script>
Only the last line before </script> was the addition.

Heyy so I changed the code of gclarkjr5 to have the table shown without being formatted.
It will show the hidden button first and not modify the display of the table.
So here goes:
Put this before the chunk you want to display:
<input type=button class=hideshow></input>
And then at the end of your markdown file:
<script>
$( "input.hideshow" ).each( function ( index, button ) {
button.value = 'Show Output';
$( button ).click( function () {
var target = this.nextSibling ? this : this.parentNode;
target = target.nextSibling.nextSibling;
if ( target.style.display == 'none') {
target.style.display = '';
this.value = 'Hide Output';
} else {
target.style.display = 'none';
this.value = 'Show Output';
}
} );
} );
$("input.hideshow").click()
</script>

Related

WordPress: wpLink `this.textarea is undefined`

In a plugin, we're using a button & text input to trigger the wpLink modal. All works well, until we hit a template that removes the main content editor and relies only on metaboxes for the page content.
The error we're getting is this.textarea is undefined. The code we're using is:
$( 'body' ).on( 'click', '.pluginxyz-add-link', function( event ) {
wpActiveEditor = true;
wpLink.open();
return false;
});
So I assume there is some dependency to the main editor. I can't find explicit info/documentation around this.. anyone have a suggestion about making this work without the main editor?
Actually, I just figured this out. In our code, the ONLY sibling text input is always where the value will go.
$( 'body' ).on( 'click', '.pluginxyz-add-link', function( event ) {
clickedEle = $( this );
textBoxID = $( clickedEle ).siblings( 'input[type=text]' ).attr( 'id' );
wpActiveEditor = true;
wpLink.open( textBoxID);
return false;
});

Linking to specific ID on another Wordpress page?

I have a header.php, that appears in every single page on my blog, with a navbar that looks like this:
<nav>
<ul>
<li>Logistics</li>
<li>Contact</li>
</ul>
</nav>
But when I click the anchor tag linking to #contact, which is located in page with id 5, as you can see by the php code, nothing happens. I tried using a slash (/#contact) but I keep getting the same behavior. Isn't this the correct way of linking to a specific id on another page?
EDIT: I also have some smooth scrolling code (below) which I think may be related to my issue.
<script>
$( document ).ready( function () {
// Add smooth scrolling to all links
$( "a" ).on( 'click', function ( event ) {
// Make sure this.hash has a value before overriding default behavior
if ( this.hash !== "" ) {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
} // End if
} );
} );
</script>
Thanks!
You have a javascript error.
<script>
$( document ).ready( function () {
// Add smooth scrolling to all links
$( "a" ).on( 'click', function ( event ) {
// Make sure this.hash has a value before overriding default behavior
if ( this.hash !== "" ) {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
} // End if
} );
} );
</script>
Here is the problem. On the home page you have a div with id #contato. On the other pages it is not there.
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
Your hash var's value is "#contato", but when js tries to get it's offset you recieve an error saying that it's impossible to read property top of 'undefined'. So, you can try to remove that part of the script from the other pages and only keep it on home. This should work like a charm. If you have any question, please ask.
LE: I'd recommend this method for smooth scroll (I didn't tested it for your case, but it always worked for me)
$(function() {
$('a[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
use
<?php echo get_page_link(5)."#contact"; ?>
instead of get permalink function

Observe does not trigger

I wanted to use the new observe feature but it does not seem to be working. At least not for me.
First things first here is the result of mrt --version
Meteorite version 0.4.6
Meteor version 0.5.9 (git checkout)
The goal is to create a bunch of draggable elements whose position gets reflected among clients.
Tis is my query:
var items = Items.find({});
var handle = items.observe( {
changed: function (newDocument, oldDocument) {
if ( newDocument._id !== dragged ) {
$( "#" + id ).style( "left", newDocument.left );
$( "#" + id ).style( "top", newDocument.top );
}
}
} );
I know the positions are changed because when I reload the page the images get synchronized. I tried with both observe and observeChanged with the same result. If I set a break point inside the callback it is never called.
could it be because I still have insecure and autopublish on?
thank you for your help
it looks like it helps to remove insecure and autopublish but more importantly, to wait until the subscription is ready.
I ended up using the Meteor.subscribe("name", function() {}); syntax and it works now.
here is the full code:
Meteor.subscribe("allItems", function() {
var items = Items.find( {} );
Session.set( "items", items.fetch() );
handle = items.observe( {
changed: function ( newDocument, oldDocument ) {
if ( newDocument._id !== dragged ) {
$( "#" + newDocument._id ).css( "left", newDocument.left );
$( "#" + newDocument._id ).css( "top", newDocument.top );
}
}
} );
});
hope that helps

how to add a "next fieldset" button to an add/edit form for a Dexterity Plone type

I have a Dexterity type that has multiple fieldsets, and the built-in Javascript that allows showing one fieldset at a time when adding or editing is wonderful.
But I'd like to invite the user to walk through the fieldsets in sequence, so my ideal situation would not present the "Submit" button until the last fieldset was visible, instead presenting NEXT> or <PREV and NEXT> buttons until that last fieldset.
I gather that this is a behavior? But I'm at a bit of a loss as to how to add it and how to control it. I'm currently using the default EditForm, and I'd much prefer to just make a tiny tweak, but if it means dropping down to building the form myself, that's OK. I just need to know whether that's the only way to get this addition, which seems unlikely.
The fieldsets can be rigged up to add 'previous' and 'next' buttons with some extra JavaScript magic. Here's what I use in a current project:
var prevnext = {
formTabs: null,
next: function() { prevnext.formTabs.data('tabs').next(); prevnext._scrollToTop(); },
prev: function() { prevnext.formTabs.data('tabs').prev(); prevnext._scrollToTop(); },
_scrollToTop: function() {
$(window).scrollTop(prevnext.formTabs.closest('form').offset().top);
},
showButtons: function(event, index) {
var tabs = prevnext.formTabs.data('tabs'),
index = typeof(index) === 'undefined' ? tabs.getIndex() : index,
current = tabs.getTabs()[index],
count = tabs.getTabs().length;
$('#prevnext_previous').toggle(index !== 0);
$('#prevnext_next').toggle(index !== (count - 1));
$('.formControls:last :submit[name=form_submit]').toggle(index === )count - 1));
},
init: function() {
var tabs;
prevnext.formTabs = $('.formTabs');
tabs = prevnext.formTabs.data('tabs');
if (tabs.getTabs().length > 0) {
if ($('fieldset#fieldset-distribution').length === 0)
return;
$('.formControls:last :submit:first')
.before($('<input id="prevnext_previous" class="context" ' +
' type="button" value="" />')
.val('< Previous')
.click(prevnext.prev))
.before(document.createTextNode(' '));
$('.formControls:last :submit:first')
.before($('<input id="prevnext_next" class="context" ' +
' type="button" value="" />')
.val('Next >')
.click(prevnext.next))
.before(document.createTextNode(' '));
prevnext.showButtons();
tabs.onClick(prevnext.showButtons);
}
}
};
$(prevnext.init());

jQuery replacement for Default Button or Link

As everyone knows, that default button doesn't work in FF, only IE. I've tried to put in the tag or in the and it's not working. I've found a js script to fix this issue, but for some reason it's not working for me. This script for a submit button, i need to use it for a LinkButton, which is should be the same.
Link:
<div id="pnl">
<a id="ctl00_cphMain_lbLogin" title="Click Here to LogIn" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$cphMain$lbLogin", "", true, "Login1", "", false, true))">Log In</a>
<input name="ctl00$cphMain$UserName" type="text" id="ctl00_cphMain_UserName" />
<input name="ctl00$cphMain$UserName" type="text" id="ctl00_cphMain_UserName1" />
</div>
<script>
$(document).ready(function() {
$("#pnl").keypress(function(e) {
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
$("a[id$='_lbLogin']").click();
return true;
}
});
});
I know that i can override original function "WebForm_FireDefaultButton"
in This post, but i really wanted to get this one to work.
Thanx in advance!!!
I found the answer to fixing linkbuttons here: http://www.sentia.com.au/2009/03/fixing-the-enter-key-in-aspnet-with-jquery/
$(document).ready(function(){
var $btn = $('.form_submit');
var $form = $btn.parents('.form');
$form.keypress(function(e){
if (e.which == 13 && e.target.type != 'textarea') {
if ($btn[0].type == 'submit')
$btn[0].click();
else
eval($btn[0].href);
return false;
}
});
});
Inspired by Larry Flewwelling's answer or rather Michael Cindric's, I came up with a modified and updated version of that javascript snippet. I've documented more detailed information on why and how in this blog post, but let me summarize the important changes:
Works with dynamically loaded content
Works with any number of "forms" on the same page
And here it is:
$('body')
.off('keypress.enter')
.on('keypress.enter', function (e) {
if (e.which == 13 && e.target.type != 'textarea') {
var $btn = $(e.target).closest('.jq-form').find('.jq-form-submit');
if ($btn.length > 0) {
if ($btn[0].type == 'submit') {
$btn[0].click();
}
else {
eval($btn[0].href);
}
return false;
}
}
});
You could expand your selector.
$("#pnl > input")
Which will then catch the input click for all the controls in the panel.

Resources