Angular material design ripple on md-list > md-item - angularjs

I have a list of items (each of which includes multiple elements) where each item is clickable and switches view. Is there a way to get the ripple effect on the whole md-item-content? I tried class="ripple" but that was not sufficient.
<md-content>
<md-list layout="column" md-padding>
<md-item ng-repeat="resto in list.data.recommendations">
<a ui-sref="resto({qname: resto.qname})" class="ripple">
<md-item-content id="resto{{$index}}">
...

If you want to use ripple effect on specific elements you can use md-ink-ripple.
<div md-ink-ripple></div>

Just add a md-ink-ripple directive and .md-clickable class to the <md-list-item> element:
<md-list-item md-ink-ripple class="md-clickable">
<p>Foo</p>
</md-list-item>
Also you can set the font-weight to 500 if you wish (that is how a default clickable-item looks like).

The other answers cover most of the cases but you can also customize the color of the ripple effect by using
<md-list-item md-ink-ripple="#03A9F4">
<p></p>
</md-list-item>
This will give a light blue ripple color.
The team behind Angular Material wanted to keep this internal and reduce customization which is why they haven't documented it well. However, I thought it was a useful customization. Hope it helps! Cheers!

Actually, there's lack of documentation over this.
I was searching for a solution and found your ask here, so I went to check their source code.
You can use md-list > md-list-item with several restrictions. In your case, the idea is to get close to their docs menu, on sidenav (theirs is a directive called menu-link, on the link itself), and I've acomplished with some modifications in my original code (which were close to yours):
<md-list>
<md-list-item
ng-repeat="section in ::admin.sections"
ng-class="{
'active': $state.includes(section.active),
'disabled': section.disabled
}"
ng-click="!section.disabled && $state.go(section.state)">
<span ng-bind="::section.label"></span>
</md-list-item>
</md-list>
Basically, isn't all elements that are accepted as action-triggers inside md-list-item. md-checkbox and md-switch are the only childs that are accepted to do a process, inside preLink function on md-list-item directive.
The other way is to put a ng-click on the md-list-item itself, or in a child element, inside it.
The preLink process is a wrapper, using a "non-styled" button that do a "proxy" on the click, and visually acomplishes the ripple effect.
Other things, like attributes, too, aren't being transferred to this "proxy", so a disabled cannot be used directly, you need to simulate its results. In my case, I interrupt the ng-click action, and put a class into the element.

I would suggest using md-button if you want ripples instead of the anchor. Then just do your ui-router state change in the controller.
See https://github.com/angular/material-start/blob/master/app/index.html#L30 for an example.
<md-list layout="column" md-padding>
<md-item ng-repeat="resto in list.data.recommendations">
<md-button ng-click="vm.navigateToResto(resto)" ng-class="{'selected' : it === vm.selected }" id="resto{{$index}}">
...
</md-button>
</md-item>
</md-list>

Here is the best way to do it:
<div md-ink-ripple class="ripple">Div like an md-button</div>
add to your div md-ink-ripple directive
add ripple class to your div:
`
.ripple {
position: relative;
&:active > .wave {
animation: ripple 0.25s;
}
.wave{
position:absolute;
width:100%;
height:100%;
background-image: radial-gradient(circle, #000 10%, transparent 10.01%);
background-repeat: no-repeat;
background-position: 50%;
background-size: 0 0;
top:0;
left:0;
transform: scale(0);
opacity:0;
}
}
#keyframes ripple {
0% {transform: scaleX(0);}
50%{transform: scaleX(1);opacity:0.3;}
100%{transform: scaleX(1);opacity:0;background-size: 1000% 1000%;}
}
`

Related

ng-show/ng-hide and ng-switch elements showing at the same time

