How to validate an input in angular so that it does not show error in the others if they are shown with an ng-repeat?

0

I have the following html to be able to add phones to a contact, I make a validation with angular so that there are not registered phones with characters if not just numbers, the problem is that if I add two phones the first one correctly and the second incorrect, I send the error message in both, I do not know if that can be avoided with the structure I have.

        <div class="input-group select-phone" ng-repeat="tel in contacto.director.telefonos">
            <select name="otroTipoTel-director" ng-model="tel.tipotel" class="input_director" id="" ng-disabled="inputDirector">
                  <option value="">--Selecciona</option>
                  <option value="Asistente">Tel. Asistente</option>
                  <option value="Personal">Tel. Personal</option>
                  <option value="Fax">Tel. FAX</option>
                  <option value="Personal2">Tel. Personal 2</option>
                  <option value="Oficina">Tel. Oficina 2</option>
            </select>
            <!-- número de teléfono-->
            <input maxlength="12" id="otroTel-director" type="text" ng-disabled="inputDirector" class="input_director" ng-model="tel.telefono" placeholder="Teléfono" name="otroTelDir" mask="99-9999-9999" ng-pattern="/^\d{2}-\d{4}-\d{4}$/" ng-class="{invalid: formContactoDependencia.otroTelDir.$error.pattern}">
            <!-- extension del teléfono-->
            <input maxlength="80" id="otroExt-director" type="text" ng-disabled="inputDirector" class="input_director extension" ng-model="tel.extension" placeholder="Extensión" name="otroExtDir" ng-pattern="/^\d+$/" ng-class="{invalid: formContactoDependencia.extDirector.$error.pattern}">
            <!-- boton X para eliminar-->
            <a href="#" id="telDirector" class="dropIt Alagoma" ng-show="Xdirector" ng-click="quitarNuevo(contacto, contacto.director.telefonos.indexOf(t), $event)">X</a>
            <div ng-show="formContactoDependencia.otroTelDir.$error.pattern">
                <span class="error" >
                    El número de telefono no cumple con el formato correcto 
                </span>
            </div> 
            <div ng-show="formContactoDependencia.otroExtDir.$error.pattern">
                <span class="error" >
                     Introduce solo numeros en la extensión
                </span>
            </div> 
       </div>

I have the following button to add a new phone ...

         <div class="adiciona Alagoma" ng-show="Adirector" id="directorTelefono" ng-click="nuevoTelefono(telefonoDirector,contacto , $event)" ng-hide="contacto.director.telefonos.length>=4"> <!-- ng-hide="dess" -->
            <div><i class="icon director-telefono" ></i></div>
                <span>Agregar</span>
        </div>

Which only creates a new space in the fix contact.irector.telephones the scope that does it is the following ...

    //Scope para agregar un nuevo telefono
    $scope.nuevoTelefono = function (obj,contacto, e) {
        var e = e.target.id;
        console.log(e, "es el valor de ...")
        if(e == "directorTelefono") {
                console.log('Contacto --> ' + JSON.stringify(contacto));
                if(contacto.director){
                    if(contacto.director.telefonos){

                        if($.isArray(contacto.director.telefonos)){
                            if (contacto.director.telefonos.length < 4) contacto.director.telefonos.push({});
                        }else{
                            $scope.contacto.director.telefonos = [];
                            if (contacto.director.telefonos.length < 4) contacto.director.telefonos.push({});
                        }

                    }else{
                        contacto.director.telefonos = [];
                            if (contacto.director.telefonos.length < 4) contacto.director.telefonos.push({});
                    }
                }else{
                    contacto.director = "sdfsdfsd";
                    console.log(contacto.director)
                    contacto.director.telefonos = [];
                            if (contacto.director.telefonos.length < 4) contacto.director.telefonos.push({});
                }
        }
    };

    
asked by Alberto Rojas 14.12.2016 в 20:47
source

1 answer

2

If I'm not wrong, in angularjs it is still not possible to create dynamic ng-models in this case when there is a ng-repeat what I advise (which solves it very well is the following:

I defined an arrangement called% co_of% empty and created an array of contacts (since I do not know how you get them)

$scope.model = [];
$scope.contactos = [
    { id: 1, nombre: "Contacto 1", telefono: '' },
    { id: 2, nombre: "Contacto 2", telefono: '' }
];

Then I do a models on each and I assign values to $scope.contactos

angular.forEach($scope.contactos, function(index, contacto){
    $scope.model[index.id] = "";
});

