0

I have a form that I want to build at run time via js and use it in a form controller in angularjs.
As you can see in the following example, it is not being thrown as html, and i want it to be binded to the model variable. http://jsfiddle.net/g6m09eb7/

<div>
    <form ng-controller="TodoCtrl" ng-submit="blabla()">
        <div ng-repeat="field in fields">{{field.input}}</div>
    </form>
</div>

function TodoCtrl($scope) {
    $scope.model = {
        'FirstName': 'Test',
        'LastName': 'Test Last'
    }
    $scope.fields = [{
        input: '<input type="text" ng-model="model.FirstName">'
    }, {
        input: '<input type="text" ng-model="model.LastName">'
    }, ];
}
SexyMF
  • 10,657
  • 33
  • 102
  • 206

1 Answers1

3

First, I'm going to show you how to make this work as you're trying to accomplish it, for the sake of being informative. This is not the approach you should use to solve your overall problem. This example will get the html in the document, but it won't be compiled with Angular. To do that, you would have to have a different directive, like this (click). This is all kinds of a bad approach.

angular.module('myApp', [])
.controller('TodoCtrl', function($scope) {
    $scope.fields = [{
        input: '<input type="text" ng-model="model.FirstName">'
    }, {
        input: '<input type="text" ng-model="model.LastName">'
    }, ];
})
// filter to make Angular trust the html
.filter('safeHtml', ['$sce', function ($sce) { 
    return function (text) {
        return $sce.trustAsHtml(text);
    };    
}])
;                     
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="myApp" ng-controller="TodoCtrl">
   <!-- use ng-bind-html on trusted html to bind it (see the js) -->
  <div ng-repeat="field in fields" ng-bind-html="field.input | safeHtml"></div>
</form>

Instead, you can do this naturally. Just use the properties of your object as the criteria for ng-repeat. Simple and clean!

angular.module('myApp', [])
.controller('TodoCtrl', function($scope) {
  $scope.model = {
    'FirstName': 'Test',
    'LastName': 'Test Last'
  };
})
;                     
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="myApp" ng-controller="TodoCtrl">
  <div ng-repeat="(key,value) in model">
      <input type="text" ng-model="model[key]"/>
  </div>
</form>

Be sure to avoid concerning your controller with DOM manipulation. If you have html snippets in a controller, your approach is probably off track. DOM manipulation should be done entirely with directives.

m59
  • 43,214
  • 14
  • 119
  • 136
  • Hi, thanks, the reason I want to generate the form is because it is really dynamic and It has alot of conditions while building the form. anyway I took your example to jsfiddle and as you can see the values are not binded: http://jsfiddle.net/g6m09eb7/2/ – SexyMF Mar 01 '15 at 06:19
  • @SexyMF that isn't my suggestion =D I'm emphatically asking you to NOT do that. The second example is the right way. See what I wrote "This is all kinds of a bad approach." and I explained that the html wouldn't be compiled and gave you a link to a resource that would fix that. Lastly, I discussed that directives are responsible for DOM manipulation. Depending on the complexity involved in your particular circumstance beyond this post, you may write your own directives to handle it. – m59 Mar 01 '15 at 06:22
  • Oh, I just saw you update. sorry, I wasnt refreshing the page. Let me ask you this, in your second example, How can I make the form more dynamic, some time I need combobox / checkbox / radios / textarea and so, your example stricked me to a single type of field. thanks – SexyMF Mar 01 '15 at 06:26
  • @SexyMF So, it sounds like you're saying that you have some data and there's a formula that you want to use to sort of convert that into a form, right? You could write a directive that has the logic to look at the data and pull in the right html snippets. That reminds me of my answer here: http://stackoverflow.com/a/20181150/1435655 Check that out and use what you learned here along with that. Since you're just starting with Angular, it will probably be tough to wrap your head around some of it at first. Just keep tinkering and studying and you'll get it. – m59 Mar 01 '15 at 06:35