Display the value only if the current value in the loop is not same as the previous value in jsp using ng- repeat - angularjs

I am using ng-repeat in my jsp to loop and display the values.if i have the value more then one time in the list i need to display only once.
Display the value only if the current value in the loop is not same as the previous value in jsp using ng- repeat
please find my code:
<td>
// obj.vm is name. name should be displayed only if it is diferrent then the previous name. otherwise it should be blank
<div obj.vm> </div>
</td>
// obj.dm is value. all the values should be displayed
<td> <div obj.dm> </div>
</td>
</tr>
<tr ng-repeat="obj in selItem.surveyRefData">
<td nowrap> // need to display ob.vm only if the current value is not same as previous value
<div style="float: left;" class="form-actions" obj.vm">
</div>
</td>
<td>
<div style="float: left;" class="form-actions"
ng-bind-html="(!validSeriesIdReqPending ?(obj.dm | seriesText):'')">
</div>
<br/>
<br/>
<tr ng-repeat="obj in selItem.surveyRefData|unique: obj">
<td> // obj.vm is name. name should be displayed only if it is diferrent then the previous name. otherwise it should be blank
<div obj.vm>
</div> </td> // obj.dm is value. all the values should be displayed
<td>
<div obj.dm> </div>
</td>
</tr>

The ideal solution is to preprocess the data and group it by the vm attribute, so you would have some structure like this:
name1
value1
value2
value3
name2
value4
value5
name3
value5
...
Then you would have a nested ng-repeat that loops over the values within each name. If, for some reason, you can't preprocess the data, you can refer to the previous item in your ng-repeat using the $index variable. Here is a simple example:
<tr ng-repeat="obj in selItem.surveyRefData">
<td>{{obj.vm !== selItem.surveyRefData[$index-1].vm ? obj.vm : ''}}</td>
<td>{{obj.dm}}</td>
</tr>
Keep in mind that this will only work if your data is ordered based on the vm attribute... if you had name1 -> name1 -> name2 -> name1, for example, you would see name1 twice in your output table.
Here is a simple example plunker: https://plnkr.co/edit/r5yxYk4Rr7mXaBeqoJNs

Related

How to get hidden input value that was dynamically stored using AngularJS

I'm trying to implement search method for "chat channels" that for every query it represents the compatible results from SQL table from the database.Each result can be distinguished by a unique ID that is also comes from the SQl table.I don't want to show the ID's so I put them in a hidden input for each result using ng-model.Also, for each, result the user have a possibility to subscribe to the channel (subscribe button) displayed in this result,so in order to save the subscription properly,I need to get the ID saved in the hidden input of the same result.
Here's what I tried:
<table class="table table-condensed">
<tr class="separating_line" ng-repeat="x in result">
<!-- ng-bind-html allows to bind a variable to the innerHTML part of the HTML element -->
<td>
<div class="col-md-8">
<h4><b style="color: gray;">{{ x.Name }}</b></h4>
<br><p> {{ x.Description }}</p>
</div>
<div class="col-md-2">
<small><label style="color: gray;">Subscribers </label>{{ x.Subscribersnum }}</label></small><br>
<input id="hiddenId" hidden="hide" ng-model="idval=x.ChanID" />
<button ng-click="subscribechannel()" class="btn btn-primary">Subscribe</button>
</div>
</td>
</tr>
</table>
In the controller I send it in the following way to convenient Servlet:
$http.get("http://localhost:8080/ExampleServletv3/subscribeservlet",{
params: {
subidval: $scope.idval
}
})
But when debugging the value that I get in the servlet is null.
How can I solve this? Any ideas?
Thanks
You don't need any hidden field to do what you want. All you need is to pass a parameter to your function:
<tr class="separating_line" ng-repeat="x in result">
...
<button ng-click="subscribechannel(x)" class="btn btn-primary">Subscribe</button>

ng-repeat or ng-options How can I automatically select the last row in a table ?

