AngularJS directive is not triggered - javascript

I am trying to create my own directive to highlight selected menu (I know this can be done with ui-sref and ui-sref-active but I need to expand my directive a bit more later on).
I can't get the element to trigger the directive. I want to be able to change a colour of a selected menu but it doesn't even trigger it to start with. I don't get what I'm doing wrong...
angular.module('app', ['ui.router'])
.config(function($stateProvider) {
$stateProvider
.state('home', {
template: '<h2>HOME</h2>'
})
.state('about', {
template: '<h2>ABOUT</h2>'
})
.state('contact', {
template: '<h2>CONTACT</h2>'
});
})
.directive('isMenuActive', ['$state', function($state) {
return {
restrict: 'A',
scope: {
matches: '=isMenuActive'
},
link: function(scope, element, attrs) {
console.log('trigger directive');
for (var i in scope.matches) {
var match = scope.matches[i];
if ($state.current.name.includes(match)) {
console.log('element', element);
element.addClass('active');
break;
}
}
}
}
}])
.controller('mainCtrl', function($state) {
var vm = this;
vm.menus = [
{
name: 'Home',
route: 'home',
matches: ['home', 'some-other-route']
},
{
name: 'About',
route: 'about',
matches: ['about', 'other-route']
},
{
name: 'Contact',
route: 'contact',
matches: ['contact', 'another-route']
}
];
vm.go = function(route) {
$state.go(route);
}
})
ul {
list-style-type: none;
}
ul li {
display: inline-block;
margin-right: 20px;
cursor: pointer;
font-weight: bold;
}
ul li:hover {
opacity: 0.7;
}
.active a {
color: red;
}
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.22/angular-ui-router.js"></script>
</head>
<body>
<div ng-controller="mainCtrl as vm">
<ul>
<li ng-repeat="menu in vm.menus" ng-click="vm.go(menu.route)" is-menu-active="menu.matches">
<a>{{menu.name}}</a>
</li>
</ul>
</div>
<div ui-view></div>
</body>
</html>

Related

The javascript onDrop event is not executing

