Feature Request: Dynamically add ng-message to ng-messages #10036

Closed
adrianandreias opened this Issue Nov 13, 2014 · 16 comments
@adrianandreias

Add the ability to programaticaly add ngMessage item to an existing ngMessages directive.

I am trying to show the field error returned by an AJAX form submit. This way frontend errors and backend errors displaying would be done the same way.

Do you this is the right approach or you would just create another way to insert the server side error in the DOM?

@caitp
Contributor
caitp commented Nov 13, 2014

I'm not sure why you'd need this, since we already have async validation, so you could just set up a message for the particular async error you're validating against. While we could allow you to add new messages, I feel like it would make the API cumbersome, so we'd have to think about this.

@petebacondarwin / @matsko thoughts?

@caitp caitp added this to the Backlog milestone Nov 13, 2014
@adrianandreias

From my understanding if the error message itself comes from the backend async validation doesn't help.

Sounds pretty limiting to me to only define the list of error message in HTML.
There could be other scenarios where you want to define error messages at run time.

Not sure what this modification implies but shouldn't be hard to add add/remove/modify message functions.

@matsko
Member
matsko commented Nov 14, 2014

@adrianandreias @caitp I think having dynamic messages is a great idea. The problem is that we can't use something like ng-repeat since there would be a conflict over how the elements are entered and removed from the ng-messages container, but if we can get that to work then it would open up a bunch of possibilities. I think it would be better if we keep as much of the message handling as possible in the HTML instead of having an imperative solution then we can do a lot more stuff.

It would be ideal if we could have something like:

<div ng-messages="myForm.myField.$error">
   <div ng-message="required">You did not enter a field</div>
   <div ng-message="key" ng-repeat="(key, message) in remoteMessages">
      {{ message }}
   </div>
</div>

@adrianandreias would this work for you?

@adrianandreias

Sure, I assume we can have $scope.remoteMessages = [] in controller initialization and if on form submit there's an error message returned from the server you'd just push it in remoteMessages and then call $setValidity.

If this is the whole idea it's perfect.

(btw @matsko I love your site!)

@jessemorton

I'd love to see this as well. There's plenty of cases where an async validator is impractical/overkill for all the fields in a form, but that it'd be desirable to display backend errors if they arise upon form submission.

@petebacondarwin petebacondarwin modified the milestone: 1.4.x, Backlog Dec 24, 2014
@petebacondarwin
Member

@matsko is going to work to support this in 1.4

@wendellm
wendellm commented Jan 3, 2015

Bah Bah, I was trying to get this to work the whole day, thinking it was me. My forms are build completely at runtime by meta data so yeah I need it. Thanks!

@matsko
Member
matsko commented Jan 7, 2015
@matsko matsko added a commit to matsko/angular.js that referenced this issue Jan 7, 2015
@matsko matsko feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This fix ensures that both
the ngMessage and ngMessages directives automatically update when
any dynamic message data changes.

BREAKING CHANGE:

The ngMessage directive now uses expressions. Therefore, all
pre-existing ngMessage attribute values (as well as the values
assigned via the `when` attribute) will not function as they did
before because ngMessage will evaluate the attribute value as an
expression. A quick fix for this is to wrap single quotes around each of
the attribute values:

```html
<!-- AngularJS 1.3.x -->
<div ng-message="required">Your message is required</div>

<!-- AngularJS 1.4.x -->
<div ng-message="'required'">Your message is required</div>
```

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="'required'">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338
3e3634d
@matsko matsko added a commit to matsko/angular.js that referenced this issue Jan 8, 2015
@matsko matsko feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This fix ensures that both
the ngMessage and ngMessages directives automatically update when
any dynamic message data changes.

BREAKING CHANGE:

The ngMessage directive now uses expressions. Therefore, all
pre-existing ngMessage attribute values (as well as the values
assigned via the `when` attribute) will not function as they did
before because ngMessage will evaluate the attribute value as an
expression. A quick fix for this is to wrap single quotes around each of
the attribute values:

```html
<!-- AngularJS 1.3.x -->
<div ng-message="required">Your message is required</div>

<!-- AngularJS 1.4.x -->
<div ng-message="'required'">Your message is required</div>
```

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="'required'">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338
b91eb65
@matsko matsko added a commit to matsko/angular.js that referenced this issue Jan 8, 2015
@matsko matsko feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This fix ensures that both
the ngMessage and ngMessages directives automatically update when
any dynamic message data changes.

