Bootstrap 3 tab('show') on long page hides tabs - twitter-bootstrap-3

I am using el.tab('show') to show a bootstrap 3 tab, it works but when content of the tab is large, tabs are not visible anymore because of page scrolling (this is not the same behavior as if clicking on the tab itself). Any idea how to workaround this? Thanks.
Update: here is a sample code. Tab One is displayed by default, and clicking on the "Go To Tab 2" anchor moves to tab 2 which contains a large page. Problem is that top tabs are not visible anymore after the click as bottom of the page embedded in tab 2 is shown.
<div class="container-fluid">
<ul class="nav nav-tabs">
<li>Tab One</li>
<li>Tab Two</li>
</ul>
<div class="tab-content">
<div id="tab_one" class="tab-pane fade in">
<ul>
<li>Go to Tab 2 </li>
</ul>
</div>
<div id="tab_two" class="tab-pane fade in">
<p>content of tab 2, long page </p>
</div>
</div>

found a way around the problem, but well, it is not pretty:
jQuery('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
setTimeout( function (e) {
window.scrollTo(0,0);
}, 1);
});

Related

Bootstrap Fixed Navbar.. how to adjust the content padding-top dynamically?

This question is for Bootstrap v3.3.7 and upwards (prior to v4).
I am using navbar-fixed-top; when the small screen break-point kicks in, and the navbar height expands when opened, i want to push down the content to be below the navbar (in much the same way that the navbar-static-top works).
How to do it? my approach would be to write a specific CSS rule for it. But how can I know at exactly what value the small screen break-point kicks in?
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header pull-right">
<!-- this is the hamburger, shown on smaller width screens -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active">My Home</li>
<li>Menu 1 </li>
<li>Menu 2</li>
<li>Menu 3</li>
</ul>
</div>
</div>
</div>
<section id="content">
<h3>using Fixed-navbar</h3>
<p>This uses <strong>FIXED NAVBAR (navbar-fixed-top)</strong>, which means navbar DOES NOT scroll out of view... i.e. it remains VISIBLE at all times.<br/>
However, it does NOT push the content down (the pink section) when the navbar needs to expands via the Hamburger button
</p>
<p>Sed dignissim blah etc...</p>
</section>
Codepen here:
Here is my own answer:
At first i tried playing with the transitionend event, but it proved to be unreliable to solve my problem; not because in itself it is unreliable, but because the nav height was not updating soon enough after transition ends.
So i resorted to polling, and other logic which works reliably
let navContainer$ = $("div.navbar > div.container");
let collapsedDiv$ = $("div.navbar > div.container > div.collapse");
let intervalHandle;
//on hamburger click...
$("button.navbar-toggle").click(() => {
let heightBeforeTrx = navContainer$.height();
console.error( 'heightBeforeTrx:', heightBeforeTrx ) //= 50
if (heightBeforeTrx === 50) {
//we are moving from collapsed to Expanded...
intervalHandle = setInterval( () => {
console.log('Yo keep polling...')
//we expect...a class 'collapse.in' to exist once expanded
let test1 = collapsedDiv$.hasClass( "in" );
if (test1) {
//STOP THE POLLING...
clearInterval(intervalHandle);
console.log('polling ended.')
$("body").css('padding-top', '176px')
}
}, 100 )
} else {
//we are moving from Expanded to Collapsed...
intervalHandle = setInterval( () => {
console.log('Yo keep polling...')
//we expect...a class 'collapse.in' to NOT exist once collapsed
let test2 = collapsedDiv$.hasClass( "in" );
if (!test2) {
//STOP THE POLLING...
clearInterval(intervalHandle);
console.log('polling ended.')
$("body").css('padding-top', '50px')
}
}, 100 )
}
})
Good enough for now, the 176px hardcoding should be adjusted accordingly; Only caters for 2 use-cases, there are other heights possible when the width gets even smaller, but i'll ignore those; also need additional jQuery for pushing content back up if re-sizing window manually, after it has been expanded from hamburger click.
Here is a codepen where you can see css only changes to push the content down when navbar is expanded. The only thing I have added is a new css class called mycss (not named correctly, i agree :)). You can change the media query based on your exact requirements.
Also, it might be worth looking at bootstrap-4.3, as it looks like they already have something like this out of the box.

Is it possible to add sitefinity widget to my custom widget?

