18

Whenver I have an Angular expression as a value to input's type, it won't work:

<input ng-model="model" type="{{'number'}}">

Numeric values get converted to strings and checkboxes won't work at all.

http://jsfiddle.net/punund/NRRj7/3/

1
  • The answer provided by vidriduch should be the accepted answer now. This is possible with more recent versions of AngularJS (at least 1.2.13, perhaps older?) Commented Apr 16, 2015 at 16:39

5 Answers 5

31

yes you can ... at least now :)

HTML:

<section ng-app="myApp" ng-controller="mainCtrl">
  <input type="{{inputType}}" placeholder="Put your password" />
  <input type="checkbox" id="checkbox" ng-model="passwordCheckbox" ng-click="hideShowPassword()" />
  <label for="checkbox" ng-if="passwordCheckbox">Hide password</label>
  <label for="checkbox" ng-if="!passwordCheckbox">Show password</label>  
</section>
<script src="http://code.angularjs.org/1.2.13/angular.min.js"></script>

JS:

var myApp = angular.module('myApp', []);
myApp.controller('mainCtrl', ['$scope', function( $scope ){

  // Set the default value of inputType
  $scope.inputType = 'password';

  // Hide & show password function
  $scope.hideShowPassword = function(){
    if ($scope.inputType == 'password')
      $scope.inputType = 'text';
    else
      $scope.inputType = 'password';
  };
}]);

source: http://codepen.io/gymbry/pen/fJchw/

UPDATE 17/04/2015:

I have randomly changed Angular version in above Codepen and this seems to work from version 1.0.2 ... Hope this help ...

Sign up to request clarification or add additional context in comments.

6 Comments

Fantastic! Thank you for giving an updated answer to this question. Any idea with what version this became possible? I'm using 1.4; however, it might be useful to others to know if this was a change with 1.2.13 or earlier?
I have tried different versionsin above codepen and the version it started to work was 1.0.2 ...
I don't think it works in all the browsers... Did you check in IE?
Didn't run extra tests, but I can confirm that this (codepen and in simple html) worked for me in IE11, FF38, Opera 30, Chrome 43 from windows and also on latest chrome and ff on Mint
Worked for me in IE10 & IE11 on Win7 with Angular 1.2.15
|
21

You can't change input's type dynamically since IE disallows this and AngularJS needs to be cross-browser compatible. So even if you might see the changed type displayed in the source code AngularJS won't pick it up - type is only evaluated once and can't be changed.

Please note that the same restriction applies to jQuery: jQuery change input type

You only options for dynamic types are either a custom directive (where you can download a dynamic template or prepare DOM on-the-fly) or using ng-include to include include partials where the input type is a static value.

2 Comments

I'd love to see some tips on creating a custom directive to see this... Banging my head against a wall here :)
The answer provided by vidriduch should be the accepted answer now. This is possible with more recent versions of AngularJS (at least 1.2.13, perhaps older?)
13

You cannot change the input type dynamically in any browser and so it is not possible to use dynamic single input statement. You are left with using conditional statement for creation of elements where type is hard-coded.

Use ng-switch on directive where you can compare the type and create elements based on the condition match. For example:

<div class="form-group" ng-repeat="elem in formElements">
 <div class="col-lg-12" ng-switch on="elem.eleType">
  <input ng-switch-when="text" type="text" id="{{elem.id}}" name="{{elem.id}}" class="{{elem.class}}" placeholder="{{elem.placeholder}}" popover-trigger="focus" popover="{{elem.popoverText}}">
  <input ng-switch-when="password" type="password" id="{{elem.id}}" name="{{elem.id}}" class="{{elem.class}}" placeholder="{{elem.placeholder}}" popover-trigger="focus"  popover="{{elem.popoverText}}">
  <input ng-switch-when="email" type="email" id="{{elem.id}}" name="{{elem.id}}" class="{{elem.class}}" placeholder="{{elem.placeholder}}" popover-trigger="focus"  popover="{{elem.popoverText}}">
 </div>
</div>

In this example you are instructing angular script to compare elem.eleType using ng-switch on in second div against actual type i.e, text, password and email in the input tag (compared using ng-switch-when, and only that input element is create where the condition matches, rest will be ignored.

Comments

3
<input type="text" ng-model="myModel" ng-if="inputType === 'text'"/>
<input type="password" ng-model="myModel" ng-if="inputType === 'password'"/>

This works for me.

3 Comments

I like this, simple and powerful.
Wonder what "powerful" means in this context.
I am using the same, however my apps keyboard is not changing appropriately. I see the DOM ng-ifs activating and deactivating, but the keyboard type on the input field does not change according.
1

Here is a slight extension to @vidriduch's answer. In this case I am using a model object 'config' of the form {type:"password", value:"topsecret"}, and displaying it like this:

<input type="{{config.type}}" ng-model="config.value">

Ideally I could change the config object as required, and use the same input element to edit any config record with matching type/value. My original way of switching records was to call the below scope function:

$scope.newRecord = function (newcfg) {
    $scope.config = newcfg;
};

However, I sometimes got conversion errors or complaints about validation. This is in Chrome 47. It really didn't like switching from text to dates, for example. The browser seemed to pick up the change of value before the change in type, or vv.

I solved this by forcing the model (and so the type) to reset in between changes.

$scope.newRecord = function (newcfg) {
   $scope.config = {}; //clear the model object
   $timeout(function() {
      $scope.config = newcfg;
   }, 0); //zero delay needed

};

This may not be an ideal solution, but it illustrates a 'gotcha' that others might experience.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.