bind different value to ng-model on some condition - angularjs

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.

Related

Angular Js orderBy with input values

I'm having issues with the orderBy filter. The following code will order my initiative column just fine. When I type a value into the input, the filter automatically begins ordering the values just as I want it to.
However, if I type a value into the input that raises that character higher in the list the input will close out before I can finish typing that value.
If the value I type into the input drops the character lower down the list then that input does not close and allows me to finish typing my value.
Can anyone explain this behavior?
<tr ng-repeat="char in localChars | orderBy: '-initiative'">
<td>{{char.name}}</td>
<td ng-hide='show' ng-click='show = true'>{{char.initiative}}</td>
<td ng-show='show'>
<input ng-blur='initiative(char)' ng-model='char.initiative' type="text">
</td>
</tr>
Here is what I believe is the sequence of events:
User types in input changing the value of char.initiative.
This causes the list to reorder via the ng-repeat.
The scope of the ng-repeat is re-initialized causing the local show variable to lose its value (remember, ng-repeat has its own scope).
To fix this you'll need to use ng-model-options to control when the model value actually gets updated. You can choose to update on blur or use a debounce. Here is how to update on blur (my recommendation). You can find info on debouncing at the link.
<input ng-blur="initiative(char)"
ng-model="char.initiative"
ng-model-options="{ updateOn: 'blur' }"
type="text" />

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>');

How to find out if input is valid without form in 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.

AngularJS ng-repeat with ng-change

I'm trying to have a way to catch the change of a variable inside of an ngRepeat so that I can modify other properties. So I have this HTML:
<tr ng-repeat="variable in variables">
<td>
<div ng-if="....">
<textarea ng-model="variable.u_field_values" ng-change="onChange(variable)">
Whenever they modify the text in that textarea, I need to update another value on the current variable that's being used. The change method doesn't seem to ever get fired though.
Try putting the ng-change ahead of the ng-model:
<textarea ng-change="onChange(variable)" ng-model="variable.u_field_values">
I have found that order sometimes matters. No idea why, though..

Angularjs ng-model nested inside ng-repeat updates all

This should be simple. For some reason, when using ng-model inside of ng-repeat it updates all ng-models inside that repeat loop.
Here's the code. Any ideas?
http://plnkr.co/edit/iAgrPwwBMilCyeReeLt9?p=info
Thanks.
Interesting!!!
Problem is that you are resetting row.field with an object from "$scope.columns"
in
<td>
<select ng-model="row.field" ng-options="column.title for column in columns"></select>
</td>
Here, row.field is reset with an object from $scope.columns and if you change this object in one row, as the other rows also use the same object, they repeat the same value.
You can change this model to row.field.type as
<td>
<select ng-model="row.field.type" ng-options="column.type as column.title for column in columns" ng-change="resetRow(row.field)"></select>
</td>
and define $scope.resetRow in your controller to reset other properties based on the field type.
Here is the updated plunker.
I would love to have a feature in ng-options to return a copy of
the object selected instead of the object reference to solve your problem though.

Resources