2

I'm working with a form and would like to add ng-model on dynamic input elements. I have a scope variable defined as:

$scope.formData = {};

On the page there are a couple of drop-down lists that users can choose an option from and based on those options we are appending some input fields to form body.

formBody.append('<input ng-model="formData.'+obj.Title+'" type="number"></input></br>');

This is not working for me because I'm assuming once the controller runs it can't register any new ng-model. Is there way to add dynamic ng-model or there is a different approach to what I'm trying to do (i.e. build predefined views that can be loaded on the page)?

EDIT: I have created a jsfiddle that outlines what I'm trying to do - http://jsfiddle.net/k5u64yk1/

3
  • Not exactly this but take a look at how I got Angular to recompile elements with directives earlier - just swap out where I change the ng-options attribute to ng-model and it should work. stackoverflow.com/questions/32334054/… Commented Sep 1, 2015 at 20:55
  • Thanks for your comment! We were able to do this with $compile. And I think it will work out well. I'll give your way a try if all goes south. Commented Sep 2, 2015 at 18:38
  • My way was with $compile :P So I hope it works out! Commented Sep 2, 2015 at 18:56

1 Answer 1

5

If you need to dynamically add html with dynamic bindings that cannot be encapsulated into ng-repeat, ng-if, etc, you have to call $compile on the template once it has been modified to alert AngularJS that it has to reparse the template and initiate a new digest cycle. This will pick up any new ng-model bindings and appropriately tie them to your scope.

HTML:

<div ng-app="MyApp" ng-controller="MyCntrl">
    <button ng-click="addInput()">Add Input</button>
    <div id="form">
        input would go here.
    </div>
</div>

JS: By placing your add input inside of a click event, you avoid an infinite compile loop. Note that this currently resets the state of your form, so if you wanted to work around that you'd need to capture your form state and restore it after compile.

$scope.addInput = function () {
    var aForm = (angular.element(document.getElementById('form')));

    if ($scope.data["Digital Conversation"][0].MetricType.Title === "Number") {
        aForm.append(
            '<input ng-model="formData.' + 
            $scope.data["Digital Conversation"][0].Title.Title + 
            '" type="number"></input>');
    }

    $compile(aForm)($scope);
}

You can find the working jsfiddle here: http://jsfiddle.net/k5u64yk1/

Sign up to request clarification or add additional context in comments.

2 Comments

@habibg I've updated my answer and attached working fiddle for you.
David the link shows the same thing I provided in the above comment but what you suggested works! I added your method on my original jsfiddle and updated it - jsfiddle.net/k5u64yk1/1

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.