Inter-controller communication between date picker components - angularjs

I would like to link two date picker components in AngularJS. Basically, I use two input fields to select a date range. As soon as the user selects a start date, the date picker for the end date should be limited and only allow selections after the start date.
However, each date picker is defined by its own controller and I suppose, that they do not share their models due to different scopes.
This is a simplified example:
<div ng-controller="DatepickerDemoCtrl">
<div style="display: inline-block; min-height: 290px;">
<div uib-datepicker ng-model="contract.startDate"
ng-change="options2.minDate = contract.startDate"
datepicker-options="options1"></div>
</div>
</div>
<div ng-controller="DatepickerDemoCtrl">
<div style="display: inline-block; min-height: 290px;">
<div uib-datepicker ng-model="contract.endDate"
datepicker-options="options2"></div>
</div>
</div>
How can I set the options2.minDate property in the first controller, so that the second controller can read it properly? Is there any simple way to do that without introducing too much overhead?

Instantiate the controller only once:
<div ng-controller="DatepickerDemoCtrl">
<div style="display: inline-block; min-height: 290px;">
<div uib-datepicker ng-model="contract.startDate"
ng-change="options2.minDate = contract.startDate"
datepicker-options="options1">
</div>
</div>
̶<̶/̶d̶i̶v̶>̶
̶<̶d̶i̶v̶ ̶n̶g̶-̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶=̶"̶D̶a̶t̶e̶p̶i̶c̶k̶e̶r̶D̶e̶m̶o̶C̶t̶r̶l̶"̶>̶
<div style="display: inline-block; min-height: 290px;">
<div uib-datepicker ng-model="contract.endDate"
datepicker-options="options2">
</div>
</div>
</div>
Then the scope will be shared.

Related

React Big Calendar style dates which have events

I would like to change the style of dates in my month calendar view which have events.
This is the design I'm developing:
So I need to change style of .rbc-date-cell to blue for each date with an event. I have searched high and low for a solution to this, most commonly I find examples for creating a CustomDateCell for dateCellWrapper which will conditionally style cells, here's one example I've tried:
React Big Calendar how to style a single day in the month view
This changes the style of .rbc-day-bg not .rbc-date-cell. The markup on RBC is complex, because the devs made it for events which can stretch over multiple days. This means that the background divs are in a different parent to the datecells. I'd prefer not to traverse/manipulate the DOM to style these cells.
Surely there must be a way to style the datecells? the docs and all answers I've found on SO and github haven't yielded anything so far. Could it be done with eventPropGetter?
EDIT
The HTML is as follows. I've also tried custom slot props and eventPropgetter but have not been able to directly manipulate the rendering of .rbc-date-cell
<div class="rbc-month-row">
<div class="rbc-row-bg">
<div class="rbc-day-bg" style="background-color: lightgreen;"></div>
<div class="rbc-day-bg" style="background-color: lightgreen;"></div>
<div class="rbc-day-bg rbc-today" style="background-color: lightgreen;"></div>
<div class="rbc-day-bg" style="background-color: lightblue;"></div>
<div class="rbc-day-bg" style="background-color: lightblue;"></div>
<div class="rbc-day-bg" style="background-color: lightblue;"></div>
<div class="rbc-day-bg" style="background-color: lightblue;"></div>
</div>
<div class="rbc-row-content">
<div class="rbc-row">
<div class="rbc-date-cell">13</div>
<div class="rbc-date-cell">14</div>
<div class="rbc-date-cell rbc-now rbc-current">15</div>
<div class="rbc-date-cell">16</div>
<div class="rbc-date-cell">17</div>
<div class="rbc-date-cell">18</div>
<div class="rbc-date-cell">19</div>
</div>
</div>
</div>
rbc-event's exist in a different row to the rbc-date-cell, in this markup there are events on the 23rd and 24th. I don't want to traverse the DOM to conditionally style divs as this isn't a very React way of doing things, it should be done before rendering if possible
<div class="rbc-row-content">
<div class="rbc-row ">
<div class="rbc-date-cell">21</div>
<div class="rbc-date-cell">22</div>
<div class="rbc-date-cell">23</div>
<div class="rbc-date-cell">24</div>
<div class="rbc-date-cell">25</div>
<div class="rbc-date-cell">26</div>
<div class="rbc-date-cell">27</div>
</div>
<div class="rbc-row">
<div class="rbc-row-segment" style="flex-basis: 28.5714%; max-width: 28.5714%;"> </div>
<div class="rbc-row-segment" style="flex-basis: 14.2857%; max-width: 14.2857%;"><button class="rbc-event"><div class="rbc-event-content" title="2/2"><p class="event-wrapper">2/2</p></div></button></div>
<div class="rbc-row-segment" style="flex-basis: 14.2857%; max-width: 14.2857%;"><button class="rbc-event"><div class="rbc-event-content" title="1/1"><p class="event-wrapper">1/1</p></div></button></div>
</div>
</div>
checkout this sandbox code https://codesandbox.io/s/73ky8rj2qj
if that's what you want to achieve so the main idea is to override month dateHeader and then with every dateHeader to render check if its date prop is between any event startDate and endDate and render it with the desired style

