如何在提交按钮位于此表单之外时使用angularJs验证表单?

时间:2022-11-24 09:55:13

I have a form element created with AngularJS with a submit button within it and I would like to put this button outside of this form. How can I do that with Angular and have my form still validated?

我有一个使用AngularJS创建的表单元素,其中包含一个提交按钮,我想将此按钮放在此表单之外。我怎么能用Angular做到这一点并让我的表格仍然有效?

e.g main html code:

例如主要的HTML代码:

<div class="sd-chk-steps" ng-show="!step_03" ng-hide="step_03">

<!-- Panel Address -->
<div id="sd-p-chk-1" class="large-8 columns sd-p-chk">
  <div class="cover step_complete" ng-show="step_01" ng-hide="!step_01">
  </div>
  <sd-panel-address >
  <!-- first form -->
  </sd-panel-address>
</div>
<!-- /. Panel Address -->

<!-- Panel delivery -->
<div id="sd-p-chk-2" class="large-8 columns sd-p-chk">
  <div class="cover" ng-show="!step_01" ng-hide="step_01"></div>
  <sd-panel-delivery>
  <!-- second form -->
  </sd-panel-delivery>
  <div class="cover step_complete" ng-show="step_02" ng-hide="!step_02"></div>
</div>
<!-- /. Panel delivery  -->

<!-- Panel payment -->
<div id="sd-p-chk-3" class="large-8 columns sd-p-chk">
  <div class="cover" ng-show="!step_02" ng-hide="step_02"></div>
  <sd-panel-payment>
  <!-- third form -->
  </sd-panel-payment>
</div>
<!-- /. Panel payment -->

<!-- group botton submit -->
<div class="sd-chk-box">
    <div class="sd-chk-box-inner">

        <div class="large-8 columns sd-box-chk-btn sd-chk-btn-sm">
          <button ng-click="clickBtn(shipping.$valid)" type="submit" class="sd-chk-btn sd-button-cta" ng-disabled="shipping.$invalid">
            Next
          </button>
        </div>

        <div class="large-8 columns sd-box-chk-btn sd-chk-btn-sm">
          <button class="sd-chk-btn sd-button-cta" ng-click="clickBtnStep02(formDelivery.$valid)" ng-disabled="formDelivery.$invalid">
            NEXT
          </button>
        </div>

        <div class="large-8 columns sd-box-chk-btn sd-chk-btn-sm">
          <button class="sd-chk-btn sd-button-cta" ng-click="clickBtnStep03(payment.$valid)" ng-disabled="payment.$invalid">
            PLACE ORDER
          </button>
        </div>

    </div>
</div>
<!-- /. group botton submit -->

e.g form html code:

例如,形式html代码:

<form id="shipping" class="shipping" name="shipping" 
      novalidate
      ng-submit="form.submit(shipping.$valid)"
      ng-class="{'loading': form.submitting, 'is-el-dirty' : shipping.$dirty || shipping.dirty}">
      <fieldset>
        <div class="row">
          <div class="large-12 columns">
            <label>
              <input type="text" name="name" placeholder="Name" ng-model="form.data.name" required/>
            </label>
            <div class="error" ng-if="shipping.$submitted || shipping.name.$touched" ng-messages="shipping.name.$error">
                <p class="text-msg" ng-message="required">You did not enter your name</p>
            </div>
          </div>
          <div class="large-12 columns">
            <label>
              <input type="text" name="surname" placeholder="Surname" ng-model="form.data.surname" required/>
            </label>
            <div class="error" ng-if="shipping.$submitted || shipping.surname.$touched" ng-messages="shipping.surname.$error">
                <p class="text-msg" ng-message="required">You did not enter your Surname</p>
            </div>
          </div>
        </div>
      </fieldset>
</form>

e.g controller code:

例如控制器代码:

