validacion - validar formulario javascript onclick
Obtener controles de formulario de FormController (4)
He encontrado una solución decente, pero aún no es lo que estaba buscando . He rescatado algún código de otro problema relacionado con la creación de objetos JSON a partir de cadenas, y propongo lo siguiente:
Esencialmente estoy nombrando mis campos de la misma manera que están vinculados al modelo, y luego construyendo un nuevo objeto para su presentación cuando se llama a form_submit.
En la demostración, si cambia cualquiera de los campos del formulario, luego presiona enviar, verá el objeto emergente con solo los valores sucios.
Necesito una forma de recorrer los controles registrados de un formulario AngularJS. Esencialmente, estoy tratando de obtener todos los $ $ controles sucios, pero no hay una matriz de controles (el FormController tiene una serie de propiedades / funciones diferentes además de contener los controles en sí mismos, cada uno como su propio objeto).
He estado buscando el código fuente, y veo que hay una matriz de controls
en el FormController que es exactamente la matriz que estoy buscando. ¿Hay alguna manera de obtener acceso a este valor o extender FormController para incluir una función que devuelva esta matriz de controls
?
Editar: demostración de Plnkr
Además, me di cuenta de que técnicamente podía verificar el primer carácter de la cadena clave por "$", pero me gustaría evitar eso en caso de que la directiva FormController / cambie en una versión futura de Angular.
Edición 2: Otra aclaración: Mi objetivo en todo esto es poder determinar qué campos específicos son $ dirty, ya sea al recorrer toda la lista de controles (sin incluir $ dirty, $ invalid, $ error, $ name, y otras propiedades que viven en el objeto Form como están) o extendiendo el FormController y creando una función que devuelve solo los controles que actualmente están sucios (y no son iguales a sus valores iniciales)
Edición 3: la solución que estoy buscando debe ser aplicable a formularios / modelos de diferentes estructuras. Los modelos en el alcance se generan a través de AJAX, por lo que su estructura ya está configurada (me gustaría evitar tener que codificar una nueva estructura para todos los datos que ya estoy recibiendo a través de AJAX). Además, estoy buscando utilizar este proceso de envío de formularios en múltiples formularios / modelos, y cada uno de ellos tiene diferentes estructuras JSON, ya que se aplican a diferentes entidades en nuestro Modelo de Objetos. Esta es la razón por la que he elegido pedir una forma de obtener acceso al objeto de controls
en el FormController (publicaré el código de FormController
continuación), porque es el único lugar donde puedo obtener una matriz plana de todos mis campos.
function FormController(element, attrs) {
var form = this,
parentForm = element.parent().controller(''form'') || nullFormCtrl,
invalidCount = 0, // used to easily determine if we are valid
errors = form.$error = {},
controls = [];
// init state
form.$name = attrs.name || attrs.ngForm;
form.$dirty = false;
form.$pristine = true;
form.$valid = true;
form.$invalid = false;
parentForm.$addControl(form);
// Setup initial state of the control
element.addClass(PRISTINE_CLASS);
toggleValidCss(true);
// convenience method for easy toggling of classes
function toggleValidCss(isValid, validationErrorKey) {
validationErrorKey = validationErrorKey ? ''-'' + snake_case(validationErrorKey, ''-'') : '''';
element.
removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey).
addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
}
/**
* @ngdoc function
* @name ng.directive:form.FormController#$addControl
* @methodOf ng.directive:form.FormController
*
* @description
* Register a control with the form.
*
* Input elements using ngModelController do this automatically when they are linked.
*/
form.$addControl = function(control) {
controls.push(control);
if (control.$name && !form.hasOwnProperty(control.$name)) {
form[control.$name] = control;
}
};
/**
* @ngdoc function
* @name ng.directive:form.FormController#$removeControl
* @methodOf ng.directive:form.FormController
*
* @description
* Deregister a control from the form.
*
* Input elements using ngModelController do this automatically when they are destroyed.
*/
form.$removeControl = function(control) {
if (control.$name && form[control.$name] === control) {
delete form[control.$name];
}
forEach(errors, function(queue, validationToken) {
form.$setValidity(validationToken, true, control);
});
arrayRemove(controls, control);
};
// Removed extra code
}
Como puede ver, el formulario en sí tiene la matriz de controls
disponible de forma privada. Me pregunto si hay alguna forma de extender el FormController
para que pueda hacer público ese objeto. ¿O crear una función pública para que al menos pueda ver la matriz privada?
intente simplemente con desde su controlador:
$scope.checkForm = function(myFormName){
console.log(myFormName.$invalid);
}
ACTUALIZAR:
<div ng-controller="MyController">
<form name="form" class="css-form" novalidate>
<input type="text" ng-model="user.uname" name="uname" required /><br />
<input type="text" ng-model="user.usurname" name="usurname" required /><br />
<button ng-click="update(form)">SAVE</button>
</form>
</div>
app.controller(''MyController'',function($scope){
$scope.user = {};
$scope.update = function (form){
var editedFields = [];
angular.forEach($scope.user, function(value, key){
if(form[key].$dirty){
this.push(key + '': '' + value);
}
}, editedFields);
console.log(editedFields);
}
});
Puede usar el siguiente código para iterar los controles:
var data = {};
angular.forEach(myForm, function (value, key) {
if (value.hasOwnProperty(''$modelValue''))
data[key] = value.$modelValue;
});
Para una solución directa a la pregunta, modifique la respuesta de @lombardo como tal;
var dirtyFormControls = [];
var myForm = $scope.myForm;
angular.forEach(myForm, function(value, key) {
if (typeof value === ''object'' && value.hasOwnProperty(''$modelValue'') && value.$dirty)
dirtyFormControls.push(value)
});
La matriz ''dirtyFormControls'' contendrá los controles de formulario que están sucios.
También puede usar este truco para mostrar los mensajes de error en el envío de formularios para las validaciones ''Requeridas'' y todas las demás. En su función submit (), hará algo como;
if (form.$invalid) {
form.$setDirty();
angular.forEach(form, function(value, key) {
if (typeof value === ''object'' && value.hasOwnProperty(''$modelValue''))
value.$setDirty();
});
//show user error summary at top of form.
$(''html, body'').animate({
scrollTop: $("#myForm").offset().top
}, 1000);
return;
}
Y en su forma mostrará mensajes de error con
<span ng-messages="myForm[''subject-'' + $index].$error" ng-show="myForm[''subject-'' + $index].$dirty" class="has-error">
<span ng-message="required">Course subject is required.</span>
</span>
La solución anterior es útil cuando tienes controles generados dinámicamente usando ''ng-repeat'' o algo similar.