Angular dragular issues when used with tables - angularjs

Found the following issues when using dragular with tables:
When dragging rows, the rows get shrunk.
It does not happen when using them with list. We are using angular 1.6.4
var app = angular.module('myApp', ['dragularModule']);
app.controller('customersCtrl', function($scope,dragularService,$interval) {
$scope.peoples = [
{firstName: 'Elinor', lastName: 'Ramirez',company:'Maxiserve',occupation:'Safety inspector'},
{firstName: 'Kathleen', lastName: 'Norton',company:'Castle Realty',occupation:'Bodyguard'},
{firstName: 'Jay', lastName: 'Joe',company:'Jackpot Consultant',occupation:'Electronic typesetting machine operator'},
{firstName: 'Karl', lastName: 'Lancaster',company:'Bonanza Produce Stores',occupation:'Molding, coremaking, and casting machine setter'},
{firstName: 'Rocio', lastName: 'Roque',company:'Buena Vista Realty Service',occupation:'Social and human service assistant'},
{firstName: 'Keller', lastName: 'Mast',company:'NA',occupation:'NA'},
{firstName: 'Heeth', lastName: 'Quest',company:'NA',occupation:'NA'},
{firstName: 'Sam', lastName: 'Chester',company:'NA',occupation:'NA'},
{firstName: 'Jason', lastName: 'Miller',company:'NA',occupation:'NA'},
{firstName: 'Path', lastName: 'Kals',company:'NA',occupation:'NA'},
{firstName: 'Such', lastName: 'Rita',company:'NA',occupation:'NA'}
];
var timer,
scrollContainer = document.getElementById('parentContainer'),
dragDropContainer = document.getElementById('drag-drop-zone'),
topBar = document.getElementById('topBar'),
bottomBar = document.getElementById('bottomBar');
dragularService.cleanEnviroment();
//initialize the DND container and model
dragularService([dragDropContainer], {
scope: $scope,
containersModel: [$scope.peoples],
lockY: true
});
registerEvents(topBar, scrollContainer, -5,20);
registerEvents(bottomBar, scrollContainer, 5,20);
function registerEvents(bar, container, inc, speed) {
if (!speed) {
speed = 20;
}
angular.element(bar).on('dragularenter', function() {
container.scrollTop += inc;
timer = $interval(function moveScroll() {
container.scrollTop += inc;
}, speed);
});
angular.element(bar).on('dragularleave dragularrelease', function() {
$interval.cancel(timer);
});
}
});
body{
background-color:black;
padding-top:10px;
}
table, th , td {
border: 1px solid grey;
border-collapse: collapse;
padding: 15px;
text-align:center;
margin-left:20%;
}
table th{
background-color: blue;
}
table tr:nth-child(odd) {
background-color: lightblue;
}
table tr:nth-child(even) {
background-color: #ffffff;
}
.bar{
height:10px;
position:fixed;
width: 90%;
}
.bar.topBar{
top: 65px;
right: 30px;
}
.bar.bottomBar{
bottom: 0;
}
<html>
<script src= "https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src= "https://rawgit.com/luckylooke/dragular/master/dist/dragular.js"></script>
<link rel="stylesheet" href="https://rawgit.com/luckylooke/dragular/master/dist/dragular.css"/>
<body id="parentContainer">
<div ng-app="myApp" ng-controller="customersCtrl">
<div id="topBar" class="bar topBar"><div>
<table id="scrollContainer">
<thead>
<tr>
<th></th>
<th>First Name</th>
<th>Last Name</th>
<th>Company</th>
<th>Occupation</th>
</tr>
</thead>
<tbody id="drag-drop-zone">
<tr ng-repeat="person in peoples">
<td class="handle"></td>
<td>{{ person.firstName }}</td>
<td>{{ person.lastName }}</td>
<td>{{ person.company }}</td>
<td>{{ person.occupation }}</td>
</tr>
</tbody>
</table>
<div id="bottomBar" class="bar bottomBar"><div>
</div>
</body>
</html>
https://codepen.io/naveen_vijayaraghavan/pen/KZQLBW
Scroll behaves weirdly. Sometimes it just does not stop scrolling or it does not scroll at all.

Related

How to create subtotals in a ng-repeat in Angular JS

