2016-09-16 2 views
4

Это типичный пример использования нг-сообщений в AngularJS (1.x):AngularJS: Скрытие нг-сообщение до удара не кнопку формы подать

<form name="demoForm"> 
    <input name="amount" type="number" ng-model="amount" max="100" required> 

    <div ng-messages="demoForm.amount.$error"> 
    <div ng-message="required">This field is required</div> 
    </div> 

    <button type="submit">test submit</button> 
</form> 

см: http://jsfiddle.net/11en8swy/3/

Теперь я хочу изменить этот пример, поэтому ошибка «Это поле обязательна» отображается только при касании поля ($touched) или пользователь нажимает кнопку отправки.

Я не могу использовать класс ng-submitted в форме, так как ошибка проверки препятствует отправке формы.

Как мне это сделать?

Благодаря

+0

Вы можете установить форму в состояние 'pristine' на init, в вашем контроллере и показать ng-сообщение на $ dirty. Или цикл через поля формы, установив их на «первозданный». Вот как я решил это в моем случае. – Kindzoku

ответ

1

Вы можете сделать это с помощью ng-show:

<div ng-messages="demoForm.amount.$error" ng-show="demoForm.amount.$touched"> 
    <div ng-message="required">This field is required</div> 
</div> 

и использовать собственную директиву. Смотрите рабочую демо:

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

 
app.controller('mainCtrl', function($scope) { 
 

 
}); 
 
app.directive('hasFocus', function($timeout) { 
 
    return { 
 
    restrict: 'A', 
 
    require: 'ngModel', 
 
    link: function(scope, element, attr, ctrl) { 
 
     element.on('focus', function() { 
 
     $timeout(function() { 
 
      ctrl.hasFocusFoo = true; 
 
     }) 
 
     }); 
 

 
     element.on('blur', function() { 
 
     $timeout(function() { 
 
      ctrl.hasFocusFoo = false; 
 
     }) 
 
     }); 
 
    } 
 
    } 
 
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-messages.js"></script> 
 

 
<body ng-app="app" ng-controller="mainCtrl"> 
 
    <form name="demoForm"> 
 
    <input name="amount" type="number" ng-model="amount" max="100" required has-focus> 
 

 
    <div ng-messages="demoForm.amount.$error" ng-show="demoForm.amount.$touched || demoForm.amount.hasFocusFoo"> 
 
     <div ng-message="required">This field is required</div> 
 
    </div> 
 

 
    <button type="submit">test submit</button> 
 
    </form> 
 
</body>

директива в основном установить другой hasFocusFoo поле на контроллере ngModel, то можно легко использовать эту директиву.

+0

Я тебя не понял. Как здесь имеет место состояние '$ error', когда вы просто хотите показать/скрыть сообщение о фокусе/размытии. –

+0

Подтверждает ли проверка, что нетронутые поля в состоянии' $ touched'? – Kindzoku

+0

Состояние '$ touched' установлено, когда вы потеряли фокус с этого поля –

0

А, наконец, на ПК.

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

<form name="mc.form"> 
    <input type="text" name="empty" ng-model="mc.empty" required /> 
    <label ng-show="mc.form.empty.$dirty && mc.form.empty.$error.required">i'm empty</label> 
</form> 

MainController.$inject = ['$timeout']; 
function MainController($timeout) { 
    var vm = this; 

    $timeout(function(){ 
     vm.form.$setPristine(); 
    }); 

    vm.submit = function(){ 
     if(vm.form.$valid){ 
      alert('yay'); 
     }else{ 
      (vm.form.$error.required || []).forEach(function(f){ 
       f.$dirty = true; 
      }); 
     } 
    } 
} 

Вот как я справиться с этой задачей в моем решении. $ setPristine() - устанавливает поле в состоянии pristine, поэтому поле не $dirty и ошибка скрыта. Но после отправки я вручную укажу обязательные поля в состоянии $dirty, поэтому ошибки становятся видимыми. +, если вы введете что-нибудь и удалите его после, ошибка будет видна без отправки формы.

+0

Это кажется сложным для реализации в каждой форме. Если я правильно понял, вам нужно будет продлить проверку в последней ветке else для каждого поля и каждой ошибки поля? – mvermand

+0

Ну, вы просто переключаетесь только на ошибки типа 'required', устанавливая em 'в' $ грязное' состояние.Это просто для случая, если вы не коснулись поля, прежде чем отправить его. Фактически в моем решении я использую директиву для этого случая, поэтому это очень компактное решение. – Kindzoku

+0

Я вижу, моя ошибка в том, что я перебираю все поля. О директиве: (как) вы вводите свой код в функцию отправки контроллера изнутри этой директивы? У вас есть образец кода? Спасибо – mvermand

Смежные вопросы