Topic: Card Animation on Angular 2

compras1 pro asked 6 years ago


Guys, I having problem to make the animation work when I pass the static HTML of "Rotating Card" sample from the 'index.html' to the 'angular component html template'. I think the problem is in the 'event binding', the angular renders the div after the page load and the event isn't binding. When we put the same code in the index html the button works fine. Is there any trick or hint to force the "binding" after the angular put the elements in the page? Thanks!!

prusikt pro answered 6 years ago


Your <div [ngClass] = “rotatingCardClasses”> should looks like: in HTML: <div [ngClass]="{rotatingCardStyle: isClick, rotatingCardStyle: !isClick}" (click)="rotateCard(isClick)"> in Dart: isClick = false; rotateCard(bool value){ isClick= !value; } Styles to do flip you can take from inspect element and just copy correct styles if you need more help: prusikt@gmail.com Tomasz

Ali Obaji free answered 6 years ago


Hello guys, I was having a similar problem today. I followed the code and it boiled down to just having to add a class to an element. So I used the ngClass directive. html <div [ngClass] = "rotatingCardClasses"> //this is the div that should flip. <button class="btn btn-simple" (click) = "rotateCard()"> component private rotatingCardClasses: any; constructor(){ this.rotatingCardClasses = {'card-container': true,'manual-flip': true, 'hover':false}; } //'hover' is the class that i need to add or remove. //this is the function which changed the class name. rotateCard(){ if(this.rotatingCardClasses.hover == false){ this.rotatingCardClasses.hover = true; } else{ this.rotatingCardClasses.hover = false; } }

Michal Szymanski staff answered 6 years ago


Hi Pruskit, thank you very much for that information, it will be for sure useful for us :)

prusikt pro answered 6 years ago


Hi Guys, I had a lot of bindings problem in the last year using Angular 1, now Angular 2 and javascript... I dont know what else are you using but I found solution for all of jquery problems and I am using it currently on MDB4. I develop apps using Angular 2 and google Dart as an example: class Component implements AfterViewChecked then call the javascript method in the implmentation of that method function bindSelect(){ $('.mdb-select').material_select(); } it works with all javascript components and MDB4 if you guys have more problems I am happy to help prusikt@gmail.com

Michal Szymanski staff answered 6 years ago


Thank you Dave also for your contribution.

Dave Fisher pro answered 6 years ago


Just sharing what we did as a reference... We went the other route and just used mbd.min.js JavaScript from Angular 2. With AngularJS that was highly frowned upon. See posts like this: http://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background?rq=1 But with Angualar 2 it seems like you can sneak in some mdb.min.js calls. Just makes life easier. For example we needed to initialize our .sideNav() component. We use the angular-cli and went to the trouble to do that one correctly by doing the appropriate typings install commands from the DefinedTypes (https://github.com/DefinitelyTyped/DefinitelyTyped) for jQuery and bootstrap, typings install jquery --ambient typings install bootstrap --ambient then wrote our own mdb.d.ts for a few mdb specific things and made a reference to it from typings.d.ts like this: /// <reference path="../typings/browser.d.ts" /> /// <reference path="mdb4.d.ts" /> declare var module: { id: string }; That lets use use mdb.js calls just fine in our Angular 2 code. We discovered that was overkill though. Any time you want, you can just include normal JavaScript in your index file in the normal way, then call the JavaScript code in the normal way (within the ngAfterViewInit). And if the angular-cli broccoli compiler won't let you compile, just do a declare var jQuery: any; (or equivalent). For example here we use the mdb.js .sideNav() call just fine because it was setup correctly, but we do the call to Waves in the lazy simple way. import { Component, AfterViewInit } from '@angular/core'; declare var Waves: any; @Component({ moduleId: module.id, selector: 'sidenav-content', templateUrl: 'sidenav-content.component.html', styleUrls: ['sidenav-content.component.css'] }) export class SidenavContentComponent implements AfterViewInit { ngAfterViewInit() { jQuery(".button-collapse").sideNav(); Waves.attach('#slide-out li', ['waves-light']); Waves.init(); } } Yes, I'm aware there are MANY times where DOM manipulations from jQuery are bad when using Angular 2, but we seemed to get away with this one just fine.

Michal Szymanski staff answered 6 years ago


Thank you Compras1 for your contribution. We'll prepare soon "Best Practices" for Angular and publish it in our documentation.

compras1 pro answered 6 years ago


Guys, Just documenting what we did at the end: we remove the binding from jquery to put it into the angular component. (we didn't remove, the page just not using this bind) The binding that was used by jquery at load is:
in the html: 
<div id="someId" class="card-rotating effect__click"> <!-- div to implement the rotation
<a><i class="fa fa-chevron-right"></i></a> <-- button to rotate the div

jquery: 
$('.rotate-btn').on('click', function () {
    var cardId = $(this).attr('data-card');
    $('#' + cardId).toggleClass('flipped');
});
We translate these things to Angular as:
in the html (component.template):
<div id="{{practice.id}}" [class]="getStyleClass()"> <!-- ID isn't important anymore because we resolve this by component TS
                                                     <!-- getStyleClass() decide what face to show

<a class="btn-floating..." (click)="onRotationButtonClick()"> <!-- we bind an Angular Event in the button (the css class 
                                                              <!-- isn't important anymore)

in the Angular "rotation div component" (TS):
  onRotationButtonClick(){
    this.flipped = !this.flipped; <!-- component property controls what side to show
  }

  getStyleClass(){
    if (!this.flipped) {
      return "card-rotating effect__click";
    } else {
      return "card-rotating effect__click flipped";
    };
  }
Its working in this way! Another alternative solution would call a JQuery binding inside TS document, it's a little tricky but it's possible. At the end, I think using angular binding instead was 'the most correct' solution.

Dave Fisher pro answered 6 years ago


Hey compras1, so we're just getting started using MDB4 with Angular 2 in our project. We will run into all the same issues you are having but it sounds like you might be farther along than us. Do you know how to call JavaScript functions from the mdb.min.js file in your Angular 2 TypeScript components? We haven't even gotten that far. Thanks for any advice you used in your setup for MDB4 + Angular 2! - Dave

Michal Szymanski staff answered 6 years ago


There isn't such a function for Rotating Card, however it's very simple script just for toggling a single CSS class. Maybe you can wrap it into a function and call it later? Take a look at Rotating Card script:
$('.rotate-btn').on('click', function () {
    var cardId = $(this).attr('data-card');
    $('#' + cardId).toggleClass('flipped');

});

compras1 pro answered 6 years ago


To advance the discussion, the problem with Angular2 is exact that: when the page loads the "mdb.min.js" adds the animations and effects listeners to page elements, but with angular the elements are added after this. There is a function in the mdb.min.js that I can manually call to 'rebind' the events? If this function exists I would call it in the ngAfterViewInit() of the Angular component.

Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Specification of the issue

  • User: Pro
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: -
  • Device: -
  • Browser: -
  • OS: -
  • Provided sample code: No
  • Provided link: No