-1

I am trying that on a button click, a div and and input tag are created and the input tag contain ng-model and the div has binding with that input. Kindly suggest some solution.

  • how are you creating the input element? with something like `document.createElement('div')`? – jeojavi Jun 07 '17 at 11:15
  • Javi, I want to create that on ng-click of a button, a div and an input shall be created and both of them are appended into another div. Beside this, both of these are linked by ng-model and ng-bind. And all these to be done with angular only. – Akash Kumar Jun 07 '17 at 11:36

4 Answers4

0

You can create the div and input beforehand and and do not show it by using ng-if="myVar". On click make the ng-if="true".

<button ng-click="myVar = true">

In controller : $scope.myVar = false;

Shoaib Khan
  • 88
  • 1
  • 9
  • Sir, I need to make it dynamically because for the work I need to do, I have to make a button on whose click, such a combination of input and div shall be created as the user may want to create multiple of them. – Akash Kumar Jun 07 '17 at 11:27
0
$scope.addInputBox = function(){    
//#myForm id of your form or container boxenter code here
$('#myForm').append('<div><input type="text" name="myfieldname" value="myvalue" ng-model="model-name" /></div>');
}
Himesh Suthar
  • 562
  • 4
  • 14
0

You should use $compile service to link scope and your template together:

angular.module('myApp', [])
.controller('MyCtrl', ['$scope', '$compile', '$document' , function MyCtrl($scope, $compile, $document) {
  var ctrl = this;

  var inputTemplate = '<div><span ng-bind="$ctrl.testModel"></span>--<span>{{$ctrl.testModel}}</span><input type="text" name="testModel"/></div>';
 
  ctrl.addControllDynamically = addControllDynamically;

  var id = 0;
  function addControllDynamically() {
    var name = "testModel_" + id; 
    var cloned = angular.element(inputTemplate.replace(/testModel/g, name)).clone();
    cloned.find('input').attr("ng-model", "$ctrl." + name); //add ng-model attribute
    $document.find('[ng-app]').append($compile(cloned)($scope)); //compile and append
    id++;
  }

  return ctrl;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.angularjs.org/1.6.2/angular.js"></script>
<div ng-app="myApp">
  <div ng-controller="MyCtrl as $ctrl">
    <input type="button" value="Add control dynamically" ng-click="$ctrl.addControllDynamically()"/>
  </div>
</div>

UPDATE: to add a new compiled template each time the button is clicked, we need to make a clone of the element.

UPDATE 2: The example above represents a dirty-way of manipulating the DOM from controller, which should be avoided. A better (angular-)way to solve the problem - is to create a directive with custom template and use it together with ng-repeat like this:

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

  ctrl.controls = [];
  ctrl.addControllDynamically = addControllDynamically;
  ctrl.removeControl = removeControl;
  
  function addControllDynamically() {
    //adding control to controls array
    ctrl.controls.push({ type: 'text' });
  }
  
  function removeControl(i) {
    //removing controls from array
    ctrl.controls.splice(i, 1);
  }

  return ctrl;
}])
.directive('controlTemplate', [function () {
        var controlTemplate = {
            restrict: 'E',
            scope: {
              type: '<',
              ngModel: '='
            },
            template: "<div>" +
              "<div><span ng-bind='ngModel'></span><input type='type' ng-model='ngModel'/></div>" +
              "</div>"
        }
        return controlTemplate;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.angularjs.org/1.6.2/angular.js"></script>

<div ng-app="myApp">
  <div ng-controller="MyCtrl as $ctrl">
    <input type="button" value="Add control dynamically" ng-click="$ctrl.addControllDynamically()"/>
    
    <div ng-repeat="control in $ctrl.controls">
      <control-template type="control.type" ng-model="control.value"></control-template>
    </div>
  </div>
</div>
Stanislav Kvitash
  • 4,614
  • 18
  • 29
  • Sir, the input should also be dynamically created and each time, I click button, I should get a new set of input and div tag. – Akash Kumar Jun 07 '17 at 12:09
  • @AkashKumar See the updated answer, but anyway Stack Overflow is not a code-writing service - I've given you the idea and a working sample, so you could modify it and make it work in your project. Also I don't see the requirement to add a new input each time the button is pressed in the your question. – Stanislav Kvitash Jun 07 '17 at 12:44
  • @AkashKumar was this useful for you? – Stanislav Kvitash Jun 15 '17 at 11:47
0

Here is another solution, in which there's no need to create a div and an input explicitly. Loop through an array of elements with ng-repeat. The advantage is that you will have all the values of the inputs in that array.

angular.module('app', [])
.controller('AppController', AppController);

AppController.$inject = ['$scope'];
function AppController($scope) {
  $scope.values = [];
  $scope.add = function() {
    $scope.values.push('');
  };
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="AppController">
  <button ng-click="add()">Click</button>
  <div ng-repeat="value in values track by $index">
    <input type="text" ng-model="values[$index]"/>
    <div>{{values[$index]}}</div>
  </div>
  <pre>{{values}}</pre>
</div>

UPDATE. And if you want only one input, it's even simpler, using ng-show.

angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <button ng-click="show = true">Click</button>
  <div ng-show="show">
    <input type="text" ng-model="value"/>
    <div>{{value}}</div>
  </div>
</div>
jeojavi
  • 876
  • 1
  • 6
  • 15