Karol F
Karol F

Reputation: 1566

Unexpected behaviour with AngularJS submit on enter

I need to make simple form with order tracking functionality with AngularJS. I created the following jsfiddle: http://jsfiddle.net/MVVcf/2/

When we hit enter on the first time the submit is working, but the second (and next) hit is not working and clear all the items from the rows above.

The strange is when we always click 'Add' button everythink works well.

HTML:

<div data-ng-app="OrderApp" data-ng-controller="OrderController" class="container">
<h1>Order</h1>
<hr/>
<form role="form" name="form" data-ng-submit="add(form)" novalidate>
    <table class="table table-striped table-hover table-bordered">
        <thead>
        <tr>
            <th class="who" colspan="2">Who</th>
            <th class="what">What</th>
            <th class="actions">Actions</th>
        </tr>
        </thead>
        <tbody>
        <tr data-ng-repeat="item in order.items">
            <td><input type="checkbox" data-ng-model="item.selected" /></td>
            <td data-ng-click="edit(item)">{{ item.who }}</td>
            <td data-ng-click="edit(item)">{{ item.what }}</td>
            <td style="text-align: center">
                <button data-ng-click="delete($index)" class="btn btn-xs btn-danger">&nbsp;x&nbsp;</button>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input name="who" type="text" placeholder="kto..." data-ng-model="formData.who" autofocus data-focus-on="submitted" required class="form-control" />
                <div data-ng-show="submitted && form.who.$error.required">To pole jest wymagane</div>
            </td>
            <td>
                <input name="what" type="text" placeholder="co..." data-ng-model="formData.what" required class="form-control" />
                <span data-ng-show="submitted && form.what.$error.required">To pole jest wymagane</span>
            </td>
            <td>
                <button type="submit" class="btn btn-primary">Add</button>
            </td>
        </tr>
        </tbody>
    </table>
</form>

JS:

angular.module('OrderApp', [])
.directive('focusOn', function() {
    return function(scope, elem, attr) {
        scope.$on(attr.focusOn, function(e) {
            elem[0].focus();
        });
    };
})
.controller('OrderController', ['$scope', function ($scope) {
    $scope.submitted = false;
    $scope.focus = true;
    $scope.order = {
        items: []
    };
    $scope.toggle = function (item) {
        item.selected = !item.selected;
    };
    $scope.add = function (form) {
        if (form.$invalid) {
            return;
        }
        $scope.order.items.push(angular.copy($scope.formData));
        $scope.submitted = false;
        $scope.$broadcast('submitted');
        $scope.formData = null;
    };
    $scope.delete = function ($index) {
        $scope.order.items.splice($index, 1);
    };
}]);

Upvotes: 3

Views: 1084

Answers (2)

Everytime you press Enter, your Delete function is being called. So the item you have just added to the list is deleted when you try to add another entry via pressing Enter on the input field.

This happens because when you press Enter, it will trigger the click on the first Submit button it finds...and that is the Delete button, even though the focus is on the input field. But, since the default behavior of a button is "Submit", it will steal your focus and execute the underlying function (delete...).

If you change the button to an Anchor tag, it will work perfectly and the appearance should be just the same:

      <a data-ng-click="delete($index)" class="btn btn-xs btn-danger">&nbsp;x&nbsp;</a>

However, if you're really fancy about it being a button, you can solve the problem by adding the "type" attribute with the value "button" to the Button tag:

      <button type="button"...

and this will prevent the "submit" behavior from stealing your focus.

Upvotes: 1

Jossef Harush Kadouri
Jossef Harush Kadouri

Reputation: 34267

http://jsfiddle.net/Qc9Fw/

Assuming that you are using bootstrap library,

changed:

<button data-ng-click="delete($index)" class="btn btn-xs btn-danger">&nbsp;x&nbsp;</button>

to :

<a data-ng-click="delete($index)" class="btn btn-xs btn-danger">&nbsp;x&nbsp;</a>

This should look and feel the same

The problem was that the X buttons 'stole' the focus on Enter key press

Upvotes: 2

Related Questions