I am displaying some data, so while the page is loading, "No data found" control is working, what should I do to prevent this ?
Here is my code
<ul id="owl-example" class="list-unstyled topContributors">
<li ng-show="TopContributors.length==0">
<p><span style="color: red; font-weight: bold;">No Contributors....</span></p>
</li>
<li ng-repeat="contributors in TopContributors">
<img ng-src="{{contributors.AccountName}}" />
<div class="contName">
<p>{{contributors.UserName}}</p>
</div>
</li>
</ul>
You can add a flag to hide "No Contributors...." until the request is not completed
<li ng-show="TopContributors.length==0 && flag">
<p><span style="color: red; font-weight: bold;">No Contributors....</span></p>
</li>
I think the below code is enough to achieve what you want rather than adding a flag:
<li ng-show="TopContributors && TopContributors.length==0">
In your controller (written in es6, but you get the drift):
export default class MyController extends Base {
constructor() {
super(arguments);
this.loading = true;
this.loadData();
}
loadData() {
// Assumes data loaded correctly;
someCodeLoadingData();
this.loading = false;
}
}
In your template:
<li ng-show="TopContributors.length === 0 && vm.loading === false">
<p>No Contributors....</p>
</li>
Put your styling in a stylesheet, keep your templates clean. The vm (in my case at least) comes from our Base where vm = this;
Use can use ng-cloak to achieve this in case data is not coming from an API using AJAX call. Basically it will wait for the variable to load before performing any function on that div or element
Add ng-cloak to your ng-show statements as shown below:
<ul id="owl-example" class="list-unstyled topContributors">
<li ng-show="TopContributors.length==0" ng-cloak>
<p><span style="color: red; font-weight: bold;">No Contributors....</span></p>
</li>
<li ng-repeat="contributors in TopContributors">
<img ng-src="{{contributors.AccountName}}" />
<div class="contName">
<p>{{contributors.UserName}}</p>
</div>
</li>
</ul>
In your css file write:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
If it is coming using an AJAX call, you can setup a flag while the call is in progress and update it when you achieve success.
The usual suggestion here recommends adding a variable for loading status. I don't think you even need that.
Besides adding ng-cloak to avoid template loading flickering, I'd suggest you default your TopContributors variable to a negative value, this way will ensure your div isn't displayed while you wait for it to load it (from a backend service I'd assume). Example:
function topContributorsController(...) {
$scope.TopContributors = -1; // 'not loaded' state
And here is the change to your template to add ng-cloak:
<ul id="owl-example" class="list-unstyled topContributors" ng-cloak>
Related
I'm stuck. Cannot figured this out. This question is very simple to show, but I'm not really sure how to put it as a question, therefore I'll try my best.
First, here's the layout of my whole app (The problem lies in the Header.jsp):
<jsp:include page="../home/Header.jsp" />
<jsp:include page="../home/Modals.jsp" />
<div data-ng-view data-save-scroll-position data-position-relative-to-menu></div>
<jsp:include page="../home/Footer.jsp" />
The problem is very simple. I have the following data-ng-class in the data-ng-view section that change a tab to active if something is true (The problem is it won't work in one scenario even though it displayed true in the tab name):
<ul class="nav nav-tabs">
<li role="presentation" data-ng-class="tab.isSelected ? 'active' : ''" data-ng-repeat="tab in ctrl.tabs"
data-ng-click="ctrl.fetchBIReports(tab)">
</li>
</ul>
In the JSP that use data-ng-include for the above markup, there's a side nav to change to this page. Once clicked this side-nav, it highlighted the tab 'active' as expected (trying not to include the whole jsp):
<div class="side-navbar">
<ul>
<li class="{{ ctrl.navigate.path == 'bi/schedule' ? 'active-link' : 'normal-link'}}">
Schedule Reports
</li>
</ul>
</div>
<div class="content-right" data-ng-include="ctrl.navigate.path"></div>
content-right includes the JSP mentioned in the second markup.
So far, so good. Here's a demo of it working (including both side-navbar and content-right):
The problem is, in my Header.jsp, there's a nav bar that takes me to the same page. If it is clicked from a different page with different controller, then it works. But if I'm in the current controller and click that nav bar link, then data-ng-class does not take 'active' as its class. Here's the markup for the Header.jsp for that link:
<li class="dropdown" data-roles="['ROLE_ADMIN']">
<a href="#/bi" class="dropdown-toggle" data-toggle="dropdown" data-ng-click="ctrl.changeNavigation('bi/schedule')"
role="button" aria-haspopup="true" aria-expanded="false">BI Management<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Schedule Reports</li>
</ul>
</li>
Here is the demo of it not working even though it is printing out true in the UI:
The only problem is with this UI. All the data are populated. Records are displayed for the correct tab. Even side nav-bar is displaying the correct active class.
Your syntax for ng-class is off a bit. The format is "{ '[class-name]': [expression that evaluates to true or false] }". You can have multiple class values separated by commas each with their own expression. When an expression is true, the corresponding class is applied to the element and when it is false the class is removed from the element. The way you have written it would almost work for the plain class attribute, but you would need to include the interpolation characters: {{ and }}. Here is a very simple example to illustrate ng-class.
angular.module('app', []);
.red {
color: #fff;
background-color: #e21d1d;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app">
<label>
<input type="checkbox" ng-model="applyRedClass" /> Apply 'red' class
</label>
<div ng-class="{'red': applyRedClass}">
This is a simple example of how to use ng-class.
</div>
</div>
what I am trying to do is: make the cursor:no-drop; using css for this, fine works, but the problem is I am still getting the click when I click in the Icon.
If you see my Icon turn to red and I inserted cursor:no-drop; by css. for the user not be able to click, but the click still on how can I solve this? and block the click when the Icon turns to red?
thank you.
html + angular
<div ng-app>
<div ng-class="{'selected-gamepad':tog==1}">
<br>
<i class="fa fa-lg fa-gamepad" ng-class="{'gamepad-blue': iTog1}"
ng-click="iTog1 = !iTog1"></i>
<span id='1' ng-click='tog=1; iTog1 = false;'>span 1</span>
</div>
<div ng-class="{'selected-gamepad':tog==2}">
<br>
<i class="fa fa-lg fa-gamepad" ng-class="{'gamepad-blue': iTog2}" ng-click="iTog2 = !iTog2"></i>
<span id='2' ng-click='tog=2; iTog2 = false;'>span 2</span>
</div>
</div>
css:
.selected-gamepad > span {
border: dotted pink 3px;
}
.selected-gamepad > i {
color: red;
cursor:no-drop;
}
.gamepad-blue,
.selected-gamepad .gamepad-blue{
color: blue;
}
jsfiddle: http://jsfiddle.net/zvLvg/290/
Changing the cursor property in CSS doesn't magically disable clicking - it just changes the cursor so it looks like you can't click. If you want to disable clicking, you need some additional logic in your code.
I've edited the code a bit to clean it up and moved some logic to controller. The code of course could be much better, but I leave it up to you - try to read some tutorials about it and get familiar with cleaner Angular syntax to write better code :-).
Coming back to the problem - what you really needed to do was to block player from clicking, when the pad is selected. I did it by adding a simple checking with if statement inside toggle function:
View:
<div ng-app="app">
<div ng-controller="GameController as vm">
<div ng-class="{'selected-gamepad':vm.tog==1}">
<br>
<i class="fa fa-lg fa-gamepad" ng-class="{'gamepad-blue': vm.iTogs[1]}" ng-click="vm.toggle(1)"></i>
<span id='1' ng-click='vm.selectPad(1)'>span 1</span>
</div>
<div ng-class="{'selected-gamepad':vm.tog==2}">
<br>
<i class="fa fa-lg fa-gamepad" ng-class="{'gamepad-blue': vm.iTogs[2]}" ng-click="vm.toggle(2)"></i>
<span id='2' ng-click='vm.selectPad(2)'>span 2</span>
</div>
</div>
</div>
Logic:
<script>
// Register module
angular.module('app', []);
// Create controller
angular.module('app')
.controller('GameController', function() {
var self = this;
self.tog = null;
self.iTogs = [false, false];
self.toggle = function(index) {
if (self.tog != index) {
self.iTogs[index] = !self.iTogs[index];
}
}
self.selectPad = function(index) {
self.tog = index;
self.iTogs[index] = false;
}
});
</script>
Here's working plunker:
http://jsfiddle.net/zvLvg/291/
A little explanation
What I did was move some of the logic to controller. Controllers let you separate different parts in the application and have more control over them. Also, the code is much cleaner when you use functions instead of direct expressions inside directives (like you did with ng-click earlier).
I've also created an array instead of naming variables with numbers. Further improvements would be to use ng-repeat to avoid code repetition - divs inside your pads list are pretty much the same and could be substituted with one div and ng-repeat. Also, names of the properties could be better - now they don't really say what they mean if you look at them.
I hope these small tips will help you to get better with Angular and with programming at all. :-)
I am trying to create custom pager for ion-slide-box. This is codepen sample
This is my js:
$scope.currentSlide = 0;
$scope.pagerClick = function (index) {
$ionicSlideBoxDelegate.slide(index);
}
$scope.slideChanged = function (index) {
$scope.currentSlide = index;
}
This is html file:
<ion-slide-box does-continue=true show-pager=false on-slide-changed="slideChanged($index)">
<ion-slide class="item-image" ng-repeat="i in getNumber(number) track by $index">
<img src='{{images[$index]}}' />
</ion-slide>
</ion-slide-box>
<div class="page-indicator" ng-repeat="i in getNumber(number) track by $index">
<a class="button" href ng-class="{activated: $index == currentSlide}" ng-click="pagerClick($index)">{{$index+1}}</a>
</div>
Almost all works fine, except one thing. When I click on my pager buttons it doesn't change active button in pager. When I swype slides all buttons change style correctly. I think it may be because of $index - I have two such variables. But I can't understand or fix it.
I finally solved this problem which was because activated is inline class of button.
When I push button this class was applying, but when I unpress button Angular delete this class.
I create my class active-button and all is now working.
<div class="page-indicator" ng-repeat="i in getNumber(number) track by $index">
<a class="button" href ng-class="{'active-button': $index == currentSlide}" ng-click="pagerClick($index)">{{$index+1}}</a>
and css
.active-button{
background-color: #b2b2b2 !important;
box-shadow: none !important;
color: #fff !important;
}
I am very new to angularjs, i have done some experimental projects in Polymer 0.5, so new to Polymer 1.0 as well.
I am facing an issue like inside ng-repeat i want to display some paper-card.
This issue is only on Chrome browser, In Firefox and IE-edge it is coming fine.
<paper-card heading="{{ team.name }}">
<div class="card-content">Some content</div>
<div class="card-actions">
<paper-button>Some action</paper-button>
</div>
</paper-card>
//--------------------------- HTML ----------
<div class="row content">
<div><h3>Teams <img ng-show="loading" ng-src='images/loader2.gif' width="30px" height="30px"/></h3></div>
<div ng-repeat="team in teams" ng-repeat="team in teams | filter:teamsFilter">
<div>
<style>
.collapse-content {
padding: 15px;
border: 1px solid #dedede;
}
</style>
<paper-card heading="{{ team.name }}">
<div class="card-content">Some content</div>
<div class="card-actions">
<paper-button>Some action</paper-button>
</div>
</paper-card>
</div>
</div>
</div>
//--------------------------- HTML -------------
I am using ng-polymer-element module,
I have the below code in my application app.js
angular.module('ng-polymer-elements').constant('$ngPolymerMappings', {
paperCard: {
ngModel: function property(element) {
return element.hasAttribute('multi') ? 'selectedValues' : 'selected';
},
ngHeading: '=heading'
}
});
window.addEventListener('WebComponentsReady ', function() {
angular.bootstrap(wrap(document), ['myApp']);
});
The Card header is coming fine but the binding variable is also displaying inside the card.
I inspect the HTML in the browser, i could see the paper-material is added twice and the second one is showing the brackets as it is.
Any help is highly appreciated. Thanks.
Most likely that Angular is not loaded properly; therefore, it hasn't kicked in to evaluate the expressions in the braces. Please post your entire HTML page.
In my Angular app I have a simple twitter-bootstrap carousel, in a tab:
<div class="tabbable">
<ul class="nav nav-pills">
<li ng-class="{active: tabSelected === 'main'}">
Main
</li>
<li ng-class="{active: tabSelected === 'photos'}">
Photos
</li>
</ul>
</div>
...
<div class="tab-content" ng-show="tabSelected === 'photos'>
<div class="slides-control">
<carousel disable-animation="false">
<slide ng-repeat="photo in person.photos" active="photo.active">
<img class="slide" ng-src="{{photo.path}}" />
</slide>
</carousel>
</div>
</div>
In the controller I have defined a method, tabSelect(tabName, photoNumber), which allows the tab to be selected in code, and - if the tab is the one named 'photos' - a specific image number can be selected:
<script>
$scope.tabSelect = function (tabName, photoNumber) {
if (tabName === 'photos') {
$scope.person.photos[0].active = false;
$scope.person.photos[photoNumber].active = true;
}
$scope.tabSelected = tabName;
};
</script>
The problem is this:
When calling, for example, $scope.tabSelect('photos', 7);, the photos tab is shown, but initially the previously active image is shown, and then immediately it slides to the selected image (the 7th, in the example). I don't want to avoid using animations, which are quite cool... Though, I want to display immediately the selected image...
I did already try to surround the $scope.tabSelected = tabName; instruction in a $timeout() block, and the selected slide is immediately shown, but not fully rendered (for example, the arrows are not present...).