Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

$submitted is not set on sub ng-form #10071

Closed

Description

@luboid

Hi,

I have <form> with inner <ng-form>
when form is submitted inner <ng-form>.$submitted is not set to true only parent

Activity

  1. pkozlowski-opensource commented on Nov 15, 2014

    @pkozlowski-opensource
    Member

    I don't think we should expect the inner ngForm to behave exactly like the <form> thing. I guess we could fix this one but would be cool to know what is your real-life use-case?

  2. added this to the milestone on Nov 15, 2014
  3. luboid commented on Nov 15, 2014

    @luboid
    Author

    Hi

    I create wizard interface,
    there are two directives, which I use to show errors after form is submitted

            .directive('bkErrorText', function () {
                return {
                    require: '^form',
                    template: '<span></span>',
                    restrict: 'E',
                    link: function ($scope, $element, $attrs, ctrl) {
                        var inputCtrl = ctrl[$attrs.bkInputName];
                        if (!inputCtrl) {
                            throw 'Can\'t find input ' + $attrs.bkInputName + ' into form.';
                        }
    
                        function showErrorText(newValue, oldValue) {
                            if (inputCtrl.$invalid && (ctrl.$submitted || ctrl.$$parentForm.$submitted)) {
                                var i, key, e, etext = [], error = inputCtrl.$error;
                                for (i in error) {
                                    if (error[i]) {
                                        key = 'bkMsg' + angular.uppercase(i.charAt(0)) + i.substr(1);
                                        e = $attrs[key] || (key + ' no message text!');
                                        etext.push(e);
                                        etext.push('&nbsp;');
                                    }
                                }
                                $element.html(etext.join(''));
                                $element.removeClass('hidden');
                            }
                            else {
                                if (!$element.hasClass('hidden')) {
                                    $element.addClass('hidden');
                                    $element.html('');
                                }
                            }
                        };
    
                        $scope.$watchCollection(function () { return inputCtrl.$error; }, showErrorText);
                        $scope.$watch(function () {
                            return inputCtrl.$invalid && (ctrl.$submitted || ctrl.$$parentForm.$submitted);
                        }, showErrorText);
                    }
                };
            })
            .directive('bkHasError', function () {
                return {
                    require: '^form',
                    restrict: 'A',
                    scope: {
                        bkHasError: '@',
                        bkHasErrorClass: '@'
                    },
                    link: function ($scope, $element, $attrs, ctrl) {
                        var cssClass = $scope.bkHasErrorClass || 'has-error',
                            inputCtrl = ctrl[$scope.bkHasError];
    
                        $scope.$watch(function () {
                            return inputCtrl.$invalid && (ctrl.$submitted || ctrl.$$parentForm.$submitted);
                        }, function (newValue, oldValue) {
                            if (newValue) {
                                $element.addClass(cssClass);
                            }
                            else {
                                $element.removeClass(cssClass);
                            }
                        });
                    }
                };
            })
    <form class="form-horizontal" role="form" novalidate="novalidate" ng-submit="submitForm()">
        <tabset>
            <tab select="tabs['common']=true" deselect="tabs['common']=false" active="tabs['common']">
                <tab-heading ng-class="{'text-danger':tabsValid['common']===false}">
                    Общи
                </tab-heading>
                <ng-form name="common" bk-submit-valid="tabsValid['common']">
                    <div class="form-group" bk-has-error="amountBuy">
                        <label class="col-md-2 control-label" for="amountBuy">amountBuy</label>
                        <div class="col-md-3">
                            <input class="form-control bk-number-lg" id="amountBuy" name="amountBuy" type="text"
                                   ng-model="model.amountBuy"
                                   bk-number="15,2"
                                   bk-number-range="0.01,999999.99"
                                   ng-model-options="{ debounce: 300 }" />
                            <bk-error-text class="help-block"
                                           bk-input-name="amountBuy"
                                           bk-msg-required="Data is required ..."
                                           bk-msg-number="Number(15,2) ..."
                                           bk-msg-number-range="Number range from 0.01 to 999 999.99 ..." />
                        </div>
                    </div>
                    <!--
                        others input fields
                    -->
                </ng-form>
            </tab>
            <!--
                others tabs
            -->
        </tabset>
        <div class="col-md-offset-2 col-md-6">
            <button class="btn btn-default" type="button" ng-click="prevTab()">Prev</button>
            <button class="btn btn-default" type="button" ng-click="nextTab()">Next</button>
            <button class="btn btn-primary" type="submit" bk-disable-pristine>Save</button>
        </div>
    </form>
  4. added a commit that references this issue on Feb 10, 2015
    c901556
  5. added 2 commits that reference this issue on Mar 5, 2015
    ca613d8
    5d39b2e
  6. awerlang commented on Mar 13, 2015

    @awerlang

    Another approach is using css:

    .ng-submitted .ng-invalid {
    .... styles styles styles ...
    }

    or looping through all parent forms:

    while (form) form = form.$$parentForm;
  7. interstella-5555 commented on May 21, 2015

    @interstella-5555
    Contributor

    👍 I would like to see that too

    My rl scenario is that I have a form where I have directive that uses ng-form and inside it I also have another directive with some input fields. That second (most inner) directive requires form controller in link function and it is the form controller from the ng-form directive. I have validation messages showing on submitted form but the only form that gets $submitted flag is the most outer form. The ng-form controller has $submitted set to false and the validation messages are not shown.

  8. awerlang commented on May 21, 2015

    @awerlang

    @kwypchlo does the css I posted above solve your issue?

  9. stryju commented on May 21, 2015

    @stryju

    real life use-case:

    some form:

    <form ng-form="form1" ng-submit="save(form1)">
      <custom-fieldset model="model.firstname" required></custom-fieldset>
      <custom-fieldset model="model.lastname" required></custom-fieldset>
      <button>save</button>
    </form>

    custom-fieldset.html:

    <fieldset ng-form="form">
      <input name="name" required ng-model="ctrl.model">
      <ng-messages role="alert"
        for="(form.$submitted || form.name.$touched) &amp;&amp; form.name.$error">
        <ng-message when="required">please enter a name</ng-message>
      </ng-messages>
    </fieldset>
  10. 20 remaining items

  11. modified the milestones: 1.6.4, on Mar 8, 2017
  12. modified the milestones: 1.6.4, 1.7.0 on Mar 23, 2017
  13. nmschulte commented on Apr 18, 2017

    @nmschulte

    "bump"

    while (form) form = form.$$parentForm;

    FYI: This doesn't actually work -- the root FormController has a "noop form" set as its parent; different looping and/or conditional are required.
    (e.g. while (form.$$parentForm.hasOwnProperty('$submitted')) form = form.$$parentForm or such).

    Note, Angular doesn't expose a static binding for FormController (or any of the types it claims to in the documentation; NgModelController included), otherwise one could use types to check the $$parentForm for real-ness.

  14. Larvalis commented on Aug 21, 2017

    @Larvalis

    Another workaround I used was a watch:

    $scope.$watch('form.$$parentForm.$submitted', function (submitted) {
        if (submitted) {
            $scope.form.$setSubmitted(true);
        }
    });
    
  15. andremw commented on Aug 24, 2017

    @andremw

    My team got into a situation where we really needed the change from #15778, so what we did was to create a copy of our installed angular.js (say, angular-mod.js), applied the change from the PR and used npm's postinstall to overwrite the original angular.js file in node_modules (a simple cp angular-mod.js node_modules/angular/angular.js).

    Worked like a charm.

  16. added a commit that references this issue on Nov 7, 2017
    28f69af
  17. self-assigned this
    on Nov 10, 2017
  18. added 3 commits that reference this issue on Dec 11, 2017
    ecb48bc
    6bf01af
    8ae29a0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions