show glyphicon based on value html angular - html

controller:
.controller('BlogController', function(blogFactory, $routeParams, $scope){
var that=this;
stat=false;
this.checkbookmark = function(bId){
console.log(bId)
blogFactory.checkBookmark(bId, function(response){
console.log(response)
if(response == "bookmarked"){
that.stat = true;
}
else{
that.stat = false;
}
})
}
html code:
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3">
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk" >
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog._id)">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.stat" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.stat" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
I want to show glyphicon based on the value of stat
I have 6 blogs, first 3 are bookmarked and next 3 are not.
The problem i'm getting is that the stat value is always set according to the last bookmark and hence it is always false / true (based on the condition of last blog).
How to resolve this?

Instead of setting the stat property on the controller you should set the property on the blog object (it obviously belongs to the object)
Replace your checkbookmark function with this:
this.checkbookmark = function(blog){ //pass the entire blog, not just the id
blogFactory.checkBookmark(blog._id, function(response){
console.log(response)
if(response == "bookmarked"){
blog.stat = true; //set the property on blog instead of the controller
}
else{
blog.stat = false;
}
})
}
And then use it like this:
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog)">
<br>
<div> > READ MORE
<a ng-if="blog.stat" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blog.stat}}</a>
<a ng-if="!blog.stat" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blog.stat}}</a>
</div>
</div>
You will need to make similar changed to your add and removebookmark functions

Related

onclick Function not working independently for each element of ng-repeat

