validate form with single message - angularjs

Here is my Code and so have many fields like this :
<input type="text" pInputText class="form-control" name="companyName" [(ngModel)]="company.Name" required #companyName="ngModel"
/>
<label>Company Name</label>
<p class="ui-message ui-messages-error ui-corner-all" *ngIf="(!companyName.valid && companyName.touched)">
Company Name is required
</p>
Instead of defining separate message for all mandatory/invalid fields, can't I use single message with place holder for field name? So whenever I want to change message, I can manage this with single line change.
e.g. "${field} is required, ${field} is not valid etc."
please give me a example if this can do

The first solution that crossed my mind was just wrap the error messages in a function:
var displayError = (field) => `${filed} is required`;
And on the HTML
<input type="text" pInputText class="form-control" name="companyName" [(ngModel)]="company.Name" required #companyName="ngModel"/>
<label>Company Name</label>
<p class="ui-message ui-messages-error ui-corner-all" *ngIf="(!companyName.valid && companyName.touched)">
{{ displayError('Company name') }}
</p>

Related

React ignores value attribute of input field

I have a react sign-up form. I want to set up an input (checkbox) that holds the value as some text - e.g:
<form onSubmit={this.validateStepTwo} id="registerForm">
<label htmlFor="short_bio">Tell the users a bit about yourself:</label>
<input type="textarea" name="short_bio" className="textarea-small"/>
<label htmlFor="bio_info">Tell the users who you are</label>
<input type="textarea" name="bio_info" className="textarea-large"/>
<label htmlFor="bio_exp">Tell the users what you did</label>
<input type="textarea" name="bio_exp" className="textarea-large"/>
<input type="checkbox" name="instructor" value="I want to be an instructor" />
<input type="submit" value="Register" className="submit"></input>
{this.state.errors !== null ? (
<h1 className="error">{this.state.errors}</h1>
) : ('')}
</form>
Where
<input type="checkbox" name="instructor" value="I want to be an instructor" />
should have a value of "I want to be an instructor" but it doesnt have anything.
I tried doing it like this:
<input ...>I want to be an instructor</input>
but that threw another error.
Is this a react thing or am i missing something in my code? Ive been on the computer for 13 hours so i wouldnt be surprised if i made a dumb mistake.
Checkbox input value is the one sent in the request and not the text that appears afterwards.
If you want it to be the text then do something like this
<input type="checkbox" name="instructor" value="instructor"> I want to be an instructor

Using protractor to test an angularjs app, how do i keep a reference to one of the rows of element.all when the array changes as I work with it?

I have an ng-repeat which has a new element added to it as soon as the existing "last" element is modified in any way. My protractor test looks something like this:
var emptyPerson = this.people.last() // this gets me the last row of the ng-repeat
emptyPerson.element(by.css('.firstName')).sendKeys('first'); // this sets the firstname correctly but then the app adds a new row to the ng-repeat because of the model change here.
emptyPerson.element(by.css('.lastName')).sendKeys('last'); // this sets the lastname of the new row instead of the row that emptyPerson previously referenced
Is there any way to essentially tell emptyPerson to stick to the same element until we're done with it?
Example HTML before firstname is edited:
<div ng-repeat="person in object.People" class="student ng-scope">
<div type="text" ng-model="person.FirstName" skip-label="true" placeholder="First" validator="svalidators[$index]" class="layout-default field field-FirstName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="First" ng-model="lModel.val" name="person-FirstName">
</div>
<div type="text" ng-model="person.LastName" skip-label="true" placeholder="Last" validator="svalidators[$index]" class="layout-default field field-LastName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="Last" ng-model="lModel.val" name="person-LastName">
</div>
example after firstname is edited:
<div ng-repeat="person in object.People" class="student ng-scope">
<div type="text" ng-model="person.FirstName" skip-label="true" placeholder="First" validator="svalidators[$index]" class="layout-default field field-FirstName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="First" ng-model="lModel.val" name="person-FirstName">
</div>
<div type="text" ng-model="person.LastName" skip-label="true" placeholder="Last" validator="svalidators[$index]" class="layout-default field field-LastName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="Last" ng-model="lModel.val" name="person-LastName">
</div>
<div ng-repeat="person in object.People" class="student ng-scope">
<div type="text" ng-model="person.FirstName" skip-label="true" placeholder="First" validator="svalidators[$index]" class="layout-default field field-FirstName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="First" ng-model="lModel.val" name="person-FirstName">
</div>
<div type="text" ng-model="person.LastName" skip-label="true" placeholder="Last" validator="svalidators[$index]" class="layout-default field field-LastName type-text">
<input type="text" ng-focus="myFocus()" ng-blur="myBlur()" class="form-control" placeholder="Last" ng-model="lModel.val" name="person-LastName">
</div>
This is how Protractor works internally. It searches for the element at the time an action is applied on the element. I am afraid you have to handle it "manually" and re-reference the desired repeater item.
To make things a little bit better in terms of coding, I would hide the first interaction with the repeater item part in a function - basically, touching the input for repeater to have one more item, then returning the item before last. Something along the lines:
var MyPageObject = function () {
this.people = element(by.repeater("person in object.People"));
this.touch = function () {
var emptyPerson = this.people.last();
emptyPerson.element(by.css('.firstName')).sendKeys('smth');
var newEmptyPerson = this.people.get(-2); // I think -1 would be the last
emptyPerson.element(by.css('.firstName')).clear();
return newEmptyPerson;
}
this.fillForm = function () {
var emptyPerson = this.touch();
emptyPerson.element(by.css('.firstName')).sendKeys('first');
emptyPerson.element(by.css('.lastName')).sendKeys('last');
}
}
Try saving to a variable before it changes:
var oldLastName = emptyPerson.element(by.css('.lastName'));
emptyPerson.element(by.css('.firstName')).sendKeys('first');
oldLastName.sendKeys('last');
Hope it helps

