ng-grid changing style on populating data and making visible - angularjs

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.

Related

object-fit fallback solution? (AngularJS&ng-repeat)

I've got an interesting compatability issue. Of course, object-fit: cover will not work on MS Edge and IE, so I've been trying to find a workaround for it. However, I can't seem to access an image created using ng-repeat via javascript.
I want to be able to edit the image styles from the controller, but querySelector('img') always returns null.
Heres the HTML:
<div class="js-image" id="danCarousel" style="height: 600px; width: 100%; background-color: grey;">
<!-- carousel image -->
<img ng-show="loaded" class="cimg {{fadeAnimation}}" ng-repeat="slide in slides"
ng-if="isCurrentSlideIndex($index)" ng-src="{{slide.src}}" style="position: absolute;
height: 100%; width: 100%; object-fit: cover; float: left; "/>
And here's the Javascript:
danApp.controller('indexController', function($scope, $document, $timeout, QueueService) {
$scope.state='index';
if('objectFit' in document.documentElement.style === false) {
console.log("This browser does not support object-fit");
//get the carousel image container
var carouselImages = document.getElementsByClassName('js-image');
for(var i=0; i < carouselImages.length; i++) {
console.log(i);
//get the image source url
var imageSrc = carouselImages[i].querySelector('img').getAttribute("ng-src");
console.log(carouselImages[i].querySelector('img'));
//hide the image
carouselImages[i].querySelector('img').style.display = "none";
//add background-size: cover
carouselImages[i].style.backgroundSize = 'cover';
//add in the background image src here
carouselImages[i].style.backgroundImage = 'url(' + imageSrc + ')';
//Add background-position: center center
carouselImages[i].style.backgroundPosition = 'center center';
}
console.log("Compatability settings added.");
}
else {
console.log('This browser supports object-fit');
}
Anyone know of a solution for this?
Use ng-class and either call a function in your controller to return the appropriate class name or add a class property to slide and reference it via ng-class.

Google Polymer - Iron Pages/Selector not updating main field

I'm cutting my teeth with Google Polymer by trying to put together a control panel style layout but unfortunately when clicking on items in my app-drawer the content doesn't load in the main field. The url updates in the bar and the CSS highlights the selection but nothing else happens.
I started with a blank app template using polymer init, tried to flesh out the structure by referencing this answer, and then referenced the starter-kit as a guide for the rest. If anyone could give me a nudge in the right direction it would be greatly appreciated as i'm still new to the concepts of routing.
<dom-module id="Panel-app">
<template>
<style>
:host {
display: block;
font-family: Fira Sans Condensed;
--app-primary-color: #1A3663;
}
app-header {
background-color: var(--app-primary-color);
color: white;
}
app-drawer {
top: 64px;
--app-drawer-content-container: {
padding: 0px;
background-color: #325999;
};
}
.drawer-list {
margin: 0 20px;
}
.drawer-list a {
display: block;
padding: 0 16px;
text-decoration: none;
color: var(--app-secondary-color);
line-height: 40px;
}
.drawer-list a.iron-selected {
color: black;
font-weight: bold;
}
</style>
<app-location route="{{route}}"></app-location>
<app-route
route="{{route}"
pattern="/:page"
data="{{routeData}}"
tail="{{subroute}}"></app-route>
<app-header-layout fullbleed>
<app-header shadow>
<app-toolbar id="toolbar">
<paper-icon-button icon="menu" onclick="drawer.toggle()"></paper-icon-button>
<div main-title>Panel</div>
<paper-menu-button>
<paper-icon-button icon="communication:live-help" class="dropdown-trigger"></paper-icon-button>
<paper-menu class="dropdown-content">
<paper-item>Live Chat</paper-item>
<paper-item>Contact List</paper-item>
<paper-item>Leave Feedback</paper-item>
</paper-menu>
</paper-menu-button>
<paper-icon-button icon="supervisor-account" class="dropdown-trigger"></paper-icon-button>
<paper-icon-button icon="settings" class="dropdown-trigger"></paper-icon-button>
</app-toolbar>
</app-header>
<app-drawer-layout>
<app-drawer id="drawer">
<iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
<a name="view1" href="/view1">One</a>
<a name="view2" href="/view2">Two</a>
<a name="view3" href="/view3">Three</a>
</iron-selector>
</app-drawer>
<iron-pages
selected="[[page]]"
attr-for-selected="name"
fallback-selection="view404"
role="main">
<my-view1 name="view1"></my-view1>
<my-view2 name="view2"></my-view2>
<my-view3 name="view3"></my-view3>
</iron-pages>
</app-drawer-layout>
</app-header-layout>
</template>
<script>
Polymer({
is: 'Panel-app',
properties: {
page: {
type: String,
reflectToAttribute: true,
observer: '_pageChanged',
},
},
observers: [
'_routePageChanged(routeData.page)',
],
_routePageChanged: function(page) {
this.page = page || 'view1';
if (!this.$.drawer.persistent) {
this.$.drawer.close();
}
},
_pageChanged: function(page) {
// Load page import on demand. Show 404 page if fails
var resolvedPageUrl = this.resolveUrl('my-' + page + '.html');
this.importHref(resolvedPageUrl, null, this._showPage404, true);
},
_showPage404: function() {
this.page = 'view404';
},
});
</script>
</dom-module>
You're missing a curly bracket here or else the binding fails:
route="{{route}"
It must be
route="{{route}}"
Then the _routePageChanged observer works

How to make one radio button option should be checked by default in angular repeat

How to make one radio button option should be checked by default.
I tried to give ng-model, and ng-init but its not working.
My Html :
<div bindonce ng-repeat="row in results.favorites" style="padding: 0px 10px; white-space: nowrap; border-bottom: 1px solid #efefef; border-top: 1px solid #eee; border-left: 1px solid #efefef;">
<input type="radio" ng-click="setFavoriteDashboard(row.id)" ng-model="selectedRow" name="favRadioSel" style="opacity: 1;" class="pointer"/>
<span bo-text="row.title" style="margin: 10px; position: relative; top: 3px;"></span>
</div>
I have given checked="checked" also but it is default selecting last value I want first option should be checked by default.
My JS:
$scope.results = {
favorites: [{
id: "WatchList1",
title: "WatchList1"
}, {
id: "WatchList2",
title: "WatchList2"
}, {
id: "WatchList3",
title: "WatchList3"
}]
};
$scope.selectedRow = "WatchList1";
Added Demo : http://plnkr.co/edit/KA9HyQ3bHxJo2Cm9qFm3?p=preview
Each radio element should have its unique value and just bind it with ng-model. In your controller, set on your model the value of your first radio element.
HTML
<input type="radio" ng-click="setFavoriteDashboard(row.id)" ng-model="selectedRow" value="{{ row.id }}" name="favRadioSel" style="opacity: 1;" class="pointer"/>
Controller
$scope.selectedRow = "" //value of your first row.id
Working example : http://plnkr.co/edit/cNcgeGZPvQKTgOtgaUqE?p=preview
each radio button need ng-model! please check oficial page for easy to understand code which you can edit in plunker and play around.
Your ng-model="selectedRow" should be an object with id property. Please see working example in my plunker

AngularJS ng-table fixed headers

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);
}
}

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.

Resources