Angular search for combined key - javascript

Say you have the following object:
var user: {firstname: 'Marc', lastname:'Ras', age:30};
You have alot of these objects in an array called: user_array
Now you wish to display them in a table so you create your table:
<table>
<thead>
<th>Full name</th>
<th>Age</th>
</thead>
<tbody>
<tr ng-repeat="user in user_array">
<td>{{user.firstname + ' '+user.lastname}}</td>
<td>{{user.age}}</td>
</tr>
</tbody>
</table>
Now you wish to create an input field where you can search for a user's full name:
And here is kinda ends for me :S how is it possible to search for a combinded key? normally you would have:
<input type="text" ng-model="search.fieldname" />
However you cant do that here since the field is combined of two fieldnames?

add this to your controller
$scope.filterNameLastName = function (user) {
var fullname = user.firstname + ' '+ user.lastname;
if(fullname == $scope.searchParamater)
return true;
else
return false;
};
and add filter to ng-repeat
<table>
<thead>
<th>Full name</th>
<th>Age</th>
</thead>
<tbody>
<tr ng-repeat="user in user_array | filter:filterNameLastName ">
<td>{{user.firstname + ' '+user.lastname}}</td>
<td>{{user.age}}</td>
</tr>
</tbody>
</table>
This should give you an idea on how custom filters work. I haven't tested the code so you may have to do some modifications.

Related

how to send object from html ng-repeat to js function

I am getting data from db and put it in a scope, then iterate on these data by ng-repeat in html.
what i am trying to do is to send the selected object when the user check on a checkbox to get another data based on an id for example . i tried to use ng-model and ng-change on the checkbox but it sends only true or false .
HTML
<div id="frame" class="widget-content" style="height:50vh; overflow:auto;">
<table style="font-size: 12px;display: inline-block;">
<thead>
<tr>
<th>Check</th>
<th>Group Code</th>
<th>Group Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="g in Groups | unique : 'Group_code'"
ng-click="showInEdit(g)"
ng-class="{selected:g === selectedRow}">
<td><input type="checkbox" ng-model="g"
ng-true-value="g" ng-change="Getrequest2(g)"/>
<td>{{g.Group_code}}</td>
<td>{{g.group_name_latin}}</td>**
</tr>
</tbody>
</table>
<table style="font-size: 12px; float: left;">
<thead>
<tr>
<th>Check</th>
<th>Item Code</th>
<th>Item Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="i in items | unique : 'Item_code'"
ng-click="showInEdit(i)"
ng-class="{selected:i === selectedRow}">
<td><input type="checkbox" />
<td>{{i.Item_code}}</td>
<td>{{i.ITEM_NAME_LATIN}}</td>
</tr>
</tbody>
</table>
</div>
angularjs
$scope.Getrequest1 = function (g) {
//console.log(g);
$scope.typecd = g.TypeCode;
$scope.ShowLoading('slow');
LOASrv.GetGroup("LOAApprovalSetup/GetGroup" +
"?typ=" + g.TypeCode +
'&hospid=' + $scope.hospitalid +
'&userky=' + $scope.userkey
).then(function (response) {
$scope.Groups = (response.data);
$scope.HideLoading('slow');
})
}
$scope.Getrequest2 = function (i) {
console.log(i);
$scope.ShowLoading('slow');
LOASrv.GetItem("LOAApprovalSetup/GetItem" +
"?typ=" + $scope.typecd +
'&hospid=' + $scope.hospitalid +
'&userky=' + $scope.userkey +
'&groupcd=' + i
).then(function (response) {
$scope.items = (response.data);
$scope.HideLoading('slow');
})
}
You’re assigning ‘g’ object to checkbox ng-model.
This changes the value of ‘g’ from object to boolean on checkbox select.
That’s why you’re getting true/false
Change ng-model=“g.someBooleanName” and try

How convert angular object to JS object