I'm just learning AngularJS and need to create the report below. I have all the detail lines working well but have no idea how to create the subtotal lines.
Detail lines...
<tr data-ng-repeat-start="t in testReferrers">
<td>{{t.ReferrerName}}</td>
<td>{{t.AddressLine1}}}</td>
<td>{{t.DatePlaced | date:'MM/dd/yyyy'}}</td>
<td>{{t.InvoiceNumber }}</td>
<td>{{t.InvoiceAmountLessDiscount | currency : $ : 2 }}</td>
</tr>
My first attempt at subtotal line, but I don't know how to calculate {{subTotal}} and how to control when this row shows up. I need a grouping and group footer capability but don't know how to do that in AngularJS. I was going to use JQuery to find the subTotalRow and either show or hide...
<tr id="subtotalRow" data-ng-repeat-end style="display:none">
<td colspan=3></td>
<td style="border-top: solid 1px #000000">Total:</td>
<td style="border-top: solid 1px #000000">{{subTotal | currency : $ : 2 }}</td>
</tr>
Desired output...
angular.module('app', []).controller('ctrl', function($scope){
$scope.data = [
{Referrer: 'Henry', Amount: 20, Location: 'NY'},
{Referrer: 'Tom', Amount: 10, Location: 'London'},
{Referrer: 'Sam', Amount: 10, Location: 'Paris'},
{Referrer: 'Henry', Amount: 10, Location: 'NY'},
{Referrer: 'Tom', Amount: 20, Location: 'London'},
{Referrer: 'Henry', Amount: 30, Location: 'NY'}
];
$scope.sum = function(name){
return $scope.data.filter(function(x) { return x.Referrer == name; })
.map(function(x) { return x.Amount; }).reduce(function(a, b) { return a + b; });
}
})
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
.totalRow{
border-style: solid;
}
.total{
text-align: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js">
</script>
<div ng-app='app' ng-controller='ctrl'>
<table>
<thead>
<tr>
<th>Referrer</th>
<th>Location</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr ng-init='next = $index + 1' ng-repeat-start='item in dataSorted = (data | orderBy : "Referrer")'>
<td>{{item.Referrer}}</td>
<td>{{item.Location}}</td>
<td>{{item.Amount}}</td>
</tr>
<tr class='totalRow' ng-repeat-end ng-if='!dataSorted[next] || (dataSorted[next].Referrer != item.Referrer)'>
<td colspan='2' class='total'>Total:</td>
<td>{{sum(item.Referrer)}}</td>
</tr>
</tbody>
</table>
</div>

Creating dynamic table using AngularJS and restful api

I'm trying to create a table using Quandl restful api along with AngularJS. While table headers created well table rows aren't filled with data at all, there are only empty rows.
Here is my controller:
angular.module('stockControllers', [])
.controller('stockController', function($scope, $http){
var results = {};
$http.get('https://www.quandl.com/api/v3/datasets/WIKI/FB.json?start_date=2017-11-01&api_key=3pg7TVEyogz6D6FXhf5g').
then(function(response) {
$scope.resulting = response.data;
console.log($scope.resulting);
});
});
HTML code:
<div ng-controller="stockController">
<div class='page-header'>
<h1> {{resulting.dataset.name}} </h1>
<p> Note: showing only OHLC data </p>
</div>
<table class="table table-striped">
<tr>
<th>{{resulting.dataset.column_names[0]}}</th>
<th>{{resulting.dataset.column_names[1]}}</th>
<th>{{resulting.dataset.column_names[2]}}</th>
<th>{{resulting.dataset.column_names[3]}}</th>
<th>{{resulting.dataset.column_names[4]}}</th>
</tr>
<tr ng-repeat="row in resulting.dataset.data">
<td>{{resulting.dataset.data[row][0]}}</td>
<td>{{resulting.dataset.data[row][1]}}</td>
<td>{{resulting.dataset.data[row][2]}}</td>
<td>{{resulting.dataset.data[row][3]}}</td>
<td>{{resulting.dataset.data[row][4]}}</td>
</tr>
</table>
</div>
And api response fragment which I want to use:
"dataset": {
"column_names": ["Date","Open","High","Low","Close","Volume","Ex-Dividend","Split Ratio","Adj. Open","Adj. High","Adj. Low","Adj. Close","Adj. Volume"],
"data": [["2017-11-13",
177.5,
179.04,
177.3,
178.77,
9431449,
0,
1,
177.5,
179.04,
177.3,
178.77,
9431449 ],,
[
"2017-11-10",
178.35,
179.0999,
177.96,
178.46,
10933405,
0,
1,
178.35,
179.0999,
177.96,
178.46,
10933405 ],,
angular.module('app', []).controller('ctrl', function($scope) {
$scope.resulting = {
dataset: {
column_names: ["Date", "Open", "High", "Low", "Close", "Volume", "Ex-Dividend", "Split Ratio", "Adj. Open", "Adj. High", "Adj. Low", "Adj. Close", "Adj. Volume"],
data: [
["2017-11-13",
177.5,
179.04,
177.3,
178.77,
9431449,
0,
1,
177.5,
179.04,
177.3,
178.77,
9431449
],
[
"2017-11-10",
178.35,
179.0999,
177.96,
178.46,
10933405,
0,
1,
178.35,
179.0999,
177.96,
178.46,
10933405
]
]
}
}
});
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app='app' ng-controller='ctrl'>
<thead>
<tr>
<th ng-repeat='head in resulting.dataset.column_names' ng-if='$index < 5'>{{head}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in resulting.dataset.data">
<td ng-repeat='val in row track by $index' ng-if='$index < 5'>{{val}}</td>
</tr>
</tbody>
</table>

Angular Js swap columns in table

I would like to swap 2 columns in a table. Finally, I succeeded the change, but only the data. The attributes of the cell (style, id, class) didn't move. I tried to move attributes with jquery (i know, not an elegant method), but it was only symptomatic treatment. After clicking the data reload button, the attributes restored.
How can I change the columns order with all attributes?
my code: https://codepen.io/qwertz_/pen/YxWMBO
<!DOCTYPE html>
<html>
<head>
<title>angT</title>
<script type="text/javascript" src="http://code.angularjs.org/angular-1.0.0rc10.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<style>
th, td{padding: 3px 20px;border: 1px solid red;}
</style>
</head>
<body>
<div ng-controller="MyCtrl" ng-app="myApp">
<button ng-click="swap(0)">first2second</button>
<button ng-click="reload()">reload</button>
<table id="myTable" >
<tr ng-repeat="row in ths">
<th class="oo1">{{col(row, 0)}}</th>
<th class="oo2">{{col(row, 1)}}</th>
<th class="oo3">{{col(row, 2)}}</th>
<th class="oo4">{{col(row, 3)}}</th>
</tr>
<tr ng-repeat="row in rows">
<td class="o1" style="background-color:yellow;">{{col(row, 0)}}</td>
<td class="o2" style="background-color:pink;">{{col(row, 1)}}</td>
<td class="o3" style="background-color:green;">{{col(row, 2)}}</td>
<td class="o4" style="background-color:blue;">{{col(row, 3)}}</td>
</tr>
</table>
</div>
<script type='text/javascript'>
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.mycol = new Array();
$scope.mycol[0] = 'id';
$scope.mycol[1] = 'name';
$scope.mycol[2] = 'db';
$scope.mycol[3] = 'let';
$scope.reload = function()
{
$scope.rows=[{id:parseInt(Math.random()*10000),name:"Liv","db":21,let:"r"},{id:parseInt(Math.random()*10000),name:"Mike",db:30,let:"u"}];
};
$scope.swap = function(i) {
var temp = $scope.mycol[i];
$scope.mycol[i] = $scope.mycol[(i+1)];
$scope.mycol[(i+1)] = temp;
};
$scope.col = function(row, mycol) {
return row[$scope.mycol[mycol]];
};
$scope.reload();
$scope.ths=[{id:"id",name:"name","db":"db",let:"letter"}];
}
</script>
</body>
Thx a lot
Simple way
You can bind colors to header name as:
$scope.styles = {
id: "yellow",
name: "pink"
};
and table will look like:
<tr ng-repeat="row in rows">
<td class="o1" ng-style="{'background-color':styles[mycol[0]]}">{{col(row, 0)}}</td>
<td class="o2" ng-style="{'background-color':styles[mycol[1]]}">{{col(row, 1)}}</td>
<td class="o3" style="background-color:green;">{{col(row, 2)}}</td>
<td class="o4" style="background-color:blue;">{{col(row, 3)}}</td>
</tr>
Once header value changes, colors will change too
Codepen DEMO
More complicated but generic
You can achieve it by replacing all table with directive (headers + data) and by using $compile rebuild all HTML table.

TypeError: Cannot read property 'indexOf' of undefined at $scope.search

Guys I am newbie to Angular JS. I am trying to do a very small POC on search in angular js.
I have a scope variable called searchText which not undefined but I don't know what wrong here.
HTML
<!DOCTYPE html>
<html ng-app="myEmp">
<head>
<title>AJS Event Handler</title>
<script src="../AngularJS/angular.js"></script>
<script src="search.js"></script>
<style type="text/css">
table {
border-collapse: collapse;
font-family: Arial;
}
table, td {
border: 1px solid black;
padding: 5px;
text-align: left;
}
th{
border: 1px solid black;
padding: 5px;
text-align: left;
cursor: pointer;
}
</style>
</head>
<body ng-controller="myController">
<input type="text" ng-model="searchText" placeholder="search by name and city">
<br/>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>DOB</th>
<th>Gender</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="emp in employees | filter:search">
<td>{{ emp.fName }}</td>
<td>{{ emp.dob | date:"dd/MM/yyyy" }}</td>
<td>{{ emp.gen }}</td>
<td>{{ emp.salary | number:2 }}</td>
</tr>
</tbody>
</table>
</body>
</html>
JS
// create the module, create controller and register controller to module in one line
angular .module("myEmp", [])
.controller("myController", function($scope){
var employees = [
{fName: 'Soham', dob: new Date("may 23,1990"), gen: 'Male', salary: 10000.506666},
{fName: 'Shardha', dob: new Date("may 23,1995"), gen: 'Female', salary: 10555000.50},
{fName: 'Bhagya', dob: new Date("april 23,1999"), gen: 'Male', salary: 4343.50},
{fName: 'Soham', dob: new Date("may 23,1999"), gen: 'Female', salary: 10043434500.50}
];
$scope.employees = employees;
$scope.searchText = undefined;
$scope.search = function(item){
if($scope.searchText == undefined){
return true;
}else{
console.log($scope.searchText);
if($scope.searchText && item.fName.indexOf($scope.searchText) != -1 ||
$scope.searchText && item.city.indexOf($scope.searchText) != -1 ){
return true;
}
}
return false;
}
});
There is no city field in employees. Just do a field check then do indexOf
angular .module("myEmp", [])
.controller("myController", function($scope){
var employees = [
{fName: 'Soham', dob: new Date("may 23,1990"), gen: 'Male', salary: 10000.506666},
{fName: 'Shardha', dob: new Date("may 23,1995"), gen: 'Female', salary: 10555000.50},
{fName: 'Bhagya', dob: new Date("april 23,1999"), gen: 'Male', salary: 4343.50},
{fName: 'Soham', dob: new Date("may 23,1999"), gen: 'Female', salary: 10043434500.50}
];
$scope.employees = employees;
$scope.searchText = undefined;
$scope.search = function(item){
if($scope.searchText == undefined){
return true;
}else{
console.log($scope.searchText);
if($scope.searchText && (item.fName.indexOf($scope.searchText) != -1 || item.city && item.city.indexOf($scope.searchText) != -1 )){
return true;
}
}
return false;
}
});

AngularJS can't fetch more than 4 records

The following code is for an AngularJS code to read data from a .txt file and echo out on the webpage. It works just fine for the entered records in the .txt file, but upon increasing the number of records above 4, the code fails to work. What could be wrong?
Index.html
<html>
<head>
<title>Angular JS Includes</title>
<style>
table, th , td {
border: 1px solid grey;
border-collapse: collapse;
padding: 5px;
}
table tr:nth-child(odd) {
background-color: #f2f2f2;
}
table tr:nth-child(even) {
background-color: #ffffff;
}
</style>
</head>
<body>
<h2>AngularJS Sample Application</h2>
<div ng-app="" ng-controller="studentController">
<table>
<tr>
<th>Name</th>
<th>Roll No</th>
<th>Percentage</th>
</tr>
<tr ng-repeat="student in students">
<td>{{ student.Name }}</td>
<td>{{ student.RollNo }}</td>
<td>{{ student.Percentage }}</td>
</tr>
</table>
</div>
<script>
function studentController($scope,$http) {
var url="data.txt";
$http.get(url).success( function(response) {
$scope.students = response;
});
}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
</body>
Data.txt
[
{
"Name" : "Collin James",
"RollNo" : 101,
"Percentage" : "81.5%"
},
{
"Name" : "Michael Ross",
"RollNo" : 201,
"Percentage" : "70%"
},
{
"Name" : "Robert Flare",
"RollNo" : 191,
"Percentage" : "75%"
},
{
"Name" : "Julian Joe",
"RollNo" : 111,
"Percentage" : "77%"
}
]

Resources