angular datatables change number of columns - angularjs

I'm using angular-datatables ( http://l-lin.github.io/angular-datatables/#/welcome ).
I put up this Plunker: http://plnkr.co/edit/ZRvQt7KBZam22Yt5S4QC?p=preview .
I'm trying to dynamically change the number of columns in my datatable, based on data pulled from the server. Is there a way to do this ? I'm using the control "the Angular way':
<table datatable="ng"></table>
Thank you in advance for taking time to look at this.
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />'); </script>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-controller="MainCtrl as mCtrl">
<table id="dtFeeDetails" datatable="ng" dt-options="mCtrl.dtOptionsForFeeDetails" dt-column-defs="mCtrl.dtColumnDefs" dt-instance="mCtrl.dtInstance">
<tbody>
<tr dt-rows ng-repeat="f in feeData">
<td ng-repeat="c in colHeadings">{{f[c.Value]}}</td>
</tr>
</tbody>
</table>
<p>
<button type="button" ng-click="changeColumnDefs()">Change column defs</button>
</p>
<script data-require="jquery#1.10.1" data-semver="1.10.1" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="//cdn.datatables.net/1.10.1/js/jquery.dataTables.js"></script>
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script type="text/javascript" src="https://rawgithub.com/l-lin/angular-datatables/dev/dist/angular-datatables.min.js"></script>
<script src="app.js"></script>
app.js
var app = angular.module('plunker', ['datatables']);
app.controller('MainCtrl', function($scope, DTOptionsBuilder, DTColumnBuilder, DTColumnDefBuilder) {
var vm = this;
$scope.feeData = [{ val1: 'data1'}, { val1: 'data2'}];
$scope.colHeadings = [{ Value: 'val1' }];
vm.dtInstance = {};
vm.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(0).withTitle($scope.colHeadings[0].Value)
];
vm.dtOptionsForFeeDetails = DTOptionsBuilder.newOptions();
var dtFeeDetailsID = "dtFeeDetails";
$scope.changeColumnDefs = function() {
//$('#' + dtFeeDetailsID).DataTable().destroy();
//$('#' + dtFeeDetailsID).dataTable();
// this won't work, because we're changing the number of columns
$scope.colHeadings = [{ Value: 'val1' }, { Value: 'val2' }];
$scope.feeData = [{ val1: 'data3', val2: 'data5'}, { val1: 'data4', val2: 'data6'}];
vm.dtColumnDefs = [];
vm.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(0).withTitle($scope.colHeadings[0].Value),
DTColumnDefBuilder.newColumnDef(0).withTitle($scope.colHeadings[1].Value)
];
// this will work, because we're keeping the same number of columns
//$scope.colHeadings = [{ Value: 'val2' }];
//$scope.feeData = [{ val2: 'data3'}, { val2: 'data4'}];
//vm.dtColumnDefs = [];
//vm.dtColumnDefs = [
// DTColumnDefBuilder.newColumnDef(0).withTitle($scope.colHeadings[0].Value),
// ];
};
});

Related

AngularJs, Search one array against another

