AngularJS: ¿Cómo configuro manualmente la entrada en $ válido en el controlador?

92

Usando el complemento TokenInput y usando la validación de formController incorporada de AngularJS.

En este momento estoy tratando de verificar si el campo contiene texto y luego establecer el campo como válido si lo tiene. El problema con el uso del complemento es que crea su propia entrada y luego un ul + li para stlying.

Tengo acceso a addItem (formname) y mis capacidades en el controlador, solo necesito configurarlo en $ valid.

Margen.

<form class="form-horizontal add-inventory-item" name="addItem">
     <input id="capabilities" name="capabilities" token-input data-ng-model="inventoryCapabilitiesAutoComplete" data-on-add="addCapability()" data-on-delete="removeCapability()" required>
     <div class="required" data-ng-show="addItem.capabilities.$error.required" title="Please enter capability."></div>
</form>

JS.

$scope.capabilityValidation = function (capability) {
  if (capability.name !== "") {
    addItem.capabilities.$valid = true;
    addItem.capabilities.$error.required = false;
  } else {
    addItem.capabilities.$valid = false;
    addItem.capabilities.$error.required = true;
  }
};

Estoy ejecutando la función CapacityValidation cuando TokenInput tiene algo ingresado y pasando el objeto.

EDITAR:

Descubrí que ng-model en mi entrada hace cosas y obtiene los resultados de autocompletar, por lo que no puedo hacer que ng-valid funcione ya que se basa en el modelo.

$scope.inventoryCapabilitiesAutoComplete = {
  options: {
    tokenLimit: null
  },
  source: urlHelper.getAutoComplete('capability')
};

No escribí esta implementación de autocompletar, ¿hay otra forma de hacer esto en la que tenga acceso al attr ng-model y mueva la función del modelo a otro lugar?

Christopher Marshall
fuente
1
Dado que su complemento está creando su propia entrada y ha escrito una función para hacer su propia validación, ¿por qué no usar su propia propiedad $ scope para la validación también? <div ... data-ng-show="capabilities_error" ...> En otras palabras, ¿hay alguna razón por la que desee / necesite usar FormController?
Mark Rajcok
2
Dado que todas mis otras formas lo están usando, me gustaría mantener el control que brinda. La entrada creada por el complemento realmente establece el valor en mi entrada original, que luego necesito verificar en mi validación, pero no actualiza el formularioController cuando hay un valor ingresado.
Christopher Marshall
Acorté el marcado a propósito para aislar la entrada. Tengo un montón de entradas más en esta misma forma.
Christopher Marshall
1
Bueno. ¿ addItem.capabilities.$valid = trueIntentó configurar addItem.capabilities. $ Error.required en true o false según corresponda?
Mark Rajcok
Probé ambos. Actualizaré mi pregunta para mostrarte. El $ valid y $ error.required se muestra como indefinido en mi punto de interrupción en el controlador, pero addItem.capabilities todavía tiene datos.
Christopher Marshall

Respuestas:

150

No puede cambiar directamente la validez de un formulario. Si todas las entradas descendientes son válidas, el formulario es válido, si no, no lo es.

Lo que debe hacer es establecer la validez del elemento de entrada. Al igual que;

addItem.capabilities.$setValidity("youAreFat", false);

Ahora la entrada (y por tanto el formulario) no es válida. También puede ver qué error causa invalidación.

addItem.capabilities.errors.youAreFat == true;
Umur Kontacı
fuente
1
¿Y si capabilitieses una variable? Tengo una matriz que contiene nombres de entrada y quiero recorrer el interior de la matriz y establecerlos como inválidos uno por uno: /
lightalex
1
¿A qué te refieres con variable? Está directamente vinculado al formulario en sí, no a los valores del formulario. Utiliza el nameatributo del formulario y el atributo de entrada id. Esto es diferente de los valores establecidos porngModel
Umur Kontacı
11
He encontrado la solución, pero esto era lo que quería decir:$scope.addItem['myVariableName'].$setValidity("youAreFat", false);
lightalex
Después de esto, parece que algunos campos de entrada ya no se validan al cambiar o desenfocar
Leonardo
4
En angular 1.4.7 y tuve que prefijar este código con $ scope ..$scope.addItem.capabilities.$setValidity("youAreFat", false);
Graham T
60

Las respuestas anteriores no me ayudaron a resolver mi problema. Después de una larga búsqueda, me encontré con esta solución parcial .

Finalmente resolví mi problema con este código para configurar el campo de entrada manualmente en ng-invalid (para configurarlo en ng-valid, configúrelo en 'verdadero'):

$scope.myForm.inputName.$setValidity('required', false);
notMyName
fuente
3
Hice lo mismo y funciona muy bien. Pero ahora tengo algunos problemas para revalidar el mismo campo. No cambia al estado cambiado, lo cual es muy molesto. Utilizo ng-model-options = "{updateOn: 'submit'}" para validar al hacer clic en un botón. Tiene alguna idea sobre esto?
OliverKK
1
@OliverKK deberá invocar $setValiditycon trueel segundo parámetro siempre que la entrada sea válida.
Bernhard Hofmann
10
no tiene sentido usar el rootscope, debería ser solo el alcance
Ryan M
1
Intenté una solución similar, pero el problema que encontré es que si luego trato de cambiar el valor del control en el formulario, sigue siendo inválido. En mi caso, ese control es una directiva con la selección interna. Si establezco el no válido para mi directiva (que es ng-form), entonces no puedo eliminar ese estado no válido.
Naomi
18

Encontré esta publicación con un problema similar. Mi solución fue agregar un campo oculto para mantener mi estado inválido para mí.

<input type="hidden" ng-model="vm.application.isValid" required="" />

En mi caso, tenía un bool anulable en el que una persona tenía que seleccionar uno de dos botones diferentes. si responden que sí, se agrega una entidad a la colección y el estado del botón cambia. Hasta que se respondan todas las preguntas (uno de los botones en cada uno de los pares tiene un clic) el formulario no es válido.

vm.hasHighSchool = function (attended) { 
  vm.application.hasHighSchool = attended;
  applicationSvc.addSchool(attended, 1, vm.application);
}
<input type="hidden" ng-model="vm.application.hasHighSchool" required="" />
<div class="row">
  <div class="col-lg-3"><label>Did You Attend High School?</label><label class="required" ng-hide="vm.application.hasHighSchool != undefined">*</label></div>
  <div class="col-lg-2">
    <button value="Yes" title="Yes" ng-click="vm.hasHighSchool(true)" class="btn btn-default" ng-class="{'btn-success': vm.application.hasHighSchool == true}">Yes</button>
    <button value="No" title="No" ng-click="vm.hasHighSchool(false)" class="btn btn-default" ng-class="{'btn-success':  vm.application.hasHighSchool == false}">No</button>
  </div>
</div>
James Fleming
fuente
2

Es muy simple. Por ejemplo: en su controlador JS use esto:

$scope.inputngmodel.$valid = false;

o

$scope.inputngmodel.$invalid = true;

o

$scope.formname.inputngmodel.$valid = false;

o

$scope.formname.inputngmodel.$invalid = true;

Todo funciona para mí para diferentes requisitos. Presiona si esto resuelve tu problema.

rahim.nagori
fuente