Angularjs ngăn gửi biểu mẫu khi xác thực đầu vào không thành công


155

Tôi đang viết một biểu mẫu đăng nhập đơn giản bằng angularjs với một số xác thực nhập vào phía máy khách để kiểm tra xem tên người dùng và mật khẩu không trống và dài hơn ba ký tự. Xem mã dưới đây:

<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>

Và bộ điều khiển:

var controller = function($scope) {

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

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

};

Vấn đề là login.submitchức năng sẽ được gọi ngay cả khi đầu vào không hợp lệ. Có thể ngăn chặn hành vi này?

Như một lưu ý phụ tôi có thể đề cập rằng tôi cũng sử dụng bootstrap và requestjs.



chúng ta có thể sử dụng nó mà không cần thẻ biểu mẫu và vẫn form.valid sẽ hoạt động trên ng-click!
Rizwan Patel

Câu trả lời:


329

Bạn có thể làm:

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

Không cần kiểm tra bộ điều khiển.


8
Đây phải là câu trả lời được chấp nhận. Không cần kiểm tra bất cứ điều gì trong bộ điều khiển
Howie

10
Tôi không đồng ý với "không cần kiểm tra bộ điều khiển". Điều gì xảy ra nếu chúng ta kiểm tra xác nhận bổ sung xảy ra trong chức năng gửi.
SlaterCodes

6
Thực hiện xác nhận bổ sung trong chỉ thị. Cập nhật xác nhận với $ setValids.
TMB

@ b1tsh1ft Nên để trạng thái xác nhận hiện tại luôn được biết đến hơn là tìm ra khi nộp. Đó là toàn bộ quan điểm xác nhận của góc. Bạn không thể có bất kỳ dấu hiệu trực quan nào về trạng thái không hợp lệ khi phạm vi không biết về nó.
Kevin Beal

1
Tôi đã thử cách tiếp cận này, nhưng có vẻ như nó đánh giá cả hai (nghĩa là nó không bị đoản mạch sau khi &&tôi đã thử chuyển giá trị như một phần của đệ trình và xác nhận rằng chính giá trị đó là "sai"
Archimedes Trajano

67

Thay đổi nút gửi thành:

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

1
Câu trả lời chính xác. Bạn đá!
Harsha.Vaswani 11/03/2015

24
Bạn vẫn có thể gửi biểu mẫu nếu bạn nhấn enter trong khi trường nhập liệu có trọng tâm!
fabsenet

2
@Red: Xem bình luận ở trên.
Andrei Rînea

Mặc dù vô hiệu hóa nút thường là cách tốt nhất để giải quyết vấn đề này, nhưng đó không phải là điều OP yêu cầu.
hạ cấp

1
Kết hợp kỹ thuật này để cung cấp phản hồi trực quan cho người dùng cùng với câu trả lời @Yashua để ngăn chặn việc gửi biểu mẫu là hoàn hảo. Cảm ơn!
tkls

43

Vì vậy, câu trả lời được đề xuất từ ​​TheHippo không hoạt động với tôi, thay vào đó tôi đã gửi biểu mẫu dưới dạng tham số cho hàm như vậy:

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

Điều này làm cho biểu mẫu có sẵn trong phương thức điều khiển:

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

Tôi gặp vấn đề tương tự. Sử dụng phương pháp của bạn làm việc, mặc dù.
Panda4Man

Điều này tốt hơn một chút so với Câu trả lời được chấp nhận vì biểu mẫu. $ Kiểm tra hợp lệ được thực hiện trong JS và không phải bằng HTML.
cellepo

Tuy nhiên, tôi không nghĩ bạn cần vượt qua loginForm để gửi hàm: Tôi nghĩ $ scope.loginform nên có sẵn trong JS (ít nhất là đối với tôi), vì vậy bạn có thể thay thế biểu mẫu. $ Hợp lệ với $ scope.loginform $ hợp lệ.
cellepo

13

Các biểu mẫu của bạn được tự động đưa vào phạm vi $ dưới dạng một đối tượng. Nó có thể được truy cập thông qua$scope[formName]

Dưới đây là một ví dụ sẽ hoạt động với thiết lập ban đầu của bạn và không phải vượt qua chính biểu mẫu dưới dạng tham số trong ng-submit.

var controller = function($scope) {

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

        }
    }

};

Ví dụ hoạt động: http://plnkr.co/edit/BEWnrP?p=preview


