How to find out if input is valid without form in AngularJS - angularjs

I've faced following issue:
I have a <table>, where <tr>'s a generated via ng-repeat, and each <tr> contains several <input> elements. Smth like this:
<table>
<tr ng-repeat="plan in plans">
<td>
<input ng-pattern="/^\d+((\.|\,)\d+)?$/" ng-model="plan.field1" ng-blur="updateRow(plan)">
</td>
<td>
<input ng-pattern="/^\d+((\.|\,)\d+)?$/" ng-model="plan.field2" ng-blur="updateRow(plan)">
</td>
</tr>
</table>
When user finishes editing input I want to update full row. But I want to do it only if this input is valid. I mean I want to execute updateRow(plan) only if this condition ng-pattern="/^\d+((\.|\,)\d+)?$/" is satisfied. Or maybe somehow check it within updateRow(). But I can't find a way to do it without forms.
1)Is there a way to do it? Or may be there is better way to implement my idea?
2)And also is there way to bind ng-blur to each input in a row? Because I have about 20 inputs in a row and it looks bad when there is such amount of repeating.
Thanks to everybody in advance!

So I solved the first question by using forms and ng-form. I put every tr element in separate tbody and applied ng-form to each tbody element.
So i believe that I have to use forms if I need validation.

Related

Change display text based upon value

I am displaying Errors on my Html page using Angular JS. The problem is I am receiving only error codes from the HTML . What are the various ways in which i can change the error code to the the Error text i like
<table>
<tr ng-repeat='item in errorsd'>
<td align="left" class="validationMsg"> {{item.message}}</td></tr>
</table>
If my item.message has one . I would like to display Beginner ,if its 2 Intermediate like that and so on . Should i use ng-if ? should i use ng-switch or should i input some logic on the controller side .
Should i use ng-if ?
ng-switch is more readable and hence a better option. Later when you look back at the code it will be intuitive to you and other developers about what this code does.
should i input some logic on the controller side .
Why put a logic in controller-side if the framework already provides a solution for such use-case?
I would do it like:
<table>
<tr ng-repeat='item in errorsd'>
<td ng-switch="item.message" align="left" class="validationMsg">
<span ng-switch-when="1">Beginner</span>
<span ng-switch-when="2">Intermediate</span>
<!-- and so on.. -->
</td>
</tr>
</table>
I say use a switch statement inside of your controller.
So depending on the value, the global message would change thus displaying the correct one when triggering the validation msg box to show.

bind different value to ng-model on some condition

I have started using Angular and don't have much experience in it.
I am stuck with an issue. I am using ng-show and ng-model.
its like
<tr ng-show="responseValid">
<td> <input id="nameId" ng-model="model.name"/> </td>
</tr>
I am pre-populating the value in model.name.
Now if response is valid the input tag is shown otherwise not.
but when I submit the form, nameId value is bind by ng-model="model.name"
Issue here is I want model.name should not contain any value if response is not Valid i.e when input tag is hidden. but its not happening.
How can I nullify/empty the value in model.name? Is there anything available that I can use in the tag itself?
You should use ng-if instead of ng-show I believe.
ng-if removes elements from the DOM while ng-show only sets display:none.
When your send your model, check the state of the validResponse and set your model data based in this
example:
$scope.sendModel = function(){
$scope.model.name = $scope.validResponse? $scope.model.name : '';
}
A more advanced example http://codepen.io/gpincheiraa/pen/mPzmxO
You can use ngSwitch or ngIf.
<tr ng-if="responseValid">
<td> <input id="nameId" ng-model="model.name"/> </td>
</tr>
If the condition is not met, angular will completely remove the DOM element, till the condition will meet.

ng-change does not work in the table row generated by ng-repeat

