使用AngularJS,如何一次将所有表单字段设置为$ dirty?

马特·卡夏特

我已经使用AngularJS创建了HTML表单,并将required属性添加到了某些字段。

对于这些字段,如果字段不是$pristine,还会显示一条错误消息,并且$invalid

<input type="text" ng-model="SomeModel.SomeProperty" name="myField" class="input-block-level" required>
<p ng-show="frmMyForm.myField.$invalid && !frmMyForm.myField.$pristine" class="error-text">This field is required!</p>

这很好。但是,如果用户只是跳过了必填字段(从未将光标放在其中),则该字段始终是原始字段,因此即使单击提交按钮后也不会显示错误消息。因此,用户面对的是他们无法提交的表单,但是没有错误文本可以告诉他们原因。

我的想法是,将所有表单字段设置$dirty为Submit动作将触发错误消息,以显示用户只是跳过的任何必填字段。这可能吗?如果是这样,怎么办?

提前致谢。

贝耶斯

我们做的事情类似于您的答案,我们有一个formSubmitted指令绑定到submit事件,如果被触发,我们在表单控制器上设置$ submitted变量。这样,您可以使用与ShowValidationMessages类似的方式来使用它,但是它是可重用的。很简单的指令:

app.directive('formSubmitted', [function () {
    return {
        restrict: 'A',
        require: 'form',
        link: function (scope, element, attrs, ctrl) {
            ctrl.$submitted = false;
            element.on('submit', function () {
                scope.$apply(function () {
                    ctrl.$submitted = true;
                });
            });
        }
    };
}]);

您将此作为属性应用于表单标签本身。

我们采取了进一步的步骤,我们的要求是仅在以下条件成立时才显示验证错误:元素无效并且表单已提交或输入元素模糊。因此,我们最后得到了另一个要求ngModel的指令,该指令设置了ngModel控制器上元素的模糊状态。

最后,为了消除所有重复的html代码,以检查所有这些内容,例如,您ng-show="frmMyForm.myField.$invalid && (!frmMyForm.myField.$pristine || MyObject.ShowValidationMessages)"也将其封装到指令中。此模板指令使用Bootstrap样板包装我们的输入元素,并处理所有验证内容。所以现在我所有的表单输入都遵循以下模式:

<div data-bc-form-group data-label="Username:">
    <input type="text" id="username" name="username" ng-model="vm.username" data-bc-focus required />
</div>

和bcFormGroup指令将其转换为以下启用了引导程序的html:

<div class="form-group" ng-class="{'has-error': showFormGroupError()}" data-bc-form-group="" data-label="Username:">
    <label for="username" class="col-md-3 control-label ng-binding">Username:</label>
    <div class="col-md-9">
        <input type="text" id="username" name="username" ng-model="vm.username" data-bc-focus="" required="" class="ng-pristine form-control ng-valid ng-valid-required">
        <span class="help-block ng-hide" ng-show="showRequiredError()">Required</span>
    </div>
</div>

这使事情保持干燥,并为支持哪种类型的输入提供了极大的灵活性。

更新:

这是bcFormGroup指令的基本清单。默认模板使用引导程序的水平形式,但可以根据您的喜好进行调整。

