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

Commit

Permalink
amend(mdInputContainer): string value on number input, textarea, data…
Browse files Browse the repository at this point in the history
…-ng-message

Closes #1188. Closes #1186. Closes #1180.
  • Loading branch information
ajoslin committed Jan 14, 2015
1 parent 8e40b35 commit d6311e8
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/components/input/demoBasicUsage/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ angular.module('inputBasicDemo', ['ngMaterial', 'ngMessages'])
address: '1600 Amphitheatre Pkwy' ,
city: 'Mountain View' ,
state: 'CA' ,
biography: 'Loves kittens, snowboarding, and can type at 130 WPM. And rumor has it she bouldered up Castle Craig!',
biography: 'Loves kittens, snowboarding, and can type at 130 WPM.\n\nAnd rumor has it she bouldered up Castle Craig!',
postalCode : '94043'
};
});
6 changes: 3 additions & 3 deletions src/components/input/demoErrors/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h1 class="md-toolbar-tools">
<md-input-container>
<label>Description</label>
<input md-maxlength="30" required name="description" ng-model="project.description">
<div ng-messages="projectForm.description.$error" ng-show="projectForm.description.$dirty">
<div ng-messages="projectForm.description.$error">
<div ng-message="required">This is required.</div>
<div ng-message="md-maxlength">The name has to be less than 30 characters long.</div>
</div>
Expand All @@ -20,14 +20,14 @@ <h1 class="md-toolbar-tools">
<md-input-container>
<label>Client Name</label>
<input required name="clientName" ng-model="project.clientName">
<div ng-messages="projectForm.clientName.$error" ng-show="projectForm.clientName.$dirty">
<div ng-messages="projectForm.clientName.$error">
<div ng-message="required">This is required.</div>
</div>
</md-input-container>

<md-input-container>
<label>Hourly Rate (USD)</label>
<input required type="number" step="any" name="rate" ng-model="project.rate" min="800" max="5000" required>
<input required type="number" step="any" name="rate" ng-model="project.rate" min="800" max="4999" required>
<div ng-messages="projectForm.rate.$error">
<div ng-message="required">You've got to charge something! You can't just <b>give away</b> a Missile Defense System.</div>
<div ng-message="min">You should charge at least $800 an hour. This job is a big deal... if you mess up, everyone dies!</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/input/demoErrors/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ angular.module('inputErrorsApp', ['ngMaterial', 'ngMessages'])
$scope.project = {
description: 'Nuclear Missile Defense System',
clientName: 'Bill Clinton',
rate: 100,
rate: 500,
};
});
3 changes: 2 additions & 1 deletion src/components/input/input-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ md-input-container.md-THEME_NAME-theme {
label {
color: '{{warn-500}}';
}
ng-message, [ng-message],
ng-message, data-ng-message, x-ng-message,
[ng-message], [data-ng-message], [x-ng-message],

This comment has been minimized.

Copy link
@gkalpak

gkalpak Jan 14, 2015

Member

You know there are more alternative forms, right ? ;)

This comment has been minimized.

Copy link
@ajoslin

ajoslin Jan 14, 2015

Author Contributor

Really?

If so, we'll just make an ng-message and ng-messages directive of our own that adds a class to the element.

This comment has been minimized.

Copy link
@gkalpak

gkalpak Jan 17, 2015

Member

@ajoslin: Basically, all directives can have a data or x prefix (you have that already), but there is also a choice on separators: it can be one on _, -, : (even intermixed in a single element).
E.g. x_ng:message should also work.

That said, ngMaterial will break (in terms of CSS) if someone uses prefixed or non-dash-delimited node names, so ng-messages will probably be the least of their concerns ;)
FWIW, I don't think it is worth it adding selectors for all possible forms of all possible directives used in CSS, but it might be nice to document it somewhere that people should use the unprefixed, dash-delimited forms.

