1

I have recently started working on AngularJS 1.6.

I am trying to submit a form programmatically. The reason is I want to validate a few fields (required field validation). I have spent a lot of efforts (probably 3-4 hours) trying to make this work but none of the existing answers on stack overflow or AngularJS docs seems to be working for me today (strange), hence I am posting this as last resort.

Below is my html

<form method="post" id="loginform" name="loginform" ng-submit="loginUser()" novalidate>
    <div>
        {{message}}
    </div>
    <div>
        <label>User Name</label>
        <input type="text" id="txtUserName" ng-model="user.UserName" name="user.UserName" />
    </div>
    <div>
        <label>Password</label>
        <input type="text" id="txtPassword" ng-model="user.Password" name="user.Password" />
    </div>
    <div>
        <input type="submit" id="btnLogin" title="Save" name="btnLogin" value="Login" />
    </div>
</form>

My angular code

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

demoApp.controller("homeController", ["$scope", "$timeout", function ($scope, $timeout) {   

    $scope.loginUser = function () {

        var form = document.getElementById("loginform");
        //var form = $scope.loginform; - tried this here...
        //var form = $scope["#loginform"]; tried this
        //var form = angular.element(event.target); - tried this...
        // tried a lot of other combinations as well...

        form.attr("method", "post");
        form.attr("action", "Home/Index");
        form.append("UserName", $scope.user.UserName);
        form.append("Password", $scope.user.Password);
        form.append("RememberMe", false);
        form.submit();
    };
}]);

I keep on getting error 'attr' is not a function.

All I need is submit a form using post method, with values. Just before that I am trying to intercept the submit call and check for validations.

I am open to try any other approach as well. Such as changing the input type from submit to button. Putting the input outside the form. I would be more than happy if validations and submit both can happen any which way. I just want it to post back the values after validating on the client side and then the server will take care of the redirect.

Note: I want the form to do a full postback so that I can get it to redirect to another form. (I know I could use Ajax, but some other day, may be!)

12
  • what validation you required Commented Mar 13, 2017 at 6:22
  • @bharatsavani savani Simple required field valdiations, for now Commented Mar 13, 2017 at 6:23
  • ok first remove both form.attr in you loginuser function add action in form tag Commented Mar 13, 2017 at 6:24
  • did just that, it postbacks, but doesn't carry the model values. Commented Mar 13, 2017 at 6:27
  • Should I be appending the form fields mannually? Commented Mar 13, 2017 at 6:28

5 Answers 5

2

1st of all avoid doing var form = document.getElementById("loginform");. Instead of using form.submit you can use the following code. Do it the angular way cheers :D

