Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit d265113

Browse files
committed
feat(position): implement auto positioning
Implementing the ability to auto position elements in the position service - positionElements function. Closes 4899
1 parent 526e6de commit d265113

File tree

12 files changed

+1161
-203
lines changed

12 files changed

+1161
-203
lines changed

src/popover/docs/demo.html

+6-5
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ <h4>Dynamic</h4>
2525
</script>
2626
<hr />
2727
<h4>Positional</h4>
28-
<button popover-placement="top" uib-popover="On the Top!" type="button" class="btn btn-default">Top</button>
29-
<button popover-placement="left" uib-popover="On the Left!" type="button" class="btn btn-default">Left</button>
30-
<button popover-placement="right" uib-popover="On the Right!" type="button" class="btn btn-default">Right</button>
31-
<button popover-placement="bottom" uib-popover="On the Bottom!" type="button" class="btn btn-default">Bottom</button>
32-
28+
<div class="form-group">
29+
<label>Popover placement</label>
30+
<select class="form-control" ng-model="placement.selected" ng-options="o as o for o in placement.options"></select>
31+
</div>
32+
<button popover-placement="{{placement.selected}}" uib-popover="On the {{placement.selected}}" type="button" class="btn btn-default">Popover {{placement.selected}}</button>
33+
3334
<hr />
3435
<h4>Triggers</h4>
3536
<p>

src/popover/docs/demo.js

+18
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,22 @@ angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function ($sco
44
templateUrl: 'myPopoverTemplate.html',
55
title: 'Title'
66
};
7+
8+
$scope.placement = {
9+
options: [
10+
'top',
11+
'top-left',
12+
'top-right',
13+
'bottom',
14+
'bottom-left',
15+
'bottom-right',
16+
'left',
17+
'left-top',
18+
'left-bottom',
19+
'right',
20+
'right-top',
21+
'right-bottom'
22+
],
23+
selected: 'top'
24+
};
725
});

src/popover/docs/readme.md

+16-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,22 @@ The popover directives provides several optional attributes to control how it
1818
will display:
1919

2020
- `popover-title`: A string to display as a fancy title.
21-
- `popover-placement`: Where to place it? Defaults to "top", but also accepts
22-
"bottom", "left", "right".
21+
- `popover-placement`: Where to place it? Defaults to "top". Passing in 'auto' seperated by a space before the placement will
22+
enable auto positioning, e.g: "auto bottom-left". The popover will attempt to position where it fits in
23+
the closest scrollable ancestor. Accepts:
24+
25+
- "top" - popover on top, horizontally centered on host element.
26+
- "top-left" - popover on top, left edge aligned with host element left edge.
27+
- "top-right" - popover on top, right edge aligned with host element right edge.
28+
- "bottom" - popover on bottom, horizontally centered on host element.
29+
- "bottom-left" - popover on bottom, left edge aligned with host element left edge.
30+
- "bottom-right" - popover on bottom, right edge aligned with host element right edge.
31+
- "left" - popover on left, vertically centered on host element.
32+
- "left-top" - popover on left, top edge aligned with host element top edge.
33+
- "left-bottom" - popover on left, bottom edge aligned with host element bottom edge.
34+
- "right" - popover on right, vertically centered on host element.
35+
- "right-top" - popover on right, top edge aligned with host element top edge.
36+
- "right-bottom" - popover on right, bottom edge aligned with host element bottom edge.
2337
- `popover-animation`: Should it fade in and out? Defaults to "true".
2438
- `popover-popup-delay`: For how long should the user have to have the mouse
2539
over the element before the popover shows (in milliseconds)? Defaults to 0.

src/position/docs/demo.html

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<div ng-controller="PositionDemoCtrl">
2+
<h4>$uibPosition service</h4>
3+
<div id="posdemoparent" ng-style="{'overflow': (parentScrollable && 'scroll'), 'position': (parentRelative && 'relative')}" style="border: 1px solid #ccc; padding: 15px;">
4+
<div class="checkbox">
5+
<label>
6+
<input type="checkbox" ng-model="parentScrollable"> Parent scrollable
7+
</label>
8+
</div>
9+
<div class="checkbox">
10+
<label>
11+
<input type="checkbox" ng-model="parentRelative"> Parent relative
12+
</label>
13+
</div>
14+
<button id="posdemobtn" class="btn btn-default" ng-click="getValues()">Get values</button>
15+
16+
<div id="posdemodiv" style="width: 100px; height: 100px; margin: 15px 0; padding: 10px; background-color: #f8f8f8; border: 1px solid #ccc;">
17+
Demo element
18+
</div>
19+
</div>
20+
<br />
21+
offsetParent: {{elemVals.offsetParent}}
22+
<br />
23+
scrollParent: {{elemVals.scrollParent}}
24+
<br />
25+
scrollbarWidth: {{scrollbarWidth}}
26+
<br />
27+
position: {{elemVals.position}}
28+
<br />
29+
offset: {{elemVals.offset}}
30+
<br />
31+
viewportOffset: {{elemVals.viewportOffset}}
32+
<br />
33+
positionElements: {{elemVals.positionElements}}
34+
</div>