I have a table, One column by expressing object with an angular ng-repeat in angular
<table class="table table-bordered table-hover table-condensed " ng-show="vm.CandidatesList">
<thead>
<tr>
<th sortable-header col="FirstName" style="text-align:center">{{::vm.resources.FirstName}}</th>
<th sortable-header col="LastName" style="text-align:center">{{::vm.resources.LastName}}</th>
<th sortable-header col="CandidateTopic" style="text-align:center">{{::vm.resources.CandidateTopic}}</th>
</tr>
</thead>
<tr ng-repeat="c in vm.CandidatesList "
row-id="{{ c.ID }}"
ng-dblclick="vm.goEdit(c.ID)">
<td ng-model="c.FirstName" style="text-align:center">{{c.FirstName}}</td>
<td ng-model="c.LastName" style="text-align:center">{{c.LastName}}</td>
<td style="text-align:center" name="TopicToCandidate" id="TopicToCandidate+{{c.ID}}"><a ng-repeat="t in vm.getTopicToCandidate(c.ID)">{{t.Name}}, </a></td>
</tr>
now I want to recive the value of the TopicToCandidateto js with
var topic= document.getElementById("TopicToCandidate+" + item.ID).innerText
but topic is null because js can not convert the angular object or HTML object to js object.
I'm not sure you understand what angularjs does in the background. Don't extract the information from the DOM if you already have it in your controller.
So in other words just use it like this:
app.controller('candidateController', function($scope) {
$scope.CandidatesList = [
{ID:1 , FirstName:"Dan1", LastName:"Doe1"},
{ID:2 , FirstName:"Dan2", LastName:"Doe2"},
{ID:3 , FirstName:"Dan3", LastName:"Doe3"}
];
//get topic of first candidate for example
var topic = $scope.getTopicToCandidate($scope.CandidatesList[0]);
}
You might want to check out 2 way binding in the angular docs.

Angular.js smart table loading symbol during ajax call

Using the pipe/ajax plugin example at http://lorenzofox3.github.io/smart-table-website I have been trying to implement an Angular.js smart table with a loading indicator whilst my ajax call is still loading.
angular-boostrap.js
var eposWebAngularStrutsApp = angular.module('eposWebAngularStrutsApp', ['ngResource','smart-table']);
angular-controller.js
eposWebAngularStrutsApp.controller('StoreHealthCheckController', ['$scope','StoreServerHealth', function ($scope, StoreServerHealth) {
//http://www.sitepoint.com/creating-crud-app-minutes-angulars-resource/
var ctrl = this;
this.displayed = [];
this.callServer = function callServer(tableState) {
ctrl.isLoading = true;
StoreServerHealth.query(function(result) {
ctrl.displayed = result.data;
ctrl.isLoading = false;
}); //query() returns all the entries
};
}]);
angular-service.js
eposWebAngularStrutsApp.factory('StoreServerHealth', function($resource) {
return $resource('json/storeHealthCheckList.action'); // Note the full endpoint address
});
My JSP...
<table class="table table-striped" st-pipe="mc.callServer" st-table="mc.displayed" ng-controller="StoreHealthCheckController">
<thead>
<tr>
<th>Store</th>
<th>Server</th>
<th>Conn Status</th>
<th>Last Updated</th>
<th>MDI</th>
<th>Last Synched (MDI)</th>
<th>DSM</th>
<th>Last Synched (DSM)</th>
<th>Trading Status</th>
<th>Build</th>
</tr>
</thead>
<tbody ng-show="!mc.isLoading">
<tr ng-repeat="row in mc.displayed">
<td>{{row.locationId}}</td>
<td>{{row.clientId}}</td>
<td>{{row.status}}</td>
<td>{{row.displayLastUpdateTime}}</td>
<td>{{row.replicationStatus}}</td>
<td>{{row.displayLastReplicationSyncTime}}</td>
<td>{{row.dsmReplicationStatus}}</td>
<td>{{row.dsmLastSynchTime}}</td>
<td>{{row.storeTradingStatus}}</td>
<td>{{row.buildVersion}}</td>
</tr>
</tbody>
<tbody ng-show="mc.isLoading">
<tr>
<td colspan="10" class="text-center">Loading ... </td>
</tr>
</tbody>
</table>
But I keep getting an error TypeError: href is null firebug/content/debugger/stackFrame/StackFrame.js.
Can someone let me know what I might be doing wrong here.
Thanks
The comment posted above was the answer to this question. I had forgotten to Alias the controller.

Repeating a set of <td>s in the same table row using AngularJS

I want to create a table that, in its header, contains the names of each player for two teams in each . The scope has a variable teams which is a list of Team objects, each one having list of Player objects as an attribute.
This is turning out to be way harder than I expected.
<table>
<thead>
<tr>
<div ng-repeat="team in teams">
<th ng-repeat="player in team.players">{[ player.name ]}</th>
<th>Partial Score</th>
<th>Total Score</th>
</div>
</tr>
</thead>
</table>
is the easiest thing I have in mind - but this doesn't work. can't be placed inside a according to W3C (from what I understand), so the browser just takes the div and places it outside the table.
I've tried directives as well - but these don't help. This is an example of my directive file.
<th ng-repeat="player in team.players">{[ player.name ]}</th>
<th>Partial Score</th>
<th>Total Score</th>
For example, if I have a <player-initials> directive with replace: 'false', the browser expels the non-<th> element out of the table. Setting replace: 'true', fixes that, but then I get an error because there's more than one root element in the directive. I can't wrap the elements in the directive with anything because that would result in invalid HTML (as above).
I've tried all combinations of element and attribute directives and replace, nothing gives me what I want. Any help?
Created a fiddle here.
Hope this is what you are looking for, if not let me know the format that you are looking for. Your HTML should look something like below.
<table ng-repeat="team in teams">
<tr>
<td colspan="3">
{{team.name}}
</td>
</tr>
<tr>
<td>Player Name</td>
<td>Partial Score</td>
<td>Total Score</td>
</tr>
<tr ng-repeat="player in team.players">
<td>{{player.name}}</td>
<td>{{player.PScore}}</td>
<td>{{player.TScore}}</td>
</tr>
</table>
You should add a method to your scope that do the logic for you.
Something like this should work:
$scope.getAllPlayers = function() {
var players = [];
this.teams.forEach(function(team){
players = players.concat(team.players);
});
return players;
}
Then in your dom:
<table>
<thead>
<tr>
<th ng-repeat="player in getAllPlayers()">{{ player.name }}</th>
<th>Partial Score</th>
<th>Total Score</th>
</tr>
</thead>
</table>
I'm not using Angular so I may be wrong, but I'm pretty sure this is the way to go. This kind of logic have to be in your controller, as simple is a nested loop.
EDIT: Referring to the comments, you could make a function that return your header cells the way you want them
$scope.getHeaderCells = function() {
var cells = [];
this.teams.forEach(function(team){
cells = cells.concat(team.players.map(function(player){
return { team: team, value: player.name };
})).concat([
{team: team, value: 'Partial Score'},
{team: team, value: 'Total Score'}
]);
});
console.log(cells);
return cells;
}
with
<th ng-repeat="cell in getHeaderCells()">{{ cell.value }}</th>
here is a fiddle
I figured it out using the ng-repeat-start and ng-repeat-end directives. I really didn't want to write functions to generate HTML for me, because that's why I switched to Angular in the first place.
Here's a screenshot: http://i.imgur.com/e5LBvQB.png.
This is the (stripped-down to relevant part) code just for the header, everything else is similar. The only 'hacky' part I don't like is the ng-show attributes for B and T to reverse it properly, but it works for me right now. I think I can get clean it up with directives.
<table class="table table-condensed table-striped table-hover table-responsive">
<thead>
<tr>
<th ng-repeat-start="team in game.getTeams()" ng-hide="true"></th>
<th ng-repeat="player in team.getPlayers()" ng-class="$parent.$first && 'text-info' || 'text-danger'">
<u>
{[ player.name | truncate ]}
</u>
</th>
<th ng-repeat-end ng-show="$first">
#
</th>
</tr>
</thead>
</table>

AngularJS filter on multiple parameters

I have table that is populated from $scope and two search textboxes in header that I am using to filter user name and e-mail:
<table class="table">
<thead>
<tr>
<th></th>
<th><input type="search" placeholder="Search" ng-model="searchName"></th>
<th><input type="search" placeholder="Search" ng-model="searchMail"> </th>
<th></th>
</tr>
<tr>
<th>ID</th>
<th>Name</th>
<th>email</th>
<th>password</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="q in dataForTable | filter:{user_fullname : searchName, user_email : searchMail}">
<td>{{q.user_id}}</td>
<td>{{q.user_fullname}}</td>
<td>{{q.user_email}}</td>
<td>{{q.user_password}}</td>
</tr>
</tbody>
dataForTable comes from controller via $http :
$http.get('http://tbrzica.comli.com/rest/index.php/simple/users').success(function(data){
$scope.dataForTable=data;
});
But when the page initially load, table is empty. Only when I write something in textboxes and delete the input, table is populated and search by both condition is working normally. Is this some kind of bug?
Thanks in advance.
EDIT: Found a solution:
I've needed to initialize two ng-model parameters inside controller:
$scope.searchName="";
$scope.searchhMail="";
tymeJV, thank you for your answers.
In the controller, you can create a scope function for filter as following:
$scope.filterUser = function(fullName, email) {
return function(user) {
return (fullName == undefined || fullName.length == 0 || user.user_fullname == fullName)
&& (email == undefined || email.length == 0 || user.user_email == email);
}
}
And in HTML, you can apply the filter following:
<tr ng-repeat="q in dataForTable | filter:filterUser(searchName, searchMail)">
<td>{{q.user_id}}</td>
<td>{{q.user_fullname}}</td>
<td>{{q.user_email}}</td>
<td>{{q.user_password}}</td>
</tr>
Hope this help!

Categories