【问题标题】:Angular form.$invalid submit button not workingAngular form.$invalid 提交按钮不起作用
【发布时间】:2015-11-21 21:30:56
【问题描述】:

所以我的验证工作正常,按钮除外。我希望它们以不透明度变灰,直到所有内容都有效并且不确定我是否正确设置了 ng-class 和/或 ng-disabled 设置正确或两者兼而有之。

这里的问题更多的是每个功能。我有一些字段显示何时将其他字段下拉列表选择到特定项目。例如,“年龄”仅在选择特定选项时显示,而对于所有其他选项,则不显示。我在下面展示我的 HTML,然后展示我的 CSS。

是的,是一个冗长的表格,但希望大家能提供帮助!

我的表格:

<form class="addClaim" name="claimForm" novalidate ng-submit="saveClaim(claimInfo)" data-ng-model="claimInfo">
    <div class="form-group col-md-6 naviaInp">
        <label for="beneSelect">Select your benefit</label>
        <select class="form-control" name="beneSelect" id="beneSelect" ng-model="benefit" ng-options="item.descr for item in claim" required>
             <option value="">Please select a benefit....</option>
         </select>
        <input type="hidden" ng-model="claimInfo.benefitId" ng-change="{{ claimInfo.benefitId = benefit.id }}"/>
    </div>
    <div ng-show="claimForm.beneSelect.$dirty && claimForm.beneSelect.$error.required" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>this is a required field</span></p>
    </div>                  
    <div class="form-group col-md-8 naviaInp" ng-show="benefit.askSecIns == true" >
        <label for="secInc">Do you have secondary insurance</label>
        <div>
            <label class="radio-inline"><input type="radio" name="optradioSecIns" data-ng-model="claimInfo.isSecIns" value="true">yes</label>
            <label class="radio-inline"><input type="radio" name="optradioSecIns" data-ng-model="claimInfo.isSecIns" value="false">no</label>
        </div>
    </div>
    <div class="checkbox form-group col-md-8 naviaInp" ng-show="benefit.askResidual == true">
        <p>If you have a Health Care FSA, any residual amount not covered by the HRA will automatically be entered into the FSA. If you do not wish to have the residual amount entered into your Health Care FSA, please indicate </p>
        <label><input type="checkbox" name="residualAmount" data-ng-value="true" ng-model="claimInfo.isNoResId">
        <p>No, please do not enter residual amounts into my Health Care FSA</p>
        </label>
    </div>
    <div class="form-group col-md-6 naviaInp" ng-show="benefit.expenseTypes != null">
        <label for="beneTypeSelect">Select type of service</label>
        <select class="form-control" name="expenseType" id="beneServiceSelect" ng-model="expense" ng-options="item.descr for item in benefit.expenseTypes" required>
             <option value="">Please select a service....</option>
         </select>
         <input type="hidden" ng-model="claimInfo.expenseTypeId" ng-change="{{ claimInfo.expenseTypeId = expense.id }}" />
    </div>
    <div ng-show="claimForm.expenseType.$dirty && claimForm.expenseType.$error.required" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>this is a required field</span></p>
    </div>                  
    <div class="form-group naviaInp">
        <label for="start">Date of Service</label>
        <div>
            <input type="text" class="form-control" name="startDate" id="start" placeholder="--/--/----" data-ng-model="claimInfo.fromDate" style="width: 200px;" required>
            <span style="padding-left: 20px; padding-right: 20px;">To</span>
            <input type="text" class="form-control" id="end" placeholder="--/--/---- (optional)" data-ng-model="claimInfo.toDate" style="width: 200px;">
        </div>
    </div>
    <div ng-show="claimForm.startDate.$dirty && claimForm.startDate.$error.required" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>this is a required field</span></p>
    </div>                  
    <div class="form-group col-md-6 naviaInp">
        <label for="providerName">Provider Name</label>
        <input type="text" name="providerName" class="form-control " id="providerName" ng-maxlength="100" data-ng-model="claimInfo.provider" required>
    </div>
    <div ng-show="claimForm.providerName.$dirty && claimForm.providerName.$error.required" style="clear: both; margin-top: 8px;">
        <p class="claimError" style="color: #ab2328;"><i class="fa fa-exclamation-circle"></i><span style="padding-left: 10px; font-size: 14px; margin-bottom:: 25px;">this is a required field</span></p>
    </div>
    <div ng-show="claimForm.providerName.$dirty && claimForm.providerName.$error.maxlength" class="errorContainer" style="clear: both; margin-top: 8px;">
        <p class="claimError" style="color: #ab2328;"><i class="fa fa-exclamation-circle"></i><span style="padding-left: 10px; font-size: 14px; margin-bottom:: 25px;">must be less than 100 characters</span></p>
    </div>                      
    <div class="form-group col-md-6 naviaInp" ng-model="claimInfo.depId" ng-show="benefit.dependents != null">
        <label for="beneTypeSelect">Select dependant</label>
        <select class="form-control" name="depSelect" id="beneDepSelect" ng-model="dependent" ng-options="item.name for item in benefit.dependents" required>
             <option value="">Please select a dependant....</option>
         </select>
         <input type="hidden" ng-model="claimInfo.depId" ng-change="{{ claimInfo.depId = dependent.id }}" required />
    </div>
    <div ng-show="claimForm.depSelect.$dirty && claimForm.depSelect.$error.required" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>this is a required field</span></p>
    </div>                  
    <div class="form-group col-md-6 naviaInp" name="forWhom" ng-show="benefit.dependents == null">
        <label for="forWhom">For Whom</label>
        <input type="text" class="form-control" id="forWhom" ng-maxlength="100" data-ng-model="claimInfo.who" required >
    </div>
    <div ng-show="claimForm.forWhom.$dirty && claimForm.forWhom.$error.required" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>this is a required field</span></p>
    </div>
    <div ng-show="claimForm.forWhom.$dirty && claimForm.forWhom.$error.maxlength" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>a maximum of 100 characters are allowed</span></p>
    </div>  
    <div class="form-group col-md-4 naviaInp" name="age" ng-show="benefit.benefCode == 'DCFSA'">
        <label for="age">Age</label>
        <input type="text" class="form-control" id="age" data-ng-model="claimInfo.age" ng-maxlength="50" required>
    </div>
    <div ng-show="claimForm.age.$dirty && claimForm.age.$error.required" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>this is a required field</span></p>
    </div>
    <div ng-show="claimForm.age.$dirty && claimForm.age.$error.maxlength" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>a maximum of 50 characters are allowed</span></p>
    </div>                      
    <div class="form-group col-md-4 naviaInp">
        <label for="claimAmount">Amount</label>
        <input type="number" name="amount" class="form-control" id="claimAmount" data-ng-model="claimInfo.amount" required ng-pattern="/^\d{1,4}(\.\d{0,2})?$/">
    </div>
    <div ng-show="claimForm.amount.$dirty && claimForm.amount.$error.required" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>this is a required field</span></p>
    </div>
    <div ng-show="claimForm.amount.$dirty && claimForm.amount.$error.pattern" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>the amount must be between $0 and $10,000</span></p>
    </div>                      
    <div class="form-group col-md-8 naviaInp">
        <label for="claimComment">Comments</label>
        <textarea class="form-control" name="comment" rows="5" id="claimComment" placeholder="optional" ng-maxlength="500" data-ng-model="claimInfo.comments">
        </textarea>
    </div>
    <div ng-show="claimForm.comment.$dirty && claimForm.comment.$error.maxlength" class="errorContainer">
        <p class="claimError"><i class="fa fa-exclamation-circle"></i><span>a maximum of 500 characters are allowed</span></p>
    </div>                          
    <div class="fileArea col-md-8 naviaInp">
        <div>
            <p>Drag and drop or upload your documentation. Remember, we cannot review your claim without at least one piece of proper documentation for each claimed expense listed above. Be sure your documentation shows the date of service, type of service, and cost of service.</p>
        </div>
        <div ngf-drop ngf-select ng-model="files" class="drop-box"
            ngf-drag-over-class="'dragover'" ngf-multiple="true" ngf-allow-dir="true"
            accept="image/*,application/pdf"
            ngf-pattern="'image/*,application/pdf'"><p>Drag and drop your documents here or click to search for your documents and upload</p></div>
        <div ngf-no-file-drop><p>File Drag/Drop is not supported for this browser</p></div>
        <div>
            <p>Files:</p>
        </div>
        <div>
            <ul>
                <li ng-repeat="f in files" style="font:smaller">{{f.name}} {{f.$error}} {{f.$errorParam}} <a class="deleteHandle" ng-click="deleteFile($index)">&times;</a> </li>
            </ul>
        </div>
    </div>
    <div style="padding-bottom: 150px; clear: both;">
        <div class="checkbox col-md-8">
          <label><input type="checkbox" value="" ng-model="checked"><p>By checking this box, you agree to Navia's <a class="naviaLink" data-toggle = "modal" data-target = "#tcModal" >Terms and Conditions</a>.</p></label>
        </div>
        <div class="form-group" style="clear: both;">
            <input type="button" class="naviaBtn naviaBlue" ng-show="editMode == true" ng-click="updateClaim(claimInfo)" value="+ update claim" ng-disabled="claimForm.$invalid" ng-class="{'disabled-class': claimForm.$invalid}">
            <input type="button" class="naviaBtn naviaBlue" ng-show="editMode == false" ng-click="saveClaim()" value="+ add another claim" ng-disabled="claimForm.$invalid" ng-class="{'disabled-class': claimForm.$invalid}">
            <input type="button" class="naviaBtn naviaBlue" ng-disabled="!checked && claimForm.$invalid" ng-show="editMode == false" ng-class="{'disabled-class': !checked}" ng-click="saveAllClaims()" value="submit claim(s)">
        </div>
        <div>
            <input type="button" class="naviaBtn naviaRed" ng-click="cancel()" value="cancel">
        </div>
        <div data-ng-hide="message == ''" data-ng-class="(savedSuccessfully) ? 'alert alert-success' : 'alert alert-danger'">
            {{message}}
        </div>
    </div>
