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

Commit

Permalink
fix(select): change placeholder computation to be handled internally
Browse files Browse the repository at this point in the history
closes #1666
  • Loading branch information
rschmukler committed Feb 25, 2015
1 parent 9e0ca44 commit b4c0a86
Showing 1 changed file with 32 additions and 21 deletions.
53 changes: 32 additions & 21 deletions src/components/select/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ function SelectDirective($mdSelect, $mdUtil, $mdTheming, $interpolate, $compile,

return {
restrict: 'E',
require: '?ngModel',
compile: compile
require: ['mdSelect', '?ngModel'],
compile: compile,
controller: function() { } // empty placeholder controller to be initialized in link
};

function compile(element, attr) {
Expand All @@ -86,7 +87,6 @@ function SelectDirective($mdSelect, $mdUtil, $mdTheming, $interpolate, $compile,
}
labelEl.append('<span class="md-select-icon" aria-hidden="true"></span>');
labelEl.addClass('md-select-label');
labelEl.addClass(intStart + attr.ngModel + ' !== undefined ? \'\' : \'md-placeholder\'' + intEnd);
labelEl.attr('id', 'select_label_' + $mdUtil.nextUid());

// There's got to be an md-content inside. If there's not one, let's add it.
Expand Down Expand Up @@ -117,11 +117,26 @@ function SelectDirective($mdSelect, $mdUtil, $mdTheming, $interpolate, $compile,

$mdTheming(element);

return function postLink(scope, element, attr, ngModel) {
return function postLink(scope, element, attr, ctrls) {
var isOpen;

var mdSelectCtrl = ctrls[0];
var ngModel = ctrls[1];
var labelEl = element.find('md-select-label');
var customLabel = labelEl.text().length !== 0;
if (!customLabel) labelEl = labelEl.children().eq(0);

mdSelectCtrl.setLabelText = function(text) {
if (customLabel) return; // Assume that user is handling it on their own
mdSelectCtrl.setIsPlaceholder(!text);
var newText = text || attr.placeholder;
var target = customLabel ? labelEl : labelEl.children().eq(0);

This comment has been minimized.

Copy link
@gkalpak

gkalpak Feb 26, 2015

Member

If customLabel is truthy, we never reach this line, so the ternary is unnecessary.

target.html(newText);

This comment has been minimized.

Copy link
@jelbourn

jelbourn Feb 25, 2015

Member

Why are you setting the html instead of the text?

};

mdSelectCtrl.setIsPlaceholder = function(val) {
val ? labelEl.addClass('md-placeholder') : labelEl.removeClass('md-placeholder');
};

This comment has been minimized.

Copy link
@jelbourn

jelbourn Feb 25, 2015

Member

These methods shouldn't be defined in the link function; if an md-select is placed inside of an ng-repeat, they will be instantiated once per repetition.

This comment has been minimized.

Copy link
@gkalpak

gkalpak Feb 26, 2015

Member

Do you imply they should be defined on the controller's prototype ?


setInitialLabelValue();

attr.$observe('disabled', function(disabled) {
Expand Down Expand Up @@ -155,30 +170,25 @@ function SelectDirective($mdSelect, $mdUtil, $mdTheming, $interpolate, $compile,
}
});


// Create a fake select to find out the label value
function setInitialLabelValue() {
if ($parse(attr.ngModel)(scope)) {
var fakeSelectEl = angular.element(selectTemplate.clone()).find('md-select-menu');
fakeSelectEl.data('$ngModelController', ngModel);
fakeSelectEl.data('$mdSelectController', mdSelectCtrl);
var fakeSelectScope = scope.$new();
fakeSelectEl = $compile(fakeSelectEl)(fakeSelectScope);
var fakeSelectCtrl = fakeSelectEl.controller('mdSelectMenu');
fakeSelectScope.$$postDigest(function() {
ngModel.$render();
setLabelText(fakeSelectCtrl.selectedLabels());
fakeSelectEl.scope().$destroy();
});
} else {
setLabelText();
mdSelectCtrl.setLabelText();
}
}

function setLabelText(text) {
if (customLabel) return; // Assume that user is handling it on their own
var newText = text || attr.placeholder;
labelEl.html(newText);
}

function openOnKeypress(e) {
var allowedCodes = [32, 13, 38, 40];
if (allowedCodes.indexOf(e.keyCode) != -1 ) {
Expand All @@ -192,29 +202,28 @@ function SelectDirective($mdSelect, $mdUtil, $mdTheming, $interpolate, $compile,
scope.$evalAsync(function() {
var selectEl = selectTemplate.clone();
selectEl.find('md-select-menu').data('$ngModelController', ngModel);
selectEl.find('md-select-menu').data('$mdSelectController', mdSelectCtrl);
isOpen = true;
$mdSelect.show({
scope: scope.$new(),
element: selectEl,
target: element[0],
hasBackdrop: true,
loadingAsync: attr.mdOnOpen ? scope.$eval(attr.mdOnOpen) : false,
setLabelText: setLabelText
}).then(function(selectedText) {
isOpen = false;
});
});
}
};

}
}

function SelectMenuDirective($parse, $mdUtil, $mdTheming) {

return {
restrict: 'E',
require: ['mdSelectMenu', '?ngModel'],
require: ['mdSelectMenu', '?mdSelect', '?ngModel'],
controller: SelectMenuController,
link: { pre: preLink }
};
Expand All @@ -223,12 +232,13 @@ function SelectMenuDirective($parse, $mdUtil, $mdTheming) {
// its child options run postLink.
function preLink(scope, element, attr, ctrls) {
var selectCtrl = ctrls[0];
var ngModel = ctrls[1];
var mdSelect = ctrls[1];
var ngModel = ctrls[2];

$mdTheming(element);
element.on('click', clickListener);
element.on('keypress', keyListener);
if (ngModel) selectCtrl.init(ngModel);
if (ngModel) selectCtrl.init(ngModel, mdSelect);
configureAria();

function configureAria() {
Expand Down Expand Up @@ -283,8 +293,9 @@ function SelectMenuDirective($parse, $mdUtil, $mdTheming) {
self.options = {};


self.init = function(ngModel) {
self.init = function(ngModel, mdSelect) {
self.ngModel = ngModel;
self.mdSelect = mdSelect;

// Allow users to provide `ng-model="foo" ng-model-options="{trackBy: 'foo.id'}"` so
// that we can properly compare objects set on the model to the available options
Expand Down Expand Up @@ -399,11 +410,13 @@ function SelectMenuDirective($parse, $mdUtil, $mdTheming) {
newSelectedHashes.forEach(function(hashKey, i) {
self.select(hashKey, newSelectedValues[i]);
});
self.mdSelect && self.mdSelect.setLabelText(self.selectedLabels());
}
function renderSingular() {
var value = self.ngModel.$viewValue || self.ngModel.$modelValue;
Object.keys(self.selected).forEach(self.deselect);
self.select( self.hashGetter(value), value );
self.mdSelect && self.mdSelect.setLabelText(self.selectedLabels());
}
}

Expand Down Expand Up @@ -666,8 +679,6 @@ function SelectProvider($$interimElementProvider) {
delete opts.disableTarget;
}

opts.setLabelText && opts.setLabelText(opts.selectEl.controller('mdSelectMenu').selectedLabels());

return $mdUtil.transitionEndPromise(element).then(function() {
element.remove();
opts.backdrop && opts.backdrop.remove();
Expand Down

0 comments on commit b4c0a86

Please sign in to comment.