How I can I automatically select the last row in a table
ng-repeat="unit in selectedOrder.products" using something like select by track by $index == desc or alternatively ng-options
<div class="search" ng-show="selectedOrder">
<table class="table table-bordered">
<tr><th>Item</th><th>Name</th><th>ValueToday</th></tr>
<tr ng-repeat="unit in selectedOrder.products">
<td><img ng- src="http:images/thumbnails/{{unit.shortname}}_tn.jpg" width=40 height=40
alt="{{ unit.shortname | limitTo: 18}} Photo"></td>
<td>{{unit.name | limitTo:18 }}</td>
<td>{{unit.valuetoday| currency:"£"}} </td>
</tr>
</table>
<div class="search" ng-show="selectedOrder">
<table class="table table-bordered">
<tr><th>Item</th><th>Name</th><th>ValueToday</th></tr>
<tr ng-repeat="unit in selectedOrder.products" ng-if="$last">
<td><img ng- src="http:images/thumbnails/{{unit.shortname}}_tn.jpg" width=40 height=40
alt="{{ unit.shortname | limitTo: 18}} Photo"></td>
<td>{{unit.name | limitTo:18 }}</td>
<td>{{unit.valuetoday| currency:"£"}} </td>
</tr>
</table>
will give you only the last row selected
In ng-repeat you can use the $last special variable to apply something only if it's the last element. see: https://docs.angularjs.org/api/ng/directive/ngRepeat
you can use it as a condition for anything you want to do in the tag. like
<img class="{{$last ? 'selected'}}" ng-class="{'selected': $last}" ng-if="$last" ....>
or however you like (these are just examples)
Always keep in mind though that using angular means that you have to edit your model to apply changes to your view, so if you want to have an element selected you have to do something to your model so that the element contains a value that makes it selected and then your view should reflect this.
For example in your controller you can check which element is the last in your ng-repeat array and add a selected variable, then in your view do something to make it look like your element is selected (for example: ng-class="{'selected': element.selected}") otherwise, by working on the view only you can make it look like the element is selected using $last but it won't be really selected in your model
In fact In ng-options (so we are talking about a select) you have to change your model in order to reflect your choice. So for example if your select has an attribute like this: ng-model="selected" then in your controller you set the $scope.selected variable to the last element of the array containing the values for your ng-options
You could use something like ng-if="$index == $last"

Prevent angular from sorting list item alphabetically in real time

I am trying to fix a bug with an angularjs list.
When an item in the list is edited, the record is sorted alphetically in real time and it jumps to a new position in the list.
This is proving problematic as when someone tries to edit a record, "ABC" for example, if they put a "Z" in front of it it jumps to the last page on the list.
The text input value is bound directly to the model, which I suspect is the issue, as the data-ng-repeat directive ensures that the data is sorted alphabetically.
As such I tried changing the data-ng-model binding to data-ng-bind, as it is my understanding that if the input value is changed, ng-model updates the model while ng-bind doesn't.
I would greatly appreciate any advice.
HTML:
<form name="companies" class="clearfix" novalidate data-ng- hide="loadingIcon">
<table>
<tbody>
<tr data-ng-repeat="company in data | orderBy: 'NAME' | siftPage: startIndex: endIndex">
<td width="60%">
<span data-ng-hide="edit"> {{ company.NAME }} </span>
<div class="form-field col-sm-9" data-ng-show="edit">
<input type="text" data-ng-bind="company.NAME" />
</div>
</td>
<td>
<a class="icon edit" data-ng-click="edit = !edit; changed = edit ? edited(company) : changed(company);" href="#"></a>
</td>
<td>
<a class="icon delete" data-ng-click="removeCompany(company)" href="#"></a>
</td>
</tr>
</tbody>
</table>
I'm new to angular so please forgive me if I haven't included enough information. I will update update with any further information as requested.
I believe it is the ng-repeat with the orderBy: 'Name' clause that is the actual issue. It will make sure that the order is maintained even after an edit.
If you want to order initially before edits, copy the name as initialName onto each of your json objects and set the orderBy to 'initialName'. Since you wont be updating the initialName on an edit it wont update via the order by.
If you create the copy as a function to create the initialNames, you could call it through a button to re-sort the data.

