angularjs ng-table/ng-repeat rows not loading - javascript

I am trying to follow the tutorial Here on using ng-Table. If I download the whole example from Git then it loads fine but trying to follow even the simplest example myself then the Column headers and filters load but there are no rows? If I add another row in the HTML manually it does appear so the issue seems to either be with the data binding or the ng-repeat. There are no errors showing in the console.
Example Code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-resource.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-route.js"></script>
<link rel="stylesheet" ; href="https://unpkg.com/ng-table#4.0.0/bundles/ng-table.css">
<script src="https://unpkg.com/ng-table#4.0.0/bundles/ng-table.js"></script>
</head>
<body>
<div ng-app="MyApp" ng-controller="MyCtrl">
<table ng-table="vm.tableParams" class="table" show-filter="true">
<tr ng-repeat="user in $data">
<td title="'Name'" filter="{ name: 'text'}" sortable="'name'">
{{user.name}}
</td>
<td title="'Age'" filter="{ age: 'number'}" sortable="'age'">
{{user.age}}
</td>
</tr>
</table>
</div>
<script>
var app = angular.module("MyApp", ["ngTable"]);
app.controller('MyCtrl', function ($scope, NgTableParams) {
var self = this;
var data = [{ name: "Moroni", age: 50 } /*,*/];
self.tableParams = new NgTableParams({}, { dataset: data });
});
</script>
</body>
</html>

You haven't specified your controller reference.
Change the code to <div ng-app="MyApp" ng-controller="MyCtrl as vm"> and it will work as you expect it.
Working example: http://codepen.io/DeividasK/pen/qrWqey?editors=1010

You didn't assign your object in scope
try this below code instead of your code
app.controller('MyCtrl', function ($scope, NgTableParams) {
var self = this;
self.data = [{ name: "Moroni", age: 50 } /*,*/];
self.tableParams = new NgTableParams({}, { dataset: self.data });
});

This is ng table, the problem is you are using the controller as vm, just remove the vm or put controller as vm and it's work.
<table ng-table="tableParams" class="table" show-filter="true">
<tr ng-repeat="user in $data">
<td title="'Name'" filter="{ name: 'text'}" sortable="'name'">
{{user.name}}
</td>
<td title="'Age'" filter="{ age: 'number'}" sortable="'age'">
{{user.age}}
</td>
</tr>
</table>

Related

angularjs without controller ng-click not firing

