AngularJS does not send hidden field value

JavascriptFormsAngularjs

Javascript Problem Overview


For a specific use case I have to submit a single form the "old way". Means, I use a form with action="". The response is streamed, so I am not reloading the page. I am completely aware that a typical AngularJS app would not submit a form that way, but so far I have no other choice.

That said, i tried to populate some hidden fields from Angular:

<input type="hidden" name="someData" ng-model="data" /> {{data}}

Please note, the correct value in data is shown.

The form looks like a standard form:

<form id="aaa" name="aaa" action="/reports/aaa.html" method="post">
...
<input type="submit" value="Export" />
</form>

If I hit submit, no value is sent to the server. If I change the input field to type "text" it works as expected. My assumption is the hidden field is not really populated, while the text field actually is shown due two-way-binding.

Any ideas how I can submit a hidden field populated by AngularJS?

Javascript Solutions


Solution 1 - Javascript

You cannot use double binding with hidden field. The solution is to use brackets :

<input type="hidden" name="someData" value="{{data}}" /> {{data}}

EDIT : See this thread on github : https://github.com/angular/angular.js/pull/2574

EDIT:

Since Angular 1.2, you can use 'ng-value' directive to bind an expression to the value attribute of input. This directive should be used with input radio or checkbox but works well with hidden input.

Here is the solution using ng-value:

<input type="hidden" name="someData" ng-value="data" />

Here is a fiddle using ng-value with an hidden input: http://jsfiddle.net/6SD9N

Solution 2 - Javascript

You can always use a type=text and display:none; since Angular ignores hidden elements. As OP says, normally you wouldn't do this, but this seems like a special case.

<input type="text" name="someData" ng-model="data" style="display: none;"/>

Solution 3 - Javascript

In the controller:

$scope.entityId = $routeParams.entityId;

In the view:

<input type="hidden" name="entityId" ng-model="entity.entityId" ng-init="entity.entityId = entityId" />

Solution 4 - Javascript

I've found a nice solution written by Mike on sapiensworks. It is as simple as using a directive that watches for changes on your model:

.directive('ngUpdateHidden',function() {
    return function(scope, el, attr) {
        var model = attr['ngModel'];
        scope.$watch(model, function(nv) {
            el.val(nv);
        });
    };
})

and then bind your input:

<input type="hidden" name="item.Name" ng-model="item.Name" ng-update-hidden />

But the solution provided by tymeJV could be better as input hidden doesn't fire change event in javascript as yycorman told on this post, so when changing the value through a jQuery plugin will still work.

Edit I've changed the directive to apply the a new value back to the model when change event is triggered, so it will work as an input text.

.directive('ngUpdateHidden', function () {
    return {
        restrict: 'AE', //attribute or element
        scope: {},
        replace: true,
        require: 'ngModel',
        link: function ($scope, elem, attr, ngModel) {
            $scope.$watch(ngModel, function (nv) {
                elem.val(nv);
            });
            elem.change(function () { //bind the change event to hidden input
                $scope.$apply(function () {
                    ngModel.$setViewValue(  elem.val());
                });
            });
        }
    };
})

so when you trigger $("#yourInputHidden").trigger('change') event with jQuery, it will update the binded model as well.

Solution 5 - Javascript

Found a strange behaviour about this hidden value () and we can't make it to work.

After playing around we found the best way is just defined the value in controller itself after the form scope.

.controller('AddController', [$scope, $http, $state, $stateParams, function($scope, $http, $state, $stateParams) {

    $scope.routineForm = {};
    $scope.routineForm.hiddenfield1 = "whatever_value_you_pass_on";

    $scope.sendData = function {
    
// JSON http post action to API 
}

}])
  

Solution 6 - Javascript

I achieved this via -

 <p style="display:none">{{user.role="store_user"}}</p>

Solution 7 - Javascript

update @tymeJV 's answer eg:

 <div style="display: none">
    <input type="text" name='price' ng-model="price" ng-init="price = <%= @product.price.to_s %>" >
 </div>

