validar reactivos formularios formulario angularjs angularjs-directive tooltip angular-ui-bootstrap

reactivos - ¿Cómo se muestran los errores de entrada de formularios usando la información sobre herramientas de Bootstrap de UI de AngularJS?



validar formulario angular 4 (5)

Por ejemplo, tengo el formulario donde estoy mostrando errores de entrada de formulario .

Necesito mostrar la insignia roja (con ''hover para mostrar los errores'') cerca de la etiqueta de entrada si hay algunos errores. Si el usuario desplaza el cursor sobre esta insignia roja, verá la lista de errores usando la información sobre herramientas de la UI de Bootstrap de AngularJS . No quiero poner la lista de errores en el atributo tooltip-html-unsafe, porque no es conveniente editar y mantener.

Este código es más declarativo:

<validation-tooltip ng-show="appForm.number.$invalid && appForm.number.$dirty"> <ul> <li ng-show="appForm.number.$error.required">this field is required</li> <li ng-show="appForm.number.$error.number">should be number</li> <li ng-show="appForm.number.$error.min">minimum - 5</li> <li ng-show="appForm.number.$error.max">miximum - 20</li> </ul> </validation-tooltip>

que este código:

<span tooltip-html-unsafe="{{<ul><li>This field is required;</li><li>...</li></ul>}}">hover to show errors</span>

¿Cómo puedo escribir una directiva de información de validación usando la información sobre herramientas de Bootstrap de UI de AngularJS?

¿O tal vez puede sugerir otro enfoque para mantener los mensajes de error de validación?


en realidad solo puede usar la propiedad enable tooltip:

<div class="showtooltip" tooltip-placement="left" tooltip-enable="$isValid" tooltip="tooltip message"></div>


Excelente respuesta de @pixelbits. Usé sus directivas y las modifiqué ligeramente para permitir que la información sobre herramientas se muestre sobre la entrada real como lo solicitaron algunos usuarios.

angular.module(''app'') .directive(''validationTooltip'', [''$timeout'', function ($timeout) { function toggleTooltip(scope) { if (!scope.tooltipInstance) { return; } $timeout(function() { if (scope.errorCount > 0 && (scope.showWhen == undefined || scope.showWhen())) { scope.tooltipInstance.enable(); scope.tooltipInstance.show(); } else { scope.tooltipInstance.disable(); scope.tooltipInstance.hide(); } }); } return { restrict: ''E'', transclude: true, require: ''^form'', scope: { showWhen: ''&'', placement: ''@'', }, template: ''<div></div>'', controller: [''$scope'', function ($scope) { var expressions = []; $scope.errorCount = 0; this.$addExpression = function (expr) { expressions.push(expr); } $scope.$watch(function () { var count = 0; angular.forEach(expressions, function (expr) { if ($scope.$eval(expr)) { ++count; } }); return count; }, function (newVal) { $scope.errorCount = newVal; toggleTooltip($scope); }); }], link: function (scope, element, attr, formController, transcludeFn) { scope.$form = formController; transcludeFn(scope, function (clone) { var tooltip = angular.element(''<div class="validationMessageTemplate" style="display: none;"/>''); tooltip.append(clone); element.append(tooltip); $timeout(function () { scope.$field = formController[attr.target]; var targetElm = $(''[name='' + attr.target + '']''); targetElm.tooltip({ placement: scope.placement != null ? scope.placement : ''bottom'', html: true, title: clone, }); scope.tooltipInstance = targetElm.data(''bs.tooltip''); toggleTooltip(scope); if (scope.showWhen) { scope.$watch(scope.showWhen, function () { toggleTooltip(scope); }); } }); }); } } }]);

El principal cambio es que la directiva utiliza jQuery para encontrar el elemento de destino (que debe ser una entrada) mediante el atributo de name , e inicializa la información sobre herramientas en ese elemento en lugar del elemento de la directiva. También agregué una propiedad showWhen al alcance, ya que es posible que no siempre desee que su información sobre herramientas aparezca cuando la entrada no es válida (vea el ejemplo a continuación).

