I've a situation where I want to display an error message on the page when my modal don't have any records to show. This could be on the initial load or after applying some filter criteria on the page.
I'm using ng-if to check the count of records on the result set after applying the filter, that is why when my page initially loads as there is no data in the filtered result rest it is showing up the error message first and then later it is showing the data.
Any insight would be highly appreciated
prod.skulist is my modal.
<ul class="prd-list">
<li ng-repeat=" p in filtered =(prod.skulist | categoryFilter:prod.selectedFormat :prod.selectedRating) | filter :priceRange" id=" {{p.sku}}">
<figure class="prd-img" ng-click="wrapCtrl.showProdDetils(p.sku,prod.catName)">
<div style="background-image: url({{wrapCtrl.imageLocation+p.image}}); background-repeat: no-repeat;"></div>
<figcaption class="prd-nam f8">{{p.title}}</figcaption>
<span class="new-item" ng-show="{{p.isnew}}"><img src="Content/images/new.png" /></span>
<span class="new-item" ng-show="wrapCtrl.compareStreetDate(p.streetdate)"><img src="/Content/images/coming-soon.png" /></span>
</figure>
<div class="prd-price f5">
{{p.currentprice | currency}}<span class="sales" ng-show="{{p.onsale}}">ON SALE</span>
<span class="cart-btn" ng-click="wrapCtrl.addCart($event)"></span>
<div class="inactive-cart-btn" ng-show="wrapCtrl.compareStreetDate(p.streetdate)"></div>
</div>
</li>
</ul>
<div ng-if="(filtered | filter :priceRange).length ==0" class="error-box">
<div class=" wrp"><span class="error-head">I hate when this happens</span></div>
<div class="wrp error-message">
<span class="f9 pad-top">It looks like I don't have exactly what you are looking for.</span>
<span class="f9 pad-bot">try adjusting your filters to see more</span>
</div>
</div>
I ran into a similar situation and found an ugly, though working solution by using the $timeout service. In your case you would have a scope variable, lets call it loadTimeGiven = false and after the $timeout you set it to true. Then simply do
ng-if="(filtered | filter :priceRange).length ==0 && loadTimeGiven"
Alternatively you could set loadTimeGiven based on a service that your modal has access to.
Related
I have an array of comments. For each of the comment, I have a hidden form where you can reply. That item in each object of the array is called: comment.showSubCommentForm. When I click on Reply, I want to be able to reply with a comment and the function called: commentOnSubPost.
I load my data in chunks of 10 (lazy loading) which I am doing by using the infinite-scroll-distance Angular module. Every time I reach the end of the page, I get the next 10 items and add them to the $scope.comments array, which you can see below is what I am running my ng-repeat on .
The problem is that, although the commentOnSubPost works really well as in it adds the reply to the comment, I have reload the data so I can get the updated $scope.comments with the new reply. BUT - as I have implemented lazy loading, how do I do that if say I am on the 20th page?
I looked at some similar posts but their approach from mine was very different so am very lost.
My HTML:
<div infinite-scroll='loadMore()' infinite-scroll-distance='1'>
<div class="row">
<div ng-repeat="comment in comments track by $index">
<ul class="comments">
<li class="clearfix">
<a ng-href="#">SomeLink</a>
<div>
<p >{{ comment.date }} <a ng-href="/wall#/profile/main/{{ comment.userID }}">{{ comment.fullname }}</a> says <i class="commentReply"><a href ng-click="comment.showSubCommentForm = !comment.showSubCommentForm"><small>Reply</small></a></i></p>
<p class="mainComment">
{{ comment.comment }}
<p class="meta"><i class="showReply"><a href ng-click="comment.showReplies = !comment.showReplies"><small>Show Replies</small></a></i></p>
</p>
</div>
<div ng-show="comment.showSubCommentForm">
<form ng-submit="commentOnSubPost( post._id, comment._id, subComment)">
<div class="form-group">
<div class="form-group">
<textarea ng-model="subComment" class="form-control" placeholder="Reply to the above comment"></textarea>
</div>
<input type="submit" value="Reply">
</div>
</form>
<div ng-show="comment.showReplies" ng-repeat="subComment in comment.subComments track by $index">
<ul class="comments">
<li class="clearfix">
<a ng-href="/wall#/profile/main/{{ comment.userID }}"><img ng-src="{{ subComment.profilePic }}" class="avatar" style="border-radius: 50%"></a>
<div class="post-subComments">
<p class="meta">{{ subComment.date }}<a ng-href="SomeLink"> {{ subComment.fullname }}</a></p>
<p>
{{ subComment.comment }}
</p>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
I won't add too much information here as I don't want to overload this post but if you need any particular information, please do let me know. I just need to know how do I reload the data (or not if there's another approach) so that I can get the latest data.
I hope this makes sense.
Thanks in advance!
Like you have $scope.comments = []; then on each call you just have to append upcoming data to this array.
Like $scope.comments = $scope.comments.concat(response.data);
In this way lazy loading will work.
I fixed this with making a Node route which gives back the exact comment I have just added. Then, I found that commentID in my $scope.comments and made it's subCommenemts to the one I have locally.
It does the job and the data is real. One drawback is that if at that time, there's another comment, it won't show up until the page's refreshed but I'm not too fussed about that.
I have included the code in http://codepen.io/sajoambattu/pen/MbezNa
I have 3 divs in which each div includes color selection, Memory and call plans. The call plans data is there after every device details(after the table).
All the data are depending on 3 JSONs. The color selection and Memory data is coming from devices JSON and call plans data is coming from callplans JSON. I have another JSON(planMapping) for mapping the device and call plan. All JSON's I have included in the JS file.
My requirement is based on the user selection of color and memory, respective call plans should display. Now the content is displaying, but the problem I'm facing is it's displaying the same content in all three sections(Apple, Samsung and Sony).
Issue Example:
Click iPhone 6s plus tab from the apple section and click on 32GB memory and then click any color, now iPhone 6s plus call plans will display. The problem is the same iPhone 6s plus call plans data is getting displayed in all other sections as well.
Any help would be appreciated.
I have updated your code....
http://codepen.io/anon/pen/dOpdXr
Changes :
HTML:
<div class="planDetails" ng-repeat="data in x.callPlanArr">
and also moved </div> of <div class="device_overview {{x.memory}}-{{x.presales_name.split(' ').join('-').replace('(','').replace(')','')}}" ng-repeat="x in v | orderBy:'memory'" ng-show="$first"> moved to end of the modified div.
JS:
item.callPlanArr = []; //at line 5770
and
item.callPlanArr.push($scope.callplanList.callplans[x]); //5784
Make following change to meet your requirement:
Shift div with class="callPlans" inside div with class="device_overview"
Here is the modification:-
<div class="device_overview {{x.memory}}-{{x.presales_name.split(' ').join('-').replace('(','').replace(')','')}}" ng-repeat="x in v | orderBy:'memory'" ng-show="$first">
<div class="device_detail">
<p>{{x.presales_vendor}}</p>
<h3>{{x.presales_name}}</h3>
<p>{{result}}</p>
</div>
<div class="color">
<div class="color-name">
<p>Choose color:</p>
<span ng-repeat="data in x.variants" class="{{data.s_code}}-{{x.presales_name.split(' ').join('-')}}" ng-show="$first">{{data.colour}}</span>
</div>
<div class="color-code" ng-repeat="data in x.variants" ng-click="changeImg(((data.s_code+' ')+(x.presales_name)).split(' ').join('-').replace('(','').replace(')',''));showPlan(x,data.s_code); showStock(data.s_code);" style="border-color:{{data.colour_code}};background-color:{{data.colour_code}}">{{data.colour_code}}</div>
</div>
<div class="callPlans" ng-if="device_class == x.device_class">
<div class="planDetails" ng-repeat="data in callPlanArr">
<div class="data">
<p>Data</p>
<h3>{{data.plan.data_allowance}}GB</h3>
</div>
<div class="minute">
<p>Minutes</p>
<h3>{{data.plan.call_allowance}}</h3>
</div>
<div class="text">
<p>Texts</p>
<h3>{{data.plan.text_allowance}}</h3>
</div>
<div class="upfront">
<ul>
<li ng-show="data.upfront != ''"><p>£{{data.upfront}}</p>up front</li>
<li><h2>£{{data.plan.rental}}/mth</h2></li>
</ul>
</div>
</div>
</div>
</div>
and add following line in $scope.showPlan function() of your controller
$scope.device_class = item.device_class;
I'm working on a project where the client has supplied a pile of html where I need to plugin the data from our database and have hit a problem that I'm finding difficult to solve....
So first problem is with routing
<div ng-repeat="class in vm.classes">
<div class="class-overview">
<a href="#">
<span class="class-title">{{class.description}}</span>
... more stuff here
</a>
</div>
<div class="class-information collapse">
<div class="full-width">
{{class.longDescription}}
</div>
</div>
</div>
he has supplied some javascript to handle the click on class-overview
$('.class-overview a').on('click',function(e) {
e.preventDefault();
});
$('.class-overview').on('click',function() {
$('.class-overview.active').removeClass('active').next('.class-information').collapse('hide');
$(this).addClass('active').next('.class-information').collapse('show');//.css('top',offset).collapse('show');
});
and i have a line like this in my state provider
// default route
$urlrouterProvider.otherwise("/")
So the problem is that the ui-router handles the click and sends me back to the home page.
The ideal solution is to leave as much of his markup intact, so can anyone tell me how I stop ui-router handling the click?
or failing that, how I might use ng-click and ng-show to get the same effect, i.e. hiding and showing the class-information div...
If I understand well your question, you want to display the .class-information div when you click on the .class-overview element.
That can be done by using a variable in a ng-show like this:
<div ng-repeat="class in vm.classes">
<div class="class-overview">
<a href="#" ng-click="display = !display">
<span class="class-title">{{class.description}}</span>
... more stuff here
</a>
</div>
<div class="class-information" ng-show="display">
<div class="full-width">
{{class.longDescription}}
</div>
</div>
</div>
The display variable will be falsy when you land on the page, therefore the ng-click will be executed, this variable will be set to true.
I see that you are using a collapse class to hide the content if it is collapsed. Then you could use angular ng-class to put the collapse class when the display variable is false. Your div.class-information would look like this:
<div class="class-information" ng-class="{collapse: !display}">
<div class="full-width">
{{class.longDescription}}
</div>
</div>
I am trying to use range slider in angularjs to filter the grid. I want a greater than and less than filter in my ng-repeat. But I am not getting how to do this. I am using the following code for now. But this is not working for me. This code is not giving me desired output
Here is my html for grid
<div class="col-md-3 product-left-grid" ng-repeat="data in Products| filter:priceSlider.max |filter:priceSlider.min">
<div class="product-grid"></div>
<div class="product-grid-text">
<a href="javascript:void(0)">
<img alt="" src="{{data.Picture1}}">
</a>
<div class="products-grid-info">
<div class="price">
<a class="btn btn-sm btn-width btn-default btn-font-weight"
href="javascript:void(0)"
ng-click="viewDetails($index)">Quick View</a>
<a href="javascript:void(0)"
class="btn btn-sm btn-width btn-default btn-font-weight"
ng-click="addToCart (data.ProductID,data.Picture1,data.ProductName,data.UnitPrice,data.Discount,data.ShippingCharges,data.wieght)">Add to cart</a>
<div class="tovar_description clearfix">
<a class="tovar_title" href="#"><b>{{data.ProductName}} </b> | {{data.UnitPrice | currency:mycurrency}}</a>
</div>
</div>
<div class="clearfix"> </div>
</div>
</div>
</div>
this is my price range slider
<rzslider rz-slider-floor="priceSlider.floor"
rz-slider-ceil="priceSlider.ceil"
rz-slider-model="priceSlider.min"
rz-slider-high="priceSlider.max"
rz-slider-on-change="onSliderChange()"></rzslider>
Now I am using filter but I have doubt that I am going wrong somewhere. Please experts help to solve this problem. Price range filter I need like every eCommerce website have.
Thanks
You have to make a custom filter :
//create an angular filter named "price"
app.filter('price', function () {
//our function will need three arguments
return function(items, greaterThan, lowerThan) {
//then we filter the array with dedicated ES5 method
items = items.filter(function(item){
//if item price is included between the two boundaries we return true
return item.price > greaterThan && item.price < lowerThan;
});
//then we return the filtered items array
return items;
};
});
You can see how Array.filter() works here
Our function will need 3 arguments to work, the items list which is passed by default and the lower and higher boundaries that we will pass as arguments in our ng-repeat filter.
Then you can use the filter as follow :
<div ng-repeat="data in Products | price:priceSlider.min:priceSlider.max | orderBy:'price'">...</div>
As I said above, items array is passed by default, then, to specify other parameters you have to separate them with a colon : right after the filter name.
You can read about custom filters in the official documentation here.
Finally you can then specified as many other filters as you want by separating them with a pipe |.
In our example I'm ordering them by price after the array has been filtered.
Here is a working JSFiddle.
PLUNKER
I have an app that allows users to see info about live music and favorite the shows they like. Pushing the star button does this. They can then see this information on their own music calendar page.
I'm able to save and update the favoriting data into my database just fine now. But I can't figure out how to style the star buttons (favoriting buttons) based on whether the user has favorited the item or not. They should change color/style if they are favorited or not.
There is data that comes from the music shows and data about the user (their personal info or favorites). These are separate bits of data. So when I bring the shows info in via ng-repeat, this is different than the info I have on whether the user has favorited that show.
The jist of the question, then, is how to style items/icons using ng-class within an ng-repeat when the info on whether those items have been favorited (true or false) comes from another object or array (can create either). Most of the examples with ng-repeat and ng-class are a alot simpler because the data on whether something is selected or not is within that same object.
HTML
<div class="list-group">
<div class="nav nav-stacked list-group-item" id="sidebar" ng-repeat=
"show in shows[0]">
<div>
<div class="col-md-3 text-center">
<h2>{{show.properties.price}}</h2>
<p id="tagtext">{{show.properties.tags}}</p>
</div>
<div class="col-md-6">
<h4 class="list-group-item-heading">{{show.properties.artist}}</h4>
<p class="list-group-item-text">{{show.properties.venue}}</p>
</div>
</div>
<div class="media col-md-3">
<h2 class="fa fa-star-o" ng-click="toggleStarred(show)" ng-class="I don't know">
</h2>
</div>
</div>
</div>
</body>
The pertinent part of the html is around <span class="pull-right star" ng-controller="StarredCtrl"> That's what creates the star icon.
Controller
I'll include the plunker so as not to have to jam this up.
The object where the user favorites are stored looks like this
$scope.loggedInUserFavorites = Object { $$conf: Object, $id: "favorites", $priority: null, show0: true, show1: false, show3: true, show5: false }
using Angular.foreach I pared it down to this:
Object { 0: false, 1: false, 3: true, 5: false }
How can I access those true/false properties of $scope.loggedInUserFavorites on my template to style the star icon?
PLUNKER
Actually this should work:
<h2 class="fa fa-star-o" ng-click="toggleStarred(show)" ng-class="{fillgreen:loggedInUserFavorites[show.properties.id]}">
As scopes prototypically inherit from their parents, you do actually have access to both the show model from the ng-repeat scope, and loggedInUserFavorites from the StarredCtrl scope.
Cheers!
Try this (where shows[$index].starred is your logic to check if the show has been favorited)
<div class="media col-md-3">
<h2 class="fa fa-star-o" ng-click="toggleStarred(show)" ng-class="{starred: shows[$index].starred, no-star: !shows[$index].starred}">
</h2>
</div>
I basically used both #sanghas26 and #HeberLZ's to come up with:
<h2 class="fa" ng-click="toggleStarred(show)" ng-class="{'fa-star': loggedInUserFavorites[show.properties.id], 'fa-star-o': !loggedInUserFavorites[show.properties.id]}"></h2>
So I changed the h2 to fa and then used the full and empty stars as the css classes. I really don't know why fillgreen and fillblue didn't work here. Will continue to investigate.
Anyway, it works. This took 6 weeks to figure out.