This code creates an index within the $scope.model array with the ids of your contacts ...

It would be something like this, if you print $scope.models

{1 : '', 2: ''}

When you draw the form with the $scope.model it would be something like this:

<div ng-repeat="contacto in contactos">
    <p>Nombre : {{contacto.nombre}}</p>
    Telefono : <input type="text" ng-model="model[contacto.id]" placeholder="Ingrese telefono">
</div>

If you notice, the phone input carries the ng-repeat , which means that an item of ng-model=model[contacto.id] is now independent with another. This will help you to validate the phone that corresponds and not all, since your formerly you had for all ng-repeat that the same ng-repeat was generated.

Suppose that you get the data from a query to your server and IF the contact already has a phone number and that value comes in the query, it costs nothing to set it to your model, since it is proper and serious :

angular.forEach($scope.contactos, function(index, contacto){
    $scope.model[index.id] = index.telefono;
});

I leave you a codepen with this same example, so that you see it, what you should add now would be the validation that you created, but with that there would be no problem.

EDITING

As you can add more than 1 phone and it is a dynamic element I recommend the following:

Add to the contact object an arrangement called telephones (they may or may not come as your data corresponds)

The ng-model fix is no longer necessary.

$scope.contactos = [
       {id:1, nombre : "Contacto 1", telefonos : [{0 : '54565432'}]},
       {id:2, nombre : "Contacto 2", telefonos : [{}]}
];

To list them is as follows:

<div ng-repeat="contacto in contactos">
    <p>Nombre : {{contacto.nombre}}</p>
    Telefono :
    <button ng-click="agregarNumero(contacto)">Agregar numero</button>
    <div ng-repeat="tel in contacto.telefonos">
        <input type="text" placeholder="Ingrese telefono" ng-model="tel[$index]">
    </div>
</div>
<input type="button" value="enviar" ng-click="enviar()">

Add a button that has the function models and send it by parameter the contact that corresponds to agregarNumero and the function does the following:

$scope.agregarNumero = function(contacto){
    if(contacto.telefonos.length < 4){
      contacto.telefonos.push({});
    }
}

That does nothing more than add an empty object to the%% contact% of the contact without exceeding 4.

Finally the function ng-repeat prints the array telefonos

If you add as you add, an input is added to enter that phone

$scope.enviar = function(){
    console.log($scope.contactos);
}

You must add to

<input type="text" placeholder="Ingrese telefono" ng-model="tel[$index]">

The validation you have.

The codepen is also updated

EDIT 2

Trying to validate the regex with enviar in a $scope.contactos made me impossible so I did the following:

Create a ng-model called ng-repeat that basically evaluates if the match is met with the regex that you gave me.

var app = angular.module('mySuperApp', ['ionic'])
var PHONE_REGEXP = /^\d{2}-\d{4}-\d{4}$/;
app.directive('phone', function() {
    return {
        restrice: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ctrl) {
            angular.element(element).bind('blur', function() {
                var value = this.value;
                if (PHONE_REGEXP.test(value)) {
                    angular.element(this).next().css('display', 'none');
                    angular.element(this).css('background', 'none');
                } else {
                    angular.element(this).next().css('display', 'block');
                    angular.element(this).css('background', 'red');
                }
            });
        }
    }
})

In the view I did the following:

Leave everything inside the directive I put the attribute phone and add <form name="form> to the input (the name=phone remains the same)

Also add the following code:

<span style="display:none;">Por favor ingresa un numero valido.</span> 

Default hidden

If you say, in the data-phone I get an element that is ng-model that would be the directive where the user is writing .. to occupy angular.element(this) I get the next one that would be <input> if the validation with the next() is invalid, the element poongo the red background (only as an example, you can give another color, a class, etc) and I give <span> to regex that was hidden.

<form name="form" novalidate>
    <div ng-repeat="contacto in contactos">
        <p>Nombre : {{contacto.nombre}}</p>
        Telefono :
        <button ng-click="agregarNumero(contacto)">Agregar numero</button>
        <div ng-repeat="tel in contacto.telefonos">
            <input type="text" name="phone" class="telefono" data-phone placeholder="Ingrese telefono" ng-model="tel[$index]" />
            <span style="display:none;">Por favor ingresa un numero valido.</span> 
        </div>
    </div>
    <input type="button" value="enviar" ng-click="enviar()">
</form>
    
answered by 14.12.2016 / 21:07
source