ng-model convert object to string

Being very new to Angular I have a kinda unusual request.
I have a bunch of input fields
<div class="blurb" ng:repeat="item in fieldData.postData">
<input type="text" class="form-control" ng-model="item.key" />
<input type="text" class="form-control" ng-model="item.operator" />
<input type="text" class="form-control" ng-model="item.value" />
</div>
The values of these fields inturn are bound to another field
<input name="finalVal" type="text" ng-model="fieldData.postData" />
All works fine and I get an object inside finalVal, but I want the object in string format. Is there a way to achieve it without any changes in my controller? The reason being finalVal is basically stored as a string in DB and I cannot modify the data type.
Appreciate the help

AngularJS Math issue

I am trying to do some math with user inputs.
I have this basic objets to start with
$scope.shape =
{id: 1, cx: 0, cy: 0, result: 0}
;
And the user can type the value of cx and cy into fields;
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
I want to multiply the 2 values cx and cy and show the result in another input.
<input type="text" class="form-control" id="A" ng-model="shape.cx * shape.cy">
This is working, I can see the the result in the field but I get an error;
Error: [ngModel:nonassign]
I would also like to asign this result to shape.result.
How can I set the value of shape.result to be shape.cx*shape.cy
See here it could be done like this :
SCENARIO 1 : Result on Button Click : (Procedural Approach)
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
<input type="button" class="form-control" ng-click="calculate()">
<input type="text" class="form-control" id="A" ng-model="shape.result">
$scope.calculate = function(){
$scope.shape.result = parseInt($scope.shape.cx) * parseInt($scope.shape.cy);
}
SCENARIO 2 : As soon as Value Changes in text boxes : (Direct Approach)
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
<input type="text" class="form-control" id="A" ng-model="parseInt(shape.cx) * parseInt(shape.cy)">
SCENARIO 3 : Using $watch : (Procedural Approach)
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
<input type="text" class="form-control" id="A" ng-model="shape.result">
$scope.$watch(function (){
$scope.shape.result = parseInt($scope.shape.cx) * parseInt($scope.shape.cy);
});
Note :
Scenario 3 is using $watch hence it should be not used untill and unless you're in real need of it.
Scenario 1 is best suited to you I think as it will make your concept.
Scenario 2 is a direct approach hence should be used after gaining some knowledge as well as experience(But it's short & best within 3 scenatios). It's a reference from #tapos answer
Thanks & Cheers
Well you need to watch for cy and cx changes and do the calculation when it change.
$scope.$watch('shape.cx', function() {
$scope.shape.result = $scope.shape.cx * $scope.shape.cy;
});
Example fiddle: http://jsfiddle.net/ccmf07k2/
Every language input field is string when a user enter any number in text box it is string
<input ng-model="shape.cx" type="text" class="form-control" id="cx">
<input ng-model="shape.cy" type="text" class="form-control" id="cy">
so you need some work in your result box ix
<input type="text" class="form-control" id="A" ng-model="parseInt(shape.cx) * parseInt(shape.cy)">
then you get your appropriate result

IBAN validation using ng-iban

I am trying to do IBAN validation. Before this step, the user gets to input the country (5 countries in this case) and then when the user enters the IBAN, it should validate depended on the country selected. I am currently trying to use ng-iban with one country (BH), but can't seem to get it to work. Any help is appreciated and I am also open to using iban.js library if anyone can provide some helpful tips for that. My code for the country selection and IBAN field is included. Thanks!
<div class="form-group col-md-3 required">
<label class ="control-label">Country of Treatment</label>
<select class="form-control" ng-model="formDetails.Country" ng-options="lookup.ID as lookup.NAME for lookup in lookupCountry" required>
</select>
<div class="form-group col-md-3 required">
<label class ="control-label" >iBAN</label>
<input ng-model="formDetails.IbanNumber" ng-required= "formDetails.PaymentType == 'Wire' " ng-readonly="formDetails.PaymentType == 'Cheque'" class="form-control" placeholder="Enter iBAN Number" ng-iban="[BH]" >
</div>

Resources