NoviceCoder
NoviceCoder

Reputation: 319

ng-required not working for enabled fields from disabled state

I am facing an issue with the Angular validation for fields which disables/enables on checkbox check.

The scenario in which it is failing is stated below:

Checkout page is having address fields and a checkbox which is checked by default and it means the shipping address and the billing address are same. If it is unchecked then I have to provide a billing address. I have a button which will show the payment option if the fields are filled up with correct data. The validation is working fine as long as the checkbox is checked. But it is failing to validate the billing address fields if the checkbox is unchecked.

What I have done:

I have disabled and hid the billing address fields if the checkbox is checked. Once unchecked, I am showing the billing address fields with all the fields in enabled and required state. The reason behind this is if I don't disable the fields then the hidden billing address fields are considered in the field validation.

The view page with the Angular validation:

<form class="form-horizontal address" name="addressForm" novalidate>
                <div class="panel-body">
                    <div class="form-group">
                        <div class="col-md-12">
                            <h4>Shipping Address</h4>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.country.$invalid && !addressForm.country.$pristine }">
                        <div class="col-md-12"><strong>Country:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="country" class="form-control" value="" ng-model="shipCountry" ng-required="true" />
                            <p ng-show="addressForm.country.$invalid && !addressForm.country.$pristine" class="help-block">Country name is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.fname.$invalid && !addressForm.fname.$pristine }">
                        <div class="col-md-12"><strong>Full Name:</strong></div>
                        <div class="col-xs-12">
                            <input type="text" name="fname" class="form-control" value="" ng-model="shipFullName" ng-required="true" />
                            <p ng-show="addressForm.fname.$invalid && !addressForm.fname.$pristine" class="help-block">Your name is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.address.$invalid && !addressForm.address.$pristine }">
                        <div class="col-md-12"><strong>Address:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="address" class="form-control" value="" ng-model="shipAddress" ng-required="true" />
                            <p ng-show="addressForm.address.$invalid && !addressForm.address.$pristine" class="help-block">Your address is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.city.$invalid && !addressForm.city.$pristine }">
                        <div class="col-md-12"><strong>City:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="city" class="form-control" value="" ng-model="shipCity" ng-required="true" />
                            <p ng-show="addressForm.city.$invalid && !addressForm.city.$pristine" class="help-block">Your city is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.state.$invalid && !addressForm.state.$pristine }">
                        <div class="col-md-12"><strong>State:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="state" class="form-control" value="" ng-model="shipState" ng-required="true" />
                            <p ng-show="addressForm.state.$invalid && !addressForm.state.$pristine" class="help-block">Your state is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.zip_code.$invalid && !addressForm.zip_code.$pristine }">
                        <div class="col-md-12"><strong>Zip / Postal Code:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="zip_code" class="form-control" value="" ng-model="shipPostal" ng-required="true" ng-pattern="/^[0-9]+$/" maxlength="7" />
                            <p ng-show="addressForm.zip_code.$invalid && !addressForm.zip_code.$pristine" class="help-block">Error in postal code field!!</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.phone_number.$invalid && !addressForm.phone_number.$pristine }">
                        <div class="col-md-12"><strong>Phone Number:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="phone_number" class="form-control" value="" ng-model="shipPhone" ng-required="true" maxlength="10"
                                ng-pattern="/^[0-9]+$/" />
                            <p ng-show="addressForm.phone_number.$invalid && !addressForm.phone_number.$pristine" class="help-block">Error in phone number field!!</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.email_address.$invalid && !addressForm.email_address.$pristine }">
                        <div class="col-md-12"><strong>Email Address:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="email_address" class="form-control" value="" ng-model="shipEmail" ng-required="true" ng-pattern="/^(([^<>()\[\]\\.,;:\s@']+(\.[^<>()\[\]\\.,;:\s@']+)*)|('.+'))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/" />
                            <p ng-show="addressForm.email_address.$invalid && !addressForm.email_address.$pristine" class="help-block">Error in email field!!</p>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-12">
                            <input type="checkbox" name="address" class="" value="" /> Save address
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-12">
                            <input type="checkbox" name="address" class="" value="" ng-model="billSameAsShip" ng-change="toggleBillAddressView()" />Billing Address same as Shipping Address
                        </div>
                    </div>
                </div>
                <!--SHIPPING METHOD END-->
                <!--BILLING METHOD START-->
                <div class="panel-body" ng-hide="billSameAsShip">
                    <div class="form-group">
                        <div class="col-md-12">
                            <h4>Billing Address</h4>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.bill_country.$invalid && !addressForm.bill_country.$pristine }">
                        <div class="col-md-12"><strong>Country:</strong></div>
                        <div class="col-md-12">
                            <input type="text" class="form-control" name="bill_country" value="" ng-model="billCountry" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
                            <p ng-show="addressForm.bill_country.$invalid && !addressForm.bill_country.$pristine" class="help-block">Your billing country is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.bill_fname.$invalid && !addressForm.bill_fname.$pristine }">
                        <div class="col-xs-12">
                            <strong>Full Name:</strong>
                            <input type="text" name="bill_fname" class="form-control" value="" ng-model="billFullName" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
                            <p ng-show="addressForm.bill_fname.$invalid && !addressForm.bill_fname.$pristine" class="help-block">Your full name is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.bill_address.$invalid && !addressForm.bill_address.$pristine }">
                        <div class="col-md-12"><strong>Address:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="bill_address" class="form-control" value="" ng-model="billAddress" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
                            <p ng-show="addressForm.bill_address.$invalid && !addressForm.bill_address.$pristine" class="help-block">Your billing address is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.bill_city.$invalid && !addressForm.bill_city.$pristine }">
                        <div class="col-md-12"><strong>City:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="bill_city" class="form-control" value="" ng-model="billCity" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
                            <p ng-show="addressForm.bill_city.$invalid && !addressForm.bill_city.$pristine" class="help-block">Your billing city is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.bill_state.$invalid && !addressForm.bill_state.$pristine }">
                        <div class="col-md-12"><strong>State:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="bill_state" class="form-control" value="" ng-model="billState" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
                            <p ng-show="addressForm.bill_state.$invalid && !addressForm.bill_state.$pristine" class="help-block">Your billing state is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.bill_zip_code.$invalid && !addressForm.bill_zip_code.$pristine }">
                        <div class="col-md-12"><strong>Zip / Postal Code:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="bill_zip_code" class="form-control" value="" ng-model="billPostal" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
                            <p ng-show="addressForm.bill_zip_code.$invalid && !addressForm.bill_zip_code.$pristine" class="help-block">Your billing zip/postal code is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.bill_phone_number.$invalid && !addressForm.bill_phone_number.$pristine }">
                        <div class="col-md-12"><strong>Phone Number:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="bill_phone_number" class="form-control" value="" ng-model="billPhone" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
                            <p ng-show="addressForm.bill_phone_number.$invalid && !addressForm.bill_phone_number.$pristine" class="help-block">Your billing phone number is required.</p>
                        </div>
                    </div>
                    <div class="form-group" ng-class="{ 'has-error' : addressForm.bill_email_address.$invalid && !addressForm.bill_email_address.$pristine }">
                        <div class="col-md-12"><strong>Email Address:</strong></div>
                        <div class="col-md-12">
                            <input type="text" name="bill_email_address" class="form-control" value="" ng-model="billEmail" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
                            <p ng-show="addressForm.bill_email_address.$invalid && !addressForm.bill_email_address.$pristine" class="help-block">Your billing email address is required.</p>
                        </div>
                    </div>
                </div>
                <div class="panel-footer">
                    <div class="form-group">
                        <div class="col-xs-12 text-right">
                            <button type="button" class="btn btn-primary btn-submit-fix" ng-click="gotoInvoice()">Show Payment Option</button>
                        </div>
                    </div>
                </div>
            </form>

Upvotes: 0

Views: 237

Answers (1)

JB Nizet
JB Nizet

Reputation: 691645

Don't use ng-hide. Use ng-if. ng-if will remove the fields from the form, which thus won't take them into accound when validating the form.

Upvotes: 2

Related Questions