How to loop in AngularJs - javascript

I am new to Angular, maybe is a fool question.
I have a result from my AngularJs and I return an Array of values:
This is the code:
$scope.searchTitle = function () {
$http.post('/svn/cms2/branches/create_function/cms/includes/find.php', {
name_title: $scope.title
})
.success(function (result) {
console.log(result);
$scope.resultName = result;
$scope.ok = "we post";
})
.error(function (data, status) {
console.log(data);
});
};
And now i have the resultName in the html and i can see the result if i do this:
<p>{{ resultName[0].article_titile }}</p>
Question:
I want to display all the array. How can I display all?
P.S.:
I use this and it is not work
<tr ng-repeat="i in [3] | toRange" >
<td>{{ resultName[i].article_titile }}</td>
</tr>
But is not working

You need to use an iterator variable (e.g. result) with your resultName array in your ng-repeat:
<tr ng-repeat="result in resultName | toRange" >
<td>{{ result.article_titile }}</td>
</tr>

Related

Vue, multifilter for html table

I'm using vue to take a returned object from an axios call and fill in an html table with it. I have the table exactly as I want but I'm wondering if there's a way (don't want to convert this whole thing to datatables) to make each header a filter for the table so that multiple columns can be filtered for the whole table. Basically, say the rows have items like 'Truck', 'Trailer' and 'Container' for the 'Resources' column. I'm thinking of a dropdown filter on the header of that column that would show rows for all resources or I could select 'Truck' so that only rows with 'Truck' show on the table.
Does that make sense? Is there an inherent way to do this with Vue?
<table style="width:100%; text-align:center;">
<thead>
<tr>
<th>Title</th>
<th>Resource</th>
<th>Location</th>
<th>Status</th>
</tr>
</thead>
<tbody v-for="dateEvent in dateEvents">
<tr>
<td v-if="dateEvent.id === '2'">{{ dateEvent.title }}</td>
<td v-if="dateEvent.id === '2'">{{ dateEvent.resource }}</td>
<td v-if="dateEvent.id === '2'">{{ dateEvent.location }}</td>
<td v-if="dateEvent.id === '2'">{{ dateEvent.status }}</td>
</tr>
</tbody>
</table>
data () {
return {
dateEvents: []
},
created() {
this.fetchItems();
},
methods: {
fetchItems() {
axios.get('/home/resource_items')
.then(response => {
// handle success
console.log(response.data)
this.dateEvents = response.data
})
.catch(function(error) {
console.log(error)
})
.finally(function() {})
}
}
You can use computed functionality to automatically calculate:
a filtered array of dateEvents to display in the table
an array of titles to display in the filter
an array of resources to display in the filter
an array of locations to display in the filter
an array of statuses to display in the filter
Here is an example:
...
<select v-model="filters.title">
<option v-for="title in titles" :value="title">{{ title }}</option>
</select>
<select v-model="filters.resource">
<option v-for="resource in resources" :value="resource">{{ resource }}</option>
</select>
<select v-model="filters.location">
<option v-for="location in locations" :value="location">{{ location }}</option>
</select>
<select v-model="filters.status">
<option v-for="status in statuses" :value="status">{{ status }}</option>
</select>
<button #click="reset">Reset</button>
...
<tbody v-for="dateEvent in filtered">
<tr>
<td>{{ dateEvent.title }}</td>
<td>{{ dateEvent.resource }}</td>
<td>{{ dateEvent.location }}</td>
<td>{{ dateEvent.status }}</td>
</tr>
</tbody>
...
...
data() {
return {
dateEvents: [],
filters: {
title: null,
resource: null,
location: null,
status: null,
},
};
},
computed() {
filtered() {
return this.dataEvents
.filter(dataEvent => !this.filters.title || dataEvent.title === this.filters.title),
.filter(dataEvent => !this.filters.resource || dataEvent.resource === this.filters.resource),
.filter(dataEvent => !this.filters.location || dataEvent.location === this.filters.location),
.filter(dataEvent => !this.filters.status || dataEvent.status === this.filters.status);
},
titles() {
return this.dataEvents
.map(dataEvent => dataEvent.title)
.filter((title, index, self) => self.indexOf(title) === index);
},
resources() {
return this.dataEvents
.map(dataEvent => dataEvent.resource)
.filter((resource, index, self) => self.indexOf(resource) === index);
},
locations() {
return this.dataEvents
.map(dataEvent => dataEvent.location)
.filter((location, index, self) => self.indexOf(location) === index);
},
statuses() {
return this.dataEvents
.map(dataEvent => dataEvent.status)
.filter((status, index, self) => self.indexOf(status) === index);
},
},
methods: {
reset() {
this.filters.title = null;
this.filters.resource = null;
this.filters.location = null;
this.filters.status = null;
},
},
...

angular ng-repeat needs changes in data that is obtained from json

I have a JSON object that does not have proper data. So i want to replace the obtained value with one from a lookup table, but I'm not sure how to replace the value of the data corresponding to the lookup table.
lookupTable = {
"pizza": function() {
console.log("food");
},
"house": function() {
console.log("building");
},
"air": function() {
console.log("nothing");
}
};
$scope.value =lookupTable["pizza"]()
my html file has
<tr ng-repeat="x in names">
<td>{{ x.lookupTable["pizza"]() }}</td>
My code is at http://plnkr.co/edit/w4lOFVRo9vSi8vqfbpXV?p=preview
Any help is appreciated!
Here are some problems in your code from the link you provided:
Functions on the lookupTable is not returning anything as pointed out in the previous answers.
lookupTable is not a property of $scope.names so using x.lookupTable is invalid.
To make it work, you should:
The functions from lookupTable should return the actual values instead of using console.log
Bind lookupTable to $scope
Use lookupTable directly inside the view as it is bound to $scope
Here is the relevant code:
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ lookupTable[x.Name]() }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("data.json")
.then(function(response) {
$scope.names = response.data.records;
});
$scope.lookupTable = {
"pizza": function() {
return 'food';
},
"house": function() {
return 'building';
},
"air": function() {
return "nothing";
}
};
});
</script>
Your code is very confused. I tried to edit your plunker, maybe is easier to see that to explain.
<!DOCTYPE html>
<html>
<scriptsrc="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ lookupTable[x.Name] }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("data.json")
.then(function(response) {
$scope.names = response.data.records;
});
lookupTable = {
"pizza": "food",
"house": "building",
"air": "nothing"
};
$scope.lookupTable = lookupTable;
$scope.value = lookupTable["pizza"]
console.log(lookupTable["house"])
});
</script>
Looking at your code, I am not sure what you want to achieve.
The ng-repeat gives you three objects out of names, but none of them has a lookupTable member, so {{ x.lookupTable["pizza"] }} fails silently.
You can make it visible, if you just bind to {{ x }}