I am practising angularjs. In below example, ng-click is not firing at all, not sure why. I actually not using any controller in my code, may be because of that, ng-click not firing?
index.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-app="myApp1">
<div ng-init="users=[{name: 'john', city: 'NY', order: 10},{name: 'james', city: 'washington', order: 20},{name: 'william', city: 'seattle', order: 30}]">
<h2>Customers</h2>
Search Customer: <input type="text" ng-model="searchText" placeholder="search customer here">
<br><br>
<table border="2">
<thead>
<tr>
<th ng-click="orderByProperty('name')">Name</th>
<th ng-click="orderByProperty('city')">City</th>
<th ng-click="orderByProperty('order')">Order</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users | filter : searchText | orderBy : orderByProperty : true">
<td>{{user.name | uppercase}}</td>
<td>{{user.city}}</td>
<td>{{user.order | currency}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
app.js
var myApp1 = angular.module('myApp1',[])
function orderByProperty(propertyName){
// alert('dsfdf')
return propertyName;
}
Please tell me what went wrong in above code? Is that mandatory to use controller in a code? If not used, ng-click do not work at all?
UPDATE
When I replaced ng-click with 'onclick', even is getting fired, but sorting functionality is not working.
UPDATE2: BELOW IS THE UPDATED CODE
index.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-app="myApp1">
<div ng-controller="MyController">
<div ng-init="users=[{name: 'john', city: 'NY', order: 10},{name: 'james', city: 'washington', order: 20},{name: 'william', city: 'seattle', order: 30}]">
<h2>Customers</h2>
Search Customer: <input type="text" ng-model="searchText" placeholder="search customer here">
<br><br>
<table border="2">
<thead>
<tr>
<th ng-click="orderByProperty('name')">Name</th>
<th ng-click="orderByProperty('city')">City</th>
<th ng-click="orderByProperty('order')">Order</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users | filter : searchText | orderBy : orderByProperty : true">
<td>{{user.name | uppercase}}</td>
<td>{{user.city}}</td>
<td>{{user.order | currency}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
app.js
var myApp1 = angular.module('myApp1',[])
myApp1.controller('MyController', ['$scope', function($scope){
$scope. orderByProperty = function(propertyName){
// alert('dsfdf')
return propertyName;
}
}])
Above I used controller, now evenT gets firing but sorting not working as expected..
Yes you need to have the ng-controller placed in order to get ng-click work.
When a controller is attached to the DOM via the ng-controller
directive, Angular will instantiate a new controller object, using the
specified controller's constructor function. A new child scope will be
available as an injectable parameter to the controller's constructor
function as $scope.
Read more on controller
As #Sajeetharan said, in angularjs all functions you call need to be declared in controllers, that is how it works
before using ng-click u must place ng-controller in your HTML.
<body ng-app="myApp1" ng-controller="myAppCtrl">
var myApp1 = angular.module('myApp1',[]);
myApp1.controller('myAppCtrl',['$scope',function ($scope) {
$scope.orderByProperty=function(propertyName){
// alert('dsfdf')
return propertyName;
}
}]);
To make it work, 2 places need to change:
Binding orderBy with a ng-model value.
var myApp1 = angular.module('myApp1',[])
myApp1.controller('MyController', ['$scope', function($scope){
$scope. orderByProperty = function(propertyName){
$scope.myorder = propertyName;
}
}])
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-app="myApp1">
<div ng-controller="MyController">
<div ng-init="users=[{name: 'john', city: 'NY', order: 10},{name: 'james', city: 'washington', order: 20},{name: 'william', city: 'seattle', order: 30}]">
<h2>Customers</h2>
Search Customer: <input type="text" ng-model="searchText" placeholder="search customer here">
<br><br>
<table border="2">
<thead>
<tr>
<th ng-click="orderByProperty('name')">Name</th>
<th ng-click="orderByProperty('city')">City</th>
<th ng-click="orderByProperty('order')">Order</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users | filter : searchText | orderBy : myorder : true">
<td>{{user.name | uppercase}}</td>
<td>{{user.city}}</td>
<td>{{user.order | currency}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

AngularJS - How to get processed HTML output from $compile?

I have the following function which is fetching custom HTML template and passing some values into the scope to generate 'report table'. Because the template is not visible to the user but processed output is directly sent to another function I used $compile function.
It seems that values passed into the $scope are processed correctly but i am not able to get pure HTML result.
I tried to do it by this way:
var templateUrl = $sce.getTrustedResourceUrl('report.html');
$templateRequest(templateUrl).then(function(template) {
$scope.rows = reportData;
var compTest = $compile(template)($scope);
console.log(compTest); //IT RETURNS A LOT OF VALUES BUT NOT HTML OUPUT OF THE PROCESSED TEMPLATE
}, function() {
// An error has occurred
});
Many thanks for any advice.
Results is following:
HTML content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Report</title>
</head>
<body>
<table>
<thead>
<td>
</td>
<td>
Breakfast
</td>
<td>
Lunch
</td>
<td>
Dinner
</td>
<td>
Snack
</td>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td>TEST</td>
<td>40</td>
<td>20</td>
<td>30</td>
<td>10</td>
</tr>
</tbody>
</table>
</body>
</html>
$compile will return a function which will then be executed by scope which in turn will returns a jQlite wrapped DOM object. So you can use outerHTML to get the Template string
or
You can use $interpolate as shown below
Demo
angular.module('myApp', []);
angular
.module('myApp')
.controller('MyController', MyController);
function MyController($scope, $compile, $interpolate) {
var template = '<a ng-click="handler()">click handler</a>';
this.tmpl = $compile(template)($scope)[0].outerHTML;
this.tmplInt = $interpolate(template)($scope);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyController as MC">
<p><b>using $compile along with outerHTML </b>{{MC.tmpl}}</p>
<p><b>using $interpolate </b>{{MC.tmplInt}}</p>
</div>
</div>

Show /hide warning messag based on filtered outputs ng-repeat

Please find the attached fiddle where I want to post a warning mesaage "No data to display" if the filter fais to match any results in the button clicks.
Fiddle ng-repeat filter
I have given condition for both table and message so that they should be displayed as and when the clicks happen.
<div ng-show="name===null">No results</div>
The above message should be displayed if there are no satisfying data in the table based on link clicks,together the table should be hidden.
I tried to give conditions based on property name but its not working.
Check your fiddle http://jsfiddle.net/w0L4o8jm/6/
By default I am making filter with Fruit. You can change it in the controller.
Coming to the answer, Calculate the filtered items length according to the filter. If length 0 or name '', then show no results. Otherwise show results in the table. Just copy paste the below code in your fiddle and check it out.
<html ng-app="app">
<a ng-click="name = 'Fruit'">Fruit</a>
<a ng-click="name = 'Nut'">Nut</a>
<a ng-click="name = 'Seed'">Seed</a>
<body ng-controller="main">
<a ng-click="name = ''">clear filter</a>
<br> <br> <br>
<div ng-show="(name=='' || !filtered.length)">No results</div>
<div ng-repeat="link in filtered = (links|filter:name)"></div>
<table class="table" ng-show="(filtered.length != 0 && name!='')">
<thead>
<tr>
<th>Target</th>
<th>Level</th>
<tr>
<tbody>
<tr ng-repeat="link in links|filter:name">
<td>
{{link.name}}
</td>
<td>
{{link.category}}
</td>
</tr>
</tbody>
</table>
</body>
Controller code
var app = angular.module('app', []);
app.controller('main', function($scope) {
$scope.filters = { };
$scope.name='Fruit';
$scope.links = [
{name: 'Apple', category: 'Fruit'},
{name: 'Pear', category: 'Fruit'},
{name: 'Almond', category: 'Nut'},
{name: 'Mango', category: 'Fruit'},
{name: 'Cashew', category: 'Nut'}
];
});
For Angular prior to 1.3
Assign the results to a new variable (e.g. filtered) and access it:
<div ng-repeat="link in filtered = (links|filter:name)"></div>
For Angular 1.3+
Use an alias expression (Docs: Angular 1.3.0: ngRepeat, scroll down to the Arguments section):
<div ng-repeat="link in links|filter:name as filtered"></div>
Try to use this code
Demo
<body ng-app="app" ng-controller="main">
<a ng-click="name = 'Fruit'">Fruit</a>
<a ng-click="name = 'Nut'">Nut</a>
<a ng-click="name = 'Seed'">Seed</a>
<a ng-click="name = ''">clear filter</a>
<br> <br> <br>
<div ng-show="name ==''">No results</div>
<table class="table" ng-show="name!=''">
<thead>
<tr>
<th>Target</th>
<th>Level</th>
<tr>
<tbody>
<tr ng-repeat="link in links | filter:name">
<td>
{{link.name}}
</td>
<td>
{{link.category}}
</td>
</tr>
</tbody>
</table>
var app = angular.module('app', []);
app.controller('main', function($scope) {
$scope.filters = { };
$scope.name = '';
$scope.links = [
{name: 'Apple', category: 'Fruit'},
{name: 'Pear', category: 'Fruit'},
{name: 'Almond', category: 'Nut'},
{name: 'Mango', category: 'Fruit'},
{name: 'Cashew', category: 'Nut'}
];
});
Here you go! Updated fiddle
You had a few issues in there:
your ng-controller was on a div but you were setting name outside controller
<div ng-show="name===null">No results</div> Here you were comparing name with null but you were setting it to empty string in clear filter
Hope it helps!
Edit: On clear filter it was not showing all the items. Fixed and updated fiddle

ng-repeat not working in angular

I am trying to pass a php Laravel array of objects with the name $event to my javascript part of the app and I am having issues with looping through the results later on.
Basically what I am doing is this
$events = Event::orderBy('id', 'DESC')->orderBy('resolved', 'desc')->get(); //get events
return View::make('events.index', compact('events')); //pass events to view
And then this is my view
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
var myevents = JSON.parse('<?php echo json_encode($events) ?>');
</script>
<div class="col-sm-12" ng-app="myApp2" ng-controller="checkboxController">
<table class="table" id="keywords" cellspacing="0" cellpadding="0">
<tr ng-repeat="event in myevents" >
<td> {{event.category}}</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</div>
</table>
</div>
</div>
<script src="http://dsproject.dev:8000/js/jquery-1.11.1.min.js"></script>
<script src="http://dsproject.dev:8000/js/bootstrap.min.js"></script>
<script src="http://dsproject.dev:8000/js/checkboxes.js"></script>
</body>
</html>
This is my controller
var myApp2 = angular.module('myApp2',[]);
myApp2.controller('checkboxController', ['$scope', function($scope) {
//var events = [];
// $scope.some = 'hehehhehehe';
//events.($scope.event);
$scope.myevents = myevents;
console.log($scope.myevents);
/*$scope.toggle = function(id) {
alert(id);
};*/
}]);
The output I get is just {{event.category}} with no value at all. When I do console.log(myevents) or console.log($scope.myevents) in my controller I get the array of objects displayed in the console like this
What am I doing wrong and how would I fix this?
The {{ curlies are being parsed by laravel, you have to change interpolation in angular.
myApp2.config(function($interpolateProvider){
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
});
and then use {[{ and }]} for the angular part of variables.

How to display only selected records in the result table

There are two tables using the same source. These tables are using source binding of kendo templates. At present the source for both these tables are employees. Both these tables are displaying the same data.
Now, we need to modify it to show only check-box selected records in the result table. Also, when user clicks on the delete button on the result table, the check-box should be un-selected in the section table.
What modification do we need to do to make it work in MVVM?
Head
<head>
<title>MVVM Test</title>
<script type="text/javascript" src="lib/kendo/js/jquery.min.js"></script>
<script type="text/javascript" src="lib/kendo/js/kendo.web.min.js"></script>
<!----Kendo Templates-->
<script id="row-template" type="text/x-kendo-template">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: age"></td>
<td><button type="button" data-bind="click: deleteEmployee">Delete</button></td>
</tr>
</script>
<script id="selection-table-template" type="text/x-kendo-template">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: age"></td>
<td>
<input type="checkbox" name="selection" value="a">
</td>
</tr>
</script>
<!--MVVM Wiring using Kendo Binding-->
<script type="text/javascript">
$(document).ready(function () {
kendo.bind($("body"), viewModel);
});
</script>
</head>
MVVM
<script type="text/javascript">
var viewModel = kendo.observable({
// model definition
employees: [
{ name: "Lijo", age: "28" },
{ name: "Binu", age: "33" },
{ name: "Kiran", age: "29" }
],
personName: "",
personAge: "",
//Note: Business functions does not access any DOM elements using jquery.
//They are referring only the objects in the view model.
//business functions (uses "this" keyword - e.g. this.get("employees"))
addEmployee: function () {
this.get("employees").push({
name: this.get("personName"),
age: this.get("personAge")
});
this.set("personName", "");
this.set("personAge", "");
},
deleteEmployee: function (e) {
//person object is created using "e"
var person = e.data;
var employees = this.get("employees");
var index = employees.indexOf(person);
employees.splice(index, 1);
}
});
</script>
Body
<body>
<table id="selectionTable">
<thead>
<tr>
<th>
Name
</th>
<th>
Age
</th>
</tr>
</thead>
<tbody data-template="selection-table-template" data-bind="source: employees">
</tbody>
</table>
<br />
<hr />
<table id="resultTable">
<thead>
<tr>
<th>
Name
</th>
<th>
Age
</th>
</tr>
</thead>
<!--The data-template attribute tells Kendo UI that the employees objects should be formatted using a Kendo UI template. -->
<tbody data-template="row-template" data-bind="source: employees">
</tbody>
</table>
</body>
REFERENCES
set method - ObservableObject - Kedo API Reference
set method - kendo Model - Kedo API Reference
Filtering source in a Kendo Template
Kendo-UI grid Set Value in grid with Javascript
First things first.
If you remove the object from the viewModel when you delete it, it will be removed from your source table as well. You would need two arrays to handle this if you wanted it to be the way you describe. But based on the first part of your question, I thought I would post a solution.
HTML
<script id="row-template" type="text/x-kendo-template">
<tr data-bind="visible: isChecked">
<td data-bind="text: name"></td>
<td data-bind="text: age"></td>
<td>
<button type="button" data-bind="click: deleteEmployee">Delete</button>
</td>
</tr>
</script>
<script id="selection-table-template" type="text/x-kendo-template">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: age"></td>
<td>
<input type="checkbox" name="selection" data-bind="checked: isChecked"/>
</td>
</tr>
</script>
<table id="selectionTable">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody data-template="selection-table-template" data-bind="source: employees"/>
</table>
<br />
<hr />
<table id="resultTable">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody data-template="row-template" data-bind="source: employees"/>
</table>
JAVASCRIPT
var viewModel = kendo.observable({
employees: [
{ name: "Lijo", age: "28", isChecked: true },
{ name: "Binu", age: "33", isChecked: true },
{ name: "Kiran", age: "29", isChecked: true }
],
personName: "",
personAge: "",
addEmployee: function () {
this.get("employees").push({
name: this.get("personName"),
age: this.get("personAge")
});
this.set("personName", "");
this.set("personAge", "");
},
deleteEmployee: function (e) {
var person = e.data;
var employees = this.get("employees");
var index = employees.indexOf(person);
var employee = employees[index];
//set
employee.set('isChecked', false);
}
});
$(document).ready(function () {
kendo.bind($("body"), viewModel);
});
JSFiddle
Fiddle
Summary
Use data-bind="visible: isChecked" in "row-template" to show only selected records in the bottom table.
Make template for checkbox as
<input type="checkbox" name="selection" data-bind="checked: isChecked"/>
In the delete function, use following
employee.set('isChecked', false);
Use a dictionary to store [employee, boolean] to store employee and the checkbox state, and bind the dictionary to the view
Check this

Categories

Resources