how to call a value from array in AngularJS controller? - angularjs

I have an array like this:
$scope.persons = [{name:'Joey', age:'27'}]
I can call the value in HTML in this way
{{person.name}}
But when I try something like this, it fails
$scope.name = $routeParams.person.name
I could read the person only (without .name), it will be displayed as an array.But I want to access to the name key. Thx in advance.
I pass the person to JS in this way (route)
<tr data-ng-repeat="person in persons">
<td headers="more">
Show Details
</td>
</tr>

Try below code, as you are accessing value from array, whenever you access value from array need to mention index.
$scope.name = $routeParams.persons[0].name

Try This
Show Details

Related

How to make a table sort-able while the whole components is passed as string via ng-bind-html in AngluarJS

Hi I have a situation in AngluarJS that the HTML is generated by back-end and the only thing that front-end should do is to put the HTML which is mostly table tags into the ng-bind-html and show it to the user. But now these tables should be sort-able too. How can I do it?
The thing that I've already done is to create my own directive using this so make the static string HTML take some actions too. But having them sorted is something else. In other word I want to make my fully generated table with all <tr> and <td> to get sorted by my actions.
Here is my simplified code (compile is my directive):
JS:
// The string is fully generated by back-end
$scope.data.html =
'<table> <tr> <th ng-click="sortByHeader($event)"> Name </th>
<th ng-click="sortByHeader($event)"> Age </th> </tr>
<tr> <td> Sara </td> <td> 15 </td> </tr>
<tr> <td> David </td> <td> 20 </td> </tr>'
HTML:
<div compile="data.html"></div>
The ng-click="sortByHeader($event) is something that back-end can prepare for me so I can use it thanks to the compile I wrote that let me find out which header has been clicked. Other than that there is nothing I can do. Unless you can help me :D
Thanks in advance, I hope my question was clear.
Since you tagged your question with sorttable.js I'm going to assume that you are using that script to sort your tables.
Now, if I understand it correctly, sorttable.js parses your HTML for any tables with the class sortable. Your table is apparently loaded dynamically, therefore sorttable.js does not know about it when it parses the HTML.
But you can tell it to make a dynamically added table sortable, too.
Relevant part taken from the following page:
https://kryogenix.org/code/browser/sorttable/#ajaxtables
Sorting a table added after page load
Once you've added a new table to the page at runtime (for example, by
doing an Ajax request to get the content, or by dynamically creating
it with JavaScript), get a reference to it (possibly with var
newTableObject = document.getElementById(idOfTheTableIJustAdded) or
similar), then do this:
sorttable.makeSortable(newTableObject);
You should be able to do that with angular. If not, I can try to put something together later.
Is the answer to the question "Does the rendered table have to exactly match the HTML retrieved by the backend?" a kind of "No"?
If that's the case, then here's a hacky way of gaining control of the table contents by parsing and capturing stuff from the backend HTML string using regular expressions.
For example: grab all row data and apply sorting client side
// Variables to be set by your sortByHeader functions in order to do client-side sorting
$scope.expression = null;
$scope.direction = null;
var regexToGetTableHead = /<table>\s*(.*<\/th>\s*<\/tr>)/g;
$scope.tableHead = regexToGetTableHead.exec($scope.data.html);
$scope.tableRows = [];
var regexToGetRowContents = /<tr>\s*<td>\s*(\w*)\s*<\/td>\s*<td>\s*(\w*)\s*<\/td>\s*<\/tr>/g;
var match;
while ((match = regexToGetRowContents.exec($scope.data.html)) != null) {
$scope.tableRows.push({
"name": match[1],
"age": match[2]
});
}
And HTML
<table>
<thead compile="tableHead"></thead>
<tbody>
<tr ng-repeat="row in tableRows | orderBy: expression : direction">
<td>{{row.name}}</td>
<td>{{row.age}}</td>
</tr>
</tbody>
</table>

add table data <td> only to one row on ng-repeat

