supersan supersan - 3 months ago 18
AngularJS Question

How to use custom directive on Input fields in Angular 1.x?

I'm trying to modify the

input
element using a custom AngularJS directive. Basically I want to replace any
<input type="country">
fields with a country drop-down.

But the directive doesn't seem to work with
input
fields. If I change it to any other tag, it works?

Here is the code:



angular.module('plunker', [])
.controller('MainCtrl', function ($scope) {
$scope.name = 'World';
});


angular.module('plunker')
.directive('input', function() {
return {
restrict: 'E',
scope: {ngModel: '=?'},
link: function(scope, elem, attr) {
if(attr.type === 'country') {
elem.html('html code for select');
alert(elem);
}
}
};
});

<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<script>document.write("<base href=\"" + document.location + "\" />");</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
Name: <input type="country" ng-model="name"/> <br/>
</body>
</html>





Can someone please explain and suggest a workaround?

P.S. I've also tried doing this in the directive, but it doesn't work either!

replace: true,
template:'<div>hello</div>'


P.S. I know I can use a
ng-country
or some other custom tag but I want to change
input
tag only because I want learn why this is happening or possibly find out what I'm doing wrong?

Answer

Latest Update:

Your code is just setting the html on the element, instead of replacing it. You would want to use replaceWith instead like this:

var app = angular.module("TestApp",[]);

app.controller("TestController", function($scope){
  $scope.message = "Input Directive Test"
});

app.directive("input", function() {
  return {
    restrict: "E",
    link: function(scope, elem, attr) {
      if(attr.type === "country") {
        var select = angular.element("<select><option>USA</option></select>");
        elem.replaceWith(select);        
      }
    }
  }
});

And here's the JSBin: https://jsbin.com/juxici/4/edit?html,js,output

Initial Version of my answer:

Here's an example that works without any issues when 'replace' and 'template' are used. I'm not checking for type and such, but you could do that in the linker code.

JSBin: https://jsbin.com/juxici/2/edit?html,js,output

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>

</head>
<body ng-app="TestApp">
  <div ng-controller="TestController">
    <h2>{{message}}</h2>
    <input type="country" ng-model="name"/>
  </div>
</body>
</html>

Javascript:

var app = angular.module("TestApp",[]);

app.controller("TestController", function($scope){
  $scope.message = "Input Directive Test"
});

app.directive("input", function() {
  return {
    restrict: "E",
    replace: true,
    template:"<select><option>USA</option></select>"
  }
});
Comments