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

Conversation

stsvilik
Copy link

@stsvilik stsvilik commented May 3, 2013

Hidden fields need to be able to set ng-model too. A good use case would be a hybrid solution such as MVC.net where forms are still submitted to the server (instead of pure AJAX post)

@revolunet
Copy link
Contributor

Why ng-model as you dont need two way data-binding? if you set value="{{ myModel }}" it works nicely.

@stsvilik
Copy link
Author

Hi,

Sorry it took a while to respond. Perhaps your suggestion works nicely, but feels unnatural and un-intuitive. Most people I know who had similar problem would naturally attempt to set the ng-model of the hidden input field just to realize that it doesn't work. I develop API's myself (including Angular) and believe that what feels natural to the user (assuming it doesn't cost much to the developer) goes a long way and saves you time answering questions that shouldn't have been raised in the first place.

Simon

@petebacondarwin
Copy link
Contributor

-1
ng-model is for "two-way" databinding. How are hidden input elements able to do two way? It is like saying that you should be able to use ng-model on say a span: <span ng-model="myModel"></span>. This is over-using the directive.

Perhaps an ng-value attribute, specific to hidden inputs would be enough syntactic sugar?

<input type="hidden" ng-value="myModel">

This is semantically equivalent to @revolunet's suggestion.

Closing unless you have a stronger argument in favour of this change.

@stsvilik
Copy link
Author

Ng-value could work, is this something considered for the future release?

@jeremyruppel
Copy link

Just stopping by to leave my 2¢ because I just had to hunt down this same issue.

I was using ng-model on my hidden inputs for the exact use case described in this PR, and I, perhaps naively, assumed everything was working properly because I could change the input type to text and observe the data binding. I get that there really should be no notion of two-way data binding for hidden inputs since they should not be edited, but I had at least expected it to be one-way.

I ended up doing exactly what @revolunet suggested, but this was still surprising to me. I'm not sure I'm in favor of an ng-value tag specifically for this use case, but rather maybe a simple input[type=hidden] entry in the docs describing why ng-model won't work. I'd be happy to help provide that if needed.

@grobmeier
Copy link

I agree this should be documented. Its perfectly clear why ng-model doesn't make sense in this use case when you read this issue (in my case, I asked at StackOverflow and was pointed to here). Submitting a form without ajax might make sense even if you want to stream something back, like Excel sheets. That being said it really doesn't hurt to document this.

@simmu
Copy link

simmu commented Aug 27, 2013

I think there is a use case where developer would like the ng-model to work with hidden value. For instance, when I have to work with wyswyg editor (that uses iframe). Usually the wyswyg script will made the target textarea hidden and using iframe to update the textarea value. Since ng-model does not work with the hidden element, I can't get the value of the textarea through the scope...instead I have to use a js selector to get the value or I can modify the script to set the textarea to visible=false instead of display=none.

@bropp
Copy link

bropp commented Aug 27, 2013

Agreed, I just ran into this issue using ng-model with a custom slider directive. The slider (similar to jquery UI slider) is hidden initially. When it is shown, the model is bound. If the directive is shown from the start, the model is correctly bound. At the very least I think this should be documented, as it seemed to be unexpected behavior.

@gyllstromk
Copy link

The select2 module uses hidden tags: http://ivaynberg.github.io/select2/index.html#doc-query

This module is incorporated into the official angular-ui via https://github.com/angular-ui/ui-select2

Thus there seems to be a case for two-way support for hidden + ng-model motivated from within the angular ecology itself.

@petebacondarwin
Copy link
Contributor

Reopening to be discussed post-1.2 release

@chirayuk chirayuk merged commit 1f686c4 into angular:master Oct 1, 2013
@shanewg
Copy link

shanewg commented Nov 28, 2013

Angular 1.2
What is the best way to save data from a pre populated hidden input field, 'user.id'. I'm getting my user.id from a json object. I can bind using ng-model="user.id" value="{{user.id}}" but cannot save the data unless I use input="text" instead of hidden and changed to ng-model="user_id", which is the foriegn key column in my table, AND I must manually enter the id value into the blank input field.

Any suggestions would be greatly appreciated.

@coolaj86
Copy link

coolaj86 commented Dec 7, 2013

What about when you have a new data type in a directive instead of an input? I was thinking to use a hidden input so that I could still get the benefit of required without having to add logic.

Examples:

<input ng-model="thingy" required type="hidden" />
<div signature-pad="thingy"></div>

@johnparn
Copy link

@shanewg - I had a similiar issue and I use the following syntax:

<input type="hidden" required  ng-model="data.userid" ng-init="data.userid=pivot.id" /> 

@risingfish
Copy link

Another use valid use for two-way binding to hidden fields is bot filters.

@Aldekein
Copy link

Aldekein commented Jun 4, 2014

http://en.wikipedia.org/wiki/Principle_of_least_astonishment should be used there.
ng-model in input type="hidden" should raise console error/warning or just work IMHO.

@alexmglover
Copy link

I'm also bumping up against issues here because I am using select2, which relies on hidden inputs.

@caitp
Copy link
Contributor

caitp commented Jul 31, 2014

it doesn't seem like there's much to this, you should be able to just <input type="hidden" value="{{someModelValue}}" /> --- because a hidden input would have no reason to respond to events or be validated, really

@alexmglover
Copy link

I may be misunderstanding what you mean, but I need to be able to detect changes to the hidden input if select2 changes the value.

@caitp
Copy link
Contributor

caitp commented Jul 31, 2014

all you need to do for that is detect when the select2 changes some value, it sounds like you're trying to solve this problem the wrong way. ngModel isn't really needed for this imo.

@alexmglover
Copy link

I disagree.  Normally you could have an ngModel on a select box and detect the value when it changes.  You should be able to do the same with a hidden input.  I will figure out a workaround.  Thanks.

@caitp
Copy link
Contributor

caitp commented Jul 31, 2014

...you can... I've already explained how...

@EvilTengil
Copy link

I work with custom controls (drop-downs) that are storing the values to a hidden field. I would like to be able to use ng-model on the hidden field to read back the value the users selects.

@gyarra
Copy link

gyarra commented Oct 31, 2014

Just ran into this issue. Here are my thoughts:

  1. There are valid situations where a hidden input may change, and the change should be reflected in the model.
  2. As a new Angular developer, I expected ng-model to work with hidden fields.
  3. There's no downside to allowing ng-model to work for hidden fields.

Conclusion: Update ng-model to work when applied to hidden fields. Developers want and expect this, for good reasons. There is no downside.

@caitp
Copy link
Contributor

caitp commented Oct 31, 2014

ng-model doesn't really make sense with hidden fields, because a user can't really interact with hidden fields.

@jakebruemmer
Copy link

Hi,

I'm very, very new to using Angular, but I've run into this issue in my code as well. I'm trying to submit the following input

<input type='hidden' value="{{song._id}}" ng-model="unique_song_id" />

and the access that value that I've binded to my model in my controller. I've read this thread, and several on StackOverflow, but I can't access the value in my controller at all. I've also tried using ng-init and ng-model to access the variable, but it still doesn't work. Is it even possible to do this with Angular?

@yoonchee
Copy link

yoonchee commented Jan 2, 2015

I am building a hybrid Django/AngularJS app and was trying to use some custom controls like sliders. I tried using ng-model on a hidden input that stores and posts the value of slider widget. To my surprise, ng-model didn't work on hidden input fields and I am commenting on this thread.

I think it should at least be documented that ng-model doesn't work with hidden inputs.

@hurkanakbiyik
Copy link

This is confusing. I think angular need ng-hidden.

@petebacondarwin
Copy link
Contributor

Most of the use cases I have seen so far in this thread are using the hidden input as some interface to 3rd party code, which updates the value of the hidden input in some way, and that people expect ngModel to deal with this and make that value appear on the scope. ngModel listens in to DOM events like change, blur and keydown to trigger updates to the $viewValue and so to the value on the scope.

The question that occurs to me is how is Angular supposed to be aware of this change on a hidden input?

In the scenarios discussed in this issue, I don't believe that the hidden input element is going to trigger any particular DOM event just because another piece of code updates its value. One needs to look at that particular 3rd party code, on a case by case basis, and create a directive that will connect to the relevant event or callback.

I think we should put in place an error message if you try to use ngModel on a hidden input, which links to documentation about how to bind data "one way" for form submission and also advice on how one might connect to a 3rd party library that happens to update hidden inputs. What do you think @caitp?

@Aldekein
Copy link

As I wrote before:

http://en.wikipedia.org/wiki/Principle_of_least_astonishment should be used there.
ng-model in input type="hidden" should raise console error/warning

If it doesn't work - let it be documented, but not silent.

@CageFox
Copy link

CageFox commented Jun 15, 2015

gyarra above posted absolutely correct thoughts:

"1) There are valid situations where a hidden input may change, and the change should be reflected in the model.
2) As a new Angular developer, I expected ng-model to work with hidden fields.
3) There's no downside to allowing ng-model to work for hidden fields.

