orderBy in ng-repeat - javascript

JS:
$scope.termexamlist = {
0:{
0id:"1",
1name:"Doe, John",
2term1:"89"
},
1:{
0id:"2",
1name:"Aayt, Ray",
2term1:"90"
}
};
HTML:
<tr ng-repeat="t in termexamlist">
<td ng-repeat="(key,value) in t">{{value}}</td>
</tr>
i got this ng-repeat code which generates list of students with their term exam grades, i want to sort it by 1name but it didnt work i use to put <tr ng-repeat="t in termexamlist | orderBy:'1name' "> but it didnt work. i tried different codings too but it didnt work either. Sorry im just a beginner in angularjs programming. Thanks for the help :D

You should not have put identifiers when you declared your array
$scope.termexamlist = [
{
0id:"1",
1name:"Doe, John",
2term1:"89"
},
{
0id:"2",
1name:"Aayt, Ray",
2term1:"90"
}
];
This will be enough and enable you to iterate through it and ordering it.
Also, it's strange the way you prefix your variables, but that's none of my business

$scope.termexamlist = [
{
0id:"1",
1name:"Doe, John",
2term1:"89"
},
{
0id:"2",
1name:"Aayt, Ray",
2term1:"90"
}
];
remove 0 and 1 in your data , it will work fine

i got it now, i add underscore to the key of the object so it will look like this $scope.termexamlist={0:{_0id:"1",_1name:"Doe, John",_2term1:"89"}}. i retain the number coz chrome sort the returned data of json_encode

Related

angularjs how to search in search in json object in html template

In Angularjs I am trying to search in json data which i am using in html template. My input json data is as below,
var data = JSON.parse(
'{
"Project": {
"_attributes": {
"gui": "ProjectGui",
"prjname": "MyProject"
},
"stringarr": [
{
"_attributes": {
"name": "Project.comments"
},
"_text": "MyComments"
},
{
"_attributes": {
"name": "Project.classpath"
},
"_text": "D:\\Project\\bin\\config.jar"
}
]
}
}'
);
And i am using this for displaying and editing name in my html template, which is working fine. When I edit input box , it reflects the changes in json data as well, that's exactly I want.
Name: <input type="text" ng-model="data.Project._attributes.prjname"><br>
But I also want to display and edit comments in same way but not getting idea how to achieve this. The difference is, I have to search within json data where data.Project.stringProp[i]._attributes.name is "Project.comments" and take "_text" as input for displaying & editing. I have tried following that is not working.
Comments: <input type="text" ng-repeat="x in data.Project.stringProp" ng-model="x">{{x._text}}<br>
Please suggest , what would be the best possible way to do this. I think it can be done using a get function and ng-change function but that approach will be lengthy and may put performance overheads.
Thanks
You can either implement a filter for filter _text value if the name is 'Project.comments', or you can simply add an ng-if statement.
Comments: <input type="text" ng-repeat="x in data.Project.stringarr" ng-if="x._attributes.name == 'Project.comments'">{{x._text}}<br>
I have resolved this by using ng-repeat and ng-if for specified condition.
<body ng-controller="Controller">
Name: <input type="text" ng-model="data[0].Project._attributes.prjname"><br>
check: <div ng-repeat="x in data[0].Project.stringarr" ng-if="x._attributes.name == 'Project.comments'">{{x._text}}</div><br><br>
comments : <input type="text" ng-repeat="x in data[0].Project.stringarr" ng-if="x._attributes.name == 'Project.comments'" ng-model="x._text"><br>
</body>
Please find the following plunkr
https://plnkr.co/edit/3jUaw73cHgAtbBZr8LuJ?p=preview

Knockout foreach binding not rendering anything

