AngularJS ng-table fixed headers - angularjs

I'm using ng-table to display some information. I would like to make the header and footer of the ng-table fixed and force the ng-table to draw scroll bars within the rows.
The ng-table documentation site has no documentation on how to make that happen.
Any ideas?

this CSS-only solution worked for me. Just add the class table-scroll to the table element and the following CSS:
.table-scroll thead {
display: table;
width: 100%;
table-layout: fixed;
}
.table-scroll tbody {
max-height: 150px;
overflow-y: auto;
display: block;
width: 100%;
table-layout: fixed;
}
.table-scroll tr {
display: table;
table-layout: fixed;
width: 100%;
}
.table-scroll td {
height: 47px; // needed in order to keep rows from collapsing
}

That is by far the most reliable solution that I found. And I've looked for hours before deciding to use a jQuery plugin.
In the version of the plugin that I am using, we can stick the header to a scrollable container.
Take a look at this plunker for a use case with ng-table:
http://plnkr.co/edit/ypBaDHIfaJWapXVs3jcU?p=preview
Javascript
app.directive('fixedTableHeaders', ['$timeout', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
$timeout(function() {
var container = element.parentsUntil(attrs.fixedTableHeaders);
element.stickyTableHeaders({ scrollableArea: container, "fixedOffset": 2 });
}, 0);
}
}
}]);
HTML
<div id="scrollable-area">
<table ng-table="tableParams" fixed-table-headers="scrollable-area">
<tr ng-repeat="user in $data">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
</tr>
</table>
</div>
CSS
#scrollable-area {
height: 150px;
overflow-y: scroll; /* <-- here is what is important*/
}
table {
width: 100%;
}
thead {
background: #fff;
}

I don't know about the footer but I had a similar requirement for the headers.
This was requested before # Github: https://github.com/esvit/ng-table/issues/41
I made my own implementation using a jquery plugin (https://github.com/jmosbech/StickyTableHeaders).
There is a plunkr here: http://plnkr.co/edit/KyilXo?p=preview
Basically we just call the plugin in the directive data-fixed-table-headers
when the data has been rendered.
angular.module('main').directive('fixedTableHeaders', ['$timeout', fixedTableHeaders]);
function fixedTableHeaders($timeout) {
return {
restrict: 'A',
link: link
};
function link(scope, element, attrs) {
$timeout(function () {
element.stickyTableHeaders();
}, 0);
}
}

Related

validate the custom checkbox in angularjs

hi i am trying to validate custom checkbox but it is not working. what i want to acquire when the checkbox is unchecked and i submit the data by clicking on send button there will show a error message, like other fields. and when i checked the checkbox the error message should be disappear...
here is the code Link https://jsfiddle.net/epn9s55x/
Html
<div class="form-row">
<div class="privacy-container">
<input type="checkbox" id="check1">
<label class="privacy-text" for="check1">If you are bussiness to bussiness (B2B) customer,tick the box</label>
</div>
<div class="privacy-container sumsung-privacy">
<input type="checkbox" id="check2">
<label class="privacy-text" for="check2">I acknowladge my information will be processed in accordance with the Sumsung Privacy Policy</label>
</div>
</div>
js
var myApp = angular.module('myApp', []);
myApp.directive('match', function($parse) {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
scope.$watch(function() {
return $parse(attrs.match)(scope) === ctrl.$modelValue;
}, function(currentValue) {
console.log("mismatched directive");
ctrl.$setValidity('mismatch', currentValue);
});
}
};
});
myApp.controller("myController", ['$scope', '$location','$anchorScroll',function($scope,$location, $anchorScroll){
$scope.showMsgs = false;
$scope.send = function(form){
if ($scope[form].$valid) {
$scope.showMsgs = false;
} else {
$scope.showMsgs = true;
$location.hash('mainContainer');
$anchorScroll();
}
}
}]);
Css
/*css for check box*/
[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
position: absolute;
}
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
position: relative;
padding-left: 2.75em;
cursor: pointer;
min-width: 300px;
width: 95%;
box-sizing: border-box;
font-size: 14px;
display: block;
font-weight: bold
}
/* checkbox aspect */
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 1.35em;
height: 1.35em;
border: 2px solid #000;
background: #fff;
}
/* checked mark aspect */
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
content: "";
position: absolute;
top: .18em;
left: .18em;
font-size: 1.3em;
line-height: 0.8;
color: #09ad7e;
width: .86em;
height: .86em;
background: #000;
transition: all .2s;
}
/* checked mark aspect changes */
[type="checkbox"]:not(:checked) + label:after {
opacity: 0;
transform: scale(0);
}
/*End of css of check boxes*/
You could just put a model on your checkbox and and test for the value:
<input type="checkbox" id="check2" ng-model="checkbox2">
<label class="privacy-text" for="check2">I acknowladge my information will be processed in accordance with the Sumsung Privacy Policy</label>
</div>
</div>
<div ng-show="!checkbox2">
This is required
</div>
Here is an update to your fiddle
Here's an update per your comment:
You can still use ng-model to do that. Just use a different $scope variable like this:
In your HTML:
<div ng-show="checkInvalid">
This is required
</div>
In your Controller on your click event:
$scope.checkInvalid = true;
Here is an updated Fiddle. Happy coding!

