I'm using the panel-group to make an accordion as shown in the "Collapse" section of the Javascript nav at http://getbootstrap.com/javascript/#collapse
Except that I want the accordion to follow the screen as the user scrolls down, so I wrapped it all in a bootstrap well and added position:fixed to the div's style. Unfortunately, once I scroll to the bottom and try to expand the accordion, it expands off the bottom of the screen. When the accordion isn't position fixed, however, the screen will grow to accommodate the new height of the accordion. Is there a way I can have my cake and eat it too?
<div class="well" style="position: fixed"> <!--Causes this div to grow off the screen-->
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a id="panelOneLabel" class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapseOne">Title</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
<!--a bunch of content here-->
</div>
</div>
</div>
<!--a bunch of other similar panel panel-defaults-->
</div>
</div>
I ended up solving the problem by defining a height for the well and setting the overflow-y to auto in css. Now when it grows off the screen the well gets a scroll bar that allows me to get to any part of the accordion no matter what.
I just necro'd the code that I implemented when I was having this problem for anyone who wants it. The solution I went with at the time uses inline styling and probably isn't the greatest, or necessarily exactly what you want for your particular situation so I'd encourage anyone looking at this to think about their own choice of whether or not to use inline styling, and how to define their own css rules to solve the problem.
<div data-spy="affix" style="width: inherit; height: 100%; max-height: 80%; overflow-y: auto" class="well">...somewhere in here is my accordion...</div>
Related
I have a problem with scrollTop that partially works that I will try to describe. First to get it work I applied the solution found here.
I have an angular component that renders a list of nested angular components in it using *ngFor. Snippet follows (parent):
<div id="scrollable-container" class="scrollable">
<div *ngIf="isAccountsToShow" class="top-row-spacing">
<div *ngIf="accountsToggle">
<div class="grid-x ruler">
<div class="small-4 cell">
<div class="text-left sub-header">Header 1</div>
</div>
<div class="small-1 cell">
<div class="text-left sub-header">Header 2</div>
</div>
<div class="small-2 cell">
<div class="text-center sub-header">Header 3</div>
</div>
<div class="small-2 cell">
<div class="text-center sub-header">Header 4</div>
</div>
<div class="small-3 cell">
<div class="text-center sub-header">Header 5</div>
</div>
</div>
<div *ngFor="let data of displayAccounts">
<member-product
[memberNumber]="mnum"
id={{data.accountNumber}}
(scrollIntoView)="scrollToView(data.accountNumber)"
[product]="data" </member-product>
</div>
</div>
</div>
</div>
The child's html contains info on each header and in addition a ellipsis toggle at the far right that looks like this:
screenshot of a single element (Apparently I need more reputation points to fully add a screenshot. Hope it helps anyway).
The problem: everytime I click the ellipsis it will expand the account information (NOTE: this is NOT another angular nested component) to reveal even more information AND the account clicked will autoscroll to the top. screenshot of expanded widgetThis works for the first accounts considering that there might be dozens or even hundreds but will fail to scroll only for the last few and it will fail gradually, meaning that it will begin to scroll less closer to the top of its container until the very last item which will not scroll at all. Also it fails when only a few elements are displayed causing no overflow-y where the scrolling simply does not happen.
Scroll code: (I'm using event emitter here as you might have already noticed)
scrollToView(accountNumber): void {
var element = document.getElementById(accountNumber);
var topPos = element.offsetTop;
document.getElementById('scrollable-container').scrollTop = topPos - 10;
}
Css code:
.scrollable {
max-height: 24rem;
position: relative;
}
I not quite sure if this is an overflow-y related issue or what. I am completely puzzled with this.
Searching for this very particular problem in Stackoverflow yielded no results, be it angular be it jquery although it doesn't apply to my angular 2 scenario.
I appreciate any insight or help on the matter.
I am working on a bootstrap page (3.0). I have several small panels across the top of the page that are visible. Below these panels I have larger panels that contain much more detail of the small panels across the top that are hidden by default. When a user clicks on one of the small panels across the top, it hides the small panel and displays hidden larger stacked vertical panels below it with the additional info.
I need to make it so that whichever hidden panel is selected to open, that it will always show 1st (above all other visible divs). The problem I am having is they are showing in the order the divs are hard coded in the HTML, however users will not see the new div load unless they scroll down to see it visible on the page. I need all newly clicked panels to load 1st, so users will always see it load above all other now visible divs.
I am still learning jQuery/js.
So, for my top (small) panels, I have a link in the panel-footer that opens the associated larger panels when clicked. It hides the small panel when clicked, then shows the hidden panel (adds a zommIn animation as well). Then when a user closes the larger panel, it hides it again, then adds the small panel back to the top panels.
It is all working great, I just need to prepend the hidden divs to ALWAYS display as 1st (above the other visible divs).
Here is an example of the jQuery I am using to show the larger panels and hide the associated small top panels...
//Device Panel
$("#openDashDevices").click(function(){
$("#dashDevice").addClass("show zoomIn");
window.setTimeout( function(){
$("#dashDevice").removeClass("zoomIn");
}, 1000);
$("#dashDevice").removeClass("hide");
$("#topPanelDevice").addClass("hide");
$("#topPanelDevice").removeClass("show-inline zoomIn");
});
And here is the jQuery I am using that closes/hides the larger panels and re-shows the hidden small panel across the top...
//Device Panel
$("#closeDevicePanel").click(function(){
$("#dashDevice").addClass("hide");
$("#dashDevice").removeClass("show zoomIn");
$("#topPanelDevice").addClass("show-inline zoomIn");
window.setTimeout( function(){
$("#topPanelDevice").removeClass("zoomIn");
}, 1000);
$("#topPanelDevice").removeClass("hide");
});
HTML of ONE of the top panels:
<!--Dashboard Top Panels-->
<div class="dashboardPanelsGroup fivecolumns sortable">
<div id="topPanelDevice" class="dashboardDevices dashboardPanels show-inline animated">
<div class="panel panel-primary">
<div class="panel-heading">
<div class="dragPanelTop"><i class="fa fa-arrows"></i></div>
<div class="row">
<div class="col-xs-3 dashIcon">
<i class="icon-device"></i>
</div>
<div class="col-xs-9 text-right">
<div class="huge">1344</div>
<div class="dashSubText">Computers</div>
</div>
</div>
</div>
<a id="openDashDevices" class="dashPanelFooter" href="javascript:void(0);">
<div class="panel-footer">
<span class="pull-left">View Devices</span>
<span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
<div class="clearfix"></div>
</div>
</a>
</div>
</div>
</div>
And here is the html of ONE of the larger panels (hidden by default)...
<!--Opened Dashboard Panels-->
<div class="openedDashboardPanelsGroup sortable">
<div id="dashDevice" class="dashboardDevices dashboardPanelsOpen col-sm-12 animated hide">
<div id="panelDevices" class="panel panel-primary">
<div class="panel-heading">
<div class="dragPanelBottom"><i class="fa fa-arrows"></i></div>
<div class="pull-right"><button id="closeDevicePanel" type="button" class="close" title="" rel="tooltip" data-original-title="Close Panel">×</button></div>
<div class="row">
<div class="openDashTitle">
<div class=""><i class="dashIcon fa fa-bar-chart"></i>Devices</div>
</div>
</div>
</div>
<div class="panelDashboardContent">
<div id="maintStatsContent" class="maintenanceStats" type="maintenanceStats">
Maint Stats goes here
</div>
</div>
</div>
</div>
</div>
Here is a screenshot showing my top panels and a couple of the larger panels opened...
Instead of hard coding the html I would create it dynamically with jquery. That way you can just prepend it to the container.
$("#closeDevicePanel").click(function() {
$('.containerclass').prepend('yourhtml');
}
I got it to work. I just needed to use prependTo. For example, to open the Alerts panel...
//Alerts Panel
$("#openDashAlerts").click(function(){
$("#dashAlerts").prependTo(".openedDashboardPanelsGroup");
$("#dashAlerts").addClass("show zoomIn");
window.setTimeout( function(){
$("#dashAlerts").removeClass("zoomIn");
}, 1000);
$("#dashAlerts").removeClass("hide");
$("#topPanelAlerts").addClass("hide");
$("#topPanelAlerts").removeClass("show-inline zoomIn");
});
This now loads with my animation just like I need, and always prepends it as the 1st child of the parent div.
I'm making an angular web-app with a sidebar view attached to the side of every page. I'm using twitter-bootstrap to handle grid/spacing on the page and ui-router to handle the different views.
My views are laid out like this:
index.html
<div ui-view="sidebar"></div>
<div ui-view="content"></div>
<div ui-view="content-2"></div>
The markup for my sidebar is as follows:
sidebar.html
<div class="col-sm-3 sidebar">
<!-- sidebar view content -->
</div>
and the markup for my content views:
content.html and content-2.html
<div class="col-sm-9 container-fluid">
<!-- content view content -->
</div>
the content views are stacked one on top of the other next to my sidebar.
The problem is that one of my pages includes a dynamically expanding component, which increases the height of the content views. This pushes the lower content view ('content-2') down the page, and when it goes below the bottom of the sidebar view, it slides left, underneath the sidebar, instead of staying on the right below the first content view.
I've tried adding style="padding-bottom:500px" and style="vh:100" to the sidebar div, which works for a bit because it extends that view down, but I'd prefer a solution that doesn't unnecessarily extend the page beyond what is currently necessary. Additionally, once the content-view2 reaches the bottom of the padding, it still slides over just like before.
Update:
I finally got my plunker up, so hopefully this will illustrate the problem and what I'm trying to do: http://plnkr.co/edit/EbGJAqxdjHRCMjjC6waA
The content.html view will dynamically increase/decrease when the user presses the button, illustrating the problem (make sure to scroll down to see what I'm talking about).
The simplest working solution without layout changes. The problem is the float:left of the 2nd content, so let's change it to right when the screen size is large enough - plunker:
<div class="content2 col-md-10 container-fluid">
<div class="container-fluid" style="background:#800000;color:white">
<h2>Content Frame Two</h2>
<p>Centered below Frame One at start, should still be centered after button press.</p>
</div>
</div>
#media (min-width: 992px) {
.content2 {
float: right;
}
}
A simpler working solution + plunker:
Remove this from sidebar - style="padding-bottom:100vh" - as we don't need it anymore.
Change your html markup, so that both content areas would be wrapped in one big float. In this way, the 2nd content, can slide left.
Index:
<div class="container">
<div ui-view="sidebar"></div>
<div class="col-md-10 container-fluid">
<div ui-view="content"></div>
<div ui-view="content-2"></div>
</div>
</div>
Content 1:
<div class="col-md-12 container-fluid" style="padding-bottom:20px">
<!-- the padding on the following container is to simulate the added space
that appears once the div dynamically increases in size -->
<div class="container-fluid" ng-style="vm.contentStyle">
<h2>Content Frame One</h2>
<button ng-click="vm.expand()" type="button" class="btn btn-default">{{ vm.change }} Size</button>
<p ng-show="vm.info">{{ vm.info }}</p>
</div>
</div>
Content 2:
<div class="col-md-12 container-fluid">
<div class="container-fluid" style="background:#800000;color:white">
<h2>Content Frame Two</h2>
<p>Centered below Frame One at start, should still be centered after button press.</p>
</div>
</div>
Previous non-working solution:
It's bit hard to hard to replicate the problem without a working plunker/fiddler, but I think that setting the height of the sidebar to 100vh or the padding to calc(100vh - height of sidebar) will solve your problem.
1vh is 1% of the view port height - ie the available browser display area, so setting it using vh will resize your sidebar or the padding dynamically according to screen height.
Note of caution - vh (and vw) are only supported by modern browsers (see caniuse).
I'm creating an accordion group using bootstrap 3, here is the code:
<div id="accordion" class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1">
<h3>Purchase No: 123 </h3>
</a>
</div>
</div>
<div id="collapse1" class="panel-collapse collapse">
content here
</div>
</div>
</div>
The code works fine when I open the accordion, but when I click it again (to close), it collapses, and open up again.
In short the accordion can't be closed once opened. I noticed the element changes at this particular div
<div id="collapse1" class="panel-collapse collapse in">
In that state the the accordion is collapsed, and when I close it, the class changes to collapsing (showing the animation) then it is removed. But briefly after that, the class "collapsing" and "in" added again so in the browser when I try to close an accordion it will like somehow shows "bouncy" animation which make it never closed when I try to close it
Any suggestions?
thanks all for the suggestions, but it is looks like i was using an older version of jquery which is not compatible with bootstrap 3, found this error on firefox's web inspector(idk but firebug does not point this error). I am now using jquery 2.x and the accordions works perfectly
I created a payment page for mobile in php with bootstrap. If visitor click the text the panel is expanding. But if visitor clicks nearby text the panel is not expanding. This is not useful.
How can we transform collapsed panel to full clickable ?
You can manually toggle the accordion with $('#myAccordion').collapse('toggle')
Just set an event handler to watch for clicks on whatever area you want to be clickable, and then toggle the accordion.
For reference: http://getbootstrap.com/javascript/#collapse
You will need to put the "href" attribute on the div element with class "panel-heading", also put there the "data-toggle" attribute. Like This:
<div class="panel-heading invisible" data-toggle="collapse" href="#collapseOne">
<h1 class="panel-title">
Title
</h1>
</div>
<div id="collapseOne" class="panel-collapse collapse">
<div class="panel-body">
</div>
</div>
Hope That Helps, dont forget to put the same ID to the "panel-collapse" element that holds the "panel-body". Good Luck :)