app.directive('bcFormGroup', ['$compile', '$interpolate', function ($compile, $interpolate) {
  return {
    restrict: 'A',
    template:
        '<div class="form-group" ng-class="{\'has-error\': showFormGroupError()}">' +
            '<label for="{{inputId}}" class="col-md-3 control-label">{{label}}</label>' +
            '<div class="col-md-9">' +
                '<bc-placeholder></bc-placeholder>' +
            '</div>' +
        '</div>',
    replace: true,
    transclude: true,
    require: '^form',
    scope: {
        label: '@',
        inputTag: '@'
    },

    link: function (scope, element, attrs, formController, transcludeFn) {

        transcludeFn(function (clone) {
            var placeholder = element.find('bc-placeholder');
            placeholder.replaceWith(clone);
        });

        var inputTagType = scope.inputTag || 'input';
        var inputElement = element.find(inputTagType);
        var fqFieldName = formController.$name + '.' + inputElement.attr('name');
        var formScope = inputElement.scope();

        if (inputElement.attr('type') !== 'checkbox' && inputElement.attr('type') !== 'file') {
            inputElement.addClass('form-control');
        }

        scope.inputId = $interpolate(inputElement.attr('id'))(formScope);
        scope.hasError = false;
        scope.submitted = false;

        formScope.$watch(fqFieldName + '.$invalid', function (hasError) {
            scope.hasError = hasError;
        });

        formScope.$watch(formController.$name + '.$submitted', function (submitted) {
            scope.submitted = submitted;
        });

        if (inputElement.attr('data-bc-focus') != null || inputElement.attr('bc-focus') != null) {
            scope.hasBlurred = false;
            formScope.$watch(fqFieldName + '.$hasBlurred', function (hasBlurred) {
                scope.hasBlurred = hasBlurred;
            });
        }

        if (inputElement.attr('required')) {
            scope.hasRequiredError = false;
            formScope.$watch(fqFieldName + '.$error.required', function (required) {
                scope.hasRequiredError = required;
            });
            inputElement.after($compile('<span class="help-block" ng-show="showRequiredError()">Required</span>')(scope));
        }

        if (inputElement.attr('type') === 'email') {
            scope.hasEmailError = false;
            formScope.$watch(fqFieldName + '.$error.email', function (emailError) {
                scope.hasEmailError = emailError;
            });
            inputElement.after($compile('<span class="help-block" ng-show="showEmailError()">Invalid email address</span>')(scope));
        }

        scope.showFormGroupError = function () {
            return scope.hasError && (scope.submitted || (scope.hasBlurred === true));
        };

        scope.showRequiredError = function () {
            return scope.hasRequiredError && (scope.submitted || (scope.hasBlurred === true));
        };

        scope.showEmailError = function () {
            return scope.hasEmailError && (scope.submitted || (scope.hasBlurred === true));
        };

    }
  };
}]);

更新:

以下伪指令设置$ focused和$ hasBlurred:

app.directive('bcFocus', [function () {
    var focusClass = 'bc-focused';
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ctrl) {
            ctrl.$focused = false;
            ctrl.$hasBlurred = false;
            element.on('focus', function () {
                element.addClass(focusClass);
                var phase = scope.$root.$$phase;
                if (phase == '$apply' || phase == '$digest') {
                    ctrl.$focused = true;
                } else {
                    scope.$apply(function () {
                        ctrl.$focused = true;
                    });
                }
            }).on('blur', function () {
                element.removeClass(focusClass);
                var phase = scope.$root.$$phase;
                if (phase == '$apply' || phase == '$digest') {
                    ctrl.$focused = false;
                    ctrl.$hasBlurred = true;
                } else {
                    scope.$apply(function () {
                        ctrl.$focused = false;
                        ctrl.$hasBlurred = true;
                    });
                }
            });
        }
    };
}]);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何访问bootstrap-ui datepicker的$ dirty,$ dirty值?

来自分类Dev

如何在表单中重置$ dirty

来自分类Dev

如何设置记录Dirty ExtJs 6

来自分类Dev

如何通过实用地更改模型来将表单设置为$ dirty?

来自分类Dev

AngularJS Radio组未在字段上设置$ dirty

来自分类Dev

在angularjs中使用$ dirty来检查何时编辑表单

来自分类Dev

I_DIRTY和I_DIRTY_SYNC有什么区别

来自分类Dev

如何在自定义指令中将字段设置为$ dirty?

来自分类Dev

AngularJS,Karma-使用setPristine清除ng-dirty

来自分类Dev

AngularJS,Karma-使用setPristine清除ng -dirty

来自分类Dev

如何在指令中使用$ dirty获取ng-class?

来自分类Dev

角度形式:在自定义指令上设置$ dirty属性

来自分类Dev

输入类型为“文件”时,$ dirty无法正常工作