src/position/docs/demo.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
angular.module('ui.bootstrap.demo').controller('PositionDemoCtrl', function ($scope, $window, $uibPosition) {
2+
3+
$scope.elemVals = {};
4+
$scope.parentScrollable = true;
5+
$scope.parentRelative = true;
6+
7+
$scope.getValues = function() {
8+
var divEl = $window.document.querySelector('#posdemodiv');
9+
var btnEl = $window.document.querySelector('#posdemobtn');
10+
11+
var offsetParent = $uibPosition.offsetParent(divEl);
12+
$scope.elemVals.offsetParent = 'type: ' + offsetParent.tagName + ', id: ' + offsetParent.id;
13+
14+
var scrollParent = $uibPosition.scrollParent(divEl);
15+
$scope.elemVals.scrollParent = 'type: ' + scrollParent.tagName + ', id: ' + scrollParent.id;
16+
17+
$scope.scrollbarWidth = $uibPosition.scrollbarWidth();
18+
19+
$scope.elemVals.position = $uibPosition.position(divEl);
20+
21+
$scope.elemVals.offset = $uibPosition.offset(divEl);
22+
23+
$scope.elemVals.viewportOffset = $uibPosition.viewportOffset(divEl);
24+
25+
$scope.elemVals.positionElements = $uibPosition.positionElements(btnEl, divEl, 'auto bottom-left');
26+
};
27+
});