$scope.loginUser = function () {
  if($scope.loginform.$valid){
      user.rememberme=false;

       $http({
         url: 'Home/Index',
         method: "POST",
         data: user 
    })
    .then(function(response) {
        // success
    }, 
     function(response) { // optional
        // failed
    });

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

1 Comment

I was confined to do it the way I did (finally... phew), as doing the angular way would have required me to change the back end C# code, which was to be avoided. I know it's not the angular way, but that's for another time I guess. The project I am working on is not a SPA. I would have loved it to be a SPA and would have lived happily ever after. :D Cheers!
1

this is a code to validation if validation not complate button is not enable

<form method="post" id="loginform" name="loginform" ng-submit="loginUser()" novalidate>
<div>
    {{message}}
</div>
<div>
    <label>User Name</label>
    <input type="text" id="txtUserName" required ng-model="user.UserName" name="UserName" />
</div>
<div>
    <label>Password</label>
    <input type="text" id="txtPassword" ng-model="Password" name="user.Password"required />
</div>
<div>
    <input type="submit"  ng-disabled="myForm.UserName.$invalid || myForm.Password.$invalid" id="btnLogin" title="Save" name="btnLogin" value="Login" />
</div>
</form>

7 Comments

I have checked this, disabling the button approach. I would accept it as a last option. Because my application users are used to click on the buttons and see validations getting fired. I do not want to change that behaviour as long as possible.
you have make a manual javascript function to validate your validation and show to user
Okay, if that's the only way then I'll probably work in that direction.
make a function of validate and check all inputs value in javascript
please up vote for me if you satisfied with my answer @DevrajGadhavi
|
1

You should use $scope when trying to access the form, something like $scope.loginform. But...... Take a look at ng-messages. Heres an example using ng-messages with your form:

<form id="loginform" name="loginform" ng-submit="loginUser()">
    <div>
        {{message}}
    </div>
    <div>
        <label>User Name</label>
        <input type="text" id="txtUserName" ng-model="user.UserName" name="user.UserName" required/>
        <div class="help-block" ng-messages="loginform.txtUserName.$error" ng-show="loginform.txtUserName.$touched">
            <p ng-message="required">Username is required.</p>
        </div>
    </div>
    <div>
        <label>Password</label>
        <input type="text" id="txtPassword" ng-model="user.Password" name="user.Password" required/>
        <div class="help-block" ng-messages="loginform.txtPassword.$error" ng-show="loginform.txtPassword.$touched">
            <p ng-message="required">Password is required.</p>
        </div>
    </div>
    <div>
        <input type="submit" id="btnLogin" title="Save" name="btnLogin" value="Login" ng-click="loginUser()" />
    </div>
</form>

Add ngMessages:

var demoApp = angular.module('demoApp', ['ngMessages']);

demoApp.controller("homeController", ["$scope", "$timeout", function ($scope, $timeout) {   

    $scope.loginUser = function () {
      if($scope.loginform.$valid){
        //Code to run before submitting (but not validation checks)
      } else{
         return false;
     }
    };
}]);

Don't forget to include ngMessages in your app declaration and include the ngMessages.js script file. Note how you can simply use HTML5 validators.

5 Comments

Disabling the button approach would be a last option. Because my application users are used to click on the buttons and see validations getting fired. I do not want to change that behaviour for them as long as possible.
I'd definitely give it a try with ngMessages and see what happens.
See edits, change the submit button to a regular button with a ngClick, and if the form is valid, submit the form.
Tried it, its posting back, but not getting the form values on the back end. Neither the validations are getting fired. No errors in the console :(
I tried with your latest edits as well. No luck in my case... Thank you for your help @garethb, I found what I needed somewhere else.
0

I found the thing I was looking for. In the end I had to create a directive for validating and then submitting. So I am posting it here as a whole answer.

My HTML

<div ng-controller="homeController" ng-init="construct()">    
    <form method="post" action="Index" role="form" id="loginform" name="loginform" ng-form-commit novalidate class="ng-pristine ng-invalid ng-invalid-required">
        <div class="form-group">
            <label for="UserName">User ID</label>
            <input autocomplete="off" class="form-control ng-valid ng-touched ng-pristine ng-untouched ng-not-empty"
                   id="UserName" name="UserName" ng-model="user.UserName" type="text" value=""
                   ng-change="userNameValidation = user.UserName.length == 0">
            <span class="field-validation-error text-danger" ng-show="userNameValidation">The User ID field is required.</span>
        </div>

        <div class="form-group">
            <label for="Password">Password</label>
            <input autocomplete="off" class="form-control ng-valid ng-touched ng-pristine ng-untouched ng-not-empty"
                   id="Password" name="Password" ng-model="user.Password" type="password" value=""
                   ng-change="passwordValidation = user.Password.length == 0">
            <span class="field-validation-error text-danger" ng-show="passwordValidation">The Password field is required.</span>
        </div>

        <div>
            <input type="button" id="btnLogin" title="Login" name="btnLogin" value="Login" ng-click="validateUser(loginform)" />
        </div>
    </form>
</div>

Look for ng-form-commit on the form element. It is the directive that I created.

My Angular code

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

demoApp.factory("commonService", function () {
    return {
        isNullOrEmptyOrUndefined: function (value) {
            return !value;
        }
    };
});

//This is the directive that helps posting the form back...
demoApp.directive("ngFormCommit", [function () {
    return {
        require: "form",
        link: function ($scope, $el, $attr, $form) {
            $form.commit = function () {
                $el[0].submit();
            };
        }
    };
}]);

demoApp.controller("homeController", ["$scope", "commonService", function ($scope, commonService) {

    $scope.construct = function construct() {
        $scope.user = { UserName: "", Password: "" };
    };

    $scope.userNameValidation = false;
    $scope.passwordValidation = false;
    $scope.isFormValid = false;

    $scope.validateUser = function ($form) {
        $scope.isFormValid = true;

        $scope.userNameValidation = commonService.isNullOrEmptyOrUndefined($scope.user.UserName);
        $scope.passwordValidation = commonService.isNullOrEmptyOrUndefined($scope.user.Password);

        $scope.isFormValid = !($scope.userNameValidation || $scope.passwordValidation);

        if ($scope.isFormValid === true) {
            $scope.loginUser($form);
        }
    };

    $scope.loginUser = function ($form) {
        $form.commit();
    };
}]);

I found the directive here

Comments

0

Example using Angular 1.5 components.

(function(angular) {
  'use strict';

  function DemoFormCtrl($timeout, $sce) {
    var ctrl = this;
    this.$onInit = function() {
      this.url = $sce.trustAsResourceUrl(this.url);
      /*$timeout(function() {
        ctrl.form.$$element[0].submit();
      });*/
    };

    this.validate = function(ev) {
      console.log('Running validation.');
      if (!this.form) {
        return false;
      }
    };
  }

  angular.module('app', [])
    .component('demoForm', {
      template: `
      <p>To run this demo allow pop-ups from https://plnkr.co</p>
      <hr>
      <p>AngularJS - submit form programmatically after validation</p>
      <form name="$ctrl.form" method="get" target="blank" action="{{::$ctrl.url}}" novalidate
       ng-submit="$ctrl.validate($event)">
        <input type='hidden' name='q' ng-value='::$ctrl.value'>
        <input type='hidden' name='oq' ng-value='::$ctrl.value'>
        <input type="submit" value="submit...">
      </form>`,
      controller: DemoFormCtrl,
      bindings: {
        url: '<',
        value: '<'
      }
    });

})(window.angular);

https://plnkr.co/edit/rrruj6vlWrxpN3od9YAj?p=preview

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.