How to use a variable in ng-if conditions?

I hope somebody can help me with this.
I'm building a messaging mobile application and i want to have my messaging style more interactive using this ng-if conditions but i'm having trouble using a variable outside my scope. "xyz" is my variable containing the email of the currentUser. Im using this xyz to make condition with the email inside my array. If the email of the message is equal to the currentUser which is the "xyz" variable the messages will be placed right and if not the messages will be placed left.
<div ng-repeat="m in messages">
<div ng-if="m.email === xyz" id="getCss" class="chat self">
<div class="user-photo"><img src="css/Image/image.png" style=" width: 60px; height: 60px;"></div>
<div class="chat-message">
<p class="mailcss">{{m.email}}</p>
<div class="messcss">{{m.message}}</div>
</div>
</div>
<div ng-if="m.email !== xyz" id="getCss" class="chat friend">
<div class="user-photo"><img src="css/Image/image.png" style=" width: 60px; height: 60px;"></div>
<div class="chat-message">
<p class="mailcss">{{m.email}}</p>
<div class="messcss">{{m.message}}</div>
</div>
</div>
</div>
If i use string like 'lenard#gmail.com' it works. I don't want to have it that way because it is only good for the user that owns the email how about the other users? Is there any way to solve this?
Thanks in advance. Happy coding!

angualrjs ng-repeat data-toggle issue

I have a below code :`
<DIV class="panel-group" ng-repeat="ent in EntitlementList | unique:'attributename'">
<DIV class="panel panel-default">
<div style="height: 40px; margin-left: 1%; margin-right: 2%; margin-top: 1%">
<a data-toggle="collapse" ng-click="getEntitlement(ent.attributename)"
data-target="#collapse{{$index}}"> {{ent.attributename}}</a>
</div>
<DIV id="collapse{{$index}}" class="panel-collapse collapse">
<div ng-repeat="ep in EndpointList"
<div style="height: 20px; margin-left: 2%; margin-top: 1%;">{{ep.endpointname}}</div>
</div>
</DIV>
</DIV>
</DIV>
` say I have 3 links,when i expand the each link after collapsing the previous one, It is working fine. But the problem i am facing is, if i expand the second link without collapsing the first one, the value of the second link is overriding the value of the first link.
Please help me to resolve this issue.
Java script file has the following function:
$scope.getEntitlement = function(selecteEntitlement)
{
var finalList=[];
$scope.EndpointList="";
$scope.entitlementInfo.forEach(function(entitlement)
{
if(entitlement.attributename == selecteEntitlement)
{
finalList.push({endpointname: entitlement.endpointname
});
}
});
$scope.EndpointList = finalList;
};
Your problem is using the same variable $scope.EndpointList for every expandable click. The solution is, you have create separate EndpointList for each ent (element from EntitlementList), then you could use
ng-repeat="ep in ent.EndpointList"

How to hide a div while scrolling in Ionic?