Within an Angular Formly (angularjs) form - I have two spans that I want to switch on a model property condition. Whilst the search text disappears to show the spinner, it subsequently shows both momentarily before the spinner disappears.
I initially tried ng-hide and ng-show:
<span ng-hide="model.validatingRegistration">Search</span>
<i class="fa fa-spinner fa-spin" ng-show="model.validatingRegistration"></i>
I tried changing the markup to use ng-switch but even that is showing both at the same time when it transitions back to the original state.
<span ng-switch="model.validatingRegistration">
<span class="animate-switch" ng-switch-when="false">Search</span>
<i class="animate-switch fa fa-spinner fa-spin" ng-switch-when="true"></i>
</span>
I tried using css to set a transition time of 0s but maybe I'm targetting it wrong in the css, or have used the wrong markup for this to work.
.animate-switch.ng-animate {
transition-duration: 0s;
}
I also tried targetting with
[ng-switch-when] {
transition-duration: 0s;
}
Update - ng-if is producing the same transition issue where both show momentarily.
Adding:
.ng-leave {
display:none !important;
}
to my css seems to have done the trick.

Using multi-select along with dropdown triangle displayed in ui-select

Is there any way to keep dropdown triangle (▼) displayed for multiple mode of ui-select?
<div ui-select multiple ng-model="selectedItems" class="form-control">
<div ui-select-match>
<span>{{$item.name}}</span>
</div>
<div ui-select-choices repeat="item in availableItems" >
<span>{{item.name}}</span>
</div>
</div>
I managed to steal the triangle from ordinary ui-select:
<i class="caret pull-right" ng-click="$select.toggle($event)"></i>
but having difficulties displaying it properly on the ordinary place to the right. Any tips? Thanks.
The solution I got so far: reused this caret class and made it displayed on top of the component using style position: relative; left: -1.5em;, placing the element right after ui-select (placing it straight inside ui-select is not possible because angularjs replaces it's content with own templates - so my caret comes after but then shifted left)
Also, I had to attach ng-click which does $select.toggle($event) to this caret element. As long as the $select is not available out of scope of ui-select, I had to introduce outer controller which includes both ui-select and caret elements - and simply assign $select a field within it using ng-init on ui-select.
So it looks something like:
<div ui-select multiple ng-model="selectedItems" class="form-control" ng-init="mySelect = $select">
<div ui-select-match>
<span>{{$item.name}}</span>
</div>
<div ui-select-choices repeat="item in availableItems" >
<span>{{item.name}}</span>
</div>
</div>
<span style="position: relative; left: -1.5em;" class="caret"
ng-click="mySelect.toggle($event)></span>
▼ is displayed only when dropdown is not opened. Also, clicking it requires some pixel-hunting (can be mitigated by putting the caret into a div that spreads vertical). So it's a partial solution.
The best approach I worked out is a scalable background SVG image applied using this CSS:
.select2-search-field {
width: 100%;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 13 6' fill='gray'><polygon points='0 1 8 1 4 5'></polygon></svg>");
background-repeat: no-repeat;
background-position-y: center;
background-position-x: right;
}

AngularMaterial: Custom md-tab-label in md-tabs

According to md-tab Documentation we can have custom md-tab-label, which I'm trying to do like this:
<md-tab-label class="my-label">
Label
</md-tab-label>
My css:
.my-label{
background: #40FF00;
}
However, the background color is not appearing for tab labels.
Am I doing something wrong ?
So, I was doing this the wrong way.
The correct way is:
Define your markup
Then add css
In this case, the css can be like:
all-tabs {font-size: 20px;}
.demo-tab {
color:green;
}
and in html:
<md-tab-label>
<all-tabs class="demo-tab"> {{$index+1}} </all-tabs>
</md-tab-label>
Resulting tabs:

Angular 1.2 - ngAnimate isn't applying .ng-move class

Angular's animate-repeat isn't applying the ng-move class when it seems like it should, so I'm confused and unable to create the animation I want.
I'm using ng-repeat with a custom filter to add and remove divs from a horizontal row:
<div id="presidents">
<div ng-repeat="president in presidents | showPresident:this" class="pres animate-repeat" id="{{ president.birth }}" >
<a href="{{ president.url }}" target="_blank">
<img src="{{ president.imageURL }}" alt="{{ president.name }}">
</a>
<p>{{ president.name }}</p>
</div>
</div>
I'm trying to create animations for when the divs are added and removed from the DOM. The Angular docs for ng-repeat state that there are three classes available for this type of animation: ng-enter, ng-leave, and ng-move. I've applied CSS animations to the enter and leave classes so that the divs fade in and out.
.ng-enter {
animation: zoomIn 1s;
}
.ng-leave {
animation: zoomOut 1s;
}
When a div fades in or out, though, the others have to slide into or out of its way and it seems like the ng-move class should be applied while that happens so that I can animate the process, but the class is never applied, so the divs just snap over instead of sliding the way I'd like. I verified that the class is never applied by giving it a red border:
.ng-move {
border: 4px solid red;
}
So, am I misunderstanding ng-move? Why is it not applied to the remaining divs when they re-position themselves?
How do I get these divs to slide over instead of snapping?
The solution I've ended up using is to animate the width and opacity of the elements myself instead of using animate.css. As they shrink in size, the others slide into place. Looks weird with text, but works fine with images. No need for the ng-move class.

How to fade in a text after page loaded?

I'm trying to get a div container with some text to fade in after the page loaded, but I fail. I was using the ng-animate directive like this:
<div class="motd" style="text-align: center;" ng-init="quote = getQuote();">
<div class="slide-fade" ng-class="animation">
<span class="quote"><i>{{quote.content}}</i></span><br><br>
<span class="author">{{quote.author}}</span>
</div>
</div>
Which obviously does not work, due to the fact that the animation does not get triggered by a click or something like that.
So how do I tell the browser that after the page loaded, it should fade in my text?
I hope you can help me!
Edit: At the date where I asked, I did not know that animations will also trigger when the page has loaded. I always thought there have to be some "user interaction" like a click or something to trigger them.
If you're using bootstrap, you can do this:
<html ng-app="myApp" ng-strict-di>
<head>...</head>
<body ng-init="ngLoaded = true" class="fade" ng-class="{ in: ngLoaded }">
<div>Content</div>
</body>
</html>
It may also work do to it this way as well:
<body
ng-app="myApp"
ng-strict-di
ng-init="ngLoaded = true"
class="fade"
ng-class="{ in: ngLoaded }">
<div> Content </div>
</body>
The fade class has 0 opacity and the in class applies the transition. ngLoaded will become true (in the $rootScope, I believe) as soon as angular has loaded due to ng-init="ngLoaded = true".
I use this so that the page doesn't blip with bits of angular brackets and such while the page loads.
I don't see the problem.
You just want to have animation when the element appears( you can think about it that way right? ).
Basicaly what I would do.
I would use then animate.css
http://daneden.github.io/animate.css/
and I would just add:
class="animated fadeIn"
Or plain css with this animation.
What I like to do is to use delay
.delayedx1{
animation-delay: 0.2s !important;
-webkit-animation-delay: 0.2s !important;
-moz-animation-delay: 0.2s !important;
-o-animation-delay: 0.2s !important;
-webkit-transition-delay:0.2s;
transition-delay:0.2s;
}
x2 x3 x4 or in ng repeat delay directly in "style" based on $index.
One way to do this is to use a flag (like $scope.fade = false;) to indicate that the page has loaded. Then, on your element, you'd use an ng-class with a conditional e.g.
class="animation" ng-class="{'fade-in': fade }"
The actual fade would be handled by CSS.
.animation { opacity:0; transition:all 200ms ease-in-out; }
.animation.fade-in { opacity:1; }
In your case, the fade-in condition could be as simple as ng-class="{'fade-in': quote }" since any truthy value you cause the class to get applied.
Here's a working plunker for you to play around with: http://plnkr.co/edit/ncqEB3PafIWbwv0UH1QG?p=preview

Resources