I'm attempting to create a custom widget in Sitefinity 11. The goal is to display tabs on the page, with panels of content below each clickable tab. I am using bootstrap to accomplish this which is simple enough.
My hope was to be able to add a Sitefinity placeholder to each tab, which would allow editors to drag and drop a widget, such as a content block to that tab. But it seems that when I try to do this, the placeholder area never displays in the CMS, like it would if I had added a placeholder to a custom template.
Is this possible?
Here is a short code example:
<div class="container mt-3">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li id="tab1" class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#panel1">#Model.Tab1Name</a>
</li>
<li id="tab2" class="nav-item">
<a class="nav-link" data-toggle="tab" href="#panel2">#Model.Tab2Name</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div id="panel1" class="container tab-pane active">
#Html.SfPlaceHolder("Panel1")
<p>here is text</p>
</div>
<div id="panel2" class="container tab-pane fade">
#Html.SfPlaceHolder("Panel2")
</div>
</div>
Appreciate any help.
You cannot put a SfPlaceHolder on a widget, it must be in your layout file (page template).
What you can do is to create a custom designer for your widget and put one or more content blocks in it, e.g. one for each tab you want to have.
Then in the view, you simply render the content.
https://www.progress.com/documentation/sitefinity-cms/create-custom-designer-views-mvc
EDIT: To achieve this you need:
Controllers / MyRichTextController.cs
public string RichText
{
get;
set;
}
Views / MyRichText / DesignerView.Default.cshtml
<div class="form-group">
<sf-html-field class="kendo-content-block"
sf-images-settings="#SettingsHelpers.GetMediaSettings("Image")"
sf-videos-settings="#SettingsHelpers.GetMediaSettings("Video")"
sf-documents-settings="#SettingsHelpers.GetMediaSettings("Document")"
sf-model="properties.RichText.PropertyValue">
</sf-html-field>
</div>
Views / MyRichText / DesignerView.Default.json
{
"priority": 1,
"components": [ "sf-html-field" ]
}
Another alternative could be to create a Layout widget with the above html structure and that will allow the user to put content blocks inside the areas of the layout.
You can just copy any of the existing layout widgets and work on that. Note, that with this approach you would probably have some css rules that hide all but the first tab panel, so you will need to have some additional css rules just for the backend in order to show all the panels so that users can drag widgets to them. That would make this approach a little bit more trickier.

Vue - Nested Click Event Bubbling Issue

I have a menu button with a click event in Vue. When the button is clicked, it's supposed to activate the menu itself. This is the parent element which when clicked activates the menu (the toggleMenu function makes menuIsActive true). This part works fine:
<div class="navbar-item has-dropdown #click="toggleMenu">
<div class="navbar-link"></div>
<app-navmenu :class="{'is-active': menuIsActive}"/>
</div>
And this is the app-navmenu component that gets rendered:
<div class="navbar-dropdown" #click.stop>
<div class="container is-fluid">
<div class="column">
<h1 class="title">Title</h1>
<router-link class="navbar-item" :to="route" exact>
<div class="navbar-content">
<p class="has-text-info">info</p>
<small>meta info</small>
</div>
</router-link>
</div>
</div>
</div>
The problem I am running into is that I don't want the menu to disappear when I click on the actual navbar-dropdown div element, hence why I have a #click.stop. However, I do want the menu to disappear when I click on a router-link element, but since I have #click.stop in the navbar-dropdown element, the menu persists. If I don't have a #click.stop event on the navbar-dropdown element, then the menu disappears as soon as the navbar-dropdown element is clicked on, which I don't want.
How can I have the menu persist when clicking on the dropdown body, but also have it disappear when I click on a router-link? I've tried other click methods like .self and .prevent, but those don't seem to do what I need.
I am exactly not sure with your requirement, but following your comment, you can use something like this:
This will even push to the router link:
<router-link class="navbar-item" :to="route" exact
#click.native.prevent="callYourMethod">
This will prevent to go to the router link:
<router-link class="navbar-item" :to="route" exact
#click.native.prevent="callYourMethod" event="">
This is what I ended up doing to fix my issue. First, I moved the click function in the parent to one of its children:
<div class="navbar-item has-dropdown">
<div class="navbar-link" #click="toggleMenu"></div>
<app-navmenu :class="{'is-active': menuIsActive}"/>
</div>
This lets the body of the menu stay active even when I click on the body without having to use a #click.stop. Then in the menu itself, I did this so that links will close the menu:
<div class="navbar-dropdown" #click.stop>
<div class="container is-fluid">
<div class="column">
<h1 class="title">Title</h1>
<div #click="toggleMenu">
<router-link class="navbar-item" :to="route" exact>
<div class="navbar-content">
<p class="has-text-info">info</p>
<small>meta info</small>
</div>
</router-link>
</div>
</div>
</div>
</div>
One strange behavior I noticed is that if I put the #click="toggleMenu" function in the <router-link/> element itself, it doesn't get called on, even if I use .prevent. Hence the need for the div wrapper around the router-link element.