(function() {

  'use strict';

  /**
   * @ngdoc function
   * @name myApp.controller:globalCtrl
   * @description
   * # globalCtrl
   * Controller of the myApp
   */

  var myApp = angular.module('myApp');


  myApp.controller('globalCtrl', function($scope, $locale, $rootScope) {

      // Check if checkbox it's checked
      $scope.checked = true;

      // got to step 2
      $scope.clickBtn = function(form) {
          //valid form
          if (form === true) {
              console.log('Form is valid, $rootScope.step_01= ' + $rootScope.step_01);
              $rootScope.step_01 = true;
              $rootScope.notValidStpe_01 = true;
          }

          //invalid form
          if (form === false) {
              $rootScope.step_01 = false;
              $rootScope.notValidStpe_01 = false;
              console.log('Form is invalid, $rootScope.step_01= ' + $rootScope.step_01);
          }
      };

      // got to step 3
      $scope.clickBtnStep02 = function(form) {
          //valid form
          if (form === true) {
              console.log('Form is valid, $rootScope.step_02 "'+ $rootScope.step_02);
              $rootScope.step_02 = true;
              $rootScope.notValidStpe_02 = true;

          }

          //invalid form
          if (form === false) {
              $rootScope.step_02 = false;
              $rootScope.notValidStpe_02 = false;
              console.log('Form is invalid, $rootScope.step_02= ' + $rootScope.step_02);
          }
      };


      // All steps completed
      $scope.clickBtnStep03 = function(form) {
          //valid form
          if (form === true) {
              console.log('Form is valid, $rootScope.step_03 "'+ $rootScope.step_03);
              $rootScope.step_03 = true;
              $rootScope.notValidStpe_03 = true;

          }

          //invalid form
          if (form === false) {
              $rootScope.step_03 = false;
              $rootScope.notValidStpe_03 = false;
              console.log('Form is invalid, $rootScope.step_03= ' + $rootScope.step_03);
          }
      };

  });

}(window, window.angular));enter code here

e.g app.js code

例如app.js代码

(function() {

    'use strict';


    var myApp = angular
        .module('myApp', [
            'ngResource',
            'ngAnimate',
            'ngMessages',
            'templates'
        ]);


    myApp.run(function($rootScope) {
        $rootScope.step_01 = false;
        $rootScope.step_02 = false;
        $rootScope.step_03 = false;

        $rootScope.notValidStpe_01 = false;
        $rootScope.notValidStpe_02 = false;
        $rootScope.notValidStpe_03 = false;
    });

}(window, window.angular));

4 个解决方案

#1


3  

As I understand You try to do form wizzard. However you don't need multiple form element, Just use one form element at the top. For child form use ng-form directive to valiadate them seperately.

据我了解你尝试做形式wizzard。但是,您不需要多个表单元素,只需在顶部使用一个表单元素。对于子表单,使用ng-form指令单独对其进行valiadate。

You can find detailed documentation https://docs.angularjs.org/api/ng/directive/ngForm about using ng-form

你可以找到关于使用ng-form的详细文档https://docs.angularjs.org/api/ng/directive/ngForm

Something like this

像这样的东西

 <form id="complateOrder" name="orderForm" ng-init="showShippingForm = true">

    <div ng-form="" name="shipping" ng-show="showShippingForm">
       shippig fields
    <button type="button" ng-disabled="shipping.$invalid" ng-click="showDeliveryForm=true">Next</button>
    </div>
    <div ng-form="" name="delivery" ng-show="showDeliveryForm && shipping.$valid" ng-hide="shipping.$invalid" >
       delivery fields
       <button type="button" ng-disabled="shipping.$invalid  && delivery.$invalid" ng-click="showPaymentForm=true">Next</button>
    </div>
    <div ng-form="" name="payment" ng-show="showPaymentForm && shipping.$valid && delivery.$valid " ng-hide="shipping.$invalid && delivery.$invalid">
       payment fields
       <button type="submit" ng-disabled="orderForm.$invalid && shipping.$invalid && payment.$invalid && delivery.$invalid">Submit All</button>
    </div>
    <div>
        <button type="button" ng-click="showPaymentForm ? (showPaymentForm = false; showDeliveryForm= true):showDeliveryForm ? (showDeliveryForm=false; showShippingForm = true):showShippingForm = true">Prev</button>
    </div>

 </form>

#2


22  

The clue is using the ngForm directive and assign a form name attribute which references to the $rootScope.

