Prevent angular from sorting list item alphabetically in real time - angularjs

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.

Related

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

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

ng-repeat directive doesn't work on <tr> / table row element

I am trying to use the ng-repeat directive to create table rows with a list of campaign names.
However, I am not able to get any results, though I am still able to see one of the children of the array displaying correctly.
Here is my view code:
<div class="modal-body">
<p>{{$ctrl.contact.Campaigns[0].CampaignName}}</p>
<tr ng-repeat="campaign in $ctrl.contact.Campaigns">
<label>
{{campaign.CampaignName}}
</label>
</tr>
</div>
I can successfully see the paragraph element above and it shows the expected data, but not the table row elements.
I don't see any errors in the browser console.
How can I make the ng-repeat directive work in the code above?
The problem was that the <tr> / table row element didn't have a parent <table> element containing it.
This is solved by simply adding in table tags around the orphaned <tr> element:
<div class="modal-body">
<table>
<tr ng-repeat="campaign in $ctrl.contact.Campaigns">
<label>
{{campaign.CampaignName}}
</label>
</tr>
</table>
</div>

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>

Hide html element with same data in ng-repeat in angularjs

I have a array of task in which there are two duplicate departments, but i dont want to show the second duplicate record in ng-repeat, but only for the first record i want to show even if it is duplicate.
Here is my code, can anyone tell me where i'm going wrong.
<tr ng-repeat="t in item.requisitionTask track by t.id">
<td>
<div ng-hide="!$first ? item.requisitionTask[$index-1].department.departmentCode==$index.department.departmentCode : false">
{{t.department.departmentName}}</div>
</td>
Solved it by targeting the data particularly.
<td><div ng-hide="!$first ? item.requisitionTask[$index-1].department.departmentCode==item.requisitionTask[$index].department.departmentCode : false">
I suspect that you want to hide data if the previous item contains the same departmentCode as your current item. As mentioned in my comment, you should move this logic into a function on your controller's scope.
<tr ng-repeat="t in item.requisitionTask track by t.id">
<td>
<div ng-hide="isNotFirstOrSameCodeAsPrevious($index)">
{{t.department.departmentName}}
</div>
</td>
</tr>
In your controller:
function isNotFirstOrSameCodeAsPrevious($index) {
if ($index === 0) return false;
return item.requisitionTask[$index - 1].department.departmentCode ===
item.requisitionTask[$index].department.departmentCode;
}

AngularJS - How to access a binding value within ng-switch

Within a ng-repeat I have a ng-switch conditional. I want the value of the ng-switch argument to be a binding. However the curly-bracket binding doesn't seem to be converted into the expected generated value. I'm aware that ng-switch creates a new scope, and that is surely causing the problem. I know about a 'dot' work-around but as the values here are coming from a service via a controller query, I can't figure out how to implement it in this situation.
html
<tr ng-repeat="user in users">
<td ng-switch on="editState"><p ng-switch-when="noEdit">{{user.username}}</p><input type="text" value="{{user.username}}" ng-switch-when="{{user.username}}"></td>
</tr>
controller.js
$scope.users = Users.query();
-edit-
this is the function that triggers the switch
$scope.editUser = function(usernameEdit) {
$scope.editState = usernameEdit;
};
A single $scope.editState won't work if you want to be able to edit multiple users at the same time. I suggest putting an edit property on each user, and use that property to control the ng-switch:
<tr ng-repeat="user in users">
<td ng-switch on="user.edit">
<span ng-switch-when="true">
<input type="text" value="{{user.username}}">
done
</span>
<p ng-switch-default>
edit {{user.username}}
</p>
</td>
</tr>
Fiddle

Resources