CapitanFindus CapitanFindus - 5 months ago 23
AngularJS Question

Validate form and show errors only for partially compiled input groups

I'm quite new to AngularJS ( ver 1 ). I've followed some courses and developed something on my own some months ago, but now I've started using it at work, and guess I've forgot something.

Guess I'm a newbie.

Anyway, this is my question:

I have a form which can be used to insert someone's data, and a button which allows the user to insert another "data section".

I've put some validation inside this form, and it's all working as expected, except for one thing: I need to show errors only for data sections which are uncompleted, not for those which all are empty.

This is my code:

app.js

(function () {
'use strict';

var app = angular.module("global_app", ['datePicker','ngMessages','ngAnimate','internationalPhoneNumber']);

app.controller('sostenitori', function () {
var _sost = this;
var _props = ['nome', 'cognome', 'location', 'email', 'professione', 'telnum', 'nascita'];
var _completed = [];
var _uncompleted = [];

_sost.validFields = false;
_sost.lista = [{}];

_sost.addSostenitore = function () {
_sost.lista.push({});
};

_sost.validateSost = function (form) {
_completed = [];
_uncompleted = [];
console.log(form.$error);
console.log(form);
var total = _sost.lista.length;
_sost.lista.forEach(function (obj) {
console.log(obj);
var filled = 0;
for (var i = 0; i < _props.length; i++) {
if (obj.hasOwnProperty(_props[i]) && obj[_props[i]] != '') {
filled++;
}
}
if (filled === _props.length) {
_completed.push(obj);
} else if (filled != 0) {
_uncompleted.push(obj);
}
});
if(_completed == 0 && _uncompleted == 0){
alert('No one inserted');
return false;
} else {
if(_uncompleted > 0){
return false;
} else {
console.log('submit');
}
}
console.log({
total: total,
completed: _completed,
uncompleted: _uncompleted
});
};

});

})();


HTML file

<div class="riga sostenitore" ng-repeat="sost in st.lista">
<h2>Sostenitore <span class="sostenitori-num">{{$index + 1}}</span></h2>
<div class="row">
<div class="col-1-2 leftbox">
<label class="col-1-3">Nome*</label>
<input type="text" ng-model="sost.nome" ng-pattern="/^[a-zA-Z ]*$/" name="no_{{$index}}" class="col-2-3" placeholder="Nome"
required/>
</div>
<div class="col-1-2 rightbox">
<label class="col-1-3">Cognome*</label>
<input type="text" ng-model="sost.cognome" ng-pattern="/^[a-zA-Z ]*$/" name="co_{{$index}}" class="col-2-3"
placeholder="Cognome" required/>
</div>
<div class="fumetto"
ng-show="st_f.no_{{$index}}.$error && st_f.$submitted"
ng-messages="st_f['no_'+$index].$error">
<div class="messaggio" ng-message="required">Inserisci il nome</div>
<div class="messaggio" ng-message="pattern">Inserisci un nome valido</div>
</div>
<div class="fumetto"
ng-show="st_f.co_{{$index}}.$error && st_f.$submitted"
ng-messages="st_f['co_'+$index].$error">
<div class="messaggio" ng-message="required">Inserisci il cognome</div>
<div class="messaggio" ng-message="pattern">Inserisci un cognome valido</div>
</div>
</div>
<div class="row">
<div class="col-full">
<div class="fumetto"
ng-show="st_f.lu_{{$index}}.$error && st_f.$submitted"
ng-messages="st_f['lu_'+$index].$error">
<div class="messaggio" ng-message="required">Inserisci un luogo</div>
</div>
<label class="col-1-3">Luogo di nascita*</label>
<input type="text" ng-model="sost.location" name="lu_{{$index}}" class="col-2-3" placeholder="Indirizzo" required/>
</div>
</div>
<div class="row">
<div class="col-full leftbox">
<div class="fumetto"
ng-show="st_f.dt_{{$index}}.$error && st_f.$submitted"
ng-messages="st_f['dt_' + $index].$error">
<div class="messaggio" ng-message="required">Inserisci una data di nascita</div>
<div class="messaggio" ng-message="pattern">La data di nascita deve avere un formato gg-mm-aaaa</div>
</div>
<label class="col-1-3">Data di nascita*</label>
<input type="text" ng-model="sost.nascita" ng-pattern="/[0-9]{2}-[0-9]{2}-[0-9]{4}/" name="dt_{{$index}}" class="col-2-3"
required/>
</div>
<div class="col-1-2 rightbox">
<div class="fumetto"
ng-show="st_f.pr_{{$index}}.$error && st_f.$submitted"
ng-messages="st_f['pr_' + $index].$error">
<div class="messaggio" ng-message="required">Inserisci una professione</div>
</div>
<label class="col-1-3">Professione*</label>
<input type="text" ng-model="sost.professione" name="pr_{{$index}}" class="col-2-3" placeholder="Professione" required/>
</div>
</div>
<div class="row border">
<div class="col-1-2 leftbox">
<div class="fumetto"
ng-show="st_f.em_{{$index}}.$error && st_f.$submitted"
ng-messages="st_f['em_' + $index].$error">
<div class="messaggio" ng-message="required">Inserisci un indirizzo email</div>
<div class="messaggio" ng-message="email">Inserisci una email valida</div>
</div>
<label class="col-1-3">Email*</label>
<input type="email" ng-model="sost.email" name="em_{{$index}}" class="col-2-3" placeholder="Email" required/>
</div>
<div class="col-1-2 rightbox">
<div class="fumetto"
ng-show="st_f.tl_{{$index}}.$error && st_f.$submitted"
ng-messages="st_f['tl_' + $index].$error">
<div class="messaggio" ng-message="required">Inserisci un numero di telefono</div>
<div class="messaggio" ng-message="pattern">Inserisci un numero valido</div>
</div>
<label class="col-1-3">Telefono*</label>
<input type="text" ng-model="sost.telefono" name="tl_{{$index}}" class="col-2-3" ng-pattern="/[0-9](.+)/"
international-phone-number preferred-countries="it" default-country="it" required />
</div>
</div>
</div>

Answer

I've solved it by checking for every single item property when form is submitted, so, those are the updated parts:

HTML code:
I've added another check inside the error messages part, the isIncomplete(object,propertyname) function, which you can find in the app.js

<div class="fumetto" 
    ng-show="st_f.tl_{{$index}}.$error && (st_f.$submitted && st.isIncomplete(sost,'telefono'))"
    ng-messages="st_f['tl_' + $index].$error">
    <div class="messaggio" ng-message="required">Inserisci un numero di telefono</div>
    <div class="messaggio" ng-message="pattern">Inserisci un numero valido</div>
</div>

Javascript code:
Only added this function

_sost.isIncomplete = function (item, prop) {
            var _incomplete = false;
            if (_uncompleted.length > 0) {
                _uncompleted.forEach(function (obj) {
                    if (obj.$$hashKey == item.$$hashKey) {
                        if (!item.hasOwnProperty(prop) || (typeof(item.prop) == 'undefined' || item.prop == '')) {
                            _incomplete = true;
                        }
                    }
                });
            }
            return _incomplete;
        };

Maybe it will help :)

Comments