D3.JS for Graphs in Angular: adding controller to app.js

I'm looking to implement the following pieces of code into my angular boiler plate. I'm a bit new to the framework, so some patience is appreciated!
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div ng-app="myApp">
<bars data="40,4,55,15,16,33,52,20"></bars>
</div>
.chart {
background: #eee;
padding: 3px;
}
.chart div {
width: 0;
transition: all 1s ease-out;
-moz-transition: all 1s ease-out;
-webkit-transition: all 1s ease-out;
}
.chart div {
font: 10px sans-serif;
background-color: steelblue;
text-align: right;
padding: 3px;
margin: 5px;
color: white;
box-shadow: 2px 2px 2px #666;
}
angular.module('myApp', []).
directive('bars', function ($parse) {
return {
restrict: 'E',
replace: true,
template: '<div id="chart"></div>',
link: function (scope, element, attrs) {
var data = attrs.data.split(','),
chart = d3.select('#chart')
.append("div").attr("class", "chart")
.selectAll('div')
.data(data).enter()
.append("div")
.transition().ease("elastic")
.style("width", function(d) { return d + "%"; })
.text(function(d) { return d + "%"; });
}
};
});
Which are the HTML, CSS and JS code excerpts for the graph only. I'm looking to implement this into my code, which is easy enough for the HTML/CSS (I've added a new div and style sheet in my header of my index.html).
I'm wondering how I would go about adding the JS bit of code to my app.js. My existing code already lists several modules, but no var app = angular.module('myApp', ['zingchart-angularjs']); type statement.
When I simply copy my code above in, I don't see any graph appear on my webpage.
Any help appreciated - thanks!

AngularJS 1.3 ng-repeat animate move items not working

