27

Given this code:

<div ng-controller="MyCtrl">
    <form ng-submit="onSubmitted()">

    Header inputs:
        <input type="name" ng-model="sample" required/>
        <input type="name" ng-model="sampleX" required/>

        <input type="submit" value="This submit triggers validation. But I wanted to put this button at the end of the page"/>
    </form>

    <hr/>

    Some other form here. Think line items

    <hr />
    <a class="btn" ng-click="/* what could should be put here, so this can trigger the firt form's validation, then submit? */">Wanted this submit button to trigger the validation+submit on the form in which this button doesn't belong</a>


</div>


var app = angular.module('myApp', []);

function MyCtrl($scope) {

    $scope.onSubmitted = function() {
        alert('submitted!');
    };
}

I want the last button to trigger the validation(then submit when things are valid) on first form. As of now, only the button inside the form can trigger that form's validation and submission. Is there any possible way for a button outside the form to do that?

Live test: http://jsfiddle.net/dzjV4/1/

6 Answers 6

7

You can create directive which you can then attach to <a class="btn".... Check this jsfiddle

http://jsfiddle.net/dzjV4/2/

Note that I added to <input type='submit' id='clickMe'... and linked it with link at the bottom <a class='btn' linked="clickMe"...

Sign up to request clarification or add additional context in comments.

3 Comments

consider to add dispose to directive and detach click event from it
Nice +1 for new learning to me, it's good to know that it's possible to simulate event on angularjs. However, I don't want to rely on simulating a click on another button. What I wanted is to simulate submit(consequently triggers the validation prior to submitting). Though I can hide the button on first form, but it feels kludgy to me. If there's an API-way to simulate a submit+validation, I'll be more than happy to learn it, and I'll accept this as an answer
I think if you call document.getElementById("myformId").submit() it will not call client validation which is "built in" in modern browsers (HTML5). But, it will work if you make validation in your Model. However if you do that this way you will support all browsers, not just modern one.
3
    for (control of $scope.[form name].$$controls) {
        control.$setDirty();
        control.$validate();
    }

You can try the above codes. Make it running before submit.

1 Comment

this worked for me. it triggers the validators on the control. although I had to use $timeout to run this after the digest cycle due to variables being passed in to my validators
2

Ideally there'd be a programmatic way to cause validation to re-run across a form. I have not investigated that completely but had a situation that required multiple controls to be re-validated based on different data in the scope -- without the user interacting with the individual controls. This arose because the form had two action buttons which each required different validation rules be in play when they were clicked.

The UI requirement changed before I fully implemented forcing re-validation but before it did I got most of what I needed by copying and then re-setting the form's data. This forced re-validation across the form within the current scope. Basically, it's along the lines of the following (not tested, but taken from the code that was working). In this case the form's data was bound to the properties in one object.

var formData = $parse(<form's model>); 
var dataCopy = angular.copy( formData($scope) ); 
formData.assign( $scope, dataCopy );

Comments

1

This may or may not be acceptable, but if you can get away with the SUBMIT button being disabled until the form is completed, you can do this:

<form name="formName">
 <input ng-required="true" />
</form>
<button ng-click="someFunction()" ng-disabled="formName.$invalid" />

It's also worth noting that this works in IE9 (if you're worried about that).

Comments

1

Since my form fields only show validation messages if a field is invalid, and has been touched by the user:

<!-- form field -->
<div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }">

    <!-- field label -->
    <label class="control-label">Suffix</label>
    <!-- end field label -->
    <!-- field input -->
    <select name="Parent_Suffix__c" class="form-control"
        ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes"
        ng-model="rfi.contact.Parent_Suffix__c" />
    <!-- end field input -->
    <!-- field help -->
    <span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched">
        <span ng-message="required">this field is required</span>
    </span>  
    <!-- end field help -->
</div>
<!-- end form field -->

I was able to use this code triggered by a button to show my invalid fields:

// Show/trigger any validation errors for this step
angular.forEach(vm.rfiForm.stepTwo.$error, function(error) {
    angular.forEach(error, function(field) {
        field.$setTouched();
    });
});
// Prevent user from going to next step if current step is invalid
if (!vm.rfiForm.stepTwo.$valid) {
    isValid = false;
}

Comments

0

Give your form a name:

<div ng-controller="MyCtrl">
    <form name="myForm">
        <input name="myInput" />
    </form>
</div>

So you can access your form validation status on your scope.

app.controller('MyCtrl', function($scope) {
    $scope.myForm.$valid // form valid or not
    $scope.myForm.myInput // input valid or not
    // do something with myForm, e.g. display a message manually
})

angular doc

There is no way to trigger browser form behavior outside of a form. You have to do this manually.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.