Problem Description:
I have an e-commerce application, in which I have to load a lot of product images. We used 200*200 images for small images, but there are modals which are 600*600 in size and appear when clicked on any product.
The problem is, when each page is loaded, all the images (200*200 and 600*600) are getting loaded, which is making the application too slow.
Question: Is there any way to avoid the (600*600) images to load before being clicked. I would like the application to load only the 200*200 images initially and load any 600*600 image on request.
Technology: (Jade, Angularjs, Nodejs)
Code:
<div ng-repeat="product in category.products | filter:query | orderBy: 'productName'">
<div class="panel-default panel thumbnail" id="imgs">
<div class="panel-body">
<a href="#" data-target="#img_modal{{product._id}}" data-toggle="modal">
<img class="img-responsive center-block" ng-src="{{product.productImage_tn}}" alt="" id="items" />
</a>
<div class="modal" id='img_modal{{product._id}}' tabindex='-1' role='dialog' area-hidden='true'>
<div class="modal-dialog" style="width: 630px;">
<div class="modal-content">
<div class="modal-header">
<h4>{{ product.productName }}
<button class="close" type='button' data-dismiss='modal' area-hidden='true'> ×</button>
</h4>
</div>
<div class="modal-body">
<img ng-src="{{product.productImage_600}}" style=" position: relative; height: 400px;" class="img-responsive center-block">
</div>
<div class="modal-footer">
<div class="row">
<div class="col-sm-4 col-md-4">
<h4>$ {{ product.productPrice }} {{ product.productUnit }}</h4>
</div>
<div class="col-sm-2 col-md-2"></div>
<div class="col-sm-6 col-md-6">
<div class="input-group number-spinner">
<span class="input-group-btn">
<button class="btn btn-default" ng-click="removeItem(product._id)">
<span class="glyphicon glyphicon-minus"></span>
</button>
</span>
<label class="form-control text-center">{{ getItemQty(product._id) }}</label>
<span class="input-group-btn">
<button class="btn btn-default" ng-click="addItem(product._id)">
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="panel-footer" id="panelfooter">
<h6>{{ product.productName }} </h6>
<h6>$ {{ product.productPrice }} {{ product.productUnit }}</h6>
</div>
<div class="input-group number-spinner">
<span class="input-group-btn">
<button class="btn btn-default" ng-click="removeItem(product._id)">
<span class="glyphicon glyphicon-minus"></span>
</button>
</span>
<label class="form-control text-center">{{ getItemQty(product._id) }}</label>
<span class="input-group-btn">
<button class="btn btn-default" ng-click="addItem(product._id)">
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
</div>
</div>
Look at ui-bootstrap and the example for Modal over there. The reason you see all images being loaded is that you have inlined all your content. What you should do is put the modal content in a separate template and use the ng-click directive to open the modal dialog. Using the templateUrl option will ensure that content is loaded when clicked and not before
Related
I wish to set the value of my dropdown and the value of my textbox in ng-model to pass it to my angular js.
The console displays null for the value of my dropdown.
What I've tried:
<form id="uploadForm">
<div id="republishSingle" class="panel-collapse collapse in desc vertical" style="text-align: left">
<div class="horizontal">
<div class="dropdown">
<button type="button" class="btn btn-light dropdown-toggle" data-toggle="dropdown" id="selectSource1" aria-haspopup="true" aria-expanded="true" ng-model="republishSource">
Source system
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu1">
<h5 class="dropdown-header">Source system</h5>
<a class="dropdown-item" href="#" data-value="s1">S1</a>
<a class="dropdown-item" href="#" data-value="s2">S2</a>
</div>
</div>
<div class="col-5">
<input class="form-control disableButton" id="policy" type="text" placeholder="Policy" ng-model="republishInput"/>
</div>
<div class="form-group mb-3">
<div class="form-group" aria-label="file upload">
<input id="republish" type="submit" class="btn btn-success"
ng-click="doRepublish(republishSource,republishInput)" value="Republish"/>
</div>
</div>
</div>
</div>
</form>
I have to remove the image from the list in the conformation model click on the YES button but after 2nd time model is not open.In the element section after 2nd time click "
<span class="glyphicon glyphicon-remove-sign" data-toggle="modal" data-target="#openImage"></span>
<div id="openImage" class="modal in">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Are you sure???</h4>
</div>
<div class="modal-body">
<p>Are you sure you want to delete this product?</p>
<div class="row">
<div class="col-12-xs text-center">
<button class="btn btn-primary btn-md" ng-click="removeSelectedProductKey($event, productObject.keyId)"> Yes</button>
<button class="btn btn-default btn-md" data-dismiss="close">No</button>
</div>
</div>
</div>
</div>
</div>
</div>
display :none" is apply tell me sir how to resolve this problem?
Try to open your modal by function using:
<span class="glyphicon glyphicon-remove-sign" ng-click="openImg()"></span>
And inside your controller write below function:
function openImg(){
angular.element('#openImage').modal();
}
I need to set a default image from my local file if profile pic is not set by user and how to set hover to it if the user moves the mouse close to the profile pic field to set the image.
My HTML :
<div class="col-lg-2 vheight1">
<h4>Profile Picture</h4>
<div class="fileinput fileinput-new" onclick='$("#my_profile_pic").click();'>
<div class="fileinput-preview thumbnail" data-provides="fileinput" data-trigger="fileinput" id="profile_pic">
<img ng-if="source" class="thumb" ng-src="{{source}}"/>
</div>
<!-- <div class="hidden-sm hidden-md hidden-lg hidden-xs">
<span>
<span class="fileinput-new" ng-show="!hasFile()">Select image</span>
<span class="fileinput-new" ng-show="hasFile()">Change</span>
</span>
<a href="#" class="btn btn-danger fileinput-new glyphicon glyphicon-trash" data-dismiss="fileinput" ng-show="hasFile()" ng-click="removefile( json, file )" ></a>
</div> -->
</div>
</div>
<input type="file" class="hidden hidden-sm hidden-md hidden-lg hidden-xs" id='my_profile_pic' file-model="photo">
Can anyone please help me.
Replace:
<img ng-if="source" class="thumb" ng-src="{{source}}"/>
with:
<img class="thumb" ng-src="{{source ? source : 'pathtodefault.png'}}"/>
To complete Piyush's answer, you can also do:
<img class="thumb" ng-show="source" ng-src="{{source}}"/>
<img class="thumb" ng-show="!source" src="defaultSrc"/>
I have a Json which m getting in $scope.notifications.
**Json**
0:{
$$hashKey: "object:31"
action: "wrote a comment"
creationDate: "2015-11-23 13:48:55.0"
post: Object
seen: true
user: Object
}
This Json has a key : seen which can be either true or false . I have to filter out those objects in ng-repeat whose key :seen is= false on clicking button unread notifications.
and then again clear the filter on clicking All Notifications button.
HTML
<div class="col-xs-12 col-sm-6 col-md-8">
<ul class="notifications-action-menu text-center">
<li>
<button type="button" class="btn btn-link btnUnreadFilter active" data-filter="all" id="btnShowAll">All Notifications</button>
</li>
<li>
<button type="button" class="btn btn-link btnUnreadFilter" data-filter="unread" id="btnShowOnlyUnread" ng-click="actions.unreadNotifications()">Unread Notifications</button>
</li>
<ul></ul>
</ul>
</div>
<div class="col-xs-12">
<div id="notificationsListWrapper" ng-repeat="notification in notifications" ng-hide="{{notification.seen == seen}}">
<div class="notification-item" ng-class="{'read' : notification.seen == true}">
<div class=" no-click-bind mark-as-read-btn">
<button type="button" class="no-click-bind" data-toggle="tooltip" data-placement="top" data-original-title="Mark as read" ng-click="actions.redirectToPost(notification.post.uuid, $index)">
<i class="fa fa-check"></i>
</button>
</div>
<div class="notification-body">
<div class="notification-details">
<a href="" class="doc-profile-img"><img class="" alt="{{notification.user.authorName}}" ng-src="{{(notification.user.thumbnailUrl) ? notification.user.thumbnailUrl :'/assets/images/avatars/avatar_100x100.png'}}">
</a>
<a>{{notification.user.authorName}}</a><span class="notification-action"> {{notification.action}}</span>
<a href="/news/abcd" class="notification-url no-click-bind">{{notification.post.title}}
</a>
<div class="notification-meta"><i class="fa notification-type-icon fa-calendar"></i> <small class="notification-datetime text-muted" title="Thursday, January 21, 2016 at 5:26 pm">Jan 21 2016</small>
</div>
<div class="notification-actions"></div>
</div>
</div>
<div ng-if="notification.post.featuredAttachmentUrl != '' " class="notification-url-img"><img alt="" ng-src="{{notification.post.featuredAttachmentUrl}}"></div>
</div>
</div>
Try something like:
ng-repeat="notification in notifications | filter:seenFilter"
where seenFilter is set to {seen:true}, {seen:false} or true by the controller. Example:
$scope.actions.unreadNotifications = function(){
$scope.seenFilter = {seen:false}
}
I have a table with an ng-repeat over a function that I want to be rerendered after a user logs in. How do I make a view load the ng-repeat and again to triger the function. Is there a way to make an ng-repeat rerender on a change in the model?
Here is the view, to give an idea why a function is used instead of just looping over a model. The repeat in question is ng-repeat="(index, event) in vm.getEvents(dayObject) track by $index" :
<!-- CALENDAR NAV -->
<div class="calendar-nav">
<div class="prev">
<button class="btn btn-default pull-right" ng-click="vm.goToPrevWeek()" ng-disabled="vm.isCurrentWeek"><i class="glyphicon glyphicon-chevron-left"></i></button>
</div>
<div class="date">
<p class="text-primary text-center">{{vm.weekViewString}}</p>
</div>
<div class="next">
<button class="btn btn-default pull-left" ng-click="vm.goToNextWeek()"><i class="glyphicon glyphicon-chevron-right"></i></button>
</div>
</div>
<!-- END CALENDAR NAV -->
<!-- CALENDAR HEADER -->
<div class="calendar-header">
<div class="weekdate-header date-header day-1 split-{{vm.weekSplit}}" ng-class="{'today': dayObject.isToday}" ng-repeat="(index, dayObject) in vm.calendarDays track by $index">
<div class="date-container"><span class="date">{{dayObject.day}}</span><span class="week-day"> {{dayObject.weekDay}}</span></div>
</div>
</div>
<!-- END CALENDAR HEADER -->
<!-- CALENDAR CONTENT -->
<div class="calendar-content">
<div class="calendar-aside">
<div class="day-hour" ng-repeat="(index, hourObject) in vm.calendarHours track by $index">
<span class="hour">{{hourObject.hour}}</span>
</div>
</div>
<div class="calendar-days">
<div class="calendar-day day-col day-1 split-{{vm.weekSplit}}" ng-class="{'today': dayObject.isToday}" ng-repeat="(index, dayObject) in vm.calendarDays track by $index">
<div class="mobile-day hidden-lg hidden-md hidden-sm">
<div class="date-container"><span class="date">{{dayObject.day}}</span><span class="week-day"> {{dayObject.weekDay}}</span></div>
</div>
<div class="day-hour hour-{{hourObject.number}}" ng-repeat="(index, hourObject) in vm.calendarHours track by $index">
<div class="hour">
<div class="half-hour"></div>
</div>
</div>
<!-- CALENDAR EVENTS -->
<div id="{{event.idName}}" class="event-container {{event.type}}" style="top: {{event.top}}px; left: {{event.left}}%; width: {{event.width}}%; height: {{event.height}}px;"
ng-repeat="(index, event) in vm.getEvents(dayObject) track by $index" ng-switch="event.type">
<div class="buttons" ng-switch-when="">
<div class="amount">{{event.spotsAvailable}}</div>
</div>
<div class="buttons" ng-switch-when="success">
<i class="glyphicon glyphicon-ok-sign"></i>
</div>
<div class="buttons" ng-switch-when="full">
<i class="glyphicon glyphicon-ban-circle"></i>
</div>
<div class="text">
<span class="title">{{event.name}}</span>
<p class="locatie-time hidden-lg hidden-md hidden-sm"> <span>{{event.startsAt | date:'HH:mm' }}</span> - <span>{{event.endsAt | date:'HH:mm' }}</span> </p>
<span class="locatie-info">{{event.formattedAddress}}</span>
</div>
</div>
<!-- END CALENDAR EVENTS -->
</div>
</div>
</div>
<!-- END CALENDAR CONTENT -->
I ended up replacing the function in the ng-repeat with a direct link to the data the function was returning and now the view is updating.