twitter-bootstrap - strap - uib-pagination angularjs
Conciliar el estilo de validaciĆ³n de la forma Angular.js y Bootstrap (12)
Creo que es demasiado tarde para responder, pero espero que te encante:
CSS puede agregar otro tipo de controles como seleccionar, fecha, contraseña, etc.
input[type="text"].ng-invalid{
border-left: 5px solid #ff0000;
background-color: #FFEBD6;
}
input[type="text"].ng-valid{
background-color: #FFFFFF;
border-left: 5px solid #088b0b;
}
input[type="text"]:disabled.ng-valid{
background-color: #efefef;
border: 1px solid #bbb;
}
HTML : no es necesario agregar nada en los controles, excepto ng-required si es
<input type="text"
class="form-control"
ng-model="customer.ZipCode"
ng-required="true">
Inténtelo y escriba algo de texto bajo su control, lo encuentro realmente útil e increíble.
Estoy usando Angular con Bootstrap. Aquí está el código de referencia:
<form name="newUserForm" ng-submit="add()" class="" novalidate>
<input type="text" class="input" ng-model="newUser.uname" placeholder="Twitter" ng-pattern="/^@[A-Za-z0-9_]{1,15}$/" required></td>
<button type="submit" ng-disabled="newUserForm.$invalid" class="btn btn-add btn-primary">Add</button>
</form>
Bootstrap tiene estilos para campos no válidos en forma de input:invalid {.... }
; estos se activan cuando el campo está vacío. Ahora también tengo una coincidencia de patrones a través de Angular. Esto crea casos extraños cuando ": inválido" está desactivado, pero ".ng-inválido" está activado, lo que requeriría que vuelva a implementar las clases de arranque de CSS para la clase ".ng-inválida".
Veo dos opciones, pero tengo problemas con ambos
- Haz que Angular use algún nombre de clase personalizado en lugar de "ng-valid" (no sé cómo hacer esto).
- Deshabilitar la validación html5 (pensé que eso es lo que debe hacer el atributo "novalidate" en la etiqueta del formulario, pero no pude hacer que funcione por alguna razón).
Las directivas Angular-Bootstrap no cubren el estilo.
Es difícil decirlo con seguridad sin un violín, pero mirando el código angular.js no reemplaza las clases, simplemente agrega y elimina las suyas propias. Por lo tanto, cualquier clase de bootstrap (agregada dinámicamente por los scripts de la IU bootstrap) no debería ser alterada por angular.
Dicho esto, no tiene sentido utilizar la funcionalidad JS de Bootstrap para la validación al mismo tiempo que Angular: solo use Angular. Le sugiero que emplee los estilos bootstrap y el JS angular, es decir, agregue las clases bootstrap css a sus elementos usando una directiva de validación personalizada.
Gracias a @farincz por una excelente respuesta. Aquí hay algunas modificaciones que he hecho para encajar con mi caso de uso.
Esta versión proporciona tres directivas:
-
bs-has-success
-
bs-has-error
-
bs-has
(una conveniencia para cuando quiere usar los otros dos juntos)
Modificaciones que he hecho:
- Se agregó un cheque para mostrar solo los estados de estado cuando el campo de formulario está sucio, es decir, no se mostrarán hasta que alguien interactúe con ellos.
- Alterado la cadena pasada a
element.find()
para aquellos que no usan jQuery, comoelement.find()
en Angular''s jQLite solo soporta encontrar elementos por tagname. - Se agregó soporte para seleccionar cuadros y áreas de texto.
- Envuelto el
element.find()
en$timeout
para admitir casos en los que el elemento aún no tiene sus hijos representados en el DOM (por ejemplo, si un elemento secundario del elemento está marcado conng-if
). - Se modificó
if
expression para verificar la longitud de la matriz devuelta (if(input)
desde la respuesta de @ farincz siempre devuelve verdadero, ya que el retorno deelement.find()
es una matriz jQuery).
¡Espero que alguien lo encuentre útil!
angular.module(''bs-has'', [])
.factory(''bsProcessValidator'', function($timeout) {
return function(scope, element, ngClass, bsClass) {
$timeout(function() {
var input = element.find(''input'');
if(!input.length) { input = element.find(''select''); }
if(!input.length) { input = element.find(''textarea''); }
if (input.length) {
scope.$watch(function() {
return input.hasClass(ngClass) && input.hasClass(''ng-dirty'');
}, function(isValid) {
element.toggleClass(bsClass, isValid);
});
}
});
};
})
.directive(''bsHasSuccess'', function(bsProcessValidator) {
return {
restrict: ''A'',
link: function(scope, element) {
bsProcessValidator(scope, element, ''ng-valid'', ''has-success'');
}
};
})
.directive(''bsHasError'', function(bsProcessValidator) {
return {
restrict: ''A'',
link: function(scope, element) {
bsProcessValidator(scope, element, ''ng-invalid'', ''has-error'');
}
};
})
.directive(''bsHas'', function(bsProcessValidator) {
return {
restrict: ''A'',
link: function(scope, element) {
bsProcessValidator(scope, element, ''ng-valid'', ''has-success'');
bsProcessValidator(scope, element, ''ng-invalid'', ''has-error'');
}
};
});
Uso:
<!-- Will show success and error states when form field is dirty -->
<div class="form-control" bs-has>
<label for="text"></label>
<input
type="text"
id="text"
name="text"
ng-model="data.text"
required>
</div>
<!-- Will show success state when select box is anything but the first (placeholder) option -->
<div class="form-control" bs-has-success>
<label for="select"></label>
<select
id="select"
name="select"
ng-model="data.select"
ng-options="option.name for option in data.selectOptions"
required>
<option value="">-- Make a Choice --</option>
</select>
</div>
<!-- Will show error state when textarea is dirty and empty -->
<div class="form-control" bs-has-error>
<label for="textarea"></label>
<textarea
id="textarea"
name="textarea"
ng-model="data.textarea"
required></textarea>
</div>
También puede instalar el paquete Bower de Guilherme que reúne todo esto.
Las clases han cambiado en Bootstrap 3:
<form class="form-horizontal" name="form" novalidate ng-submit="submit()" action="/login" method="post">
<div class="row" ng-class="{''has-error'': form.email.$invalid, ''has-success'': !form.email.$invalid}">
<label for="email" class="control-label">email:</label>
<div class="col">
<input type="email" id="email" placeholder="email" name="email" ng-model="email" required>
<p class="help-block error" ng-show="form.email.$dirty && form.email.$error.required">please enter your email</p>
<p class="help-block error" ng-show="form.email.$error.email">please enter a valid email</p>
...
Tenga en cuenta las citas de ''has-error''
y ''has-success''
: tomó un tiempo para encontrar que ...
Mejora menor a la respuesta de @ farincz . Estoy de acuerdo con que una directiva es el mejor enfoque aquí, pero no quería tener que repetirla en cada elemento .form-group
, así que actualicé el código para permitir agregarlo al .form-group
o al <form>
padre <form>
elemento (que lo agregará a todos los elementos .form-group
):
angular.module(''directives'', [])
.directive(''showValidation'', [function() {
return {
restrict: "A",
link: function(scope, element, attrs, ctrl) {
if (element.get(0).nodeName.toLowerCase() === ''form'') {
element.find(''.form-group'').each(function(i, formGroup) {
showValidation(angular.element(formGroup));
});
} else {
showValidation(element);
}
function showValidation(formGroupEl) {
var input = formGroupEl.find(''input[ng-model],textarea[ng-model]'');
if (input.length > 0) {
scope.$watch(function() {
return input.hasClass(''ng-invalid'');
}, function(isInvalid) {
formGroupEl.toggleClass(''has-error'', isInvalid);
});
}
}
}
};
}]);
Mejora menor a la respuesta de Andrew Smith. Cambio los elementos de entrada y uso de palabra clave require
.
.directive(''showValidation'', [function() {
return {
restrict: "A",
require:''form'',
link: function(scope, element, attrs, formCtrl) {
element.find(''.form-group'').each(function() {
var $formGroup=$(this);
var $inputs = $formGroup.find(''input[ng-model],textarea[ng-model],select[ng-model]'');
if ($inputs.length > 0) {
$inputs.each(function() {
var $input=$(this);
scope.$watch(function() {
return $input.hasClass(''ng-invalid'');
}, function(isInvalid) {
$formGroup.toggleClass(''has-error'', isInvalid);
});
});
}
});
}
};
}]);
Mi mejora a la respuesta de Jason Im lo siguiente agrega dos nuevas directivas show-validation-errors y show-validation-error.
''use strict'';
(function() {
function getParentFormName(element,$log) {
var parentForm = element.parents(''form:first'');
var parentFormName = parentForm.attr(''name'');
if(!parentFormName){
$log.error("Form name not specified!");
return;
}
return parentFormName;
}
angular.module(''directives'').directive(''showValidation'', function () {
return {
restrict: ''A'',
require: ''form'',
link: function ($scope, element) {
element.find(''.form-group'').each(function () {
var formGroup = $(this);
var inputs = formGroup.find(''input[ng-model],textarea[ng-model],select[ng-model]'');
if (inputs.length > 0) {
inputs.each(function () {
var input = $(this);
$scope.$watch(function () {
return input.hasClass(''ng-invalid'') && !input.hasClass(''ng-pristine'');
}, function (isInvalid) {
formGroup.toggleClass(''has-error'', isInvalid);
});
$scope.$watch(function () {
return input.hasClass(''ng-valid'') && !input.hasClass(''ng-pristine'');
}, function (isInvalid) {
formGroup.toggleClass(''has-success'', isInvalid);
});
});
}
});
}
};
});
angular.module(''directives'').directive(''showValidationErrors'', function ($log) {
return {
restrict: ''A'',
link: function ($scope, element, attrs) {
var parentFormName = getParentFormName(element,$log);
var inputName = attrs[''showValidationErrors''];
element.addClass(''ng-hide'');
if(!inputName){
$log.error("input name not specified!")
return;
}
$scope.$watch(function () {
return !($scope[parentFormName][inputName].$dirty && $scope[parentFormName][inputName].$invalid);
},function(noErrors){
element.toggleClass(''ng-hide'',noErrors);
});
}
};
});
angular.module(''friport'').directive(''showValidationError'', function ($log) {
return {
restrict: ''A'',
link: function ($scope, element, attrs) {
var parentFormName = getParentFormName(element,$log);
var parentContainer = element.parents(''*[show-validation-errors]:first'');
var inputName = parentContainer.attr(''show-validation-errors'');
var type = attrs[''showValidationError''];
element.addClass(''ng-hide'');
if(!inputName){
$log.error("Could not find parent show-validation-errors!");
return;
}
if(!type){
$log.error("Could not find validation error type!");
return;
}
$scope.$watch(function () {
return !$scope[parentFormName][inputName].$error[type];
},function(noErrors){
element.toggleClass(''ng-hide'',noErrors);
});
}
};
});
})();
Los errores show-validation se pueden agregar a un contenedor de errores para que muestre / oculte el contenedor en función de la validez de los campos del formulario.
y el show-validation-error muestra u oculta un elemento basado en la validez de los campos de formulario en un tipo dado.
Un ejemplo de uso previsto:
<form role="form" name="organizationForm" novalidate show-validation>
<div class="form-group">
<label for="organizationNumber">Organization number</label>
<input type="text" class="form-control" id="organizationNumber" name="organizationNumber" required ng-pattern="/^[0-9]{3}[ ]?[0-9]{3}[ ]?[0-9]{3}$/" ng-model="organizationNumber">
<div class="help-block with-errors" show-validation-errors="organizationNumber">
<div show-validation-error="required">
Organization number is required.
</div>
<div show-validation-error="pattern">
Organization number needs to have the following format "000 000 000" or "000000000".
</div>
</div>
</div>
</form>
Otra solución: Crear directiva que alterna la clase de has-error
acuerdo con la entrada de un niño.
app.directive(''bsHasError'', [function() {
return {
restrict: "A",
link: function(scope, element, attrs, ctrl) {
var input = element.find(''input[ng-model]'');
if (input.length) {
scope.$watch(function() {
return input.hasClass(''ng-invalid'');
}, function(isInvalid) {
element.toggleClass(''has-error'', isInvalid);
});
}
}
};
}]);
y luego simple usarlo en la plantilla
<div class="form-group" bs-has-error>
<input class="form-control" ng-model="foo" ng-pattern="/.../"/>
</div>
Sé que este es un hilo de pregunta muy antiguo cuando no escuché el nombre de AngularJS :-)
Pero para otros que llegan a esta página buscando la validación de la forma Angular + Bootstrap de una manera limpia y automatizada, he escrito un módulo bastante pequeño para lograr lo mismo sin alterar el HTML o Javascript de ninguna forma.
Validación Angular Bootstrap de Checkout.
Los siguientes son los tres pasos simples:
- Instalar a través de Bower
bower install bootstrap-angular-validation --save
- Agregue el archivo de script
<script src="bower_components/bootstrap-angular-validation/dist/bootstrap-angular-validation.min.js"></script>
- Agregue la dependencia
bootstrap.angular.validation
a su aplicación y eso es todo!
Esto funciona con Bootstrap 3 y jQuery no es obligatorio .
Esto se basa en el concepto de validación jQuery. Este módulo proporciona cierta validación adicional y mensajes genéricos comunes para el error de validación.
Si el problema es el estilo, pero no desea deshabilitar la validación nativa, ¿por qué no anula el estilo con un estilo más específico ?
input.ng-invalid, input.ng-invalid:invalid {
background: red;
/*override any styling giving you fits here*/
}
¡Elimine sus problemas en cascada con la especificidad del selector de CSS!
Utilice la clase de "error" de Bootstrap para el diseño. Puedes escribir menos código.
<form name="myForm">
<div class="control-group" ng-class="{error: myForm.name.$invalid}">
<label>Name</label>
<input type="text" name="name" ng-model="project.name" required>
<span ng-show="myForm.name.$error.required" class="help-inline">
Required</span>
</div>
</form>
EDITAR: Como otras respuestas y comentarios señalan, en Bootstrap 3 la clase ahora tiene "error de has", no "error".
<div class="form-group has-feedback" ng-class="{ ''has-error'': form.uemail.$invalid && form.uemail.$dirty }">
<label class="control-label col-sm-2" for="email">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" ng-model="user.email" name="uemail" placeholder="Enter email" required>
<div ng-show="form.$submitted || form.uphone.$touched" ng-class="{ ''has-success'': form.uemail.$valid && form.uemail.$dirty }">
<span ng-show="form.uemail.$valid" class="glyphicon glyphicon-ok-sign form-control-feedback" aria-hidden="true"></span>
<span ng-show="form.uemail.$invalid && form.uemail.$dirty" class="glyphicon glyphicon-remove-circle form-control-feedback" aria-hidden="true"></span>
</div>
</div>
</div>