I have, what I thought was a fairly straightforward knockout situation. I have a model that comes in from WebApi that has an array of things with a Success element. I need the value of success to determine what of the properties render. I've validated that all the data is coming down from WebApi ok but nothing but the table shell renders. There are no errors in the dev console.
The HTML
<div id="model1Wrapper">
<table class = "table">
<thead >
<tr >
<th >Stuff</th><th>Things</th>
</tr>
</thead>
<tbody data-bind = "foreach: $data.historyArray" >
<!--ko if: Success -->
<tr class = "success" >
<td data-bind = "text: $data.ThingA" > </td>
<td data-bind = "text: ThingB" > </td>
</tr>
<!-- /ko -->
<!--ko ifnot: Success -->
<tr class = "danger" >
<td colspan="3" data-bind = "text: ThingC" > </td>
</tr>
<!-- /ko -->
</tbody>
</table>
</div>
Example Model Data
[{
"ThingA": "A",
"ThingB": "B",
"ThingC": "C",
"Success": false
}, {
"ThingA": "A",
"ThingB": "B",
"ThingC": "C",
"Success": true
}]
This is monitoring a process that has feeds from several endpoints so I have multiple ViewModels on the page. So I framed up a rough example of how that is working elsewhere on the page.
That business
<script>
var sampleModelData = [{
"ThingA": "A",
"ThingB": "B",
"ThingC": "C",
"Success": false
}, {
"ThingA": "A",
"ThingB": "B",
"ThingC": "C",
"Success": true
}]
var viewModel1 = {
historyArray: ko.observableArray()
};
function onNewHistory(data) {
viewModel1.historyArray(data);
}
$(document).ready(function(){
ko.applyBindings(viewModel1, document.getElementById("model1Wrapper"));
onNewHistory(sampleModelData);
})
</script>
I had to mask of some of the speciffics but the gist is, the ajax call returns an array in the example. There is a function that is called to update the new data into the observable and I would expect the table to rerender, it does not.
Other deets
Sometimes there is no model data in the table so I load it and wait
for an update. All the other Viewmodels are loaded like this but this
is the only one with an array and the only one I'm having trouble
with.
I have tried taking out the if/ifnot business and that does not work.
Fiddler hates me and I have not been able to set up a clean version of this to try.
I leafed though some of the related questions and nothing seems to fit my issue. Or the example is much more complicated to apply.
Thanks!
The problem is in this code:
var viewModel1 = {
historyArray = ko.observableArray();
}
You're mixing the syntax for declaring objects with the syntax for code inside functions. When declaring an object, don't use = and ;. Instead use : and ,.
If you change the declaration to something like below, it should work.
var viewModel1 = {
historyArray: ko.observableArray()
}
Just adding another answer to this question in case someone comes across it in future. I had this issue and it was a result of initialising my observable array within the method. I didn't mean to do this (copy paste error) and it didn't produce any errors in the console so was difficult to trace.
For example:
LoadJSArrayIntoObservable(results) {
vm.validationResults = ko.observableArray(); <---- THIS IS INVALID.
vm.validationResults([]); <---- THIS IS WHAT I MEANT TO DO!!
$.each(results, function () {
try {
vm.validationResults.push(new ValidationResult(this));
}
catch (err) {
alert(err.message);
}
});

Accessing Image Arrays via JSON with AngularJS

UPDATE:
I can now do what I wanted to do, sort of. I can click on the thumb and the large image will display in the lighbox. A second a tag with the same data-lightbox name uses another ng-repeat as etee suggested.
As you can see from the code it is not perfect and I would still like to do it properly. I alos managed to use a nested forEach to get to the 'large' array in the JSON file, and they show in the console.log but I don't know how to get them from there to the original lighbox so it displays the set, and you'll see the current way shows the same image twice.
Here is some of the JSON file:
[
{
"name":"Cedar Run",
"album_name":"CedarRun",
"img":[
{
"thumb":["cedarRun.jpg", "cedarRun.jpg","cedarRun.jpg"]
},
{
"large":["IMG_6001.jpg","IMG_6009.jpg"]
}
],
"cabin_id":"17",
"sleeps":"2",
"description":"1 Room",
"number_of_bedrooms":"1",
"bedrooms":
{
"bedroom1":"1 Queen",
"bedroom2":"",
"bedroom3":"",
"bedroom4":""
},
"pull_out":"",
"living_room":"",
"bathrooms":"",
"bathroom_info":"Bath with Tub/Shower",
"other_info":"",
"winter_info":"Winter RR Only",
"winter_rate":"198.90",
"summer_info":"Summer RR Only",
"summer_rate":"198.90",
"cabin_description":"Quaint cabin perfect for two. A unique location with a view of the horseback rides going by throughout the day. Also has one small dorm refrigerator and working fireplace with firewood supplied by the ranch."
},
{
"name":"Pioneer",
"album_name":"Pioneer",
"img":[
{
"thumb": ["pioneer.jpg"]
},
{
"large":["IMG_8561.jpg","IMG_8567.jpg", "IMG_8568.jpg"]
}
],
"cabin_id":"25",
"sleeps":"2",
"description":"1 Room",
"number_of_bedrooms":"1",
"bedrooms":
{
"bedroom1":"1 Queen",
"bedroom2":"",
"bedroom3":"",
"bedroom4":""
},
"pull_out":"",
"living_room":"",
"bathrooms":"",
"bathroom_info":"Bath with Tub/Shower",
"other_info":"",
"winter_info":"Winter RR Only",
"winter_rate":"198.90",
"summer_info":"Summer RR Only",
"summer_rate":"198.90",
"cabin_description":"One cozy cabin built in the log style with country charm in mind. Located along the hillside of the sledding hill overlooking the ranch. Also has one small dorm refrigerator and working fireplace with firewood supplied by the ranch."
}
]
The AngularJS
<table class="table table-hover">
<tr ng-repeat="x in cabins | filter:search:true">
<td>
<div>
<a data-lightbox="{{x.name}}" data-title="{{x.name}}" href="_img/_lodging/{{x.album_name}}/1200w/{{x.img[1].large[0]}}">
<img class="cabin-thumb-main" ng-src="_img/_lodging/cabin_tn/{{x.img[0].thumb[0]}}">
</a>
<a ng-repeat="y in x.img[1].large" data-lightbox="{{x.name}}" data-title="{{x.name}}" href="_img/_lodging/{{x.album_name}}/1200w/{{y}}" ></a>
<td>
<h3><strong>{{x.name}}</strong></h3>
<span>{{x.description}}</span><span><small> (Sleeps {{x.sleeps}})</small></span>
<h4>{{x.other_info}}</h4>
<br>
<h4>Description</h4>
<p>{{x.cabin_description}} </p>
<h5>Bed & Bath</h5>
<p>{{x.bedrooms.bedroom1}}</p>
<p>{{x.bedrooms.bedroom2}}</p>
<p>{{x.bedrooms.bedroom3}}</p>
<p>{{x.bedrooms.bedroom4}}</p>
<p>{{x.pull_out}}</p>
<p>{{x.bathroom_info}}</p>
<br>
</tr>
</table>
The call using ng-app
$scope.search = {};
$http.get('_js/lodging.json').then(function (response) {
$scope.cabins = response.data;
$scope.images = []
angular.forEach($scope.cabins, function(item){
angular.forEach(item.img, function(i){
var large_img = i.large;
// return large_img;
console.log(large_img);
})
})
});
Link to Test Page
<div ng-repeat="img in x.img[1].large">
<p>{{img}}</p>
</div>
Try this and here is the working plunker
Now since you have fetched the images you can add them to ng-src.

Using splice on dynamic array in Angular repeater

I have an issue when trying to delete an object from an array using splice. I have an array that is dynamically created through a UI and stored in a scope variable called $scope.productAttributes.Products. This is an example of what it looks like...
[
{
"ProductLabel":"Net",
"Code":"ela",
"Site":"SITE1"
},
{
"ProductLabel":"Link",
"Code":"eli",
"Site":"SITE1"
},
{
"ProductLabel":"24-port managed PoE switch",
"Code":"24p",
"Site":"SITE2"
},
{
"ProductLabel":"Dedicated Firewall",
"Code":"ded",
"Site":"SITE2"
},
{
"ProductLabel":"Link",
"Code":"eli",
"Site":"SITE3"
},
{
"ProductLabel":"IPv4 Addresses",
"Code":"ip4",
"Site":"SITE3"
}
]
I then display that array in an angular repeater and group it by 'site' (which might be part of the problem)...
<div ng-repeat="(key, value) in productAttributes.Products | groupBy: 'Site'">
<strong>{{key}}</strong>
<div ng-repeat="site in value">
<h4>{{site.ProductLabel}}</h4>
<sapn href="" ng-click="deleteItem($index)" class="text-danger">Remove {{site.ProductLabel}}</span>
</div>
</div>
</div>
On the delete button I pass in the index of the object and use the splice function...
$scope.deleteItem = function (index) {
$scope.productAttributes.Products.splice(index, 1);
};
So the issue is that the $index is always zero (I noticed this from a console.log) as I mentioned that I think it might be down to the groupBy but I am not sure. anyone know whats going wrong? Thanks
UPDATE:
It would seem the problem is with the $index in the nested repeater. So if the json above the structure would be...
SITE1:
Product: Net - $index: 0
Product: Link - $index: 1
SITE2:
Product: 24-port - $index: 0
Product: Dedicated - $index: 1
SITE3:
Product: Link - $index: 0
Product: IPV4 - $index: 1
So if I try to delete the IPV4 product in SITE3, it removes the LINK product in Site1 as it has the same $index. any ideas how I can fix that?
We can not rely on $index as it does not contain the updated value after you remove an item from array.
Pass the object dynamically from UI and delete it from model using below code:
In Html:
<div ng-repeat="(key, value) in productAttributes.Products | groupBy: 'Site'">
<strong>{{key}}</strong>
<div ng-repeat="site in value">
<h4>{{site.ProductLabel}}</h4>
<sapn href="" ng-click="deleteItem(site)" class="text-danger">Remove {{site.ProductLabel}}</span>
</div>
</div>
</div>
In JavaScript:
$scope.productAttributes.Products.splice
($scope.productAttributes.Products.indexOf(site), 1);
This causes model to update with updates values in repeater and re-renders it on UI.
OK - I ended up doing it this way and it seems to work
$scope.deleteItem = function (item) {
var index = $scope.productAttributes.Products.indexOf(item);
$scope.productAttributes.Products.splice(index, 1);
};
So passing in the whole object seems to have worked. I'm not sure why.

How to handle array in angular js/HTML

I'm using a Web API to display values in HTML via Angular.
I have 4 attributes: Id, MovieName, Date and Cast. Cast is an array. I don't know how to handle the Cast attribute.
Controller.js
app.controller('MyController', function ($scope, MyService) {
$scope.getemploy = function () {
var promise = MyService.getMovies();
promise.then(function (pl) {
$scope.Movies= pl.data
},
function (error) {
$log.error('Some Prob', error);
});
}
GetMovies()--> will bring movie details(Cast attribute will have male, female lead names in the array).
HTML File :
<tr ng-repeat="mov in Movies">
<td>{{mov.Id}}</td>
<td>{{mov.MovieName}}</td>
<td>{{mov.Date}}</td>
<td>{{mov.Cast}}</td>
</tr>
But it's not working. I think I'll need some other way to handle Cast attributes, whether in html or angular.
My Json output for your reference:
[
{
"_movieId": 1,
"_moviename": "Olympus Has Fallen",
"_releaseDate": 2013,
"_cast": [
"Gerard Butler",
"Dylan McDermott",
"Aaron Eckhart",
"Angela Bassett"
]
}
Can anyone please help?
But its not working....
Because according to posted JSON your receive, HTML should be with different keys. Try this:
<tr ng-repeat="mov in Movies">
<td>{{mov._movieId}}</td>
<td>{{mov._moviename}}</td>
<td>{{mov._releaseDate}}</td>
<td>{{mov._cast.join(', ')}}</td>
</tr>
I used simple join method of array to render comma separated list of actors. If you need something more specific, you will need to make use of one more ngRepeat on mov._cast array (see Danny's answer).
I'm not sure what you mean by the Cast is not working, but I'm guessing it's just showing the JSON object in the HTML? You could show all the cast members in a list doing something like:
<tr ng-repeat="mov in Movies">
<td>{{mov.Id}}</td>
<td>{{mov.MovieName}}</td>
<td>{{mov.Date}}</td>
<td>
<ul>
<li ng-repeat="member in mov.Cast">{{ member }}</li>
</ul>
</td>
</tr>

Categories

Resources