Solution 8 - Javascript

I had facing the same problem, I really need to send a key from my jsp to java script, It spend around 4h or more of my day to solve it.

I include this tag on my JavaScript/JSP:

 $scope.sucessMessage = function (){  
    	var message =     ($scope.messages.sucess).format($scope.portfolio.name,$scope.portfolio.id);
    	$scope.inforMessage = message;
    	alert(message);  
}
 

String.prototype.format = function() {
    var formatted = this;
    for( var arg in arguments ) {
        formatted = formatted.replace("{" + arg + "}", arguments[arg]);
    }
    return formatted;
};

<!-- Messages definition -->
<input type="hidden"  name="sucess"   ng-init="messages.sucess='<fmt:message  key='portfolio.create.sucessMessage' />'" >

<!-- Message showed affter insert -->
<div class="alert alert-info" ng-show="(inforMessage.length > 0)">
    {{inforMessage}}
</div>

<!-- properties
  portfolio.create.sucessMessage=Portf\u00f3lio {0} criado com sucesso! ID={1}. -->

The result was: Portfólio 1 criado com sucesso! ID=3.

Best Regards

Solution 9 - Javascript

Just in case someone still struggles with this, I had similar problem when trying to keep track of user session/userid on multipage form

Ive fixed that by adding

.when("/q2/:uid" in the routing:

    .when("/q2/:uid", {
        templateUrl: "partials/q2.html",
        controller: 'formController',
        paramExample: uid
	})

And added this as a hidden field to pass params between webform pages

<< input type="hidden" required ng-model="formData.userid" ng-init="formData.userid=uid" />

Im new to Angular so not sure its the best possible solution but it seems to work ok for me now

Solution 10 - Javascript

Directly assign the value to model in data-ng-value attribute. Since Angular interpreter doesn't recognize hidden fields as part of ngModel.

<input type="hidden" name="pfuserid" data-ng-value="newPortfolio.UserId = data.Id"/>

Solution 11 - Javascript

I use a classical javascript to set value to hidden input

$scope.SetPersonValue = function (PersonValue)
{
	document.getElementById('TypeOfPerson').value = PersonValue;
	if (PersonValue != 'person')
	{
		document.getElementById('Discount').checked = false;
		$scope.isCollapsed = true;
	}
	else
	{
		$scope.isCollapsed = false;
	}
}

Solution 12 - Javascript

Below Code will work for this IFF it in the same order as its mentionened make sure you order is type then name, ng-model ng-init, value. thats It.

Solution 13 - Javascript

Here I would like to share my working code :

<input type="text" name="someData" ng-model="data" ng-init="data=2" style="display: none;"/>
OR
<input type="hidden" name="someData" ng-model="data" ng-init="data=2"/>
OR
<input type="hidden" name="someData" ng-init="data=2"/>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChristianView Question on Stackoverflow
Solution 1 - JavascriptMickaelView Answer on Stackoverflow
Solution 2 - JavascripttymeJVView Answer on Stackoverflow
Solution 3 - JavascriptNorthstriderView Answer on Stackoverflow
Solution 4 - JavascriptJoan JBView Answer on Stackoverflow
Solution 5 - JavascriptdcpartnersView Answer on Stackoverflow
Solution 6 - JavascriptvivexView Answer on Stackoverflow
Solution 7 - JavascriptAlbert.QingView Answer on Stackoverflow
Solution 8 - JavascriptLeoJavaView Answer on Stackoverflow
Solution 9 - JavascriptmaciekuView Answer on Stackoverflow
Solution 10 - JavascriptNikhil.HmathView Answer on Stackoverflow
Solution 11 - JavascriptIvan KuznietsovView Answer on Stackoverflow
Solution 12 - JavascriptPawan ParasharView Answer on Stackoverflow
Solution 13 - JavascriptJ. MiddyaView Answer on Stackoverflow