I have a list of items (divs) and when I click on any of them I need them to move (with animation) to the top of the list.
However, move animation is not working for me.
HTML code:
<body ng-controller="myCtrl">
<div ng-init="items=[1,2,3,4,5,6,7,8,9]">
<div data-ng-repeat="item in items track by $index"
ng-click="move2Top($index)"
class="my-repeat-animation boxy">
{{item}}
</div>
</div>
</body>
Javascript controller (contains an Array prototype method for pushing array element to top of array)
var myApp = angular.module("MyApp", ["ngAnimate"]);
myApp.controller('myCtrl', function($scope){
$scope.move2Top = function (idx) {
console.log('moving element ' + idx);
if (idx > 0)
$scope.items.moveToTop(idx);
};
Array.prototype.moveToTop = function(from) {
this.splice(0, 0, this.splice(from, 1)[0]);
};
});
And the CSS:
.my-repeat-animation.ng-enter,
.my-repeat-animation.ng-leave,
.my-repeat-animation.ng-move {
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
position:relative;
}
.my-repeat-animation.ng-enter {
left:-10px;
opacity:0;
}
.my-repeat-animation.ng-enter.ng-enter-active {
left:0;
opacity:1;
}
.my-repeat-animation.ng-leave {
left:0;
opacity:1;
}
.my-repeat-animation.ng-leave.ng-leave-active {
left:-10px;
opacity:0;
}
.my-repeat-animation.ng-move {
opacity:0.5;
}
.my-repeat-animation.ng-move.ng-move-active {
opacity:1;
}
.boxy {
border: solid 1px;
margin: 3px;
padding: 3px;
border-radius: 4px;
width: 30px;
text-align: center;
}
Please take a look at the example:
http://plnkr.co/edit/asHtC5WOt9qnePyzPqk5?p=preview
Animated move simply doesn't work.
Maybe you can refer to this question on stack. This is possibly similar what you are trying to achieve.
Animating ng-move in AngularJS ngRepeat is animating the wrong items
It is not complete but it might give you some idea or lead you in right direction.
I think that this has to do with your Array.prototype function.
If you do the splicing in $scope.move2Top it works, at least in my example.
var myApp = angular.module("MyApp", ["ngAnimate"]);
myApp.controller('myCtrl', function($scope){
$scope.move2Top = function (idx) {
console.log('moving element ' + idx);
if (idx > 0)
$scope.items.splice(0, 0, $scope.items.splice(idx, 1)[0]);
};
});
http://plnkr.co/edit/H5UpIZoqIMnJofz0mndL?p=preview

AngularJS directives with HTML5 drag and drop -- issue with scope object