Conclusion: Update ng-model to work when applied to hidden fields. Developers want and expect this, for good reasons. There is no downside"

Everyone can check it by yourself, just find definition of

var inputType = {

In angular.js and replace

'hidden': noop,

with

'hidden': textInputType,

This simple update completely resolves the issue without any noticeable downside effects

So, my vote is for "Update ng-model to work when applied to hidden fields"

@lgalfaso
Copy link
Contributor

#2574 (comment) is spot on. ngModel is for 2-way binding and a hidden field is not for 2-way binding.
The only thing that would make sense it to generate a warning when putting an ngModel on a hidden field.

@petebacondarwin
Copy link
Contributor

Could someone provide a PR with this warning in place?

@CageFox
Copy link

CageFox commented Jun 15, 2015

Explain, please, why the hidden field is bad for 2-way binding.

Why not to allow 2-way bind it for those who need it

Why not to implement simple and highly demanded feature, that can be implemented by changing 1 line of code?

@lgalfaso
Copy link
Contributor

@CageFox browsers generate no events when the value of a input[type=hidden] changes, so the one line change that you posted only does 1-way data binding.

@lgalfaso lgalfaso self-assigned this Jun 15, 2015
@lgalfaso lgalfaso modified the milestones: 1.4.x, 1.4.0-beta.6 / 1.3.15 Jun 15, 2015
@CageFox
Copy link

CageFox commented Jun 15, 2015

The change event didn't generated automatically, but can easyly be fired by code

Of course it is simplier to force all users to fully refactor all old code (jquery/native javascript), but may be it is more fair not to force and allow to mix it?

@lgalfaso
Copy link
Contributor

@CageFox what do you mean with "but can easily be fired by code"? You mean that angular should watch the value of the element and then generate the event?

@CageFox
Copy link

CageFox commented Jun 15, 2015

Easily fired bo code like $(".change_me").trigger("change")

I manage 15+ years old business web application, and there is ton of old code written by many different people. Storing variables in hidden inputs is typical for old school apps. I personally always use patched like "'hidden': textInputType" angular, it allows me to use ng-model to inputs and freely change between input types without changing other directives

And I think this patch costs nothing at all for those not using hidden inputs, so why not implement it?

@hiteshghanshas
Copy link

${Token}
and in angular part.
var data = { Token:$scope.signup_form.Token.$modelValue, };
all my data is going in post , just not this 'token' in hidden field. what should i do.

@hiteshghanshas
Copy link

input class="field_camp" type="text" name="Token" style="display: none;" ng-model="signup.Token" ng-init="signup.Token=Token ${Token}

@gkalpak
Copy link
Member

gkalpak commented Dec 11, 2015

@hiteshghanshas, this sounds like a general support question. You should try on one of the appropriate support channels.
GitHub issues are reserved for bug reports and feature requests.

Thx !

@WillsB3
Copy link

WillsB3 commented Feb 2, 2017

Sorry, but this assumption is silly in my opinion.

Just because the user cannot interact with a hidden input doesn't mean that another directive isn't interacting with it dynamically.

For example:

We have a component which allows you to add/remove items from a list (very similar to Todo MVC). The items are modelled as objects in an array called items on the directive controller. This array is used to render the list of items in the directive template. When a user adds an item via the widget a new object gets added to this items array.

Now, we need a way to submit the contents of the list to the server. Our Application is a combination of Django rendered pages and Angular "components". These Angular components are most often just custom field widgets. In the above example we use a input field, along with ngModel, and ngModels $parsers, $formatters and $validators to serialise the representation of items into a string of JSON, and to handle validation using the usual validation pipeline as offered by the built in directives. When the user submits the form the stringified JSON it sent to the backend via a normal POST request where the server then converts the data back into a dictionary.

This works great, as long as the input is type text and not hidden. We're using Angulars built in support for $parsers, $formatters and $validators to do conversion between $viewValue and $modelValue data formats, which feels correct. We're also implementing a custom $validator which ensures that our custom field is marked as invalid if it's marked as required and the user deletes all the items in the list - This also feels correct, again, because we're using Angulars built in support for providing custom $validators. If we use ng-value (to make the value actually update correctly, as per this issues discussion) we loose the ability to use $parsers, $formatters and $validators on this field.

Many apps aren't 100% Angular/SPA and still use server rendered pages. In these cases where the frontend does not submit data over an API, but instead uses regular old form fields and form POST, the inability to use plain text fields containing serialized json behind custom UI controls means that we have to resort to things like using <input type="text>" and then just hiding the input with CSS and setting tabindex=-1`...

Of course, in an "ideal" world we'd all be building SPAs in Angular where the only backend we have is an API, but that's simply not the case for everyone ;)