I am building an application using Ionic (version 1) and would like to hide a div from the controller when the user is scrolling. I am stuck and don't know where to start.
This is my code:
<body ng-app="starter" style="padding-top:150px;">
<div ng-controller="AppCtrl" id="header" >
<div class="bar-aaa">
<div class="myLogo">
<img src="img/images/logo.png" style="display: block;margin-left:auto;margin-right:auto;height:50px;margin-top:10px;margin-bottom:30px;" alt=""/>
</div>
<div class="row" style="padding-bottom: 0px;">
<div class="col col-33" style="border-bottom: 2px solid {{oneLine}};margin-bottom: 0;height: 59px;"><img src="{{one}}" style="display: block;margin-left:auto;margin-right:auto;" alt=""/></div>
<div class="col col-33" style="border-bottom: 2px solid {{twoLine}};margin-bottom: 0;height: 59px;"><img src="{{two}}" style="height:17px;display: block;margin-left:auto;margin-right:auto;" alt=""/></div>
<div class="col col-33" style="border-bottom: 2px solid {{threeLine}};margin-bottom: 0;height: 59px;"><img src="{{three}}" style="height:17px;display: block;margin-left:auto;margin-right:auto;" alt=""/></div>
</div>
</div>
</div>
<span ng-show="loading" style="position: absolute;z-index: 99999;margin-left:-75px;top:150px;left:50%;right:50%;background:rgba(0,0,0,0.5);text-align:center;padding:15px;width:150px;" >
<div>
<ion-spinner icon="spiral"></ion-spinner>
<h5 style="color:#fff;">Processing...</h5>
</div>
</span>
<ion-nav-view></ion-nav-view>
</body>
Your question does not explain which <div> you are trying to hide and what code you have tried to use already, but can you assign a function to the on-scroll directive of the ion-content and do whatever you want to do in that function. So like this:
<ion-content on-scroll="scrollFunction()">
And then in your controller add a function called scrollFunction or preferably something more descriptive.
$scope.getScrollPosition = function() {
// Here you can do whatever you want when someone is scrolling.
}
You could for example update a variable in this function and assigned that variable to the ng-show of the <div> you want to show or hide.
To answer your other question regarding why the getScrollPosition() function keeps returning 0. It is a known issue, you can find similar reports here. I am not entirely sure why this happens, but it seems like Ionic is grabbing the scroll position of a different view causing it to stay 0. You can solve this by assigning a delegate-handler to your <ion-content>, which basically gives you an unique identifier to work with. It would look something like this:
<ion-content delegate-handle="scrollHandler" on-scroll="getScrollPosition()">
And then in your controller, instead of doing the following:
$ionicScrollDelegate.getScrollPosition().top;
You need to do this:
$ionicScrollDelegate.$getByHandle("scrollHandler").getScrollPosition().top;
That should solve the issues you are experiencing.

ng-click first apply class, then execute function

I have a shopping cart (a rootScope array) which gets turned into a list of items in it, including a button to delete that item from the cart array (the red X).
I don't have enough reputation to add an image, so here's a link to what it looks like
What I want to have happen is when I click one of the red X buttons, the item first does an animation(some sort of fade out), and then the actual cart has the item spliced from it. Using ng-click I am able to either do one or the other, but not both. When both is applied the animation doesn't trigger because it doesn't have time to. Is there a way to wait for the animation to finish, then perform the function?
(the animation executed by applying a class to the div on ng-click, so possibly a watch for class change?)
Here's my code. The code won't work in the snippet but you can see my functions and html.
$scope.removeFromCart = function(removedGame) {
index = $rootScope.cartArray.indexOf(removedGame);
$rootScope.cartArray.splice(index, 1);
};
$(".disappear").hasClass('fadeOutRight')(function(){
$scope.removeFromCart(cartArray[0]) ;
});
.cartGameDiv {
height: 140px;
width: auto;
}
<div ng-repeat = "newGame in cartArray" ng-class="disappear">
<div>
<div class="col-sm-11 col-lg-11 col-md-11 cartGameDiv">
<div class="thumbnail">
<div class="pull-left">
<img style="height: 100px; width: 213px; padding: 5px; margin-top: 5px" src="{{newGame.thumbnail}}" alt="">
<div id="ratingDiv" style="margin-left: 8px; margin-right: 8px; margin-bottom: 5px;">
<div style="display: inline-block" ng-bind-html="getTrustedHtml(newGame)"></div>
<p class="pull-right" style="color: #d17581">{{newGame.numberReviews}} reviews</p>
</div>
</div>
<div class="caption">
<h4 style="margin-top: 0" class="pull-right">{{newGame.price}}</h4>
<h4 style="margin-top: 0"><a class="categoryGameName" href="#details/{{myGamesList.indexOf(newGame)}}">{{newGame.name | removeSubName}}</a>
</h4>
<p>{{newGame.description.substring(0,290) + '...'}}</p>
</div>
</div>
</div>
</div>
<div class="col-sm-1 col-lg-1 col-md-1 cartGameDiv">
<img style="margin-bottom: 10px; margin-top: 10px;" src="images/glyphIconCheckmark.png" alt=""/>
<img ng-click="disappear='animated fadeOutRight'; removeFromCart(newGame)" style="margin-bottom: 10px" src="images/glyphIconRemoveGame.png" alt=""/>
<img src="images/glyphIconLike.png" alt=""/>
</div>
</div>
If you have any idea how to delay the function call until after the animation I'd really appreciate it! Thanks!
This is very simple to do using ngAnimate. Add the ngAnimate script to your page (you can get this from numerous CDNs), include ngAnimate as a dependency to your module and then just add some simple CSS.
.ng-leave{
-webkit-animation: fadeOutRight 1s;
-moz-animation: fadeOutRight 1s;
-o-animation: fadeOutRight 1s;
animation: fadeOutRight 1s;
}
In your example, you need not do any work applying the class yourself, ngAnimate will do it for you.
Here is a Plunker demonstrating how you would do it.

Resources