src/position/docs/readme.md

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
The `$uibPosition` service provides a set of DOM utilities used internally to absolute-position an element in relation to another element (tooltips, popovers, typeaheads etc...).
2+
3+
### getRawNode(element)
4+
Takes a jQuery/jqLite element and converts it to a raw DOM element.
5+
6+
##### parameters
7+
8+
* `element` _(Type 'object')_ - The element to convert.
9+
10+
##### returns
11+
12+
_(Type 'element')_ - A raw DOM element.
13+
14+
### parseSyle(element)
15+
Parses a numeric style value to a number. Strips units and will return 0 for invalid (NaN) numbers.
16+
17+
##### parameters
18+
19+
* `value` _(Type 'string')_ - The style value to parse.
20+
21+
##### returns
22+
23+
_(Type 'number')_ - The numeric value of the style property.
24+
25+
### offsetParent(element)
26+
Gets the closest positioned ancestor.
27+
28+
##### parameters
29+
30+
* `element` _(Type 'element')_ - The element to get the offset parent for.
31+
32+
##### returns
33+
34+
_(Type 'element')_ - The closest positioned ancestor.
35+
36+
### scrollbarWidth()
37+
Calculates the browser scrollbar width and caches the result for future calls. Concept from the TWBS measureScrollbar() function in [modal.js](https://github.com/twbs/bootstrap/blob/master/js/modal.js).
38+
39+
##### returns
40+
41+
_(Type 'number')_ - The width of the browser scrollbar.
42+
43+
### scrollParent(element, includeHidden)
44+
Gets the closest scrollable ancestor. Concept from the jQueryUI [scrollParent.js](https://github.com/jquery/jquery-ui/blob/master/ui/scroll-parent.js).
45+
46+
##### parameters
47+
48+
* `element` _(Type 'element')_ - The element to get the closest scrollable ancestor for.
49+
50+
* `includeHidden` _(Type 'boolean', optional - default is false)_ - Should scroll style of 'hidden' be considered.
51+
52+
##### returns
53+
54+
_(Type 'element')_ - The closest scrollable ancestor.
55+
56+
### position(element, includeMargins)
57+
A read-only equivalent of jQuery's [position](http://api.jquery.com/position/) function, distance to closest positioned ancestor. Does not account for margins by default like jQuery's position.
58+
59+
##### parameters
60+
61+
* `element` _(Type 'element')_ - The element to get the position for.
62+
63+
* `includeMagins` _(Type 'boolean', optional - default is false)_ - Should margins be accounted for.
64+
65+
##### returns
66+
67+
_(Type 'object')_ - An object with the following properties:
68+
69+
* width: _(Type 'number')_ The width of the element.
70+
* height: _(Type 'number')_ The height of the element.
71+
* top: _(Type 'number')_ Distance to top edge of offset parent.
72+
* left: _(Type 'number')_ Distance to left edge of offset parent.
73+
74+
### offset(element)
75+
A read-only equivalent of jQuery's [offset](http://api.jquery.com/offset/) function, distance to viewport.
76+
77+
##### parameters
78+
79+
* `element` _(Type 'element')_ - The element to get the offset for.
80+
81+
##### returns
82+
83+
_(Type 'object')_ - An object with the following properties:
84+
85+
* width: _(Type 'number')_ The width of the element.
86+
* height: _(Type 'number')_ The height of the element.
87+
* top: _(Type 'number')_ Distance to top edge of the viewport.
88+
* left: _(Type 'number')_ Distance to left edge of the viewport.
89+
90+
### viewportOffset(element, useDocument, includePadding)
91+
Gets the elements available space relative to the closest scrollable ancestor. Accounts for padding, border, and scrollbar width.
92+
Right and bottom dimensions represent the distance to the respective edge of the viewport element, not the top and left edge.
93+
If the element edge extends beyond the viewport, a negative value will be reported.
94+
95+
##### parameters
96+
97+
* `element` _(Type 'element')_ - The element to get the viewport offset for.
98+
* `useDocument` _(Type 'boolean', optional - default is false)_ - Should the viewport be the document element instead of the first scrollable element.
99+
* `includePadding` _(Type 'boolean', optional - default is true)_ - Should the padding on the viewport element be accounted for, default is true.
100+
101+
##### returns
102+
103+
_(Type 'object')_ - An object with the following properties:
104+
105+
* top: _(Type 'number')_ Distance to top content edge of the viewport.
106+
* bottom: _(Type 'number')_ Distance to bottom content edge of the viewport.
107+
* left: _(Type 'number')_ Distance to left content edge of the viewport.
108+
* right: _(Type 'number')_ Distance to right content edge of the viewport.
109+
110+
### parsePlacement(placement)
111+
Gets an array of placement values parsed from a placement string. Along with the 'auto' indicator, supported placement strings are:
112+
113+
* top: element on top, horizontally centered on host element.
114+
* top-left: element on top, left edge aligned with host element left edge.
115+
* top-right: element on top, right edge aligned with host element right edge.
116+
* bottom: element on bottom, horizontally centered on host element.
117+
* bottom-left: element on bottom, left edge aligned with host element left edge.
118+
* bottom-right: element on bottom, right edge aligned with host element right edge.
119+
* left: element on left, vertically centered on host element.
120+
* left-top: element on left, top edge aligned with host element top edge.
121+
* left-bottom: element on left, bottom edge aligned with host element bottom edge.
122+
* right: element on right, vertically centered on host element.
123+
* right-top: element on right, top edge aligned with host element top edge.
124+
* right-bottom: element on right, bottom edge aligned with host element bottom edge.
125+
126+
A placement string with an 'auto' indicator is expected to be space separated from the placement, i.e: 'auto bottom-left'.
127+
If the primary and secondary placement values do not match 'top, bottom, left, right' then 'top' will be the primary placement and
128+
'center' will be the secondary placement. If 'auto' is passed, true will be returned as the 3rd value of the array.
129+
130+
##### parameters
131+
132+
* `placement` _(Type 'string', e.g. 'auto top-left')_ - The placement string to parse.
133+
134+
##### returns
135+
136+
_(Type 'array')_ - An array with the following values:
137+
138+
* [0]: _(Type 'string')_ - The primary placement.
139+
* [1]: _(Type 'string')_ - The secondary placement.
140+
* [2]: _(Type 'boolean')_ - Is auto place enabled.
141+
142+
### positionElements(hostElement, targetElement, placement, appendToBody)
143+
Gets gets coordinates for an element to be positioned relative to another element.
144+
145+
##### parameters
146+
147+
* `hostElement` _(Type 'element')_ - The element to position against.
148+
* `targetElement` _(Type 'element')_ - The element to position.
149+
* `placement` _(Type 'string', optional - default is top)_ - The placement for the target element. See the parsePlacement() function for
150+
available options. If 'auto' placement is used, the viewportOffset() function is used to decide where the targetElement will fit.
151+
* `appendToBody` _(Type 'boolean', optional - default is false)_ - Should the coordinates be cacluated from the body element.
152+
153+
##### returns
154+
155+
_(Type 'object')_ - An object with the following properties:
156+
157+
* top: _(Type 'number')_ The targetElement top value.
158+
* left: _(Type 'number')_ The targetElement left value.
159+
* right: _(Type 'number')_ The resolved placement with 'auto' removed.
160+
161+
### positionArrow(element, placement)
162+
Positions the tooltip and popover arrow elements when using placement options beyond the standard top, left, bottom, or right.
163+
164+
##### parameters
165+
166+
* `element` _(Type 'element')_ - The element to position the arrow element for.
167+
* `placement` _(Type 'string')_ - The placement for the element.

0 commit comments

Comments
 (0)