线索是使用ngForm指令并指定一个引用$ rootScope的表单名称属性。

<form name="$root.myForm" id="form_id">
    <input type="text" name="myField" required>
</form>

<button form="form_id" ng-disabled="$root.myForm.myfield.$invalid">
    Submit
</button>

That works.

这样可行。

#3


0  

If the submit button is outside of the form, then you can wrap your button and form with an ngForm (yes, ngForms can be nested). Give your ngForm a name so that you can handle the submit click and reference the form object by name in the same scope context

如果提交按钮位于表单之外,那么您可以使用ngForm包装您的按钮和表单(是的,ngForms可以嵌套)。为您的ngForm命名,以便您可以处理提交单击并在同一范围上下文中按名称引用表单对象

#4


0  

Even more concise than this answer:

比这个答案简洁得多:

<form name="myForm">
    <input type="text" name="myField" required>
</form>

<button ng-disabled="myForm.myField.$invalid">
    Submit
</button>

(Note that you don't even need to define myForm in the underlying controller and you can also omit the form attribute.)

(请注意,您甚至不需要在底层控制器中定义myForm,也可以省略form属性。)

#1


3  

As I understand You try to do form wizzard. However you don't need multiple form element, Just use one form element at the top. For child form use ng-form directive to valiadate them seperately.

据我了解你尝试做形式wizzard。但是,您不需要多个表单元素,只需在顶部使用一个表单元素。对于子表单,使用ng-form指令单独对其进行valiadate。

You can find detailed documentation https://docs.angularjs.org/api/ng/directive/ngForm about using ng-form

你可以找到关于使用ng-form的详细文档https://docs.angularjs.org/api/ng/directive/ngForm

Something like this

像这样的东西

 <form id="complateOrder" name="orderForm" ng-init="showShippingForm = true">

    <div ng-form="" name="shipping" ng-show="showShippingForm">
       shippig fields
    <button type="button" ng-disabled="shipping.$invalid" ng-click="showDeliveryForm=true">Next</button>
    </div>
    <div ng-form="" name="delivery" ng-show="showDeliveryForm && shipping.$valid" ng-hide="shipping.$invalid" >
       delivery fields
       <button type="button" ng-disabled="shipping.$invalid  && delivery.$invalid" ng-click="showPaymentForm=true">Next</button>
    </div>
    <div ng-form="" name="payment" ng-show="showPaymentForm && shipping.$valid && delivery.$valid " ng-hide="shipping.$invalid && delivery.$invalid">
       payment fields
       <button type="submit" ng-disabled="orderForm.$invalid && shipping.$invalid && payment.$invalid && delivery.$invalid">Submit All</button>
    </div>
    <div>
        <button type="button" ng-click="showPaymentForm ? (showPaymentForm = false; showDeliveryForm= true):showDeliveryForm ? (showDeliveryForm=false; showShippingForm = true):showShippingForm = true">Prev</button>
    </div>

 </form>

#2


22  

The clue is using the ngForm directive and assign a form name attribute which references to the $rootScope.

线索是使用ngForm指令并指定一个引用$ rootScope的表单名称属性。

<form name="$root.myForm" id="form_id">
    <input type="text" name="myField" required>
</form>

<button form="form_id" ng-disabled="$root.myForm.myfield.$invalid">
    Submit
</button>

That works.

这样可行。

#3


0  

If the submit button is outside of the form, then you can wrap your button and form with an ngForm (yes, ngForms can be nested). Give your ngForm a name so that you can handle the submit click and reference the form object by name in the same scope context

如果提交按钮位于表单之外,那么您可以使用ngForm包装您的按钮和表单(是的,ngForms可以嵌套)。为您的ngForm命名,以便您可以处理提交单击并在同一范围上下文中按名称引用表单对象

#4


0  

Even more concise than this answer:

比这个答案简洁得多:

<form name="myForm">
    <input type="text" name="myField" required>
</form>

<button ng-disabled="myForm.myField.$invalid">
    Submit
</button>

(Note that you don't even need to define myForm in the underlying controller and you can also omit the form attribute.)

(请注意,您甚至不需要在底层控制器中定义myForm,也可以省略form属性。)