Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit e07c52d

Browse files
committed
feat(select): add support for raw HTML in options
closes #2242, closes #5847
1 parent f780beb commit e07c52d

File tree

2 files changed

+45
-33
lines changed

2 files changed

+45
-33
lines changed

src/components/select/select.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,6 @@
55

66
/***************************************************
77
8-
### TODO ###
9-
**DOCUMENTATION AND DEMOS**
10-
11-
- [ ] ng-model with child mdOptions (basic)
12-
- [ ] ng-model="foo" ng-model-options="{ trackBy: '$value.id' }" for objects
13-
- [ ] mdOption with value
14-
- [ ] Usage with input inside
15-
168
### TODO - POST RC1 ###
179
- [ ] Abstract placement logic in $mdSelect service to $mdMenu service
1810
@@ -257,7 +249,7 @@ function SelectDirective($mdSelect, $mdUtil, $mdTheming, $mdAria, $compile, $par
257249
var tmpPlaceholder = attr.placeholder || (containerCtrl && containerCtrl.label ? containerCtrl.label.text() : '');
258250
text = text || tmpPlaceholder || '';
259251
var target = valueEl.children().eq(0);
260-
target.text(text);
252+
target.html(text);
261253
};
262254

263255
mdSelectCtrl.setIsPlaceholder = function(isPlaceholder) {
@@ -638,7 +630,7 @@ function SelectMenuDirective($parse, $mdUtil, $mdTheming) {
638630
var selectedOptionEls = $mdUtil.nodesToArray($element[0].querySelectorAll('md-option[selected]'));
639631
if (selectedOptionEls.length) {
640632
return selectedOptionEls.map(function(el) {
641-
return el.textContent;
633+
return el.innerHTML;
642634
}).join(', ');
643635
} else {
644636
return '';

src/components/select/select.spec.js

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ describe('<md-select>', function() {
1717
backdrops.remove();
1818
}));
1919

20-
it('should preserve tabindex', inject(function($document) {
20+
it('should preserve tabindex', function() {
2121
var select = setupSelect('tabindex="2", ng-model="val"').find('md-select');
2222
expect(select.attr('tabindex')).toBe('2');
23-
}));
23+
});
2424

25-
it('supports non-disabled state', inject(function($document) {
25+
it('supports non-disabled state', function() {
2626
var select = setupSelect('ng-model="val"').find('md-select');
2727
expect(select.attr('aria-disabled')).toBe('false');
28-
}));
28+
});
2929

3030
it('supports disabled state', inject(function($document) {
3131
var select = setupSelect('disabled="disabled", ng-model="val"').find('md-select');
@@ -34,7 +34,7 @@ describe('<md-select>', function() {
3434
expect(select.attr('aria-disabled')).toBe('true');
3535
}));
3636

37-
it('supports passing classes to the container', inject(function($document, $timeout) {
37+
it('supports passing classes to the container', inject(function($document) {
3838
var select = setupSelect('ng-model="val", md-container-class="test"').find('md-select');
3939
openSelect(select);
4040

@@ -142,7 +142,7 @@ describe('<md-select>', function() {
142142

143143
openSelect(select);
144144

145-
var opt = $document.find('md-option')[0].click();
145+
$document.find('md-option')[0].click();
146146

147147
waitForSelectClose();
148148

@@ -158,17 +158,17 @@ describe('<md-select>', function() {
158158
expect(el).not.toHaveClass('md-input-has-value');
159159
}));
160160

161-
it('should match label to given input id', inject(function($rootScope) {
161+
it('should match label to given input id', function() {
162162
var el = setupSelect('ng-model="$root.value", id="foo"');
163163
expect(el.find('label').attr('for')).toBe('foo');
164164
expect(el.find('md-select').attr('id')).toBe('foo');
165-
}));
165+
});
166166

167-
it('should match label to automatic input id', inject(function($rootScope) {
167+
it('should match label to automatic input id', function() {
168168
var el = setupSelect('ng-model="$root.value"');
169169
expect(el.find('md-select').attr('id')).toBeTruthy();
170170
expect(el.find('label').attr('for')).toBe(el.find('md-select').attr('id'));
171-
}));
171+
});
172172
});
173173

174174
describe('label behavior', function() {
@@ -212,6 +212,29 @@ describe('<md-select>', function() {
212212
expect(label.text()).toBe('One, Three');
213213
expect(label.hasClass('md-select-placeholder')).toBe(false);
214214
}));
215+
216+
it('supports raw html', inject(function($rootScope, $compile, $sce) {
217+
$rootScope.val = 0;
218+
$rootScope.opts = [
219+
{ id: 0, label: '<p>Hello World</p>' },
220+
{ id: 1, label: 'Hello World' }
221+
];
222+
angular.forEach($rootScope.opts, function(opt) {
223+
opt.label = $sce.trustAs('html', opt.label);
224+
});
225+
var select = $compile('<md-input-container>' +
226+
'<label>Placeholder</label>' +
227+
'<md-select ng-model="val" placeholder="Placeholder">' +
228+
'<md-option ng-value="opt.id" ng-repeat="opt in opts" ng-bind-html="opt.label"></md-option>' +
229+
'</md-select>' +
230+
'</md-input-container>')($rootScope).find('md-select');
231+
var label = select.find('md-select-value').children().eq(0);
232+
$rootScope.$digest();
233+
234+
235+
expect(label.text()).toBe('Hello World');
236+
expect(label.html()).toBe('<p>Hello World</p>');
237+
}));
215238
});
216239

217240
it('auto-infers a value when none specified', inject(function($rootScope) {
@@ -221,7 +244,7 @@ describe('<md-select>', function() {
221244
expect(selectedOptions(el).length).toBe(1);
222245
}));
223246

224-
it('errors for duplicate md-options, non-dynamic value', inject(function($rootScope) {
247+
it('errors for duplicate md-options, non-dynamic value', inject(function() {
225248
expect(function() {
226249
setup('ng-model="$root.model"', '<md-option value="a">Hello</md-option>' +
227250
'<md-option value="a">Goodbye</md-option>');
@@ -582,7 +605,7 @@ describe('<md-select>', function() {
582605
it('does not let an empty array satisfy required', inject(function($rootScope, $compile) {
583606
$rootScope.model = [];
584607
$rootScope.opts = [1, 2, 3, 4];
585-
var form = $compile('<form name="testForm">' +
608+
$compile('<form name="testForm">' +
586609
'<md-select ng-model="model", name="multiSelect" required="required" multiple="multiple">' +
587610
'<md-option ng-repeat="opt in opts" ng-value="opt"></md-option>' +
588611
'</md-select></form>')($rootScope);
@@ -689,25 +712,24 @@ describe('<md-select>', function() {
689712
expect(select.attr('aria-label')).toBe('Pick');
690713
}));
691714

692-
it('preserves existing aria-label', inject(function($rootScope) {
715+
it('preserves existing aria-label', function() {
693716
var select = setupSelect('ng-model="someVal", aria-label="Hello world", placeholder="Pick"').find('md-select');
694717
expect(select.attr('aria-label')).toBe('Hello world');
695-
}));
718+
});
696719

697720
it('should expect an aria-label if none is present', inject(function($compile, $rootScope, $log) {
698721
spyOn($log, 'warn');
699-
var select = setupSelect('ng-model="someVal"', null, true).find('md-select');
722+
setupSelect('ng-model="someVal"', null, true).find('md-select');
700723
$rootScope.$apply();
701724
expect($log.warn).toHaveBeenCalled();
702725

703726
$log.warn.calls.reset();
704-
select = setupSelect('ng-model="someVal", aria-label="Hello world"').find('md-select');
727+
setupSelect('ng-model="someVal", aria-label="Hello world"').find('md-select');
705728
$rootScope.$apply();
706729
expect($log.warn).not.toHaveBeenCalled();
707730
}));
708731

709-
it('sets up the aria-expanded attribute', inject(function($document, $timeout) {
710-
disableAnimations();
732+
it('sets up the aria-expanded attribute', inject(function($document) {
711733

712734
expect(el.attr('aria-expanded')).toBe('false');
713735
openSelect(el);
@@ -725,7 +747,7 @@ describe('<md-select>', function() {
725747

726748
expect(el.attr('aria-multiselectable')).toBe('true');
727749
}));
728-
it('sets up the aria-selected attribute', inject(function($rootScope) {
750+
it('sets up the aria-selected attribute', function() {
729751
var el = setup('ng-model="$root.model"', [1,2,3]);
730752
var options = el.find('md-option');
731753
expect(options.eq(2).attr('aria-selected')).toBe('false');
@@ -734,7 +756,7 @@ describe('<md-select>', function() {
734756
target: el.find('md-option')[2]
735757
});
736758
expect(options.eq(2).attr('aria-selected')).toBe('true');
737-
}));
759+
});
738760
});
739761

740762
describe('keyboard controls', function() {
@@ -786,9 +808,7 @@ describe('<md-select>', function() {
786808
});
787809

788810
describe('md-select-menu', function() {
789-
it('can be closed with escape', inject(function($document, $rootScope, $animate) {
790-
disableAnimations();
791-
811+
it('can be closed with escape', inject(function($document) {
792812
var el = setupSelect('ng-model="someVal"', [1, 2, 3]).find('md-select');
793813
openSelect(el);
794814
var selectMenu = angular.element($document.find('md-select-menu'));

0 commit comments

Comments
 (0)