4
Làm thế nào bạn sẽ truy cập vào biểu mẫu nếu bạn sử dụng ký hiệu "Là Trình điều khiển" thay vì phạm vi $?
masimplo

@masimakopoulos: Bạn chỉ có thể sử dụng if(this.loginform.$invalid).. thay vào đó, nhưng trong HTML bạn phải đặt tên cho mẫu <form name="ctrl.loginform" ... Và đó là giả sử bạn đang sử dụng <div ng-controller="controller as ctrl"..trong cú pháp điều khiển của bạn. Cảm ơn @JoshCaroll
Bart

13

HTML:

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

Trong bộ điều khiển của bạn:

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

có thực sự cần thiết phải kiểm tra trong phương thức onsubmit không? Điều này có nghĩa là bạn phải kiểm tra xem đầu vào có đáp ứng tất cả các tiêu chí cả trong đánh dấu (thông qua góc) và trong mã js. Theo tôi góc cạnh không nên gọi onsubmit khi đầu vào không hợp lệ. xem ben Meat.com/2012/11/angular-js-form-validation.html nói rằng "ng-submit không thể được gọi cho đến khi toàn bộ biểu mẫu là $ hợp lệ"
Runar Halse

Bạn cũng có thể vô hiệu hóa nút để không cho phép gửi nếu biểu mẫu hợp lệ. Bạn cũng có thể sử dụng mẫu ng-submit. Nếu góc không xử lý xác nhận mẫu thì đó event.preventDefault()là cách để đi, dừng việc gửi biểu mẫu.
TheHippo

@RunarHalse Thực sự cần thiết phải kiểm tra. Tôi đồng ý với bạn rằng nó không nên theo cách này. Lý do mà phương thức onsubmit không được gọi trong ví dụ mà bạn đã liên kết là vì ví dụ đó không có tập hợp novalidate. Trình duyệt đang ngăn các sự kiện tăng, không phải Angular. Dưới đây là ví dụ của anh ấy w / nobalidate trên: plnkr.co/edit/R0C8XA?p=preview . Thông báo các hình thức nộp.
davidmdem

hoàn hảo đúng như những gì tôi đang tìm kiếm, một cách để chặn biểu mẫu bằng cách sử dụng angular
setebos

3

Mặc dù không phải là giải pháp trực tiếp cho câu hỏi OP, nếu biểu mẫu của bạn nằm trong ng-appngữ cảnh, nhưng bạn muốn Angular bỏ qua nó hoàn toàn, bạn có thể thực hiện điều này một cách rõ ràng bằng cách sử dụng lệnh ngNonBindable:

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

2

Chỉ cần thêm vào các câu trả lời ở trên,

Tôi đã có 2 nút thông thường như hình dưới đây. (Không có loại = "gửi" bất cứ nơi nào)

<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>

Cho dù tôi đã cố gắng bao nhiêu, nhấn enter một khi biểu mẫu hợp lệ , nút "Xóa biểu mẫu" được gọi, xóa toàn bộ biểu mẫu.

Như một cách giải quyết,

Tôi đã phải thêm một nút gửi giả đã bị vô hiệu hóa và ẩn. Và nút giả này phải nằm trên tất cả các nút khác như hình bên dưới .

<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>

Chà, ý định của tôi là không bao giờ gửi trên Enter, vì vậy bản hack đã cho ở trên chỉ hoạt động tốt.


bạn cũng có thể dừng gửi khi nhấn enter bằng cách xóa thuộc tính ng-submit khỏi biểu mẫu của bạn
Kieran

1

Tôi biết đây là một chủ đề cũ nhưng tôi nghĩ tôi cũng sẽ đóng góp. Giải pháp của tôi tương tự như bài viết đã được đánh dấu là một câu trả lời. Một số kiểm tra JavaScript nội tuyến thực hiện các mẹo.

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

1
Bạn vẫn có thể gửi biểu mẫu nếu bạn nhấn enter trong khi trường nhập liệu có trọng tâm!
Yevgeniy Afanasyev

0

Tôi biết đã muộn và đã được trả lời, nhưng tôi muốn chia sẻ những thứ gọn gàng tôi đã làm. Tôi đã tạo một lệnh ng-xác thực mà móc ra các phần tử của biểu mẫu, sau đó nó sẽ phát sinh lỗi mặc định nếu $ eval là sai:

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();            
    });
  };
});

Trong html của bạn:

<form name="offering" method="post" action="offer" ng-validate="<boolean expression">
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.