La directiva validationMessage no ha cambiado

angular.module(''app'').directive(''validationMessage'', function () { return { restrict: ''A'', priority: 1000, require: ''^validationTooltip'', link: function (scope, element, attr, ctrl) { ctrl.$addExpression(attr.ngIf || true); } } });

El uso en Html también es similar, con solo agregar showWhen cuando lo desee:

<div class="form-group" ng-class="{ ''has-error'' : aForm.note.$invalid && (aForm.note.$dirty) }"> <label class="col-md-3 control-label">Note</label> <div class="col-md-15"> <textarea name="note" class="form-control" data-ng-model="foo.Note" ng-required="bar.NoteRequired"></textarea> <validation-tooltip target="note" show-when="aForm.note.$invalid && (aForm.note.$dirty)"> <ul class="validation-list"> <li validation-message ng-if="$field.$error.required">Note required</li> </ul> </validation-tooltip> </div> </div>


Demo Fiddle

Directiva de validación de información sobre herramientas

ValidationTooltip es la directiva principal. Tiene las siguientes responsabilidades:

  1. Definir la plantilla de punta de herramienta a través de su contenido transcluido
  2. Mantenga un registro de las expresiones de validación para que puedan ser evaluadas con cada ciclo de resumen.
  3. Exponer una API de controlador para permitir que las directivas de valiationMessage se registren
  4. Proporcione un atributo ''objetivo'' en la directiva para especificar a qué campo de formulario se vinculará la insignia (y la información sobre herramientas asociada)

Notas adicionales

La plantilla de información sobre herramientas utiliza la función de transclusión de la función de enlace para vincular la plantilla al alcance de la directiva. Hay dos propiedades que están dentro del alcance al que se puede vincular la plantilla:

  1. $ form : Vinculado al modelo de formulario definido en el alcance principal. es decir $ scope.myForm
  2. $ field : Vinculado al modelo form.name en el alcance principal. es decir $ scope.myForm.myInput

Esto permite que la plantilla se vincule a propiedades de validación como $ valid, $ invalid, $ pristine, $ dirty y $ error sin hacer referencia directamente al nombre del formulario o al nombre del campo de entrada. Por ejemplo, todas las siguientes expresiones son expresiones de enlace válidas:

$ propiedades de formulario:

  • `$ form. $ valid`
  • `$ form. $ invalid`
  • `$ form. $ dirty`
  • `$ form. $ pristine`
  • `$ form. $ error.required` etc ...

$ propiedades de campo:

  • `$ campo. $ válido`
  • `$ campo. $ inválido`
  • `$ campo. $ sucio`
  • `$ campo. $ prístino`
  • `$ field. $ error.required` etc ...

Implementación Directiva

app.directive(''validationTooltip'', function ($timeout) { return { restrict: ''E'', transclude: true, require: ''^form'', scope: {}, template: ''<span class="label label-danger span1" ng-show="errorCount > 0">hover to show err</span>'', controller: function ($scope) { var expressions = []; $scope.errorCount = 0; this.$addExpression = function (expr) { expressions.push(expr); } $scope.$watch(function () { var count = 0; angular.forEach(expressions, function (expr) { if ($scope.$eval(expr)) { ++count; } }); return count; }, function (newVal) { $scope.errorCount = newVal; }); }, link: function (scope, element, attr, formController, transcludeFn) { scope.$form = formController; transcludeFn(scope, function (clone) { var badge = element.find(''.label''); var tooltip = angular.element(''<div class="validationMessageTemplate tooltip-danger" />''); tooltip.append(clone); element.append(tooltip); $timeout(function () { scope.$field = formController[attr.target]; badge.tooltip({ placement: ''right'', html: true, title: clone }); }); }); } } });

Directiva de mensajes de validación