</form>

我尽可能地简化了代码,但仍然显示我在做什么。

还有我的 CSS:

.disabled-class {
    background-color: #999999;
    opacity: .30;
}

.disabled-class:hover {
    background-color: #999999;
    opacity: .30;
}

input.ng-invalid.ng-dirty {
    border: 1px solid red;
}

.errorContainer {
    clear: both; 
    margin-top: 8px;
}

.claimError {
    color: #ab2328;
}

.claimError > span {
    padding-left: 10px; 
    font-size: 14px; 
    margin-bottom:: 25px;
}

.disabled {
    background-color: #999999;
    opacity: .30;
}

.disabled:hover {
    background-color: #999999;
    opacity: .30;
}

这里应该发生的是,在所有必填字段都已输入并且输入在参数设置范围内之前,按钮将变为灰色并禁用。

【问题讨论】:

  • 抱歉不清楚您的问题是什么,您可以尝试改写一下吗?
  • 基本上,我的输入按钮永远不会显示为禁用,我认为这是因为我在所有需要的输入上设置了“必需”设置,但并非全部显示,因为取决于什么选中后,一些输入将显示,而另一些则不显示。
  • 哦,需要更改为 ng-required="true"
  • @Yeysides - 'ng-required = true' 和只是 'required' 是一样的。

标签: html css angularjs


【解决方案1】:

角度形式同时具有有效性和无效性属性。

实际上,所有角形元素都可以,它们是可嵌套的并且无效会冒泡。如果一个元素是无效的,那么直到表单本身的所有祖先都自动拥有$invalid == true

您可以通过$scope 中的名称来调用表单,属性分别为$valid$invalid

这是您表单的相关代码:

<form name="claimForm">
    // your form logic here
    <button type="submit" ng-disabled="claimForm.$invalid" />
</form>

更新:如果您的表单不符合您的要求,您应该对其进行调试:

  • 根据表单的逻辑将表单划分为字段集
  • 当您的每个字段集都有效时,您的表单有效
  • 分别测试每个字段集并添加一些 div 以显示每个字段集的 $valid$invalid 值,直到您对其进行排序

我还认为您通过在 html 级别使用内联条件逻辑为您的问题增加了不必要的复杂性。我会将它保存在控制器中,这样更容易理解和构建。

当某些事情的行为与您期望的不同时,console.log(it)

还有一件事:一旦变脏,元素将保持$dirty,无论是否禁用,除非您在其上调用$setPristine()。所以你应该尽量避免在 yoru 逻辑中使用$dirty,它可能会产生不必要的混淆。

大多数时候,value.length 和/或$valid 足以使表单工作。

【讨论】:

  • Andrei - 代码已经在里面了。因此,尚不清楚您要提出什么建议。如果您仔细查看输入,您会看到我的 ng-disabled="claimForm.$invalid" 在那里
  • @Mark,您说的是“不确定我是否正确设置了 ng-class 和/或 ng-disabled 设置是否正确或两者兼而有之”。我的回答指出了验证如何以角度形式工作。起泡部分很重要。请参阅我的答案的补充内容。
猜你喜欢
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 2018-03-09
  • 2017-03-13
  • 2015-03-27
相关资源
最近更新 更多