Angularjs препятствуют отправке формы при неудачной проверке ввода

Я пишу простую форму входа с помощью angularjs с некоторой проверкой ввода на стороне клиента, чтобы проверить, что имя пользователя и пароль не пусты и длиннее трех символов. См. Приведенный ниже код:

<form name="loginform" novalidate ng-submit="login.submit()" class="css-form">
    <fieldset>

        <div class="control-group input-prepend">
            <span class="add-on"><i class="icon-user"></i></span>
            <input type="text" ng-model="login.username" name="username" required ng-minlength="3" placeholder="username" />
        </div>

        <div class="control-group input-prepend">
            <span class="add-on"><i class="icon-lock"></i></span>
            <input type="password" ng-model="login.password" name="password" required ng-minlength="3" placeholder="" />
        </div>

        <div class="control-group">
            <input class="btn" type="submit" value="Log in">
        </div>

    </fieldset>
</form>

И контроллер:

var controller = function($scope) {

    $scope.login = {
        submit: function() {

            Console.info($scope.login.username + ' ' + $scope.login.password);
        }
    }

};

Проблема в том, что функция login.submit будет вызываться, даже если вход недействителен. Возможно ли предотвратить это поведение?

В качестве побочного примечания я могу упомянуть, что я также использую bootstrap и requirejs.

Ответ 1

Измените кнопку отправки на:

<button type="submit" ng-disabled="loginform.$invalid">Login</button>

Ответ 2

Вы можете сделать:

<form name="loginform" novalidate ng-submit="loginform.$valid && login.submit()">

Нет необходимости в проверке контроллера.

Ответ 3

Таким образом, предложенный ответ от TheHippo не работал у меня, вместо этого я отправил форму как параметр в функцию, например:

<form name="loginform" novalidate ng-submit="login.submit(loginForm)" class="css-form">

Это делает форму доступной в методе контроллера:

$scope.login = {
    submit : function(form) {
        if(form.$valid)....
    }

Ответ 4

Ваши формы автоматически помещаются в $scope как объект. Доступ к нему возможен через $scope[formName]

Ниже приведен пример, который будет работать с вашей исходной настройкой и без необходимости передавать форму в качестве параметра в ng-submit.

var controller = function($scope) {

    $scope.login = {
        submit: function() {
            if($scope.loginform.$invalid) return false;

        }
    }

};

Рабочий пример: http://plnkr.co/edit/BEWnrP?p=preview

Ответ 5

HTML:

<div class="control-group">
    <input class="btn" type="submit" value="Log in" ng-click="login.onSubmit($event)">
</div>

В вашем контроллере:

$scope.login = {
    onSubmit: function(event) {
        if (dataIsntValid) {
            displayErrors();
            event.preventDefault();
        }
        else {
            submitData();
        }
    }
}

Ответ 6

Хотя это не является прямым решением для вопроса OPs, если ваша форма находится в контексте ng-app, но вы хотите, чтобы Angular игнорировал ее вообще, вы можете сделать это явно, используя ngNonBindable:

<form ng-non-bindable>
  ...
</form>

Ответ 7

Чтобы добавить к ответам выше,

У меня были две обычные кнопки, как показано ниже. (Нет типа = "отправить" в любом месте)

<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>
<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>

Независимо от того, насколько я старался, нажав, введите форму, когда форма была действительной, вызывается кнопка "Очистить форму", очищая всю форму.

В качестве обходного пути

Мне пришлось добавить пустую кнопку отправки, которая была отключена и скрыта. И эта фиктивная кнопка должна быть поверх всех остальных кнопок, как показано ниже.

<button type="submit" ng-hide="true" ng-disabled="true">Dummy</button>

<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>

<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>

Ну, мое намерение никогда не отправлялось на Enter, поэтому вышеупомянутый взлом просто отлично работает.

Ответ 8

Я знаю, что это старый поток, но я думал, что тоже внесет свой вклад. Мое решение похоже на сообщение, уже отмеченное как ответ. Некоторые встроенные проверки JavaScript делают трюк.

ng-click="form.$invalid ? alert('Please correct the form') : saveTask(task)"

Ответ 9

Я знаю это поздно и был дан ответ, но я хотел бы поделиться аккуратным материалом, который я сделал. Я создал директиву ng-validate, которая перехватывает onsubmit формы, затем она выдает предупреждение-default, если $eval ложно:

app.directive('ngValidate', function() {
  return function(scope, element, attrs) {
    if (!element.is('form'))
        throw new Error("ng-validate must be set on a form elment!");

    element.bind("submit", function(event) {
        if (!scope.$eval(attrs.ngValidate, {'$event': event}))
            event.preventDefault();
        if (!scope.$$phase)
            scope.$digest();            
    });
  };
});

В вашем html:

<form name="offering" method="post" action="offer" ng-validate="<boolean expression">