I have a simple table row.
The row is generated by below code.
<tr ng-init="cacheChanged">
<td>Expiration Period</td>
<td ng-repeat="system in tableData.regions[0].systems">
<input type="text" ng-model="system.cacheDuration" ng-change="cacheChanged=true">
<span>h</span>
</td>
<td>
<button type="button" ng-click="saveCache()" ng-disabled="!cacheChanged">Save</button>
</td>
</tr>
When any of the four values changed, the save button is supposed to be enabled. However, it is still disabled all the time. Anyone knows why? Thanks in advance!
In your case you should use $parent.cacheChanged instead of cacheChanged variable. As ng-repeat does create child scope for each loop while rendering DOM. In short the cacheChanged variable inside ng-repeat is not same as that of cacheChanged used there on button.
Markup
<td ng-repeat="system in tableData.regions[0].systems">
<input type="text" ng-model="system.cacheDuration" ng-change="$parent.cacheChanged=true">
<span>h</span>
</td>
There is better way to go for it will be using Dot rule while defining ng-model, look at this detailed answer here.

add table data <td> only to one row on ng-repeat

in a table with ng-repeat is it possible to add a cell only to one row?
in my code:
<tbody>
<tr ng-repeat="user in users ng-click="selectUser(user)">
<td>{{user.username}}</td>
<td><input type="text"....></td>
<td><input type="checkbox"...></td>
<td><input type="submit" ... ng-show="user==selectedUser" /></td>
</tr>
</tbody>
in this code I want the last td appears only on the selected row and does not affect other rows, is it possible? or it is JS or CSS thing ?
First off you should be using the controller as syntax, it automatically puts everything in the controller under 1 object, which can cause issues with Angular. But I don't think that's the issue here.
The user you select could be equal to the selectedUser, but if they aren't pointing to the same reference, they won't be able. If usernames are distinct I'd change the ng-show="user.username == selectedUser.username"
and that should work fine.
It is possible, it seems like your code is mostly correct, but you're using selectedUser as a function and as an object representation of user. Maybe your function would be called selectUser which would set $scope.selectedUser. ng-show="user == selectedUser" would make since then.
I'm personally not a big fan of having conditions in the view, so I'd have a function in the controller which does the comparison and returns true or false.
function isSelectedUser(user) {
return user == $scope.selectedUser;
}
then you can just use ng-show="isSelectedUser(user)"
Use JQuery to append the <td> on the selected row <tr>. The :nth-child() is an easy way for you to select a row.
var selectedRow = 2;
$('tbody tr:nth-child('+ selectedRow +')').append('<td><input type="submit" /></td>');

Validating form using Angular when name field has dots and brackets

The form to be validated is master detail i.e. it has two portions. master portion contains two fields while detail portion initially has two rows but they can be increased by pressing a button on DOM. The form looks like the following
The problem is that in detail portion I have to create the inputs using ng-repeat like
<div class="form-group">
<table style="margin-left:10%;">
<tr>
<th>Account id</th>
<th>Amount</th>
</tr>
<tr class="edit-row" ng-repeat ="entry in model.Entries">
<td>
<input type="text" ng-model="model.Entries[$index].AccountId" required name="Entries[{{$index}}].AccountId"/>
</td>
<td>
<input type="text" ng-model="model.Entries[$index].Amount" required name="Entries[{{$index}}].Amount"/>
<span class="field-validation-error text-danger" ng-show="transactionForm['Entries['{{$index}}'].Amount'].$invalid && transactionForm['Entries['{{$index}}'].Amount'].$dirty">
Amount is Required
</span>
</td>
</tr>
</table>
</div>
But the ng-show attribute is not working fine for the detail portion. This is because, I have dots (.) and brackets ([) in the name of input fields. How can I perform validation in such scenario. Someone may argue to change the names of the input but I have to use this convention for input names in the detail portion. In current code, I have used bracket notation in ng-show attribute of Amount field as described in This SO question, but to no avail. you can find complete example at plunker
Can you do something like this?
ng-show="model.Entries[$index].Amount === ''"
Rather than trying to check the form value check the actual model value. This will work assuming you are just checking to make sure there is a value other than the empty string. You will have to make the check more specific to what you are looking for. You can also set the type="number" if you only want to allow the user to enter a numeric value.

Resources