Validating form using Angular when name field has dots and brackets - angularjs

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.

Related

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.

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.

Toggle Currency Format in AngularJS

Basically I am attempting to do is allow the user to choose to show dollar formatting or not. Easy enough, just use ng-class to toggle the class, right? Except that now in empty cells a dollar sign shows.
What about if we use a custom filter? Well, I don't really know a way to toggle the custom filter on or off.
Any suggestions would be helpful.
Here is the button that toggles the formatting (it runs a function that sets format to true or false).
<button class="btn format-toggle" ng-click="setFormat();">Show <span ng-show="format">Hours</span><span ng-hide="format">Dollars</span></button>
The code that I'm trying to affect
<table>
<tr ng-repeat="project in projects">
<td>{{project.name}}</td>
<td ng-repeat="month in project.months" ng-class="{dollar : format}">{{month.total}}</td>
</tr>
</table>
I actually answered my own question but I suppose I'll leave it up in case someone else finds it useful.
I ended up just using ng-class along with another condition to check that there was a value in the cell.
<td ng-repeat="month in project.months" ng-class="{dollar : format && month !== undefined}">{{month.total}}</td>
CSS:
.dollar:before{
content:'$';
}

AngularJS - Search Filter nested array

AngularJS newbie trying to limit a search filter to one very nested array item. Here's a shot of my output:
<div ng-controller="listController">
<input type="text" ng-model="searchMe" />
<table class="table">
<tr>
<th>Product Name</th>
<th>Color</th>
<th>Size</th>
<th>Features</th>
</tr>
<tr ng-repeat="p in prods | filter:searchMe">
<td>{{p.products.1.ProductName}}</td>
<td>{{p.products.1.Color}}</td>
<td>{{p.products.1.Size}}</td>
<td>
<ul ng-repeat="feats in p.features">
<li>{{feats}}</li>
</ul>
</td>
</tr>
</table>
</div>
Which displays all the items in the list correctly, including the additional features. Now there are at least another dozen items in the products array, including description, price, etc. The issue is if I search something in the box, it searches the entire array. Now I've tried changing the search input to:
<input type="text" ng-model="search.products.1.ProductName" />
<input type="text" ng-model="search.p.products.1.ProductName" />
<input type="text" ng-model="search.ProductName" />
However as soon as I type one character everything disappears. Yes I've also taken the "me" off the search filter (| filter:search). How can I bind the search to a specific item in a nested array? I'll also need to be able to search by features, but I'm hoping by solving this first it'll lead my to the features. Also my content is being pulled in by a json file if that makes a difference. The search features will eventually be checkboxes as well, and not text inputs, but I figure it shouldn't matter, I will still need to target the specific items (name, color, size, etc).
Thoughts/ideas/suggestions?
My solution for the time being is restructuring the json file. Maybe when my knowledge of Angular expands I'll be able to revisit.

ng-model table show data angularjs

I ma very beginner in Angularjs and pardon my silly mistakes. I have a table which shows data in three columns and i want to filter this table based on a condition and hide unnecessary data in one column which contains integers. I have used ng-show with some condition linked to ng-model and this is working perfect if i enter data in my ng-model only after loading total form. But, i want to show all the table data in the beginning and then hide unnecessary data based on ng-show condition.
How can i do this? I am struggling!
<tr ng-show= "change > val1 " ng-repeat="change in montlyProjection();" >
<td>some data</td>
<td class="number">some data</td>
<td class="number" ng-class="positiveNegative(convertToNumber(startBalance) + change)">some data</td>
</tr>
</strong><input type="text" ng-model="val1" placeholder="Enter Amount" />
<tr ng-show="((change > val1) || !val1)" ng-repeat="change in monthlyProjection()">
Try adding additional conditions to the ng-show directive. If !val doesn't work try using "angular.equals(val1,'')" or "angular.isDefined(val1)"

Resources