.md-char-counter {
color: '{{warn-500}}';
}
Expand Down
62 changes: 34 additions & 28 deletions src/components/input/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function labelDirective() {
* <md-input-container>
* <label>Last Name</label>
* <input name="lastName" ng-model="lastName" required md-maxlength="10" minlength="4">
* <div ng-messages="userForm.lastName.$error">
* <div ng-messages="userForm.lastName.$error" ng-show="userForm.bio.$dirty">
* <div ng-message="required">This is required!</div>
* <div ng-message="md-maxlength">That's too long!</div>
* <div ng-message="minlength">That's too short!</div>
Expand Down Expand Up @@ -150,7 +150,7 @@ function labelDirective() {
* <md-input-container>
* <label>Biography</label>
* <textarea name="bio" ng-model="biography" required md-maxlength="150"></textarea>
* <div ng-messages="userForm.bio.$error">
* <div ng-messages="userForm.bio.$error" ng-show="userForm.bio.$dirty">
* <div ng-message="required">This is required!</div>
* <div ng-message="md-maxlength">That's too long!</div>
* </div>
Expand Down Expand Up @@ -195,30 +195,29 @@ function inputTextareaDirective($mdUtil, $window, $compile, $animate) {
if (ngModelCtrl) {
scope.$watch(function() {
return ngModelCtrl.$dirty && ngModelCtrl.$invalid;
}, function(isDirtyAndInvalid) {
containerCtrl.setInvalid(isDirtyAndInvalid);
});
}, containerCtrl.setInvalid);

ngModelCtrl.$formatters.push(checkHasValue);
ngModelCtrl.$parsers.push(checkHasValue);
} else {
element.on('input', function() {
containerCtrl.setHasValue( (""+element.val()).length > 0 );
});
containerCtrl.setHasValue( (""+element.val()).length > 0 );
checkHasValue();
}
element.on('input', checkHasValue);

function checkHasValue(value) {
containerCtrl.setHasValue(!ngModelCtrl.$isEmpty(value));
if (attr.name === 'rate' && window.debug)debugger;
containerCtrl.setHasValue(
!ngModelCtrl.$isEmpty(value) ||
(element[0].validity || {}).badInput
);
return value;
}

element
.on('focus', function(e) {
.on('focus', function(ev) {
containerCtrl.setFocused(true);
})
.on('blur', function(e) {
if (e.target && e.target.validity && e.target.validity.badInput) {
containerCtrl.setHasValue(false);
}
.on('blur', function(ev) {
containerCtrl.setFocused(false);
});

Expand All @@ -230,30 +229,33 @@ function inputTextareaDirective($mdUtil, $window, $compile, $animate) {

function setupTextarea() {
var node = element[0];
var onChangeTextarea = $mdUtil.debounce(growTextarea, 1);

function pipelineListener(value) {
onChangeTextarea();
return value;
}

if (ngModelCtrl) {
ngModelCtrl.$formatters.push(growTextarea);
ngModelCtrl.$parsers.push(growTextarea);
ngModelCtrl.$formatters.push(pipelineListener);
ngModelCtrl.$viewChangeListeners.push(pipelineListener);
} else {
element.on('input', growTextarea);
growTextarea();
onChangeTextarea();
}
element.on('keyup', growTextarea);
element.on('keydown input', onChangeTextarea);
element.on('scroll', onScroll);
angular.element($window).on('resize', growTextarea);
angular.element($window).on('resize', onChangeTextarea);

scope.$on('$destroy', function() {
angular.element($window).off('resize', growTextarea);
angular.element($window).off('resize', onChangeTextarea);
});

function growTextarea(value) {
function growTextarea() {
node.style.height = "auto";
var line = node.scrollHeight - node.offsetHeight;
node.scrollTop = 0;
var height = node.offsetHeight + (line > 0 ? line : 0);
node.style.height = height + 'px';

return value; // for $formatter/$parser
}

function onScroll(e) {
Expand All @@ -280,9 +282,14 @@ function mdMaxlengthDirective() {
var containerCtrl = ctrls[1];
var charCountEl = angular.element('<div class="md-char-counter">');

// Stop model from trimming. This makes it so whitespace
// over the maxlength still counts as invalid.
attr.$set('ngTrim', 'false');
containerCtrl.element.append(charCountEl);

ngModelCtrl.$formatters.push(renderCharCount);
element.on('input', renderCharCount);
ngModelCtrl.$viewChangeListeners.push(renderCharCount);
element.on('input keydown', renderCharCount);

scope.$watch(attr.mdMaxlength, function(value) {
maxlength = value;
Expand All @@ -298,11 +305,10 @@ function mdMaxlengthDirective() {
});

ngModelCtrl.$validators['md-maxlength'] = function(modelValue, viewValue) {
var value = modelValue || viewValue;
if (!angular.isNumber(maxlength) || maxlength < 0) {
return true;
}
return (value || '').length < maxlength;
return ( element.val() || modelValue || viewValue || '' ).length <= maxlength;
};

function renderCharCount(value) {
Expand Down
6 changes: 4 additions & 2 deletions src/components/input/input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ md-input-container {
}
}

ng-messages, [ng-messages] {
ng-messages, data-ng-messages, x-ng-messages,
[ng-messages], [data-ng-messages], [x-ng-messages] {
order: 3;
position: relative;
}
ng-message, [ng-message],
ng-message, data-ng-message, x-ng-message,
[ng-message], [data-ng-message], [x-ng-message],
.md-char-counter {
-webkit-font-smoothing: antialiased;
position: absolute;
Expand Down

0 comments on commit d6311e8

Please sign in to comment.