Why AngularJS filter matches incomplete values

I'm getting incomplete values when trying to use ng-model + text input as search bar.
As an example : When I write "li" in the text input I get the results back "B Lifting", but when I try to write "lifting" it will show no results. If I write "kl" I can get up "Gulklokken", but if I search for "Gulklokken" it won't show the result.
I can't seem to figure out the reason for it.
Code for search bar :
<div id="searchBar" class="input-group input-group-lg">
<input type="text" ng-model="search.hovedkunde" class="form-control" placeholder="Search here" ng-focus="focused = true" ng-blur="focused = false">
</div>
Code to display results :
<div class="col-md-6">
<div ng-if="search.hovedkunde" ng-controller="paginationCtrl">
<table class="table table-hover">
<tr>
<th>ID</th>
<th> Hovedkunde</th>
<th>Kundenavn</th>
<th></th>
</tr>
<tr ng-repeat="pro in filtered = (projects | filter: search) | sliceArray:bigCurrentPage*pageSize | limitTo : pageSize | unique:pro.projectId | orderBy:predicate:reverse ">
<td ng-click="setInfo(pro.projectId)">{{pro.hovedkundE_ID}}</td>
<td ng-click="setInfo(pro.projectId)">{{pro.hovedkunde}}</td>
<td ng-click="setInfo(pro.projectId)">{{pro.lonG_NAME}}</td>
<td ng-click="setInfo(pro.projectId)"><button type="button" class="btn btn-primary">Retrieve</button></td>
</tr>
</table>
<div class="text-center">
<pagination total-items="bigTotalItems" ng-model="bigCurrentPage" max-size="maxSize" class="pagination" boundary-links="false" rotate="false" num-pages="numPages"></pagination>
</div>
</div>
</div>
The filter expression allows you to specify a comparator.
Comparator which is used in determining if the expected value (from the filter expression) and actual value (from the object in the array) should be considered a match.
Can be one of:
function(actual, expected): The function will be given the object value and the predicate value to compare and should return true if the item should be included in filtered result.
true: A shorthand for function(actual, expected) { return angular.equals(expected, actual)}. this is essentially strict comparison of expected and actual.
false|undefined: A short hand for a function which will look for a substring match in case insensitive way.
In your case, you should define the filter like this
filter:search.hovedkunde:true

generating a series of buttons in two rows using angular ng-repeat

I have a angular controller that defines an array of elements as follows:
$scope.tasks = [{val=1},{val=2},{val=3},{val=4},{val=5},{val=6},{val=7},{val=8},{val=9},{val=10}];
I want to generate a series of elements for this and I can do this as follows:
<div ng-repeat-"button in tasks">
<button id = {{ $index}} value='{{task.val}}'></button>
</div>
However, I want the buttons to appear in two rows - like 1-5 in first row and 6-10 in the 2nd row. I think I have to use $index for this, but now sure how to do it.
Can someone help?
You can do it like that
<div ng-repeat-"button in tasks">
<button id = {{$index}} value='{{button.val}}'></button><br ng-if="$index == 5">
</div>
It would be better to show it in a table...
Divide the array into a 2D array with required no. of cols...
var tempArry = angular.copy($scope.tasks);
var cols = 5; //in your case 5
while (tempArry.length > 0)
$scope.DisplayArray.push(tempArry.splice(0, cols));
and the html...
<table>
<tr ng-repeat="row in DisplayArray track by $index">
<td ng-repeat="col in row track by $index">
<button value='{{col.val}}'></button>
</td>
</tr>
</table>

Resources