@petebacondarwin
Copy link
Contributor

IMO the component that handles the list manipulation should support ngModel instead, then you could apply the result of that to the ngValue on the hidden input.

@WillsB3
Copy link

WillsB3 commented Feb 3, 2017

Hi Pete,

I agree - in hindsight that would probably have been a better solution. I still believe that the ng-model behaviour not working on input type hidden is not obvious. We're not yet running the latest version of 1.x, so I wasn't seeing the warning that sounds like it was implemented.

Perhaps a small addition to the ngModel section in the docs would be helpful for furture users too?

@artoale
Copy link

artoale commented Feb 3, 2017

@petebacondarwin true enough, adding support for ng-model in the list manipulation directive makes total sense. Still, there might be plenty of reason for it not being able to support it. Simple one, depending on an external library you have no control over.

@petebacondarwin
Copy link
Contributor

A workaround could be to use a non-visible text input element rather than a hidden input element.
E.g.

  <input type="text" ng-model="$ctrl.listValue" some-formatter-directive style="display: none">

See http://plnkr.co/edit/EY8EkysbgQMXt38YxG20?p=preview for a working example.

@whiplashomega
Copy link

Use case I encountered, that I then had to do a jQuery workaround. My login page is server-rendered, and includes a hidden field with a cfsr token as a preset value. I am submitting the login information via AJAX post in angular. I needed angular to pull the server provided cfsr token from the hidden field into the model so that it could be submitted with the login request. ng-value data-binds the wrong way for my purposes. I had to workaround using jQuery().val() and set the value of my cfsr token at login submission time rather than use angular native data-binding.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.