La directiva validationMessage realiza un seguimiento de los mensajes de validación para mostrar en la información sobre herramientas. Utiliza ng-if para definir la expresión para evaluar. Si no se encuentra ng-if en el elemento, entonces la expresión simplemente se evalúa como verdadera (siempre se muestra).

app.directive(''validationMessage'', function () { return { restrict: ''A'', priority: 1000, require: ''^validationTooltip'', link: function (scope, element, attr, ctrl) { ctrl.$addExpression(attr.ngIf || true ); } } });

Uso en HTML

  1. Agregue un formulario con un atributo de nombre
  2. Agregue uno o más campos de formulario, cada uno con un atributo de nombre y una directiva ng-model.
  3. Declare un elemento <validation-tooltip> con un atributo de target referencia al nombre de uno de los campos del formulario.
  4. Aplique la directiva de validation-message a cada mensaje con una expresión de enlace ng-if opcional.

<div ng-class="{''form-group'': true, ''has-error'':form.number.$invalid}"> <div class="row"> <div class="col-md-4"> <label for="number">Number</label> <validation-tooltip target="number"> <ul class="list-unstyled"> <li validation-message ng-if="$field.$error.required">this field is required </li> <li validation-message ng-if="$field.$error.number">should be number</li> <li validation-message ng-if="$field.$error.min">minimum - 5</li> <li validation-message ng-if="$field.$error.max">miximum - 20</li> </ul> </validation-tooltip> </div> </div> <div class="row"> <div class="col-md-4"> <input type="number" min="5" max="20" ng-model="number" name="number" class="form-control" required /> </div> </div> </div>


La respuesta de @pixelbits es genial. Usé esto en su lugar:

<div class="form-group" ng-class="{ ''has-error'': form.name.$dirty && form.name.$invalid }"> <label for="name" class="col-sm-4 control-label">What''s your name?</label> <div class="col-sm-6"> <input class="form-control has-feedback" id="name" name="name" required ng-minlength="4" ng-model="formData.name" tooltip="{{form.name.$valid ? '''' : ''How clients see your name. Min 4 chars.''}}" tooltip-trigger="focus" tooltip-placement="below"> <span class="glyphicon glyphicon-ok-sign text-success form-control-feedback" aria-hidden="true" ng-show="form.name.$valid"></span> </div> </div>

La técnica es la información sobre herramientas de ui-bootstrap y establece el texto de la información sobre herramientas en '''' cuando sea válido.

http://jsbin.com/ditekuvipa/2/edit


Mi objetivo era aprovechar los mensajes ng y ui-bootstrap popover para obtener comentarios de validación. Prefiero el popover versus la información sobre herramientas, ya que muestra los estilos de bloque de ayuda más claramente.

Aquí está el código:

<!-- Routing Number --> <div class="form-group-sm" ng-class="{ ''has-error'' : form.routingNumber.$invalid && !form.routingNumber.$pristine }"> <label class="control-label col-sm-4" for="routing-number">Routing #</label> <div class="col-sm-8"> <input class="form-control input-sm text-box" id="routing-number" name="routingNumber" ng-model="entity.ROUTINGNUM" popover-class="help-block" popover-is-open="form.routingNumber.$invalid" popover-trigger="none" required uib-popover-template="''routing-number-validators''" string-to-number type="number" /> </div> <!-- Validators --> <script type="text/ng-template" id="routing-number-validators"> <div ng-messages="form.routingNumber.$error"> <div ng-messages-include="/app/modules/_core/views/validationMessages.html"></div> </div> </script> </div>

Aquí está el validationMessages.html

<span ng-message="required">Required</span> <span ng-message="max">Too high</span> <span ng-message="min">Too low</span> <span ng-message="minlength">Too short</span> <span ng-message="maxlength">Too long</span> <span ng-message="email">Invalid email</span>

Nota: tuve que actualizar a jQuery 2.1.4 para que funcione la directiva uib-popover-template.

Dependencias: