2

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?

2
  • Instead of declaring your directive as an element, why not declare it as an attribute? Commented Aug 14, 2016 at 3:36
  • You should give the restriction to class/attribute level and custom directive name as any myInput etc., Commented Aug 14, 2016 at 3:40

1 Answer 1

2

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>"
  }
});
Sign up to request clarification or add additional context in comments.

4 Comments

thanks! it does seem to work but there is still one problem.. when I run the $compile on element it doesn't seem to work still? Any ideas?
@supersan why are you using $compile? show some code. Did this answer help you with your original question and you are extending the question? Just trying to understand.
hi, please see this code: jsbin.com/yiyideyomu/edit?html,js,output (i need to compile it because I want to use ng-options in select)
See it now: jsbin.com/guqekop/edit?html,js,output. You just need to compile it first and then replace. HTH. Don't forget to upvote/mark as answer if this helped you. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.