The javascript onDrop event is not executing when an object is dropped into a drop zone. I've tried re-writing this in at least half a dozen ways with no luck and no error message either. I was looking around for reasons that would prevent the ondrop event from executing and found:
HTML5/Canvas onDrop event isn't firing?
and
https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#droptargets
To the best of my knowledge, I've accomplished all three requirements to trigger an ondrop event. I implemented both the ondragenter and ondragover events which both contain event.preventDefault(); and return false;. I also have event.preventDefault(); in the ondrop event.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.lists = [{name: "A", list: ["A Object 1", "A Object 2", "A Object 3"]},
{name: "B", list: ["B Object 1", "B Object 2", "B Object 3"]}];
$scope.drag_index = null;
$scope.drag_obj = null;
});
var dragging = false;
function toggle_dz() {
$(".drop-it").toggle();
}
function get_gbls(cs) {
while (cs.$parent) {
cs = cs.$parent;
}
return cs;
}
app.directive('zoneIt', function(){
return {
restrict: 'A',
link: function(scope, element, attrs){
$(element).on('dragenter',function(event){
event.preventDefault();
console.log("Drag Enter!");
return false;
});
$(element).on('dragover',function(event){
event.preventDefault();
console.log("Drag Over!");
return false;
});
}
};
});
app.directive('dragIt', function(){
return {
restrict: 'A',
link: function(scope, element, attrs){
$(element).on('drag',function(event){
var scope = angular.element(event.target).scope();
get_gbls(scope).drag_index = scope.$index;
get_gbls(scope).drag_obj = scope.obj;
if (!dragging) {
toggle_dz();
dragging = true;
}
});
$(element).on('drop',function(event){
event.preventDefault();
alert("DROPPED!");
});
$(element).on('dragend',function(event){
toggle_dz();
dragging = false;
var scope = angular.element(event.target).scope();
get_gbls(scope).drag_index = null;
get_gbls(scope).drag_obj = null;
get_gbls(scope).$apply();
});
}
};
});
.zone-it {
height: 150px;
width: 90%;
background-color: #1B6269;
border: 10px dashed #4D3A44;
border-radius: 10px;
margin: 10px 5%;
padding: 15px;
font-size: 100px;
color: #4D3A44;
text-shadow: 0 0 10px black;
}
.zone-it span {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid" ng-app="myApp" ng-controller="myCtrl">
<h2>Angular Drag n Drop</h2>
<div class="col-xs-6" ng-repeat="list in lists">
<h3>{{list.name}}</h3>
<hr>
<div class="col-xs-12 drop-it zone-it" zone-it style="display: none;"><span class="text-center glyphicon glyphicon-download"></span></div>
<div class="drop-it container-it">
<div class="col-sm-6 col-md-4 col-lg-3" ng-repeat="obj in list.list">
<div class="thumbnail drag-it" draggable="true" drag-it style="cursor:pointer">
<div class="caption text-center">{{obj}}</div>
</div>
</div>
</div>
</div>
</div>
Here is a fiddle of my code: https://jsfiddle.net/Ashkeelun/2uLwd077/1/
So, I figured it out. The ondrop event belongs with the drop zone not the item being dragged.
https://jsfiddle.net/Ashkeelun/2uLwd077/4/
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.lists = [{name: "A", list: ["A Object 1", "A Object 2", "A Object 3"]},
{name: "B", list: ["B Object 1", "B Object 2", "B Object 3"]}];
$scope.drag_index = null;
$scope.drag_obj = null;
});
var dragging = false;
function toggle_dz() {
$(".drop-it").toggle();
}
function get_gbls(cs) {
while (cs.$parent) {
cs = cs.$parent;
}
return cs;
}
app.directive('zoneIt', function(){
return {
restrict: 'A',
link: function(scope, element, attrs){
$(element).on('dragenter',function(event){
event.preventDefault();
console.log("Drag Enter!");
return false;
});
$(element).on('dragover',function(event){
event.preventDefault();
console.log("Drag Over!");
return false;
});
$(element).on('drop',function(event){
event.preventDefault();
alert("DROPPED!");
});
}
};
});
app.directive('dragIt', function(){
return {
restrict: 'A',
link: function(scope, element, attrs){
$(element).on('drag',function(event){
var scope = angular.element(event.target).scope();
get_gbls(scope).drag_index = scope.$index;
get_gbls(scope).drag_obj = scope.obj;
if (!dragging) {
toggle_dz();
dragging = true;
}
});
$(element).on('dragend',function(event){
toggle_dz();
dragging = false;
var scope = angular.element(event.target).scope();
get_gbls(scope).drag_index = null;
get_gbls(scope).drag_obj = null;
get_gbls(scope).$apply();
});
}
};
});
.zone-it {
height: 150px;
width: 90%;
background-color: #1B6269;
border: 10px dashed #4D3A44;
border-radius: 10px;
margin: 10px 5%;
padding: 15px;
font-size: 100px;
color: #4D3A44;
text-shadow: 0 0 10px black;
}
.zone-it span {
display: block;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div class="container-fluid" ng-app="myApp" ng-controller="myCtrl">
<h2>Angular Drag n Drop</h2>
<div class="col-xs-6" ng-repeat="list in lists">
<h3>{{list.name}}</h3>
<hr>
<div class="col-xs-12 drop-it zone-it" zone-it style="display: none;"><span class="text-center glyphicon glyphicon-download"></span></div>
<div class="drop-it container-it">
<div class="col-sm-6 col-md-4 col-lg-3" ng-repeat="obj in list.list">
<div class="thumbnail drag-it" draggable="true" drag-it style="cursor:pointer">
<div class="caption text-center">{{obj}}</div>
</div>
</div>
</div>
</div>

Open/close div toggle and click outside div

This post looks like duplicate, but I think is not. Now you can click Show box and show red box, if you want close this box, click outside.
Question: How close this red box on click again Show box text except click outside. And how change css style after click e.g. change font-size Show box after click
var myApplication = angular.module('myApp', []);
myApplication.directive('hideLogin', function($document){
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
elem.bind('click', function(e) {
e.stopPropagation();
});
$document.bind('click', function() {
scope.$apply(attr.hideLogin);
})
}
}
});
myApplication.controller('hideContainer',function ($scope){
$scope.openLogin = function(){
$scope.userLogin = true;
};
$scope.hideLoginContainer = function(){
$scope.userLogin = false;
};
});
body {
position:relative;
}
.loginBox {
z-index:10;
background:red;
width:100px;
height:80px;
padding:10px;
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<body ng-app="myApp" ng-controller="hideContainer">
Show box
<div hide-login="hideLoginContainer()" class="loginBox" ng-show="userLogin" style="display:none;">
</div>
</body>
To be able to hide the box on click on it, use $scope.userLogin = !$scope.userLogin condition.
To change it's css style, e.g. font-size, use ng-class. If userLogin variable is true, it will add fontSize class into it, changing it's font-size.
var myApplication = angular.module('myApp', []);
myApplication.directive('hideLogin', function($document) {
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
elem.bind('click', function(e) {
e.stopPropagation();
});
$document.bind('click', function() {
scope.$apply(attr.hideLogin);
})
}
}
});
myApplication.controller('hideContainer', function($scope) {
$scope.openLogin = function() {
$scope.userLogin = !$scope.userLogin;
};
$scope.hideLoginContainer = function() {
$scope.userLogin = false;
};
});
body {
position: relative;
}
.loginBox {
z-index: 10;
background: red;
width: 100px;
height: 80px;
padding: 10px;
position: absolute;
}
.fontSize {
font-size: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<body ng-app="myApp" ng-controller="hideContainer">
Show box
<div hide-login="hideLoginContainer()" class="loginBox" ng-show="userLogin" style="display:none;">
</div>
</body>
instead of using multiple $scope for achieve something like this you can use a single $scope variable, take look at code snippet.
var myApplication = angular.module('myApp', []);
myApplication.directive('hideLogin', function($document){
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
elem.bind('click', function(e) {
e.stopPropagation();
});
$document.bind('click', function() {
scope.$apply(attr.hideLogin);
})
}
}
});
myApplication.controller('hideContainer',function ($scope){
$scope.userLogin = true;
$scope.hideLoginContainer = function(){
$scope.userLogin = true;
};
});
body
{
position:relative;
}
.loginBox
{
z-index:10;
background:red;
width:100px;
height:80px;
padding:10px;
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<body ng-app="myApp" ng-controller="hideContainer">
Show box
<div hide-login="hideLoginContainer()" class="loginBox" ng-show="!userLogin" style="display:none;">
</div>
</body>
You could rename openLogin() to toggleLogin() and change the function accordingly to
$scope.toggleLogin = function(){
$scope.userLogin != $scope.userLogin;
};
That will toggle the box when you click on the link.
For the CSS part, use ng-class to conditionaly sign a class to the element if userLogin ==true
<div ng-class="{'myConditionalClass':userLogin }"></div>

CSS Star Rating with ng-repeat and json data using angularjs

Want to show a div n times according to the value which was received from JSON.
My object:
$scope.pro = [
{
product: "chicken",
rating: 3
},
{
product: "fish",
rating: 3
},
{
product: "pizza",
rating: 4
}
];
If a product has 3 ratings means the div have to show three times, like a star rating.
How to do it in angular.js?
My Plunker Demo
Can you try this,
JS
$scope.pro = [{product: "chicken", rating: 3},{product: "fish", rating: 3},{product: "pizza", rating: 4}];
var ratingTotal = 5;
$scope.getRepeater = function() {
return new Array(ratingTotal);
};
Html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script data-require="angular.js#1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="myController">
<div ng-repeat="array in pro">{{array.product}} <span class="star-icon" ng-repeat="r in getRepeater() track by $index" ng-class="{'full': ($index + 1) <= array.rating, 'half': ($index + .5) == array.rating}" ></span></div>
</body>
</html>
Note: The class name for selected star is mentioned as 'full' and feel free to change this.
geNumber() will create an empty array with the size of the rating. ng-repeat will iterate over it no matter what is inside
track by $index is necessary in this case because you will display multiple times the same value and duplicates in a repeater are not allowed
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.pro = [{
product: "chicken",
rating: 3
}, {
product: "fish",
rating: 3
}, {
product: "pizza",
rating: 4
}];
$scope.getNumber = function(num){
return new Array(num);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myController">
<div ng-repeat="item in pro">
<div ng-repeat="n in getNumber(item.rating) track by $index">
{{item.product}}
</div>
</div>
</body>
You can create an array, based on the rating. Then repeat over that array:
<div ng-repeat="array in pro">
{{array.product}} , <span ng-repeat="n in createArray(array.rating) track by $index">X</span>
</div>
In your controller:
$scope.createArray = function(n){
return new Array(n);
}
https://plnkr.co/edit/gUPn6m7Tiu01yksa9VOs?p=preview
If you're feeling fancy, you can use this ES6 solution to show x number of *:
Note: no IE support at all.
JS
$scope.getAsterisks = rating => Array.from('*'.repeat(parseInt(rating, 10)));
HTML
<span ng-repeat="x in getAsterisks(array.rating) track by $index">{{x}}</span>
Plunker: https://plnkr.co/edit/9H3j3NH9w5xNvqM142Gq?p=preview
Info on the ES6 functions:
Array.from (no support in IE) creates an array from a string, each character becomes an array item.
String.prototype.repeat (no support in IE and Opera) ... repeats the string X times.
<div ng-repeat="array in pro">{{array.product}} ,
<span ng-repeat=" arr in array.rating ">{{arr.j}}</span>
</div>
// Code goes here
// Code goes here
var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
$scope.pro = [{product: "chicken", rating: 3},{product: "fish", rating: 4},{product: "pizza", rating: 6}];
for(var i=0;i<$scope.pro.length;i++)
{
if($scope.pro[i].rating >0)
{
$scope[$scope.pro[i].product]=[];
for(var j=0;j< $scope.pro[i].rating;j++)
{
$scope[$scope.pro[i].product].push({j:'*'});
}
$scope.pro[i].rating = $scope[$scope.pro[i].product];
}
}
});
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script data-require="angular.js#1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="myController">
<div ng-repeat="array in pro">{{array.product}} ,
<span ng-repeat=" arr in array.rating ">{{arr.j}}</span>
</div>
</body>
</html>
An AngularJS directive ratings:
angular
.module('myApp', [])
.directive('ratings', function () {
return {
restrict: 'E',
scope: false,
template: '<span ng-repeat="x in arrRating track by $index">★</span>',
link: function ($scope, $el, $attr) {
$scope.arrRating = new Array(+$attr.rating);
}
};
})
.controller('myController', function ($scope) {
$scope.pro = [{product: "chicken",rating: 3}, {product: "fish",rating: 3}, {product: "pizza",rating: 4}, {product: "steak",rating: 10}];
});
<script data-require="angular.js#1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
<div ng-app="myApp" ng-controller="myController">
<div ng-repeat="p in pro">
{{p.product}} <ratings rating="{{p.rating}}"></ratings>
</div>
</div>
A better way to do this is to create a star component via a custom directive it can also be reused throughout the Angular app, this directive takes the rating and generates the number of stars in the DOM.
angular
.module('demo', [])
.controller('DefaultController', DefaultController)
.controller('StarController', StarController)
.directive('star', star);
function DefaultController() {
var vm = this;
vm.products = [{
product: "chicken",
rating: 3
}, {
product: "fish",
rating: 4
}, {
product: "pizza",
rating: 5
}];
}
function star() {
var directive = {
restrict: 'E',
scope: {
rating: '=',
max: '='
},
link: linkFunc,
controller: StarController,
controllerAs: 'star',
bindToController: true
};
return directive;
function linkFunc(scope, element, attrs, ngModelCtrl) {
for (var i = 0; i < scope.max; i++) {
var fillStyle = '';
if (i < scope.rating) {
fillStyle = 'fill';
} else {
fillStyle = 'empty';
}
element.append('<span class="star-icon ' + fillStyle + '">☆</span>');
}
}
}
function StarController() {
var vm = this;
}
ul {
font-size: 20px;
list-style-type: none;
padding: 0;
}
ul li {
padding: 10px;
}
ul li > span {
display: inline-block;
width: 100px;
}
star span {
margin: 0px 5px;
}
.star-icon {
color: #ddd;
font-size: 1.5em;
position: relative;
top: 3px;
}
.star-icon.fill:before {
text-shadow: 0 0 1px rgba(0, 0, 0, 0.7);
color: #FDE16D;
content: '\2605';
position: absolute;
left: 0;
}
.star-icon.empty:before {
text-shadow: 0 0 1px rgba(0, 0, 0, 0.7);
color: #FFF;
content: '\2605';
position: absolute;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo">
<div ng-controller="DefaultController as ctrl">
<ul>
<li ng-repeat="product in ctrl.products">
<span ng-bind="product.product"></span>
<star rating="product.rating" max="5"></star>
</li>
</ul>
</div>
</div>
Star rating inspired by https://coderwall.com/p/iml9ka/star-ratings-in-css-utf8

how to popup profile picture in ionic

I am new to ionic.I am creating a app with user list i have succesfully populated users list.but i want to popup particular users profile picture whenever i click on picture. Like whatsapp popup window.
i am unable to do it.following is my code.
app.js
angular.module('shoppingPad', ['ionic','shoppingPad.controller', 'shoppingPad.service'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
// Each tab has its own nav history stack:
.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.chats', {
url: '/chats',
views: {
'tab-chats': {
templateUrl: 'templates/chat.html',
controller: 'ChatCtrl'
}
}
})
.state('tab.chat-details', {
url: '/chats/:chatId',
views: {
'tab-chats': {
templateUrl: 'templates/chat-details.html',
controller: 'ChatDetailCtrl'
}
}
})
.state('tab.groups',{
url:'/groups',
views: {
'tab-chats':{
templateUrl:'templates/groups.html',
controller:'groupCtrl'
}
}
})
.state('tab.newGroups',{
url:'/new',
views: {
'tab-chats':{
templateUrl:'templates/newGroup.html'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/chats');
});
controller.js:
angular.module('shoppingPad.controller', [])
.controller('DashCtrl', function($scope) {})
.controller('ChatCtrl', function($scope, Contents) {
//$scope.contents = Contents.query();
$scope.contents = Contents.all();
$scope.remove = function(chat) {
Contents.remove(chat);
};
})
.controller('ChatDetailCtrl', function($scope, $stateParams, Contents, $ionicPopup) {
alert('details');
// $scope.contents = Contents.get({content_id: $stateParams.content_id});
//alert($stateParams.content_id);
$scope.content = Contents.get($stateParams.chatId);
alert($stateParams.chatId);
alert('data');
$scope.showPopup=function(){
alert('alertpopup');
var alertPopup=$ionicPopup.alert({
title:'hey',
templateUrl:'templates/chat-details.html'
});
alertPopup.then(function(res){
console.log('popup');
});
};
})
.controller('groupCtrl',function($scope,Groups){
$scope.groups=Groups.group();
});
chatServices.js
angular.module('shoppingPad.service',['ngResource']).
factory('Contents',function() {
//return $resource('http://54.86.64.100:3000/api/v1/content/content-info');
var contents = [{
id: 0,
name: 'Ben Sparrow',
lastText: 'You on your way?',
face: 'img/ben.png'
}, {
id: 1,
name: 'a',
lastText: 'Hey, it\'s me',
face: 'img/007.gif'
}, {
id: 2,
name: 'b',
lastText: 'I should buy a boat',
face: 'img/ionic.png'
}, {
id: 3,
name: 'c',
lastText: 'Look at my mukluks!',
face: 'img/profile-no-photo.png'
}, {
id: 4,
name: 'd',
lastText: 'This is wicked good ice cream.',
face: 'img/profile-unknown-male.png'
}];
return {
all: function() {
return contents;
},
remove:function(content){
contents.splice(contents.indexOf(content),1);
},
get:function(chatId) {
for (var i = 0; i < contents.length; i++) {
if (contents[i].id === parseInt(chatId)) {
return contents[i];
}
}
return null;
}
};
});
chat.html
<ion-view view-title="Chats">
<ion-header-bar class="bar-subheader bar-light">
Groups
New group
</ion-header-bar>
<ion-content>
<ion-list>
<div class="modal image-modal transparent" ng-click="showPopup()">
<ion-item class="item-remove-animate item-avatar item-icon-right" ng-repeat="content in contents" type="item-text-wrap" href="#/tab/chats/{{content.id}}">
<img ng-src="{{content.face}}" >
<h2>{{content.name}}</h2>
<p>{{content.lastText}}</p>
<i class="icon ion-chevron-right icon-accessory"></i>
<ion-option-button class="button-assertive" ng-click="remove(content)">
Delete
</ion-option-button>
</ion-item>
</div>
</ion-list>
</ion-content>
</ion-view>
Add below code in your ChatCtrl in controller.js file
$ionicModal.fromTemplateUrl('user_photo.html', { // Use Ionic Modal to show user photo
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.closeModal = function() {
$scope.modal.hide();
};
$scope.$on('$destroy', function() {
$scope.modal.remove();
});
$scope.showUser = function (user, event){
if (event){
event.stopPropagation(); //to prevent calling of showUser() and showPop() functions at same time
}
$scope.current_user = user;
$scope.openModal();
}
Note: Don't forget to inject $ionicModal service to your controller
.controller('ChatCtrl', function($scope, Contents, $ionicModal) {
And below code with user_photo.html template and showUser() function on user thumbnail is for your chat.html file
Note: Replace the whole code in chat.html with below code
<style type="text/css">
.image-modal {
width: 100% !important;
height: 100%;
top: 0 !important;
left: 0 !important;
}
.transparent {
background: rgba(0, 0, 0, 0.7);
}
.image {
width: 100%;
height: 600px;
background-size: contain;
background-repeat: no-repeat;
background-position: center, center;
}
</style>
<ion-view view-title="Chats">
<ion-header-bar class="bar-subheader bar-light">
Groups
New group
</ion-header-bar>
<ion-content>
<ion-list>
<ion-item class="item-remove-animate item-avatar item-icon-right" ng-repeat="content in contents"
type="item-text-wrap" href="#/tab/chats/{{content.id}}" ng-click="showPopup()">
<img ng-src="{{content.face}}" ng-click="showUser(content, $event)">
<h2>{{content.name}}</h2>
<p>{{content.lastText}}</p>
<i class="icon ion-chevron-right icon-accessory"></i>
<ion-option-button class="button-assertive" ng-click="remove(content)">
Delete
</ion-option-button>
</ion-item>
</ion-list>
<script id="user_photo.html" type="text/ng-template">
<div class="modal image-modal transparent" on-swipe-down="closeModal()">
<ion-scroll direction="xy"
zooming="true" min-zoom="1" style="width: 100%; height: 100%"
overflow-scroll="false">
<div class="image" style="background-image: url( {{current_user.face}} )"></div>
</ion-scroll>
</div>
</script>
</ion-content>
</ion-view>
You can use ionic modal
angular.module('ionicApp', ['ionic'])
.controller('MyController', function($scope, $ionicModal) {
$ionicModal.fromTemplateUrl('my-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.closeModal = function() {
$scope.modal.hide();
};
//Cleanup the modal when we're done with it!
$scope.$on('$destroy', function() {
$scope.modal.remove();
});
// Execute action on hide modal
$scope.$on('modal.hidden', function() {
// Execute action
});
// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
});
});
<html>
<head>
<script src="http://code.ionicframework.com/1.0.0-rc.5/js/ionic.bundle.js"></script>
<link href="http://code.ionicframework.com/1.0.0-beta.14/css/ionic.css" rel="stylesheet"/>
</head>
<body>
<div ng-app="ionicApp">
<ion-content has-tabs="true" ng-controller="MyController">
<script id="my-modal.html" type="text/ng-template">
<ion-modal-view>
<ion-header-bar>
<h1 class="title">My Modal title</h1>
</ion-header-bar>
<ion-content>
Hello!
</ion-content>
</ion-modal-view>
</script>
<p class="padding">
<button class="button button-positive button-block button-outline" ng-click="openModal()">Trigger modal</button>
</p>
</ion-content>
</div>
</body>
</html>

Rendering a Star Rating System using angularjs

My app is in this Fiddle
I need to render a star rating system dynamically from a http service, where the current stars and maximum stars can vary with each case.
Is it a good idea to create arrays from $scope.current and
$scope.max - $scope.current and pass them and run ng-repeat over them, or there is a more optimised solution than this.
Iteration ng-repeat only X times in AngularJs
Star Rating can be done either statically (read-only) or dynamically
If you want just simply to display Rating as star then try the below one
Static Star Rating
Working Example
html
<body ng-app="starApp">
<div ng-controller="StarCtrl"> <span ng-repeat="rating in ratings">{{rating.current}} out of
{{rating.max}}
<div star-rating rating-value="rating.current" max="rating.max" ></div>
</span>
</div>
</body>
script
var starApp = angular.module('starApp', []);
starApp.controller('StarCtrl', ['$scope', function ($scope) {
$scope.ratings = [{
current: 5,
max: 10
}, {
current: 3,
max: 5
}];
}]);
starApp.directive('starRating', function () {
return {
restrict: 'A',
template: '<ul class="rating">' +
'<li ng-repeat="star in stars" ng-class="star">' +
'\u2605' +
'</li>' +
'</ul>',
scope: {
ratingValue: '=',
max: '='
},
link: function (scope, elem, attrs) {
scope.stars = [];
for (var i = 0; i < scope.max; i++) {
scope.stars.push({
filled: i < scope.ratingValue
});
}
}
}
});
If you want to do Star Rating dynamically try this out
Dynamic Star Rating
Working Demo
Html
<body ng-app="starApp">
<div ng-controller="StarCtrl"> <span ng-repeat="rating in ratings">{{rating.current}} out of
{{rating.max}}
<div star-rating rating-value="rating.current" max="rating.max" on-rating-selected="getSelectedRating(rating)"></div>
</span>
</div>
</body>
script
var starApp = angular.module('starApp', []);
starApp.controller('StarCtrl', ['$scope', function ($scope) {
$scope.rating = 0;
$scope.ratings = [{
current: 5,
max: 10
}, {
current: 3,
max: 5
}];
$scope.getSelectedRating = function (rating) {
console.log(rating);
}
}]);
starApp.directive('starRating', function () {
return {
restrict: 'A',
template: '<ul class="rating">' +
'<li ng-repeat="star in stars" ng-class="star" ng-click="toggle($index)">' +
'\u2605' +
'</li>' +
'</ul>',
scope: {
ratingValue: '=',
max: '=',
onRatingSelected: '&'
},
link: function (scope, elem, attrs) {
var updateStars = function () {
scope.stars = [];
for (var i = 0; i < scope.max; i++) {
scope.stars.push({
filled: i < scope.ratingValue
});
}
};
scope.toggle = function (index) {
scope.ratingValue = index + 1;
scope.onRatingSelected({
rating: index + 1
});
};
scope.$watch('ratingValue', function (oldVal, newVal) {
if (newVal) {
updateStars();
}
});
}
}
});
There is a wonderful tutorial here for more explanation about Angular Star Rating
You can even try angular-ui. Here is the link.
Just need to add this tag.
<rating ng-model="rate" max="max"
readonly="isReadonly"
on-hover="hoveringOver(value)"
on-leave="overStar = null">
//Controller
var starApp = angular.module('starApp', []);
starApp.controller('StarCtrl', ['$scope', function ($scope) {
$scope.maxRating = 10;
$scope.ratedBy = 0;
$scope.rateBy = function (star) {
$scope.ratedBy = star;
}
}]);
.rating {
color: #a9a9a9;
margin: 0;
padding: 0;
}
ul.rating {
display: inline-block;
}
.rating li {
list-style-type: none;
display: inline-block;
padding: 1px;
text-align: center;
font-weight: bold;
cursor: pointer;
}
.rating .filled {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="starApp">
<div ng-controller="StarCtrl">
<ul class="rating">
<li ng-repeat="n in [].constructor(maxRating) track by $index">
<span ng-click="rateBy($index+1)" ng-show="ratedBy > $index" class="filled">★</span>
<span ng-click="rateBy($index+1)" ng-show="ratedBy <= $index">★</span>
</li>
</ul>
</div>
</body>
You could hold an array of objects like so:
var starApp = angular.module('starApp',[]);
starApp.controller ('StarCtrl', ['$scope', function ($scope) {
$scope.ratings = [];
var rating = {
current : 5,
max : 10
}
$scope.ratings.push(rating); // instead you would push what your http service returns into thearray.
}]);
Then in your view you could use ng-repeat like so:
<body ng-app="starApp">
<div ng-controller="StarCtrl">
<span ng-repeat="rating in ratings">{{rating.current}} out of {{rating.max}}</span>
</div>
</body>
My minimalistic approach:
The view
<head>
<!-- alternatively you may use another CSS library (like FontAwesome) to represent the star glyphs -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"></link>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0-rc.2/angular.min.js"></script>
<!-- insert the JavaScript controller and the CSS enhancements here -->
</head>
<body>
<div ng-app="StarRatings">
<div ng-controller="myController as ctrl">
<div ng-repeat="n in ctrl.getStarArray()" ng-class="ctrl.getClass(n)" ng-mouseover="ctrl.setClass($event,n)"> </div>
<p>
You have chosen {{ctrl.selStars}} stars
</p>
</div>
</div>
</body>
Note: if you want to use the onClick event instead onMouseOver event then replace ng-mouseover with ng-click in the HTML above.
The controller
<script>
(function() {
var app = angular.module('StarRatings', []);
app.controller('myController', function() {
this.selStars = 0; // initial stars count
this.maxStars = 5; // maximum number of stars
// a helper function used within view
this.getStarArray = function() {
var result = [];
for (var i = 1; i <= this.maxStars; i++)
result.push(i);
return result;
};
// the class used to paint a star (filled/empty) by its position
this.getClass = function(index) {
return 'glyphicon glyphicon-star' + (this.selStars >= index ? '' : '-empty');
};
// set the DOM element class (filled/empty star)
this.setClass = function(sender, index) {
this.selStars = index;
sender.currentTarget.setAttribute('class', this.getClass(index));
};
});
})();
</script>
Optionally some CSS enhancements
<style>
.glyphicon {
color: gold;
cursor: pointer;
font-size: 1.25em;
}
</style>
Not convinced? Try this JSFiddle: https://jsfiddle.net/h4zo730f/2/
let app = angular.module ('myapp',[])
-
##star Rating Styles
----------------------*/
.stars {
padding-top: 10px;
width: 100%;
display: inline-block;
}
span.glyphicon {
padding: 5px;
}
.glyphicon-star-empty {
color: #9d9d9d;
}
.glyphicon-star-empty,
.glyphicon-star {
font-size: 18px;
}
.glyphicon-star {
color: #FD4;
transition: all .25s;
}
.glyphicon-star:hover {
transform: rotate(-15deg) scale(1.3);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app= "myapp" >
<div class="stars">
<div id="stars" class="star">
<span ng-repeat="x in [0,1,2,3,4,5]" ng-if="($index < 4)" class="glyphicon glyphicon-star"> </span>
<span ng-repeat="x in [0,1,2,3,4,5]" ng-if="($index >= 4 && $index < 5) " class="glyphicon glyphicon-star-empty"></span>
</div>
</div>
</div>
hmc.starRating.js
angular.module('starRatings',[]).directive('starRating', function () {
return {
restrict: 'A',
template: '<ul class="rating">' +
'<li ng-repeat="star in stars" ng-class="star">' +
'\u2605' +
'</li>' +
'</ul>',
scope: {
ratingValue: '=',
max: '='
},
link: function (scope, elem, attrs) {
console.log(scope.ratingValue);
function buildStars(){
scope.stars = [];
for (var i = 0; i < scope.max; i++) {
scope.stars.push({
filled: i < scope.ratingValue
});
}
}
buildStars();
scope.$watch('ratingValue',function(oldVal, newVal){
if(oldVal !== newVal){
buildStars();
}
})
}
}
});
<script src="hmc.starRating.js"></script>
**app.js**
var app = angular.module('app', ['ui.bootstrap', 'starRatings']);
**indix.html**
<div star-rating rating-value="7" max="8" ></div>
.rating {
color: #a9a9a9;
margin: 0 !important;
padding: 0 !important;
}
ul.rating {
display: inline-block !important;
}
.rating li {
list-style-type: none !important;
display: inline-block !important;
padding: 1px !important;
text-align: center !important;
font-weight: bold !important;
cursor: pointer !important;
width: 13px !important;
color: #ccc !important;
font-size: 16px !important;
}
.rating .filled {
color: #ff6131 !important;
width: 13px !important;
}

Categories