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

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

Closed
adrianandreias opened this issue Nov 13, 2014 · 16 comments
Closed

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

adrianandreias opened this issue Nov 13, 2014 · 16 comments

Comments

@adrianandreias
Copy link

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
Copy link
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?

@adrianandreias
Copy link
Author

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
Copy link
Contributor

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
Copy link
Author

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
Copy link

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
Copy link
Member

@matsko is going to work to support this in 1.4

@wendellmva
Copy link

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
Copy link
Contributor

matsko commented Jan 7, 2015

Here's a work in progress: http://plnkr.co/edit/EqxV25DMumMR9fPiBdnZ?p=preview

matsko added a commit to matsko/angular.js that referenced this issue Jan 7, 2015
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 angular#10036
Closes angular#9338
matsko added a commit to matsko/angular.js that referenced this issue Jan 8, 2015
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 angular#10036
Closes angular#9338
matsko added a commit to matsko/angular.js that referenced this issue Jan 8, 2015
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 angular#10036
Closes angular#9338
@matsko
Copy link
Contributor

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
Copy link

Thanks @matsko!

@adrianandreias
Copy link
Author

That's great @matsko :)

@adrianandreias
Copy link
Author

Will this be included in 1.4?

@matsko
Copy link
Contributor

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
Copy link
Author

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

@matsko
Copy link
Contributor

matsko commented Jan 29, 2015

Not yet. Still negotiating a proper naming convention.

matsko added a commit to matsko/angular.js that referenced this issue Feb 11, 2015
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 angular#10036
Closes angular#9338
@matsko
Copy link
Contributor

matsko commented Feb 11, 2015

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

matsko added a commit to matsko/angular.js that referenced this issue Feb 12, 2015
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 angular#10036
Closes angular#9338
matsko added a commit to matsko/angular.js that referenced this issue Feb 12, 2015
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 angular#10036
Closes angular#9338
@matsko matsko closed this as completed in c9a4421 Feb 12, 2015
matsko added a commit to matsko/angular.js that referenced this issue Feb 12, 2015
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 angular#10036
Closes angular#9338

Conflicts:
	src/ngMessages/messages.js
netman92 pushed a commit to netman92/angular.js that referenced this issue Aug 8, 2015
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 angular#10036
Closes angular#9338
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.