So i have two arrays, One looks a little liek this
$scope.users = {id: 1, email: xxx} {id: 2, email: xxx}....
and i have this one
$scope.booking = {id: 20, regid: 2} ....
So the users is being displayed in a table at the moment.
however if the user has a booking, i want the table row to have a red flag against it (cant share table but its a basic ng-repeat) So if the usersid exists the regid in the booking array, push something to the user
Any help would be wicked
First of All your $scope.users and $scope.booking are objects not arrays...
i make an example how to know if users has book, so heres is the code and the
plnkr
the magic is in the foreach and for loops.
HTML
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<table>
<thead>
<th>ID</th>
<th>NAME</th>
<th>HAS BOOK</th>
</thead>
<tbody>
<tr ng-repeat="user in users">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.hasBook}}</td>
</tr>
</tbody>
</table>
</body>
</html>
CONTROLLER
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.users = [
{id:1, name:'john'},
{id:2, name:'barney'},
{id:3, name:'moroni'},
{id:4, name:'adam'},
{id:5, name:'sam'}
];
$scope.books = [
{id:1, regId:1, name:'book1'},
{id:2, regId:2, name:'book1'},
{id:5, regId:3, name:'book1'},
];
angular.forEach($scope.users, function(value, index){
for(var i =0; i< $scope.books.length; i++){
if(value.id === $scope.books[i].id){
value.hasBook = true;
}
}
});
console.log($scope.users);
});
You can use filters to find if any user with a conrcrete userid is in booking table.
Check this example:
[http://jsbin.com/ewitun/1/edit?html,js,output][1]

Bitmask checkbox group in angular

Quite straightforward, but I am fairly new to angular, and I think I have bitwise-sick, so I am kinda stuck :
// Checkboxes control existence of value in an array
var app = angular.module('myApp', []);
app.controller('MainController', function($scope) {
$scope.bitMaskFromDB = 5;
$scope.fruits = [{value:1, label: 'apple'}, {value:2, label:'orange'}, {value:4, label:'pear'}, {value:8, label:'naartjie'}];
});
app.directive('bitMask', function() {
return {
scope: {
bitMask: '=',
value: '#'
},
link: function(scope, elem, attrs ) {
var handler = function(setup) {
if (setup){
var checked = scope.bitMask&scope.value;
elem.prop('checked', checked);
}else{
var checked = elem.prop('checked');
if (!scope.bitMask&scope.value)
scope.bitMask |= scope.value
// elem.prop('checked', !checked);
scope.bitMask ^= scope.value
}
console.log ('bit = '+ scope.bitMask)
// console.log ('value = '+ scope.value)
// console.log ('checked ='+ checked)
};
var setupHandler = handler.bind(null, true);
var changeHandler = handler.bind(null, false);
elem.on('change', function() {
scope.$apply(changeHandler);
});
scope.$watch('bitMask', setupHandler, true);
}
};
});
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script src="app.js"></script>
</head>
<body ng-app="myApp" ng-controller='MainController'>
Bitmask checkboxes <br>
<span ng-repeat="fruit in fruits">
<input type='checkbox' value="{{fruit.value}}" bit-mask='bitMaskFromDB' > {{fruit.label}}<br />
</span>
<div>Current value of bitmask: {{bitMaskFromDB }}</div>
</body>
</html>
I failed to
1/ change the bit mask value correctly to checkbox values and
2/ show/bind value back to controller
http://plnkr.co/edit/3M8KNyOxMBgPwj9jf01q
You are very close my friend.
Here is the fix for you. Well, I don't really remember what they said about that. But there are weird behavior binding primitive to scope
updated your plkr
// Checkboxes control existence of value in an array
var app = angular.module('myApp', []);
app.controller('MainController', function($scope) {
$scope.IforgetHowTheyExplainThis = {bitMaskFromDB:5};
$scope.fruits = [{value:1, label: 'apple'}, {value:2, label:'orange'}, {value:4, label:'pear'}, {value:8, label:'naartjie'}];
});
app.directive('bitMask', function() {
return {
scope: {
bitMask: '=',
value: '#'
},
link: function(scope, elem, attrs ) {
var handler = function(setup) {
if (setup){
console.log ('value1 = '+ scope.value)
var checked = scope.bitMask&scope.value;
elem.prop('checked', checked);
}else{
console.log ('value2 = '+ scope.value)
var checked = elem.prop('checked');
if (!scope.bitMask&scope.value)
scope.bitMask |= scope.value
else
scope.bitMask ^= scope.value
}
console.log ('bit = '+ scope.bitMask)
// console.log ('value = '+ scope.value)
// console.log ('checked ='+ checked)
};
var setupHandler = handler.bind(null, true);
var changeHandler = handler.bind(null, false);
elem.on('change', function() {
scope.$apply(changeHandler);
});
scope.$watch('bitMask', setupHandler, true);
}
};
});
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script src="app.js"></script>
</head>
<body ng-app="myApp" ng-controller='MainController'>
Bitmask checkboxes <br>
<span ng-repeat="fruit in fruits">
<input type='checkbox' value="{{fruit.value}}" bit-mask='IforgetHowTheyExplainThis.bitMaskFromDB' > {{fruit.label}}<br />
</span>
<div>Current value of bitmask: {{IforgetHowTheyExplainThis.bitMaskFromDB }}</div>
</body>
</html>

get array values based on checkbox

I have a situation where there are 3 check box ("initially checked"). Since it as 3 check box it will use ng-repeat for 3 time and loops the division for there time. Now once i uncheck any of the check box it should display div for 2 time. So far ,
$scope.items = [
{id: 0, title: "apple",selected:true},
{id: 1, title: "orange",selected:true},
{id: 2, title: "grapes",selected:true},
];
On ng-click in each check box i have called a function test("apple").
$scope.test = function(vals) {
$scope.vl=[];
for(var i=0;i<$scope.items.length;i++) {
if($scope.items[i].title == vals) {
console.log("dnt push");
}
else {
$scope.vl.push({
id: $scope.items[i].id,
title: $scope.items[i].title,
selected:true
});
}
}
console.log("vl array");
console.log($scope.vl);
}
Problem I am facing is it works fine for 1st uncheck but not when i do for multiple uncheck. When i check unchecked its not loading div.
In HTML I am using like,
<div ng-repeat="item in vl"> some tags </div>
not quite sure about your question, but hope my answer can give you some hints.
plunker demo
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.items = [{
id: 0,
title: "apple",
selected: true
}, {
id: 1,
title: "orange",
selected: true
}, {
id: 2,
title: "grapes",
selected: true
}];
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<div ng-repeat="item in items">
<input type="checkbox" ng-model="item.selected">{{item.title}}
</div>
{{items | json}}
</body>
</html>
If and only if you want to put in an array the item who are checked :
http://plnkr.co/edit/DvoPBBvKf3AhYM4qcBhx?p=preview
html
<div ng-repeat="item in items">
<input type="checkbox"
ng-model="item.selected" ng-click="test(item.title)"> {{item.title}}
</div>
controller
$scope.test = function(vals) {
$scope.vl=[];
$scope.vlChecked=[];
for(var i=0;i<$scope.items.length;i++) {
if($scope.items[i].selected) {
$scope.vlChecked.push({
id: $scope.items[i].id,
title: $scope.items[i].title,
selected:true
});
}
}
console.log("vlChecked array");
console.log(JSON.stringify($scope.vlChecked));
}

need to update value of a property in all objects of an array of objects

In my angularjs application have an array of objects as shown below :
$scope.rowData = [{
"expNum": "678",
"itemHr": "10",
"highRe": "C"
}, {
"expNum": "978",
"itemHr": "3",
"highRe": "Y"
}]
Now on a click event I need to update 'itemHr' of each object in the array to some new value let say (25). I don't want to create new Array of object rather modify the existing only. If we can use angularjs utilities to do it or underscore library, both are fine for me. can any one help me with that.
Why not vanila js with for loop?
for(var i = 0; i<$scope.rowData.length; i++)
{
$scope.rowData[i].itemHr = 25;
}
or underscore
_.each($scope.rowData, function(item){ item.itemHr = 25;});
or angular
angular.forEach($scope.rowData,function(item){ item.itemHr = 25; });
var app = angular.module("myApp", ['ui.bootstrap']);
app.controller("maincontroller", function($scope) {
$scope.rowData = [{
"expNum": "678",
"itemHr": "10",
"highRe": "C"
}, {
"expNum": "978",
"itemHr": "3",
"highRe": "Y"
}];
$scope.update = function(){
for(var i = 0; i<$scope.rowData.length; i++)
{
$scope.rowData[i].itemHr = 25;
}
}
});
<!doctype html>
<html lang="en" ng-app="myApp" ng-controller="maincontroller">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="script.js"></script>
<script data-require="angular-bootstrap#0.12.0" data-semver="0.12.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.min.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div>
<table class="table table-hover table-bordered" >
<tbody >
<tr ng-repeat="row in rowData">
<td>
{{row.expNum}}
</td>
<td>
{{row.itemHr}}
</td>
<td>
{{row.highRe}}
</td>
</tr>
</tbody>
</table>
</div>
<input type="button" class="btn btn-danger" ng-click="update()" value="Update ItemHr to 25">
</body>
</html>
angular.forEach($scope.rowData, function(item,index){
item["itemHr"] = "25";
})

How to filter array if filter is in angular directive?

I try to create general directive for filtering array in angular.
<body ng-controller="MainCtrl">
controller: <input type="text" ng-model="query.name" /> - work<br>
directive: <span filter by="name"></span> - not work
<ul>
<li ng-repeat="item in list | filter:query">{{item.name}}</li>
</ul>
</body>
controller and directive are:
app.controller('MainCtrl', function($scope) {
$scope.list = [
{id: 1, name:'aaa'},
{id: 2, name:'bbb'},
{id: 3, name:'ccc'}
];
});
app.directive('filter', function () {
return {
scope: {
by: '#'
},
link: function postLink(scope, element, attrs) {
element.append(
'<input type="text" ng-model="query.' + attrs.by + '">');
}
}
});
Filter in controller works but filter in directive doesn't. I don't know how to fix it.
Solution is fixed in plunker: http://plnkr.co/edit/WLGd6RPQEwMFRBvWslpt?p=preview
Since you have isolated the scopes you have to use eiter $parent or you have to set up two way binding using '=' i have update your example with two way binding
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
controller: <input type="text" ng-model="query.name" /> - work<br>
directive: <span filter by="query"></span> - not work
<ul>
<li ng-repeat="item in list | filter:query">{{item.name}}</li>
</ul>
<script>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function ($scope) {
$scope.list = [
{ id: 1, name: 'aaa' },
{ id: 2, name: 'bbb' },
{ id: 3, name: 'ccc' }
];
alert("123");
$scope.query = { name: "" }
});
app.directive('filter', function () {
return {
scope: {
by: '='
},
replace: true,
template:'<input ng-model="by.name"></input>'
}
});
</script>
</body>
</html>

Resources