I'm fairly new to angular and I'm having a hard time wrapping my head around where the items are being pushed to. I am not sure if I am correctly setting up the functions to be used with drag/drop and if its getting bound to an older scope object and the ng-repeat isn't being updated properly. I'm thinking there is some slight issue with the way I have this setup. Any pointers or help would be much appreciated.
What should happen is when you drag a color from the Draggable container into the Droppable container it should update the text which is linked to the scope object items. I am successfully pushing an item onto the scope object but ng-repeat isn't picking it up. I am not sure if I need a watch or what to do to get it to pay attention to the newly added items.
JS Fiddle Here: http://jsfiddle.net/RV23R/
HTML CODE:
<div ng-app="my-app" ng-controller="MainController">
<div class="container">
<header><h1>Draggables</h1></header>
<section>
<div draggable="true" ng-repeat="drag_type in drag_types">{{drag_type.name}}</div>
</section>
</div>
<div class="container">
<header><h1>Drop Schtuff Here</h1></header>
<section droppable="true">
<div><span>You dragged in: </span><span ng-repeat="items in items">{{item.name}},</span></div>
</section>
</div>
ANGULAR CODE:
var module = angular.module('my-app', []);
module.directive('draggable', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element[0].addEventListener('dragstart', scope.handleDragStart, false);
element[0].addEventListener('dragend', scope.handleDragEnd, false);
}
}
});
module.directive('droppable', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element[0].addEventListener('drop', scope.handleDrop, false);
element[0].addEventListener('dragover', scope.handleDragOver, false);
}
}
});
function MainController($scope)
{
$scope.drag_types = [
{name: "Blue"},
{name: "Red"},
{name: "Green"},
];
$scope.items = [];
$scope.handleDragStart = function(e){
this.style.opacity = '0.4';
e.dataTransfer.setData('text/plain', this.innerHTML);
};
$scope.handleDragEnd = function(e){
this.style.opacity = '1.0';
};
$scope.handleDrop = function(e){
e.preventDefault();
e.stopPropagation();
var dataText = e.dataTransfer.getData('text/plain');
$scope.items.push(dataText);
console.log($scope.items);
};
$scope.handleDragOver = function (e) {
e.preventDefault(); // Necessary. Allows us to drop.
e.dataTransfer.dropEffect = 'move'; // See the section on the DataTransfer object.
return false;
};
}
CSS (if anyone cares)
.container {
width: 600px;
border: 1px solid #CCC;
box-shadow: 0 1px 5px #CCC;
border-radius: 5px;
font-family: verdana;
margin: 25px auto;
}
.container header {
background: #f1f1f1;
background-image: -webkit-linear-gradient( top, #f1f1f1, #CCC );
background-image: -ms-linear-gradient( top, #f1f1f1, #CCC );
background-image: -moz-linear-gradient( top, #f1f1f1, #CCC );
background-image: -o-linear-gradient( top, #f1f1f1, #CCC );
box-shadow: 0 1px 2px #888;
padding: 10px;
}
.container h1 {
padding: 0;
margin: 0;
font-size: 16px;
font-weight: normal;
text-shadow: 0 1px 2px white;
color: #888;
text-align: center;
}
.container section {
padding: 10px 30px;
font-size: 12px;
line-height: 175%;
color: #333;
}
There are a couple of typos in the fiddle, but the basic problem is that your drag events are outside an angular digest cycle. You should wrap your changes in $scope.$apply (code sample coming). This forked and bugfixed (FIDDLE) shows that when you click the button, angular shows the changes and refreshes the display with new values.
Fix: (FIDDLE)
$scope.$apply(function() {
$scope.items.push(dataText);
});
A bug you had is in this code:
<span ng-repeat="items in items">{{item.name}},</span>
This should probably be ng-repeat="item in items", also items only contains the dropped text so it is an array of strings and not the original item objects.

ng-grid changing style on populating data and making visible

I'm schooling up on Angularjs' ng-grid component and have encountered a rather disappointing issue. Basically, the flow is this: page loads and only a button is visible. Button is clicked and AJAX request gets json data and binds it to the grid.
This is what I see when I first click the button:
If I resize the browser at all, it snaps back into the correct size:
My controller looks like this:
myAppModule.controller('PodcastController', function ($scope, $http) {
$scope.getData = function () {
$http.get('/Home/PodcastDataAsJson').success(function (data) {
$scope.podcasts = data;
});
$scope.gridVisibilty = 'gridStyle';
};
$scope.gridOptions = {
data: 'podcasts',
columnDefs: [
{ field: 'Id', displayName: 'Id' },
{ field: 'Name', displayName: 'Name' },
{ field: 'Artist', displayName: 'Artist' }
]
};
$scope.gridVisibilty = 'notDisplayed';
});
The View looks like this:
<div ng-app="gridExampleApp">
<div ng-controller="PodcastController">
<button ng-click="getData()">Click to get Data</button>
<div id="datagrid" ng-grid="gridOptions" class="ng-class: gridVisibilty;"></div>
</div>
</div>
My css looks like this:
.notDisplayed
{
display: none;
}
.displayed
{
display: block;
border: 1px solid rgb(212,212,212);
width: 800px;
height: 300px;
}
.gridStyle
{
display: block;
border: 1px solid rgb(212,212,212);
width: 400px;
height: 300px
}
I'd like to know whether this is me, or whether it is a bug that I should lodge with the Angular ng-grid peeps.
Cheers
You did not show how you load the ng-grid stylesheet but I had similar problems when I tried to get it with a direct link.
Here is a demo with a local file for the ng-grid stylesheet: http://plnkr.co/edit/2pq9YotA4RJIMll5BJvh?p=preview. I also used the ng-show directive binded to the podcasts variable as the condition to show/hide the grid.
In the head of index.html, if you try to use the direct link to the stylesheet, there is a weird display effect. But if you put the same code in a local file, it works.

Resources