in a table with ng-repeat is it possible to add a cell only to one row?
in my code:
<tbody>
<tr ng-repeat="user in users ng-click="selectUser(user)">
<td>{{user.username}}</td>
<td><input type="text"....></td>
<td><input type="checkbox"...></td>
<td><input type="submit" ... ng-show="user==selectedUser" /></td>
</tr>
</tbody>
in this code I want the last td appears only on the selected row and does not affect other rows, is it possible? or it is JS or CSS thing ?
First off you should be using the controller as syntax, it automatically puts everything in the controller under 1 object, which can cause issues with Angular. But I don't think that's the issue here.
The user you select could be equal to the selectedUser, but if they aren't pointing to the same reference, they won't be able. If usernames are distinct I'd change the ng-show="user.username == selectedUser.username"
and that should work fine.
It is possible, it seems like your code is mostly correct, but you're using selectedUser as a function and as an object representation of user. Maybe your function would be called selectUser which would set $scope.selectedUser. ng-show="user == selectedUser" would make since then.
I'm personally not a big fan of having conditions in the view, so I'd have a function in the controller which does the comparison and returns true or false.
function isSelectedUser(user) {
return user == $scope.selectedUser;
}
then you can just use ng-show="isSelectedUser(user)"
Use JQuery to append the <td> on the selected row <tr>. The :nth-child() is an easy way for you to select a row.
var selectedRow = 2;
$('tbody tr:nth-child('+ selectedRow +')').append('<td><input type="submit" /></td>');

Knockout foreach accessing 2D json array

Hope someone can help me out with this:
I'm working with knockout and have the following json array:
[[174302,"BUSINESS - APPLICATION TO CONDUCT A BUSINESS FROM HOME.pdf",".pdf","DK89639"],[120183,"Glovent-Brochure.pdf",".pdf","DK472894"]]
inside my "consumerData" variable.
As you can see there are 2 arrays with 4 elements inside each.
Here is how I am trying to access it:
<div data-bind="foreach: consumerData" style="margin-bottom:100px;">
<table>
<tr>
<td colspan="2">
<p style="font-size:larger; margin-bottom:5px;"><a data-bind="attr: { href: 'http://someaddress/address/'+consumerData[0]+''+consumerData[2]+'?key='+consumerData[3]+'' }"><div data-bind="text: consumerData[1]"></div></a></p>
</td></tr>
</table>
</div>
So this is looping twice which is correct but how do I access my data inside each array?
PLease help!
Thanks!
Regards
Francois
You can access unnamed data within a loop by accessing the $data object (instead of consumerData again), which represents the current context
See this fiddle:
https://jsfiddle.net/5c6y46bo/
Also, you don't need to put a div inside your link to hold the text of the current object, just put the text binding within the <a> element's binding alongside the attr binding.

Repeat over a collection of Prototypes

I have a collection of Prototype instances that I ng-repeat over.
The current solution I found is from here https://groups.google.com/forum/#!topic/angular/rdMf0DZHVvE
I basically define a controller on the ng-repeat directive and then initialize the prototype in there something like this:
<li ng-repeat="user in users" ng-controller="MyUserExtender">
{{user.name}}
</li>
The controller then extends the user:
controllers.controller('MyUserExtender', function($scope) {
$scope.user = new User($scope.user);
});
For the complete code please see here:
http://jsfiddle.net/5d5v6b5j/
The problem now is, if I change the name of a user via. ng-model for example, the ng-repeat does not update and the user-name that is output stays the same.
Thank you for your input cheers
christoph
It's dead simple, just pass in an array of allready initialized prototypes.
var users = [new User({name: 'test'})];
<li ng-repeat="user in users"></li>

Passing variable in ng-repeat

I have a ng-repeat loop and I want to pass a variable inside it...
<tr bindonce ng-repeat="row in elasticsearch.savedSearches | orderBy:['_id']">
<td><a ng-click="changeServices('row._id')" bo-text="row._id"></a></td>
</tr>
but it only passes the string "row._id".
changeServices('{{row._id}}')
doest work either.
Loose the '':
<a ng-click="changeServices(row._id)" bo-text="row._id"></a>
this should work:
hope it helps
You can also pick the row._id value in your controller without the need to passing it as above by doing:
id = $scope.row._id
Try this:
<a ng-click="changeServices(row._id)" bo-text="row._id"></a>
ie, remove the quotes from the 'row._id' else it would be treated as a string instead of variable.

Resources