Skip to content

Commit 76bd950

Browse files
Merge pull request #625 from dtaylor113/pf-bootstrap-select
New (old) pf-bootstrap-select directive
2 parents ccc746f + ec645a4 commit 76bd950

File tree

7 files changed

+241
-3
lines changed

7 files changed

+241
-3
lines changed

Gruntfile.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ module.exports = function (grunt) {
168168
image: 'misc/logo-alt.svg',
169169
scripts: [
170170
'node_modules/jquery/dist/jquery.js',
171+
'node_modules/bootstrap/dist/js/bootstrap.min.js',
172+
'node_modules/bootstrap-select/js/bootstrap-select.js',
171173
'node_modules/components-jqueryui/jquery-ui.min.js',
172174
'node_modules/datatables.net/js/jquery.dataTables.js',
173175
'node_modules/datatables.net-select/js/dataTables.select.js',

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ Note:
7979
<!-- Angular -->
8080
<script src="node_modules/angular-patternfly/node_modules/angular/angular.min.js"></script>
8181
82+
<!-- Bootstrap-Select (Optional): The following lines are only required if you use the pfBootstrapSelect directive -->
83+
<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
84+
<script src="node_modules/bootstrap-select/js/bootstrap-select.js"></script>
85+
8286
<!-- Angular-Bootstrap -->
8387
<script src="node_modules/angular-patternfly/node_modules/angular-ui-bootstrap/dist/ui-bootstrap.js"></script>
8488
<script src="node_modules/angular-patternfly/node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@
6060
"optionalDependencies": {
6161
"angularjs-datatables": "^0.5.9",
6262
"angular-drag-and-drop-lists": "2.0.0",
63-
"bootstrap-select": "~1.10.0",
63+
"bootstrap": "~3.3.7",
64+
"bootstrap-select": "~1.12.4",
6465
"c3": "~0.4.11",
6566
"components-jqueryui": "components/jqueryui#1.12.1",
6667
"d3": "~3.5.17",
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
angular.module('patternfly.select').directive('pfBootstrapSelect', function () {
2+
'use strict';
3+
4+
return {
5+
restrict: 'A',
6+
require: '?ngModel',
7+
scope: {
8+
selectPickerOptions: '=pfBootstrapSelect'
9+
},
10+
link: function (scope, element, attrs, ngModel) {
11+
var optionCollectionList, optionCollectionExpr, optionCollection, $render = ngModel.$render;
12+
13+
var selectpickerRefresh = function (argument) {
14+
scope.$applyAsync(function () {
15+
element.selectpicker('refresh');
16+
});
17+
};
18+
19+
var selectpickerDestroy = function () {
20+
element.selectpicker('destroy');
21+
};
22+
23+
element.selectpicker(scope.selectPickerOptions);
24+
25+
ngModel.$render = function () {
26+
$render.apply(this, arguments);
27+
selectpickerRefresh();
28+
};
29+
30+
if (attrs.ngOptions) {
31+
optionCollectionList = attrs.ngOptions.split('in ');
32+
optionCollectionExpr = optionCollectionList[optionCollectionList.length - 1].split(/track by|\|/);
33+
optionCollection = optionCollectionExpr[0];
34+
35+
scope.$parent.$watchCollection(optionCollection, selectpickerRefresh);
36+
}
37+
38+
if (attrs.ngModel) {
39+
scope.$parent.$watch(attrs.ngModel, selectpickerRefresh);
40+
}
41+
42+
attrs.$observe('disabled', selectpickerRefresh);
43+
44+
scope.$on('$destroy', selectpickerDestroy);
45+
}
46+
};
47+
});
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @ngdoc directive
3+
* @name patternfly.select.directive:pfBootstrapSelect
4+
* @element select
5+
*
6+
* @param {string} ngModel Model binding using the {@link https://docs.angularjs.org/api/ng/type/ngModel.NgModelController/ NgModelController} is mandatory.
7+
* @param {string=} ngOptions The `{@link https://docs.angularjs.org/api/ng/directive/select/ ngOptions}` attribute can be used to dynamically generate a list of `<option>`
8+
* elements for the `<select>` element.
9+
*
10+
* @description
11+
* An AngularJS wrapper for the {@link http://silviomoreto.github.io/bootstrap-select/ Bootstrap-select} jQuery plugin which is used
12+
* as a default select decorator in {@link https://www.patternfly.org/widgets/#bootstrap-select Patternfly}.
13+
*
14+
* @example
15+
<example module="patternfly.select">
16+
17+
<file name="index.html">
18+
<div ng-controller="SelectDemoCtrl">
19+
20+
<form class="form-horizontal">
21+
<div class="form-group">
22+
<label class="col-sm-2 control-label" for="pet">Preferred pet:</label>
23+
<div class="col-sm-10">
24+
<select pf-bootstrap-select ng-model="pet" id="pet" ng-options="o as o for o in pets"></select>
25+
</div>
26+
</div>
27+
28+
<div class="form-group">
29+
<label class="col-sm-2 control-label" for="fruit">Preferred fruit:</label>
30+
<div class="col-sm-10">
31+
<select pf-bootstrap-select ng-model="fruit" id="fruit">
32+
<option value="orange">Orange</option>
33+
<option value="apple" ng-selected="true" selected>Apple</option>
34+
<option value="banana">Banana</option>
35+
</select>
36+
</div>
37+
</div>
38+
39+
<div class="form-group">
40+
<label class="col-sm-2 control-label" for="drink">Preferred drink:</label>
41+
<div class="col-sm-10">
42+
<select pf-bootstrap-select="{ noneSelectedText: 'None' }" ng-model="drink" id="drink" ng-options="o as o for o in drinks">
43+
<option value="">No drink selected</option>
44+
</select>
45+
</div>
46+
</div>
47+
48+
</form>
49+
50+
<p>Your preferred pet is {{pet}}.</p>
51+
<p>Your preferred fruit is {{fruit}}.</p>
52+
<p>Your preferred drink is {{drink || 'No drink selected'}}.</p>
53+
54+
</div>
55+
</file>
56+
57+
<file name="script.js">
58+
angular.module( 'patternfly.select' ).controller( 'SelectDemoCtrl', function( $scope ) {
59+
$scope.drinks = ['tea', 'coffee', 'water'];
60+
$scope.pets = ['Dog', 'Cat', 'Chicken'];
61+
$scope.pet = $scope.pets[0];
62+
$scope.fruit = 'orange';
63+
});
64+
</file>
65+
66+
</example>
67+
*/

src/select/examples/select.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* @param {function(item)} onSelect Function to call upon user selection of an item.
1111
*
1212
* @description
13-
* The pfSelect component provides a wrapper for the angular ui bootstrap dropdown container allowing for use of ng-model and ng-options
13+
* The pfSelect component provides a wrapper for the angular ui bootstrap dropdown.
1414
*
1515
* @example
1616
<example module="patternfly.select">
@@ -37,7 +37,7 @@
3737
</div>
3838
</form>
3939
<p>Your preferred pet is {{pet || noPet}}.</p>
40-
<p>Your preferred drink is {{fruit.name}}.</p>
40+
<p>Your preferred fruit is {{fruit.name}}.</p>
4141
<p>Your preferred drink is {{drink ? drink.name : noDrink}}.</p>
4242
</div>
4343
</file>
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
describe('pf-bootstrap-select', function () {
2+
3+
var $scope, $compile;
4+
5+
beforeEach(module('patternfly.select'));
6+
7+
beforeEach(inject(function (_$rootScope_, _$compile_) {
8+
$scope = _$rootScope_;
9+
$compile = _$compile_;
10+
}));
11+
12+
describe('Page with pf-select directive', function () {
13+
14+
var compileSelect = function (markup, scope) {
15+
var el = $compile(markup)(scope);
16+
scope.$digest();
17+
return el;
18+
};
19+
20+
it('should generate correct options from ng-options', function () {
21+
22+
$scope.options = ['a','b','c'];
23+
$scope.modelValue = $scope.options[1];
24+
25+
var select = compileSelect('<select pf-bootstrap-select ng-model="modelValue" ng-options="o as o for o in options"></select>', $scope);
26+
27+
$scope.$digest();
28+
29+
expect(select.text()).toBe('abc');
30+
expect(select).toEqualSelect(['a', ['b'], 'c']);
31+
32+
var bsSelect = angular.element(select).siblings('.dropdown-menu');
33+
var bsSelItems = bsSelect.find('li');
34+
expect(bsSelItems.length).toBe($scope.options.length);
35+
expect(bsSelItems.text()).toBe('abc');
36+
37+
var bsSelected = bsSelect.find('li.selected');
38+
expect(bsSelected.length).toBe(1);
39+
expect(bsSelected.text()).toBe('b');
40+
});
41+
42+
it('should respond to changes in ng-options', function () {
43+
44+
$scope.options = ['a','b','c'];
45+
$scope.modelValue = $scope.options[0];
46+
var select = compileSelect('<select pf-bootstrap-select ng-model="modelValue" ng-options="o as o for o in options"></select>', $scope);
47+
48+
expect(select.text()).toBe('abc');
49+
expect(select).toEqualSelect([['a'], 'b', 'c']);
50+
51+
var bsSelect = angular.element(select).siblings('.dropdown-menu');
52+
var bsSelItems = bsSelect.find('li');
53+
expect(bsSelItems.length).toBe($scope.options.length);
54+
expect(bsSelItems.text()).toBe('abc');
55+
56+
$scope.$apply(function() {
57+
$scope.options.push('d');
58+
});
59+
60+
$scope.$digest();
61+
62+
expect(select.text()).toBe('abcd');
63+
expect(select).toEqualSelect([['a'], 'b', 'c', 'd']);
64+
65+
bsSelect = angular.element(select).siblings('.dropdown-menu');
66+
bsSelItems = bsSelect.find('li');
67+
expect(bsSelItems.length).toBe($scope.options.length);
68+
expect(bsSelItems.text()).toBe('abcd');
69+
});
70+
71+
it('should respond to ng-model changes', function () {
72+
73+
$scope.options = ['a','b','c'];
74+
$scope.modelValue = $scope.options[0];
75+
var select = compileSelect('<select pf-bootstrap-select ng-model="modelValue" ng-options="o as o for o in options"></select>', $scope);
76+
77+
expect(select.text()).toBe('abc');
78+
expect(select).toEqualSelect([['a'], 'b', 'c']);
79+
80+
var bsSelect = angular.element(select).siblings('.dropdown-menu');
81+
var bsSelItems = bsSelect.find('li');
82+
expect(bsSelItems.length).toBe($scope.options.length);
83+
expect(bsSelItems.text()).toBe('abc');
84+
85+
var bsSelected = bsSelect.find('li.selected');
86+
expect(bsSelected.length).toBe(1);
87+
expect(bsSelected.text()).toBe('a');
88+
89+
$scope.$apply(function() {
90+
$scope.modelValue = $scope.options[1];
91+
});
92+
93+
$scope.$digest();
94+
95+
expect(select.text()).toBe('abc');
96+
expect(select).toEqualSelect(['a', ['b'], 'c']);
97+
98+
bsSelected = bsSelect.find('li.selected');
99+
expect(bsSelected.length).toBe(1);
100+
expect(bsSelected.text()).toBe('b');
101+
102+
$scope.$apply(function() {
103+
$scope.modelValue = $scope.options[2];
104+
});
105+
106+
$scope.$digest();
107+
108+
expect(select.text()).toBe('abc');
109+
expect(select).toEqualSelect(['a', 'b', ['c']]);
110+
111+
bsSelected = bsSelect.find('li.selected');
112+
expect(bsSelected.length).toBe(1);
113+
expect(bsSelected.text()).toBe('c');
114+
});
115+
116+
});
117+
});

0 commit comments

Comments
 (0)