angular ng-repeat not working as expected

<body ng-app="myApp">
<div ng-controller="customersCtrl">
<table>
<tr ng-repeat="res in customers">
<td>{{ $index + 1 }}</td>
<td>{{ res.Name }}</td>
<td>{{ res.City }}</td>
</tr>
</table>
</div>
</body>
var myApp = angular.module('myApp', []);
myApp.controller("customersCtrl", function ($scope,$http) {
$http.post('Default.aspx/Getdata', { data: {} })
.success(function (response) {
$scope.customers = response.d;
})
.error(function (data, status, headers, config) {
alert(status+"-------"+data);
});
});
server side function:
[WebMethod]
public static string Getdata()
{
List<customors> people = new List<customors>{
new customors{Name = "biss",City="Lebanon"},
new customors{Name = "jiji",City="America"}
};
JavaScriptSerializer serialiser = new JavaScriptSerializer();
string json = serialiser.Serialize(people);
return json; // [{"Name":"biss","City":"Lebanon"},{"Name":"jiji","City":"America"}]
}
public class customors
{
public string Name{get;set;}
public string City{get;set;}
}
but No result is being displayed . what i am doing wrong ?
Replace your succes function with this:
.success(function (response) {
$scope.customers = JSON.parse(response.d);
})
Your objects are in string format, it will never be able to find .Name if 'Name' is a string. Parsing your response will fix this.
As RGraham stated, this is not ideal. You want to handle this correctly on your server's side.

VueJS Resource plugin example

I am attempting to display a JSON response from PHP. I was pointed in the direction of the VueJS resource plugin. Unfortunately, the examples it gives are vague at best.
Is anyone able to provide a simple example of how to display the return JSON object in a list?
HTML:
<table id="list-items">
<tr v-for="item in items">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</table>
JS:
new Vue({
el: '#list-items',
data: {
items: []
},
ready: function() {
this.items = this.getItems();
},
methods: {
getItems: function() {
this.$http.get('items.php', function(data){
this.items = data;
});
}
}
});
items.php must return a JSON encoded array like this:
[{id: 1, name: 'foo'},{id: 2, name: 'bar'}]
In vue 1.0.1 you can use v-for instead of v-repeat like this:
<table id="list-items">
<tr v-for="item in items">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</table>
I think you are looking for
{{ $data | json }}

AngularJS : directive does not update scope after $http response in parent scope

I got this directive:
.directive('studentTable', [function() {
return {
restrict: 'A',
replace: true,
scope: {
students: "=",
collapsedTableRows: "="
},
templateUrl: 'partials/studentTable.html',
link: function(scope, elem, attrs) {
...
}
}
}
Template:
<table class="table">
<thead>
<tr>
<th><b>Name</b></th>
<th><b>Surname</b></th>
<th><b>Group</b></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="student in students track by $index">
<td>{{ student.name }}</td>
<td>{{ student.surname }}</td>
<td>{{ student.group }}</td>
</tr>
</tbody>
</table>
Use directive in my html like this:
<div student-table students="students"
collapsedTableRows="collapsedTableRows"></div>
And the parent controller:
.controller('SchoolController', ['$scope', 'User', function($scope, User){
$scope.students = [];
$scope.collapsedTableRows = [];
$scope.search = function(value) {
if(value) {
var orgId = $state.params.id;
var search = User.searchByOrg(orgId, value);
search.success(function (data) {
$scope.students = data;
$scope.collapsedTableRows = [];
_(data).forEach(function () {
$scope.collapsedTableRows.push(true);
});
});
}
}
}])
Now at the beginnig, the table is empty, because no users in students array. After I click search, and get list of students object, I put them to scope variable, but the directive does not update, neither it find change in model (scope.$watch('students',...). What am I missing?
P.S. If I simulate the data using $httpBackend, directive works as it should.
Please make sure that data object returning array of student because somtimes you have to use data.data that simple demo should helps you:
http://plnkr.co/edit/UMHfzD4oSCv27PnD6Y6v?p=preview
$http.get('studen.json').then(function(students) {
$scope.students = students.data; //<-students.data here
},
function(msg) {
console.log(msg)
})
You should try changing the controller this way
...
$scope.$apply(function() {
$scope.students = data;
})
...
This will start a digest loop, if it's not already in progress.
Another form that will do almost the same thing is this:
...
$scope.students = data;
$scope.$digest()
...
PS:
The first method is just a wrapper that execute a $rootScope.$digest() after evaluating the function, considering that a $digest evaluates the current scope and all it's children calling it on the $rootScope is pretty heavy.
So the second method should be preferred if it works.

Categories