BREAKING CHANGE:

The ngMessage directive now uses expressions. Therefore, all
pre-existing ngMessage attribute values (as well as the values
assigned via the `when` attribute) will not function as they did
before because ngMessage will evaluate the attribute value as an
expression. A quick fix for this is to wrap single quotes around each of
the attribute values:

```html
<!-- AngularJS 1.3.x -->
<div ng-message="required">Your message is required</div>

<!-- AngularJS 1.4.x -->
<div ng-message="'required'">Your message is required</div>
```

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="'required'">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338
8ece832
@matsko
Member
matsko commented Jan 14, 2015

@adrianandreias @jessemorton @wendellm this feature now exists in a PR and it's tested and functional, but we're just taking this week to decide on a proper naming convention.

@jessemorton

Thanks @matsko!

@adrianandreias

That's great @matsko :)

@adrianandreias

Will this be included in 1.4?

@matsko
Member
matsko commented Jan 14, 2015

The goal is to have it for both 1.3 and 1.4 so long as it doesn't break anything.

@adrianandreias

I think this didn't make it into v1.4.0-beta.2 and v1.3.10, right?

@matsko
Member
matsko commented Jan 29, 2015

Not yet. Still negotiating a proper naming convention.

@matsko matsko added a commit to matsko/angular.js that referenced this issue Feb 11, 2015
@matsko matsko feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This feature patch ensures
that both ngMessages can render expressions and automatically update
when any dynamic message data changes.

BREAKING CHANGE:

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="required">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338
912b03f
@matsko
Member
matsko commented Feb 11, 2015

We're almost there. Just waiting on a final review for #10676.

@matsko matsko added a commit to matsko/angular.js that referenced this issue Feb 12, 2015
@matsko matsko feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This feature patch ensures
that both ngMessages can render expressions and automatically update
when any dynamic message data changes.

BREAKING CHANGE:

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="required">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338
5d55976
@matsko matsko added a commit to matsko/angular.js that referenced this issue Feb 12, 2015
@matsko matsko feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This feature patch ensures
that both ngMessages can render expressions and automatically update
when any dynamic message data changes.

BREAKING CHANGE:

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="required">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338
c118182
@matsko matsko added a commit that closed this issue Feb 12, 2015
@matsko matsko feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This feature patch ensures
that both ngMessages can render expressions and automatically update
when any dynamic message data changes.

BREAKING CHANGE:

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="required">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338
c9a4421
@matsko matsko closed this in c9a4421 Feb 12, 2015
@matsko matsko added a commit to matsko/angular.js that referenced this issue Feb 12, 2015
@matsko matsko feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This feature patch ensures
that both ngMessages can render expressions and automatically update
when any dynamic message data changes.

BREAKING CHANGE:

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="required">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338

Conflicts:
	src/ngMessages/messages.js
d97733f
@netman92 netman92 added a commit to netman92/angular.js that referenced this issue Aug 8, 2015
@matsko @netman92 matsko + netman92 feat(ngMessages): provide support for dynamic message resolution
Prior to this fix it was impossible to apply a binding to a the
ngMessage directive to represent the name of the error. It was also
not possible to use ngRepeat or any other structural directive to
dynamically update the list of messages. This feature patch ensures
that both ngMessages can render expressions and automatically update
when any dynamic message data changes.

BREAKING CHANGE:

The `ngMessagesInclude` attribute is now its own directive and that must
be placed as a **child** element within the element with the ngMessages
directive. (Keep in mind that the former behaviour of the
ngMessageInclude attribute was that all **included** ngMessage template
code was placed at the **bottom** of the element containing the
ngMessages directive; therefore to make this behave in the same way,
place the element containing the ngMessagesInclude directive at the
end of the container containing the ngMessages directive).

```html
<!-- AngularJS 1.3.x -->
<div ng-messages="model.$error" ng-messages-include="remote.html">
  <div ng-message="required">Your message is required</div>
</div>

<!-- AngularJS 1.4.x -->
<div ng-messages="model.$error">
  <div ng-message="required">Your message is required</div>
  <div ng-messages-include="remote.html"></div>
</div>
```

Closes #10036
Closes #9338
6ac5959
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment