Schileru
Schileru

Reputation: 325

AngularJS input not updating with ng-model

I have a form with three input fields:

<form name="myForm" novalidate ng-controller="MainController as vm">
    <div>
        <input type="text" ng-model="vm.id" name="idInput" required>
        <input type="email" ng-model="vm.email" name="emailInput" required>
        <input type="text" ng-model="vm.output" name="output">
    </div>
</form>

vm.output is a variable defined in my controller that contains some strings plus vm.id and vm.email:

vm.output = 'myurl.com?id=' + vm.id + '&email=' + vm.email;

I want to generate an output URL based on the user input in the id and email fields. However, the output-field does not update when I enter some input into the two other fields. It just says myurl.com?id=undefined&email=undefined,

I can get it working if I use

ng-value="'myurl.com?id=' + vm.id + '&email=' + vm.email"

However, I'm using ng-clip which gets the content to copy by using ng-model so I need to use that.

Also, here's my controller:

angular
    .module("app")
    .controller("MainController",[MainController);

function MainController(){
    var vm = this;

    vm.output = 'myurl.com?id=' + vm.id + '&email=' + vm.email;
}

Any suggestions?

Upvotes: 1

Views: 16077

Answers (2)

dfsq
dfsq

Reputation: 193251

I would go with custom directive that would set model value properly:

app.directive('concatModel', function($parse) {

    var pattern = function(data) {
        return 'myurl.com?id=' + data.id + '&email=' + data.email;
    };

    return {
        require: 'ngModel',
        scope: {
            data: '=concatModel'
        },
        link: function(scope, element, attrs, controller) {
            scope.$watchCollection('data', function(newVal) {
                controller.$setViewValue(pattern(newVal));
                controller.$render();
            });
        }    
    };
});

and use it like this:

<div>
    <input type="text" ng-model="vm.id" name="idInput" required="" />
    <input type="email" ng-model="vm.email" name="emailInput" required="" />
    <input type="text" concat-model="{id: vm.id, email: vm.email}" ng-model="vm.output" name="output" />
</div>

Demo: http://plnkr.co/edit/sFW16LLZK3TezNAvYk5F?p=info

Upvotes: 0

Davin Tryon
Davin Tryon

Reputation: 67296

You could accomplish this a few different ways. One way is to set up ng-change events on each of the inputs you want to watch:

<div>
    <input type="text" ng-model="vm.id" ng-change="updateOutput()" name="idInput" required />
    <input type="email" ng-model="vm.email" ng-change="updateOutput()" name="emailInput" required />
    <input type="text" ng-model="vm.output" name="output" />
</div>

Then, you have to build the update method on the controller scope:

app.controller = app.controller('MainController', function($scope) {

    $scope.vm = {
      output: '',
      email: '',
      id: ''
    };

    $scope.updateOutput = function() {
      $scope.vm.output = 'myurl.com?id=' + $scope.vm.id + '&email=' + $scope.vm.email;
    }
});

Here is a working plunker.

Upvotes: 1

Related Questions