I am working on a single-page-application using AngularJS, supported by Bootstrap. But Bootstrap is mainly used for modal dialogs. My DOM consists of various absolutely placed nested divs.
It works fine on most browsers, except for iOS (even the Windows Safari does it correctly) - but I have the problem, that on iPad the modal-backdrop is behind certain other elements.
The most common answer I found was to move the modals outside "everything". However this is not easily possible, since most of them are Angular directives that depend on the scope they are in.
The buildup looks something like this:
<header>..</header> <!-- position absolute -->
<content> <!-- position absolute -->
<sidebar>..</sidebar> <!-- position absolute -->
<part> <!-- position absolute -->
<button ng-click="openModal()">Click</button>
<my-modal parent="part"></my-modal>
</part>
</content>
part is a "wrapper" that manages the display of data.
my-modal is an Angular directive, whose template looks like a standard Bootstrap modal:
<div class="modal fade" class="my-modal-finder">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2>...</h2>
</div>
<div class="modal-body">
...
</div>
</div>
</div>
</div>
openModal basically looks for "my-modal" and then uses $('.my-modal-finder').modal('show'). As mentioned: on iPad, the header and the sidebar are shown over the backdrop and the modal content.
I have already updated to Bootstrap 3.3.2.
I suppose I could write two directives "my-modal-init" and "my-modal", where "my-modal-init" compiles the contents of "my-modal" and appends them to $('body') - and cleans up on $destroy.
This does feel rather hacky though, so I'd rather not.
Does anyone have experience with this problem and knows of a better solution?
Related
I am using Bootstrap's modal for displaying a dropdown menu containing a list of countries. There is an issue when the list shows up as it is much longer than the window (it is worth mentioning I am working on a browser extension).
Since I am using Vue.js, my code is:
<template>
<div class="modal fade" id="chooseCountry">
<div class="absolute justify-content-center modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="container">
<div class="mb-2">How can I prevent that from happening?</div>
<v-select label="name" :options="countries"></v-select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
</template>
...which is a generic Bootstrap template but with added vSelect - a select/dropdown component. I tried adding overflow-y: hidden; to #chooseCountry and despite hiding the outer scrollbar, the left gap would still appear every time the little arrow was clicked(i.e. dropdown was appearing)
The modal has the same width as the parent and the issue appears with the outer scrollbar. It adjusts its width such that the scrollbar can fit on the right (1st image), creating a whitespace on the left too, matching the right gap. The problem is, when a scrollbar is hidden, it still adds the gap on the left-hand side anyway (2nd image)..
So is there a way to force the modal to keep its original width? Alternatively, what could also work is another dropdown list with a dedicated input field for searching. I noticed I used vSelect since it was quicker for me to use a pre-made solution but if it would solve my issue, then I am keen on removing it :-).
Any help will be highly appreciated and sorry if a similar post has been already posted but I found nothing that could help me and my program, especially because it is a browser extension...
If I missed any code that might be relevant please let me know and I will provide it happily.
Ohh okay, my bad - the solution is easier than I thought.
Apparently Bootstrap offers a special Modal, which solves the issue:
Combining it with overflow-y:hidden; does everything I wanted.
I am having a lot of tabs in my website designed with Bootstrap which I tried to make responsive using https://github.com/flatlogic/bootstrap-tabcollapse (Demo here:http://tabcollapse.okendoken.com/example/example.html)
I was able to make the tabs responsive but the problem is I am loading content into the tabs using AJAX (like https://coderwall.com/p/1lnxba/load-bootstrap-tabs-dynamically) and the problem is that the entire markup of the tab changes to panel when resized to small size and id of the element is also changed.
So, how will I load the elements inside those tabs using ajax since markup is changed. I dont want to write separate code for loading for both cases.
Or is there any other better alternative to this? Or some solution which does not change markup of tabs but still is responsive?
Thanks in advance.
Try using Bootstrap's Containers to hold the AJAX-loaded content.
I'm assuming your code is something like this (just the tab-pane bit), but you should update your question with at least a layout to get better responses.
<div class="tab-pane fade in active" id="home">
<!-- ... Other Content ... -->
<div id="ajaxContent" class="container">
<!-- Where Tab 1 Content would go because it's active -->
</div>
<!-- ... Other Content ... -->
</div>
See Bootstrap's Components page for a full list of classes that you can use.
I have a Bootstrap accordion on my web app which is not doing what I want, I am passing dynamic data and if you know the usage of the accordion you must provide a data-target or href attributes to it and then a div id to the parent element of the panel body.
Ok look at my code:
<div class="panel panel-default" ng-repeat="sport in sports">
<div class="panel-heading" ng-click="addSportToLines(sport)"
data-toggle="collapse"
data-parent="#accordion"
data-target="{{sport.id}}">
<h4 class="panel-title">
<a>
{{::sport.name }}
</a>
</h4>
</div>
<div id="{{sport.id}}" class="panel-collapse collapse" role="tabpanel">
<div class="panel-body">
<div class="list-group leagues-margin"
class="list-group-item"
ng-repeat="league in sport.leagues"
ng-click="addLeagueToLines(league)">{{:: league.name}}
</div>
</div>
In this case the {{sport.id}} is the data-target which is the same id on the parent element of the .panel-body as you can see, if I put Inspect Element on my browser, every single element appears with a different and unique id and that's why I am here asking this, it is very weird because everything seems to be right but the behavior of my accordion is not the proper. The accordion is not opening the panels. So what suggestions do you have?
Second question: I am using Angular-Strap and the project is almost done, I am about to get done so I can not switch to Angular Bootstrap UI, is there a way to add Angular Bootstrap UI without having any conflict with Angular-Strap ? I tried yesterday but some conflicts comes up, and all I need is the accordion/collapse plugin from Angular Bootstrap UI, the reason why I am not using the Angular-Strap collapse, is because the plug in does not have the behavior I am looking for.
tldr; Never mix the original bootstrap.js with angular, instead use some angular module that implements bootstrap widgets.
Looks like you are mixing the bootstrap original components with angular. You can't do that, I mean, you must not let any other library manipulate the DOM if you are using angular, unless you wrap the DOM manipulation in a directive.
There are some angular modules implementing the behavior for bootstrap components. I use UI Bootstrap.
I am resizing Bootstrap modal windows based on their content with a little help of jQuery. The whole thing is basically working as a custom-built lightbox. Now I would be very happy if I could use AngularJS to populate the website with data.
First of all, I'm aware that I should ideally migrate to native AngularJS UI Bootstrap. However, it seems to me that the frontend is at the stage of development where ditching the work which has been put into making vanilla Bootstrap work as expected, would not be feasible. Especially, when considering the lack of my JavaScript coding skills and the fact that I had to put a considerable effort even into this simple jQuery script.
Here's an extremely simplified version of my perfectly working static code:
<a href="#modal-000" data-toggle="modal" data-target="#modal-000">
Open modal #000
</a><br/>
<div class="modal" id="modal-000" role="dialog">
<div class="modal-dialog" id="modal-dialog-000">
<div class="modal-content">
<div class="modal-body">
I am modal #000.
Close<br/>
<img src="http://i.imgur.com/4rLrHBa.png" id="image-000"/>
</div>
</div>
</div>
</div>
<script>
// Resizing modal window
$('#modal-000').on('shown.bs.modal', function () {
var modalWidth = $('#image-000').width() + 30;
$('#modal-dialog-000').css('width', modalWidth);
});
</script>
And here's a jsFiddle which also includes the hypothetical AngularJS part: http://jsfiddle.net/evaldass/xy3zu0w1/
How can I achieve this inside a ng-repeat? Should jQuery be removed altogether? Or maybe it's possible to choose a quicker path that would be not very puristic? Thanks.
I'm building a tabbed interface for displaying posts from various social networks (timelines) but not all tabs will have the same HTML markup. My factory service is returning JSON response so that part is fine.
Also, a sidebar contains tabs onto which I put ng-click for opening appropriate panes.
Now, I'm wondering if I should proceed with creating a custom directive to reside inside my tab-pane wrapper:
<div class="tab-pane">
<div timeline=""></div>
or
<timeline></timeline>
</div>
If so, I'm unsure whether $compile is the right approach? I've read that it is rarely used but it seems to me that it would allow me to dynamically decide which custom directive template to use, based on the clicked tab.
If there is a better approach to the solution, let me know. I'm really new to AngularJS but I'm eager to learn it, and learn it properly, applying best practices whenever possible.
The easy way might be:
<div class="tab-pane" ng-repeat="tab in tabs" ng-switch="tab.network">
<div ng-switch-when="Network_A">
/* Template for Network A here... */
</div>
<div ng-switch-when="Network_B">
/* Template for Network B here... */
</div>
<div ng-switch-when="Network_C">
/* Template for Network C here... */
</div>
</div>
So, you will need to add a network attribute to the tab objects, which tells what is the type of the social network.
Using directives might be a more efficient solution, but also more complicated.