I have used ng-repeat to print out some divs. In each div I have given a p tag which says view more. On clicking that I want that the particular div that has been clicked for view more shows the data that I have put to be shown on that click. But instead all the divs are triggered together on clickin any view more p tag. Also in the content that will be shown on click I have a p tag that says view less and it hides back that content and that does the same thing. How do I make them work independently?
here is the html and angularjs code
<div ng-repeat="rent in RentSummDtl" class="rentSummCard">
<div ng-if="rent.property_id == propId">
<p id="rentSummPropName">{{ rent.month_yr }}</p>
<p class="rentSummDetl">{{ rent.propertypayamount }}</p>
<p class="rentSummDetl">{{ rent.calculatedpropertypayamount }}</p>
<p class="rentSummDetl" ng-click="isShowHide('show')" ng-show="viewMore">View More <i class="fas fa-chevron-down"></i></p>
<div ng-show="showrentDtl">
<p class="rentSummDetl">{{ rent.addition }}</p>
<p class="rentSummDetl">{{ rent.deduction }}</p>
<p class="rentSummDetl">{{ rent.percentage | number:2 }}</p>
<p class="rentSummDetl">{{ rent.ad_remark }}</p>
<p class="rentSummDetl">{{ rent.de_remark }}</p>
<p ng-click="isShowHide('hide')">View Less <i class="fas fa-chevron-up"></i></p>
</div>
</div>
</div>
$scope.showrentDtl = false;
$scope.hiderentDtl = false;
$scope.viewMore = true;
$scope.isShowHide = function (param) {
if(param == "show"){
$scope.showrentDtl = true;
$scope.hiderentDtl = false;
$scope.viewMore = false;
}
else if(param == "hide"){
$scope.showrentDtl = false;
$scope.hiderentDtl = true;
$scope.viewMore = true;
}
else{
$scope.showrentDtl = false;
$scope.hiderentDtl = false;
}
}
Is this because I have put the ng-click inside the ng-repeat and hence it works for all of them at a time together. But then how would I keep the view more inside each div if I keep it outside the ng-repeat.
Since ng-repeat creates its own local scope, you can take advantage of this by defining a variable that is local to each item in your ng-repeat. To do this simply remove your viewMore variable from your controller and set its value directly in the view. Here's a simple example to illustrate this technique.
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.items = [];
for (var i = 1; i <= 5; i++) {
var item = {
name: 'Item ' + i,
details: 'Here are some details for Item ' + i + ' so that we have something to show in the view.'
}
$scope.items.push(item);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="item in items">
<h3>{{ item.name }}</h3>
<button ng-click="viewMore = !viewMore">
<span ng-hide="viewMore">Show</span>
<span ng-show="viewMore">Hide</span>
Details
</button>
<div ng-show="viewMore">
{{ item.details }}
<a ng-click="viewMore = false"
style="cursor: pointer; color: orange;">[hide]</a>
</div>
</div>
</div>

Run controller only first time tab was clicked - AngularJS

I'm developing a website for our company, and one of the pages contains several tabs :
I want the loading operation to be done for each tab only once and not every time I click it, because these tabs have some API calls, and reloading takes time.
What is the best way to do it? I'm using Ui-router and ui-sref to move between each tab :
<div class="col-xs-2">
<div class="panel panel-default">
<div class="list-group panel panel-default">
<a ui-sref="dashboards.firstTab" ui-sref-active="active" class="list-group-item" id="firstTab_button">
<i style="color:darkblue" class="fa fa-area-chart"></i> TAB1 </a>
<a ui-sref="dashboards.secondTab" ui-sref-active="active" class="list-group-item" id="secondTab_button">
<i style="color:darkblue" class="fa fa-line-chart"></i> TAB2 </a>
<a ui-sref="dashboards.thirdTab" ui-sref-active="active" class="list-group-item" id="thirdTab_button">
<i style="color:darkblue" class="fa fa-server"></i> TAB3 </a>
</div>
</div>
</div>
<div ui-view class="col-xs-12">
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabOneSelected">
<div ng-include src="'components/Cards/Tabs/TabOne/TabOne.html'"></div>
</div>
</div>
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabTwoSelected">
<div ng-include src="'components/Cards/Tabs/TabTwo/TabTwo.html'"></div>
</div>
</div>
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabThreeSelected">
<graph-panel panel-title="TabThree {{vm.isTabThreeSelected}}" chart-config="vm.charts.TabOneChartSite"></graph-panel>
</div>
</div>
</div>
On Each Controller, You can cache your loaded data in a service, and when you load your controller you will start by checking this service if it does not have the data, then you will request it from your APIs , in this case you only request your data once you access the tab for the first time :
eg. your service
app.service('dataService', function() {
this.firstTabData = null;
this.getFirstTabData = function () {
return this.firstTabData;
};
this.setFirstTabData = function (data) {
this.firstTabData = data;
};
});
your controller
app.controller('tabOne', function($scope, dataService) {
$scope.data = {};
$scope.load = function () {
if(dataService.getFirstTabData()) {
$scope.data = dataService.getFirstTabData();
}
else {
$scope.data = getDataFromAPI();
}
};
var getDataFromAPI = function () {
//get your data
dataService.setFirstTabData(dataFromAPI);
};
});

how to use large array with ngfor in angular 5

When i display more than 100 products with ngfor page is very slow.
Is there any problem about performance on browser if call a method inside ngFor with one hundred items or set a lot of elements inside ngFor for one item?
here is my typescript code that i get some products from server with http post request
public products:any = [] ;
constructor(
private setRouter: SetRouterService,
private header :HeaderService,
private cdr: ChangeDetectorRef,
private router : Router,
private crypto:EncryptDecryptService ,
private dataservices: DataService ,
private Httpservice :HttpService ,
private route: ActivatedRoute
) {
this.dataservices.update_loader(true);
this.dataservices.create_object_request( 'products', { 'type': 'default', 'number_click': 1 } );
this.my_products = this.Httpservice.Http_Post( this.dataservices.object_request ) // make request ......
.subscribe( // take success
data => {
if ( data['status'] == 'product' ) {
this.products = data['data']['products'];
this.build_pages_link( data['data']['pages_details']);
this.dataservices.update_loader(false);
}
},
error => console.log( error['data'] ) // take error .....
);
}
here is my html code that i display products with ngFor
<div class="width_products products-animation " *ngFor="let product of products ; let i = index" [ngClass]="{ 'width_products_open_menu':header.status_menu }" >
<div class="each_width_product" >
<div class="title_products more_detail_product" (click)="set_router({ path:product['company'].company_name+'/'+product.product_title , data:product.product_id , relative:true })">
{{product.product_title }}
</div>
<div class="dropdown_products">
<span class="glyphicon glyphicon-chevron-down"></span>
</div>
<div class="date_products">
<span class='glyphicon glyphicon-time'></span> {{product.product_date}}
</div>
<div class="image_profile_company " (click)="set_router({ path:product['company'].company_name , data: product['company'].company_id , relative:true })">
<img class="image_prof_admin" src="../../assets/images/products_image/{{product['company'].company_image}}">
</div>
<div class="image_product_primary " (click)="set_router({ path:product['company'].company_name+'/'+product.product_title , data:product.product_id , relative:true })">
<img class="image_product img_primary_product{{product.product_id}}" src="../../assets/images/products_image/{{product.product_image}}">
</div>
<div class="wish_list hover_all_wish notCloseDropdawnFavorite notCloseDropdawnCard" (mouseleave)="mouseLeave_wish( product )" (mouseenter) ="mouseHover_wish( product ,i )" id="wish_list{{product.product_id}}" (click)="header.add_wish_list( product )" [ngClass]="{'wish_list_hover': product_properties.index_product == i }">
</div>
<div class="about_wish" >
<div class="wish_list_write">
<div class="plus_icon">{{dataservices.language.add_wishlist}}</div>
</div>
<div class="wish_list_icon">
<button mat-mini-fab class="button_heart" >
<div *ngIf="header.wish_properties.wishList.length > 0; else emtyWish " >
<div *ngIf="check_wish( product ) ; else notinwish">
<mat-icon>favorite</mat-icon>
</div>
<ng-template #notinwish >
<mat-icon class="notCloseDropdawnFavorite notCloseDropdawnCard" [ngClass]="{'hide_border_heart' : product_properties.hover_wish_list && product_properties.index_product == i } ">favorite_border</mat-icon>
<mat-icon class="hearts_div_hover notCloseDropdawnFavorite notCloseDropdawnCard" [ngClass]="{'show_full_heart' : product_properties.hover_wish_list && product_properties.index_product == i } ">favorite</mat-icon>
</ng-template>
</div>
<ng-template #emtyWish>
<mat-icon [ngClass]="{'hide_border_heart' : product_properties.hover_wish_list && product_properties.index_product == i } ">favorite_border</mat-icon>
<mat-icon class="hearts_div_hover" [ngClass]="{'show_full_heart' : product_properties.hover_wish_list && product_properties.index_product == i } ">favorite</mat-icon>
</ng-template>
</button>
</div>
</div>
<div class="footer_products">
<span matTooltip="Views!">
<div class="button_footer_products">
<span class="glyphicon glyphicon-eye-open icon_eye"></span>
<div class="both_write ">
12889
</div>
</div>
</span>
<span matTooltip="Add to your card" class="notCloseDropdawnCard notCloseDropdawnFavorite " (click)="header.add_cart_list( product )">
<div class="button_footer_products">
<span class="glyphicon glyphicon-plus icon_eye notCloseDropdawnCard notCloseDropdawnFavorite" *ngIf="!check_cart( product ) ; else incart "></span>
<ng-template #incart>
<span class="glyphicon glyphicon glyphicon-ok icon_eye notCloseDropdawnCard notCloseDropdawnFavorite"></span>
</ng-template>
<div class="both_write ">
Cart
</div>
</div>
</span>
<span matTooltip="See Details!">
<div (click)="set_router({ path:product['company'].company_name+'/'+product.product_title , data:product.product_id , relative:true })" class="button_footer_products more_detail_product" id="<?php echo $result_all_products['id'] ?>">
<span class=" glyphicon glyphicon-option-horizontal icon_eye"></span>
<div class="both_write ">
More
</div>
</div>
</span>
</div>
<div class="prise_products">
Price:
<div class="both_prise_products prise_primary">
<del>$2500</del>
</div>
<div class="both_prise_products prise_secondary">
$3500
</div>
</div>
<div class="plus_height"></div>
</div>
</div>
what should i do to solve it ? thank you.
the problem is the code of your function is execute every time that you do something in the template (mouse moved, for example). The lifecycle of the template is causing this,add to that the fact that your are creating a instance of that function for every item in your array. I suggest you try to
1- change the change detection strategy of component
Component({
...,
changeDetection: ChangeDetectionStrategy.OnPush
})
MyComponent {}
2- reduce the number of call from your template to methods in your component (try to use pipe instead if can be applied)

show glyphicon based on value in angular

my controller :
.controller('BlogController', function(blogFactory, $routeParams, $scope){
var that=this;
stat=false;
this.checkbookmark = function(bId){
console.log(bId)
blogFactory.checkBookmark(bId, function(response){
console.log(response)
if(response == "bookmarked"){
that.stat = true;
}
else{
that.stat = false;
}
})
}
my html code :
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3">
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk" >
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog._id)">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.stat" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.stat" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
service factory :
factory.checkBookmark = function(info, callback){
$http({
url:'api/check_bookmark_blog',
method:'POST',
headers:{'x-access-token': token},
params:{'user_id': userid},
data:{'blog_id':info}
}).success(function(data){
console.log(data);
callback(data)
})
}
I want to show glyphicon based on the value of stat
I have 6 blogs, first 3 are bookmarked and next 3 are not.
The problem i'm getting is that the stat value is always set according to the last bookmark and hence it is always false / true (based on the condition of last blog).
How to resolve this issue and set glyphicon respective to value of stat for each blog?
So there are multiple ways of implementing it.
You can either store the true/false values in either an array or you can run a function every time which returns true/false.
Using function which returns true/false values:
Modify your checkbookmark function to return true/false values as follows,
Controller code:
.controller('BlogController', function (blogFactory, $routeParams, $scope) {
this.checkbookmark = function (bId) {
blogFactory.checkBookmark(bId, function (response) {
if(response == "bookmarked"){
return true; // returns true if bookmarked
} else {
return false; // returns false if not bookmarked
}
});
};
});
HTML code:
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3 track by $index">
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk track by $index" >
<!-- removed ng-init here -->
<div class="innerbox3">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.checkbookmark(blog._id)" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.checkbookmark(blog._id)" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
Using an array:
Store the true/false values in an array and access them in html using
track by $index in your ng-repeat clause.
Controller code:
.controller('BlogController', function (blogFactory, $routeParams, $scope) {
this.stat = []; // initializing array
this.checkbookmark = function (bId) {
blogFactory.checkBookmark(bId, function (response) {
if(response == "bookmarked"){
this.stat.push(true);
} else {
this.stat.push(false);
}
});
};
});
HTML code:
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3 track by $index">
<!-- note the usage of track by $index in ng-repeat -->
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk track by $index" >
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog._id)">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.stat[$index]" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.stat[$index]" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
Hope this solves the problem.
I exactly don't know which implementation is better or any other implementations for the same. May be other folks in stackoverflow could suggest.

AngularJS Refresh ng-repeat in other controller

My code is simple. I need to refresh a ng-repeat.
HTML
<div class="quick-actions" ng-controller="DashboardController">
<div class="ui accordion segment">
<div class="ui top attached label active title">
<?php echo __('My Tasks'); ?>
<i class="minus icon"></i>
</div>
<div class="active content">
<div class="ui items" ng-show="myTasks" id="myTasks">
<!-- Creacion de Items de los Taks -->
<div class="item" ng-repeat="T in myTasks">
<div class="content">
<a class="header" href="/angular/#/task/{{ T.Task.id }}">
{{ T.Task.name }}
</a>
<div class="meta">
{{ T.Task.due_date | date : 'dd-MMM-yyyy' }}
</div>
<div class="extra high-priority" ng-if="T.Task.priority == 50">
<i class="circle icon"></i>
<?php echo __('High'); ?>
</div>
<div class="extra medium-priority" ng-if="T.Task.priority == 25">
<i class="circle icon"></i>
<?php echo __('Medium'); ?>
</div>
<div class="extra low-priority" ng-if="T.Task.priority == 0">
<i class="circle icon"></i>
<?php echo __('Low'); ?>
</div>
</div>
</div>
<!-- Termina Creacion de los Items -->
</div>
</div>
</div>
</div>
When income is well DashboardController in angularjs load ng-repeat. Data is correct here.
.controller('DashboardController', function ($scope, $state, $rootScope, $stateParams, $q, $timeout, $http, $sce, $location, Sesion, Dashboard, Fullscreen) {
Dashboard.get_all_tasks().then(function (response) {
$scope.myTasks = response;
});
})
What I need is that when I'm in another controller I can update this ng-repeat. It does not work (data incorrect) here.
.controller('NewTaskController', function ($scope, $state, $rootScope, $stateParams, $q, $timeout, $http, $sce, Sesion, Users, Opportunities, Dashboard) {
Dashboard.get_all_tasks().then(function (response) {
$timeout(function () {
$scope.$apply(function () {
$scope.myTasks = response;
});
});
});
})
Any idea what I'm doing wrong?
You need to implement a service to pass data between controllers. Here is a simplified example. It is in this plunkr here to play with.
var projectModule = angular.module('project',[]);
projectModule.factory('Service', function() {
return {
thing : {
x : 100
}
};
});
function FirstCtrl($scope, Service) {
$scope.thing = Service.thing;
$scope.name = "First Controller";
}
function SecondCtrl($scope, Service) {
$scope.foo = Service.thing;
$scope.name = "Second Controller!";
}
In this way $scope.thing from the first controller is linked to scope.foo in the second controller via the service using thing
You will need to define the structure of myTasks in the service you define so that all the elements gets passed correctly.
Try implementing this into your project and if you have a specific hangup comment here and we will help but I don't know all your code or structure of myTasks so I'm not giving copy/paste code.