1

I want to have a dropdown button inside the card-title which upon clicking should display a dropdown of options like this:

image of card-reveal with list

I know this can be done by setting the overflow of the card as overflow: visible !important. But this leads to bad animation of card-reveal upon clicking. you can check the animation here: https://jsfiddle.net/506ubrxh/2/

I want the card-reveal's reveal animation to animate normally like this: https://jsfiddle.net/su23or05/

So i want to dynamically change the overflow property of the card upon clicking the list icon so that it changes to overflow: visible !important when the user clicks the list button and reverts back to overflow: hidden when the user closes the dropdown. I have written the jQuery to perform this action but the code doesn't seem to work. Below are my html, css and jquery codes.

html code:

<div class="card">
  <div class="card-image waves-effect waves-block waves-light">
    <img class="activator" src="http://materializecss.com/images/office.jpg">
  </div>
  <div class="card-content">
    <span class="card-title activator grey-text text-darken-4">Card Title</span>
    <i class="material-icons right dropdown-button" data-activates="dropdown1">list</i>
  </div>
  <div class="card-reveal">
    <span class="card-title grey-text text-darken-4">Card Title<i class="material-icons right listExpand">close</i></span>
    <p>Here is some more information about this product that is only revealed once clicked on.</p>
  </div>
  <ul id='dropdown1' class='dropdown-content'>
    <li><a href="#!">one</a></li>
    <li><a href="#!">two</a></li>
    <li class="divider"></li>
    <li><a href="#!">three</a></li>
  </ul>
</div>

css code:

.card {
  width: 60%;
  overflow: visible !important;
}

jQuery code:

$(document).ready(function(){
  $('.listExpand').click(function(){
    if($(this).hasClass('active'))
      $('.card').css("overflow", "visible !important");
  });
});

JSFiddle link: https://jsfiddle.net/506ubrxh/2/

It would be awesome if someone could help!

hulkinBrain
  • 746
  • 8
  • 28
  • What is the issue in the fiddle you provide? It looks exactly like the image you provide and seems to work well. The only slight issue I can see is that there's no key line between the `one` and `two` items. – Rory McCrossan Jun 09 '16 at 08:16
  • The issue is the animation of card-reveal, upon clicking the card to reveal its contents, the whole block which is sliding up is visible, which doesnt look nice. I want the normal animation of card-reveal. Check here: https://jsfiddle.net/su23or05/ – hulkinBrain Jun 09 '16 at 08:19

1 Answers1

3

While CSS frameworks like Twitter Bootstrap and Zurb Foundation provide APIs for their components, unfortunately the MaterializeCSS framework mostly suffers from lack of public APIs to set custom event handlers to the components, especially for the dropdowns.

Hence we have to set the handlers manually until they provide the APIs – Example Here:

.card--visible-overflow {
  overflow: visible !important;
}
$(document)
  // remove the visibility class from all cards
  // if the target of the click event is not a dropdown button
  .on('click', function(e) {
    if (! $(e.target).hasClass('dropdown-button')) {
      $('.card').removeClass('card--visible-overflow');
    }
  })

  // add the visibility class to the closest card
  // by clicking on each dropdown button inside the card
  .on('click', '.card .dropdown-button', function() {
    var $card = $(this).closest('.card'),
        openedClass = 'card--visible-overflow',
        dropDownIsOpened = $card.hasClass(openedClass);

    if (! dropDownIsOpened) {
      $card.addClass(openedClass); 
    }
  });
Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164
  • 2
    Awesome! Thanks, this worked like a charm, its a shame that such a beautiful framework doesn't have APIs for this. – hulkinBrain Jun 09 '16 at 12:10
  • One more thing @Hashem Qolami, if i have more than 1 card of the same type side by side using `display: inline-block` for the cards, whenever i click the list button, of that card, the card on which i'm focusing on or other cards (depending on the browser width) slide down a little bit, but if i don't have the cards side by side, the cards stay at their correct position. Why is that? Here is the link to view this issue: https://jsfiddle.net/2tdnztv2/ – hulkinBrain Jun 09 '16 at 14:58
  • 1
    @hulkinBrain Great question! __TL:DR:__ adding [`vertical-align: top`](http://stackoverflow.com/questions/17154707/using-display-inline-block-columns-move-down/17154832#17154832) to the `.card`s would [solve](https://jsfiddle.net/2tdnztv2/1/) the issue. __Long Answer:__ inline level elements including `inline-block`s are placed on their baseline which is aligned with the baseline of their parent by default. Setting an `overflow` with a value other than `visible` changes the baseline of an inline level element, in which case the baseline would be the bottom margin edge of the element... – Hashem Qolami Jun 09 '16 at 17:31
  • @hulkinBrain In this particular case where 3 inline level boxes--the cards--have `overflow: hidden` in the first place (before clicking on any dropdowns), their baseline is their bottom margin edge. After clicking on a dropdown where we set the parent card's `overflow` to `visible`, the baseline of the card re-sets to the default which is the baseline of the parent element. That is why the box is misaligned when the dropdown is opened. – Hashem Qolami Jun 09 '16 at 17:39
  • @hulkinBrain Also notice that there is a whitespace between inline level elements due to white-spaces, tabs or new lines between the HTML elements in the source code. Have a look at: http://stackoverflow.com/questions/5078239/how-to-remove-the-space-between-inline-block-elements – Hashem Qolami Jun 09 '16 at 17:44
  • Awesome explanation @Hashem Qolani ! I had monitored each of the card for any position changes, but none appeared in the console explicitly. Your explanation helped me understand the issue. I have one doubt though, on what basis is the baseline set? The height of the hidden dropdown?(i dont think so because the height of the hidden dropdown is greater than the space which gets created after clicking the dropdown button) I even tried increasing and decreasing the list items but the space which gets added(which causes misalignment) remains the same. – hulkinBrain Jun 09 '16 at 17:58
  • 1
    @hulkinBrain It is a bit challenging to explain that with words :) so I ended up with this picture: https://i.imgsafe.org/9b31a194ac.png (for `inline-block`s) Hope it makes sense. – Hashem Qolami Jun 09 '16 at 18:20
  • 1
    Qolani again, BRILLIANT explanation! I fully understood what's happening! (I know Thanking posts are not desirable but i have to write this). Thank you for all your help and all the time spent on my issue! That image made it perfectly clear! :D Thanks again! – hulkinBrain Jun 09 '16 at 18:31
  • @hulkinBrain My pleasure. I'm glad I could help. BTW, this is Hashem :) – Hashem Qolami Jun 09 '16 at 18:37
  • Yeah sorry, I made a typo, when i noticed i had spelled your name wrong, 5 minutes had already passed. @Hashem Qolami thanks! – hulkinBrain Jun 09 '16 at 18:38
  • @hulkinBrain Also please notice that the last line box of nested **in-flow** elements is considered as the baseline of an inline-block element. I.e. the absolutely positioned dropdown is NOT taken into account in case of line boxes. – Hashem Qolami Jun 09 '16 at 18:41
  • Yes, i noticed that earlier when i was studying the elements of the card in the console. @Hashem Qolami Thanks for pointing it out though! :D – hulkinBrain Jun 09 '16 at 18:42
  • UPDATE: fixed the [broken](http://stackoverflow.com/questions/37720358/change-overflow-of-materializecss-card-reveal-on-clicking-an-element-contained-w/37724966#comment62938137_37724966) image URL: http://i.stack.imgur.com/d3qsf.png – Hashem Qolami Jul 21 '16 at 17:55
  • Thanks @Hashem Qolami ! :D – hulkinBrain Jul 22 '16 at 18:31