AngularJS - Search Filter nested array - arrays

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.

Related

angularjs NgTable ng-repeat groupby with show/hide

I can't get the 'groupBy' working.
I have a data set returned from a $http factory. The data is passed to the $scope 'territoryReq' variable.
the data set looks like:
[{"Country":"Netherlands","Name":"firstName lastName","Phone":"+12345678","Mobile":"+987654321"},{"Country":"Netherlands","Name":"firstName2 lastName2","Phone":"+12345678","Mobile":"+987654321"}]
I have a simple 'dump' of the data by using:
<div>
<table ng-table="" class="table table-condensed table-bordered table-hover">
<tr class="ng-table-group" ng-repeat="entries in territoryReq">
<td>
{{entries.Country}}
</td>
<td>
{{entries.Name}}
</td>
<td>
{{entries.Phone}}
</td>
<td>
{{entries.Mobile}}
</td>
</tr>
</table>
</div>
This is all working. No problem.
Now I want to have the results grouped by Country. Preferably by being able to click on the country which then unhides the rows with the correct country.
I was looking at the example of example of ng-table with grouping
But I can't get it working for my data..
In the example they use e.g. group in $groups but I can't figure out where $groups come from?
Anyway, I hope someone can help me in the right direction...
thanks!
For straight up grouping, groupBy takes an object property as the parameter. It should be as simple as
<tr class="ng-table-group" ng-repeat="entries in territoryReq | groupBy: 'Country'">
But it sounds more like you want to filter the list based on criteria, like country.
I mocked this up to demonstrate what I think you're looking for. Please take a look and see if it helps... It has ordering via the table headers and filtering from a dynamic list of countries.
https://stackblitz.com/edit/angularjs-yvxdrd

How to fill table with many editable rows in AngularJs

In my AngularJS website, I would like to show a table containing adresses that should be editable in the cells. This is how the columns look like:
Id, Label, Address, Geolocation, Additional Information
The Address column contains an input element, so that I can search for another address to change the data.
The table has sometimes more than 200 rows. I am experiencing massive performance problems when loading the table the first time and also when resizing the div in which the table is.
My approach so far:
Table HTML:
<div>
<table>
<tbody>
<tr table-row
address="address"
ng-repeat="address in data">
</tr>
</tbody>
</table>
</div>
I came up with a custom directive "table-row" which contains the td elements for a single row. It also has its own scope under which the address can be changed.
Table-row HTML:
<td>
{{ address.id }}
</td>
<td>
{{ address.label }}
</td>
<td>
<input type="text"
ng-model="addresstext"/>
</td>
...
Some thoughts on how this could be done better:
The main problem with my code is that the table is getting pretty big and I keep creating a scope for every single row. I suppose that the performance is going to increase if there would just be a single scope. However, I do not see how to do this without an ng-repeat to create the rows.
Isn't there a way to have one scope for the table and still a dynamic number of rows in the table, each being editable with the input textboxes in the cells?

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.

Filter table results by filter box input, with Javascript

I am attempting to filter a table based on the value of an input box.
I have it currently working on the HTML side, like so...
<tr ng-repeat="person in model.info | filter:inputFilter" ..... >
<td> {{ person.name }} </td>
<td> {{ person.height }} </td>
</tr>
<input class="filterBox" type="text" ng-model="inputFilter">
As said before, it works swell. It filters as I type, and is very quick and snappy.
In an effort to make the code reusable, I'd really like to be able to convert this into a Javascript function, but the syntax is escaping me. Yes, I've read the documents, but am not sure how I could just have it update in real time like it does through the HTML side.
Thanks :D
Austin

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