23
votes

I have a simple form like so:

<form name="add-form" data-ng-submit="addToDo()">
    <label for="todo-name">Add a new item:</label>
    <input type="text" data-ng-model="toDoName" id="todo-name" name="todo-name" required>
    <button type="submit">Add</button>
</form>

with my controller as follows:

$scope.addToDo = function() {
    if ($scope.toDoName !== "") {
        $scope.toDos.push(createToDo($scope.toDoName));
    }
}

what I'd like to do is clear the text input after submission so I simply clear the model value:

$scope.addToDo = function() {
    if ($scope.toDoName !== "") {
        $scope.toDos.push(createToDo($scope.toDoName));
        $scope.toDoName = "";
    }
}

Except now, because the form input is 'required' I get a red border around the form input. This is the correct behaviour, but not what I want in this scenario... so instead I'd like to clear the input and then blur the input element. Which leads me to:

$scope.addToDo = function() {
    if ($scope.toDoName !== "") {
        $scope.toDos.push(createToDo($scope.toDoName));
        $scope.toDoName = "";
        $window.document.getElementById('todo-name').blur();
    }
}

Now, I know that modifying the DOM from the controller like this is frowned upon in the Angular documentation - but is there a more Angular way of doing this?

3

3 Answers

31
votes

When you give a name to your form it automatically gets added to the $scope.

So if you change your form name to "addForm" ('cause I don't think add-from is a valid name for angular, not sure why), you'll have a reference to $scope.addForm.

If you use angular 1.1.1 or above, you'll have a $setPristine() method on the $scope.addForm. which should recursively take care of resetting your form. or if you don't want to use the 1.1.x versions, you can look at the source and emulate it.

2
votes

For those not switching over to 1.1.1 yet, here is a directive that will blur when a $scope property changes:

app.directive('blur', function () {
  return function (scope, element, attrs) {
    scope.$watch(attrs.blur, function () {
        element[0].blur();
    });
  };
});

The controller must now change a property whenever a submit occurs. But at least we're not doing DOM manipulation in a controller, and we don't have to look up the element by ID:

function MainCtrl($scope) {
    $scope.toDos = [];
    $scope.submitToggle = true;
    $scope.addToDo = function () {
        if ($scope.toDoName !== "") {
            $scope.toDos.push($scope.toDoName);
            $scope.toDoName = "";
            $scope.submitToggle = !$scope.submitToggle;
        }
    };
}

HTML:

<input type="text" data-ng-model="toDoName" name="todo-name" required 
  blur="submitToggle">

Plnkr

0
votes

I have made it work it as below code.

HTML SECTION

<td ng-show="a">
 <input type="text" ng-model="e.FirstName" />
</td>

Controller SECTION

e.FirstName= '';