来自分类Dev

输入类型为“文件”时,$ dirty无法正常工作

来自分类Dev

失败,日食中的DIRTY_WORKTREE,如何解决?

来自分类Dev

写回缓存(“ dirty”)似乎被限制为甚至小于dirty_background_ratio。受什么限制?如何计算此限制?

来自分类Dev

修改ng-messages指令以仅在字段为$ dirty时显示

来自分类Dev

即使正在编辑输入,也不会将窗体设置为$ dirty

来自分类Dev

检测上一次更新期间属性值是否更改与Active Model Dirty不兼容

来自分类Dev

不允许使用$ dirty和$ pristine导航表单上的任何更改

来自分类Dev

当所有表单字段完成时,jQuery将图像添加到列表项一次

来自分类Dev

直到选中最后一个按钮,AngularJS单选按钮才标记为$ dirty

来自分类Dev

无法在Angular 1.x中观看表单$ dirty(或$ pristine)值

来自分类Dev

在提交表单时以编程方式将所有表单字段设置为ng-touch

来自分类Dev

无法访问form.inputName。$ dirty,其中inputName在具有隔离范围的指令模板内

来自分类Dev

ContentProvider(联系人)-没有此类列:metadata_dirty

来自分类Dev

什么是“ Dirty COW”错误,如何保护我的系统免受该错误?

来自分类Dev

无法使用/etc/sysctl.conf更改vm.dirty_ratio

来自分类Dev

如何一次将所有表列设置为 NOT NULL?

Related 相关文章

  1. 1

    如何访问bootstrap-ui datepicker的$ dirty,$ dirty值?

  2. 2

    如何在表单中重置$ dirty

  3. 3

    如何设置记录Dirty ExtJs 6

  4. 4

    如何通过实用地更改模型来将表单设置为$ dirty?

  5. 5

    AngularJS Radio组未在字段上设置$ dirty

  6. 6

    在angularjs中使用$ dirty来检查何时编辑表单

  7. 7

    I_DIRTY和I_DIRTY_SYNC有什么区别

  8. 8

    如何在自定义指令中将字段设置为$ dirty?

  9. 9

    AngularJS,Karma-使用setPristine清除ng-dirty

  10. 10

    AngularJS,Karma-使用setPristine清除ng -dirty

  11. 11

    如何在指令中使用$ dirty获取ng-class?

  12. 12

    角度形式:在自定义指令上设置$ dirty属性

  13. 13

    输入类型为“文件”时,$ dirty无法正常工作

  14. 14

    输入类型为“文件”时,$ dirty无法正常工作

  15. 15

    失败,日食中的DIRTY_WORKTREE,如何解决?

  16. 16

    写回缓存(“ dirty”)似乎被限制为甚至小于dirty_background_ratio。受什么限制?如何计算此限制?

  17. 17

    修改ng-messages指令以仅在字段为$ dirty时显示

  18. 18

    即使正在编辑输入,也不会将窗体设置为$ dirty

  19. 19

    检测上一次更新期间属性值是否更改与Active Model Dirty不兼容

  20. 20

    不允许使用$ dirty和$ pristine导航表单上的任何更改

  21. 21

    当所有表单字段完成时,jQuery将图像添加到列表项一次

  22. 22

    直到选中最后一个按钮,AngularJS单选按钮才标记为$ dirty

  23. 23

    无法在Angular 1.x中观看表单$ dirty(或$ pristine)值

  24. 24

    在提交表单时以编程方式将所有表单字段设置为ng-touch

  25. 25

    无法访问form.inputName。$ dirty,其中inputName在具有隔离范围的指令模板内

  26. 26

    ContentProvider(联系人)-没有此类列:metadata_dirty

  27. 27

    什么是“ Dirty COW”错误,如何保护我的系统免受该错误?

  28. 28

    无法使用/etc/sysctl.conf更改vm.dirty_ratio

  29. 29

    如何一次将所有表列设置为 NOT NULL?

热门标签

归档