4

I would like to create a custom input that looks like that:

<my-input ng-model="aScopeProperty" placeholder="Enter text" 
data-title="This is my title"></my-input>

my-input should receive any property that regular input can get (like placeholder and etc...).

the output should be like this (myInputTemplate.html):

<div class="my-input">
    {{title}}           
    <input type="text" ng-model="text" />    
</div>

I created a directive:

myApp.directive('myInput', function(){
     return {
        restrict: 'E',
        require: 'ngModel',
        templateUrl: '/myInput/myInputTemplate.html',
        replace: true,
        scope: {
            text: '=ngModel',
            title: '=title'
        },            
    }

});

the ng-model is bindded ok now, my question is: How can I pass the attributes (like placeholder and etc) from my-input to the inside input?

I think that I approached it the wrong way, maybe I need to do it like that:

  <input my-input ng-model="aScopeProperty" placeholder="Enter text" 
   data-title="This is my title"></input>

and to wrap the input with:

 <div class="my-input">
    {{title}}  
    <here will be the original input> 
</div>
Shlomi Aharoni
  • 482
  • 7
  • 9

3 Answers3

2

directive call should be like

<my-input ng-model="aScopeProperty" placeholder="'Enter text'" title="'This is my title'"></my-input>

note the placeholder="'Enter text'" Enter text with in quotes ('), this indicate these values are string so angular will not search for scope variable.

and in the directive

myApp.directive('myInput', function(){
   return {
      restrict: 'E',
      require: 'ngModel',
      templateUrl: '/myInput/myInputTemplate.html',
      replace: true,
      scope: {
          text: '=ngModel',
          title: '=title',
          placeholder : '=placeholder'
      },            
  }
});

and the template

<div class="my-input">
    {{title}}           
    <input type="text" ng-model="text" placeholder="{{ placeholder }}" />    
</div>

here is the demo Plunker

Kalhan.Toress
  • 21,683
  • 8
  • 68
  • 92
0

You can use ng-attr as the following:

<input type="text" ng-model="text" ng-attr-placeholder="{{placeholder}}"/>

And send placeholder as attribute in your scope as the following:

scope: {
      text: '=ngModel',
      title: '=title',
      placeholder : '=placeholder'
  }

I recommend to read about ng-attr-attrName, and this useful answer.

Dynamic attributes

Read my question, and accepted answer.

Community
  • 1
  • 1
Mohamed Yakout
  • 2,868
  • 1
  • 25
  • 45
  • thanks for the quick response, but "placeholder" was just an example, today is "placeholder" tomorrow it will be another attribute, can I make it generic? that all the attributes will go to the input? – Shlomi Aharoni Jan 06 '15 at 11:41
  • @ShlomiAharoni I updated my answer, I asked your question but with another way :) – Mohamed Yakout Jan 06 '15 at 13:53
0

The second approach succeeded!

final code:

<input my-input ng-model="aScopeProperty" placeholder="Enter text" 
data-title="This is my title">

The Directive:

app.directive('myInput', function () {
return {
    restrict: 'A',
    scope: {
        title: '=title'
    },
    link: function ($scope, $element) {
        var wrap = angular.element('<div class="my-input-wrapper" />');
        $element.addClass('form-control').removeAttr('my-input');
        wrap.insertBefore($element);
        $element.appendTo(wrap);
        if ($scope.title) {
            var title = angular.element('<span class="my-title">' + $scope.title + '</span>');
            title.appendTo(wrap);
        }
    },
}

});

I even created my first Plunker for it, unfortunately, the Plunker don't works because it doesn't recognize: insertBefore and appendTo

http://plnkr.co/edit/XnFM75vOBg4ifHUQzGOt?p=preview

Shlomi Aharoni
  • 482
  • 7
  • 9