change active tab on document ready

I would like to change the active pill/tab on document load. I know you can set the active pill like I have below but for other reasons I want to change it after document load. I have tried various bits of JS but nothing seems to work. Here's the HTML and JS (I have also tried replacing data-toggle="pill" with data-toggle="tab" below and still doesn't work).
<div>
<ul class="nav nav-pills pillstyle">
<li class="active tabstyle"><a data-toggle="pill" href="#apple">Apple</a></li>
<li class="tabstyle"><a data-toggle="pill" href="#banana">Banana</a></li>
<li class="tabstyle"><a data-toggle="pill" href="#pear">Pear</a></li>
<li class="tabstyle"><a data-toggle="pill" href="#orange" >Orange</a></li>
</ul>
</div> <!-- nav pills close -->
<div class="tab-content">
<div id="apple" class="tab-pane fade in active"> `
.... content of tabs.
JS
$(document).ready(function(){
$('#banana').tab('show');
});
or
$(document).ready(function(){
$('#banana').pill('show');
});
You just need to change your jQuery selector to address the a element instead of the tab-pane div.
$(document).ready(function(){
$('a[href="#banana"]').tab('show');
});
If you need, you can find more detailed description about bootstrap tabs in the official documentation.
#Stu Here you go.
HTML:
Assign an ID myTab to UL element.
<ul class="nav nav-pills pillstyle" id="myTab">
JS:
$(function () {
$('#myTab a[href="#banana"]').tab('show');
});
Also refer to Bootstrap documentation on selecting different elements on load here. It will give you better understanding.
http://getbootstrap.com/2.3.2/javascript.html#tabs
Working demo: https://jsfiddle.net/tf9k9j27/
Note: Just to answer your trial and error.
You can activate a tab or pill navigation without writing any JavaScript by simply specifying data-toggle="tab" or data-toggle="pill" on an element. Adding the nav and nav-tabs classes to the tab ul will apply the Bootstrap tab styling. (From bootstrap docs. read more to get better clarity)

Jquery tabs with scroll in each tab

I use jqueryUI tabs and want to implement a smooth scroll bar inside each tab. I tried several scrollable plugins like jQuery custom content scroller, TinyScrollbar and now areaaperta NiceScroll, but each time I stack with the same problem - scrollbar works only inside one tab..
<script>
$(function() {
$( "#tabs" ).tabs();
});
</script>
<div id="tabs" style="width:900px; font-size:100%;">
<ul>
<li><a href="#tabs-1" >FIRST</a></li>
<li>SECOND</li>
<li>THIRD</li>
</ul>
<div id="tabs-1">
<div id="thisdiv">
<p><b>FIRST SCROLLABLE PARAGRAPH</b>...</p></div></div>
<div id="tabs-2"><div id="thisdiv2">
<p><b>SECOND SCROLLABLE PARAGRAPH</b>...</p>
</div></div>
<div id="tabs-3">
<p>THIRD TAB </p>
</div>
</div>
<script>
$(document).ready(
function() {
$("#thisdiv").niceScroll({cursorcolor:"#00F"});
$("#thisdiv2").niceScroll({cursorcolor:"#00F"}); }
);
</script>
Here is jsfiddle that shows that there is no conflicts between UItabs and two scrollbars of niceScroll plugin: http://jsfiddle.net/Fluc/EhcqX/4/
And here I tried to use same divs with scroll bars inside each tab:
http://jsfiddle.net/Fluc/cJPT3/2/
As you can see, scrollable works only inside the first tab.. Same with other scrollable plugs..
I'm not jquery programmer but It feels like the problem is related to display property somewhere.
Any help would be very appreciated!