Angular set variable after View Init - css

Situation:
Currently I have two tabs on my site, both containing a text. The text has a fixed height and the content-overflow is not shown (overflow: hidden).
Problem:
I would like to add three dots (icon) if my text is overflowing. To detect if overflowing occurs I use the following expression, that works perfectly and adds an expandButton if overflowing occurs.
isOverflown: boolean;
hasExpandButton: boolean;
[...]
const overflown = this.isOverflown() ? this.hasExpandButton = true : this.hasExpandButton = false;
The problem is, that I don't know where I should check if my content is overflowing, because I use this statement in two differnet locations (here: tabs).
If I choose ngAfterViewInit, const overflown is getting set to true if my content is overflowing on the first tab. BUT not on the second tab (if the content is there also overflowing). The reason for that is, that the view only gets rendered on the first tab and not on the second tab. Therefore if I switch to the second tab the ngAfterViewInit will not trigger.
I also tried to use other lifecycle-hooks, but none of them worked for me.
I thought maybe about ngAfterContentInit and use a variable to detect if ngAfterContentInit is called for the first time, but this did not work for me either.
Thank you in advance.
SOLUTION
I disabled lazy loading for this component and that solved the issue.

You can check it after the view inits (ngAfterViewInit) AND when user switches tab - add (click)="checkOverflow()" to the tab tag in html.

Try solving this using CSS:
.txt-overflow {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
so you can get rid of extra component logic

Related

Disable Scroll When Dragging in MUI Grid

I'm currently writing an app where I have many columns in a MUI Grid, scrolling horizontally. It's a task planner app, and when I create a task, I want to be able to drag it between the different columns that are visible on the screen. I'm using hello-pangea/dnd to control the drag and drop functionality of the tasks, and as mentioned earlier, Material UI for the Grid that stores the columns.
However, I don't like the fact that it scrolls while I'm dragging - the Grid automatically scrolls while I'm dragging tasks. I want to disable this.
I already tried dynamically setting the overflow CSS style of the Grid depending on whether or not I'm dragging - if dragging, set overflow-x to hidden, otherwise, keep it as scroll. I expected this to disable the ability to scroll in the Grid, because if I initialize the Grid to have overflow-x: hidden, then scrolling is disabled. But, as you can see below, this does not help. Even though the style changes from overflow: scroll to overflow: hidden, the Grid still scrolls while dragging:
(yes the UI needs work, I'll get to it eventually)
I tested this on both Google Chrome as well as Safari. I also tried using a state variable and setting the sx of the Grid component as follows. This didn't work either. My code looks something like the following:
const View = (props) => {
const [currentOverflow, setCurrentOverflow] = useState("scroll");
// ...definition of taskView, etc...
// props.dragging is a boolean passed down from the parent element
// that is true when an item is being dragged, otherwise false
useEffect(() => {
setCurrentOverflow((props.dragging) ? "hidden" : "scroll");
}, [props.dragging])
return (
<Grid
id={taskViewGridId}
className="taskview"
sx={{
overflow: currentOverflow
}}
>
{taskView}
</Grid>
)
}
The way I was trying to set the overflow parameter using CSS as I showed in that GIF before this code snippet was similar to the above, except the callback in the useEffect looked like this:
var gridElt = document.getElementById(taskViewGridId);
if (props.dragging) {
gridElt.classList.remove("enable-scroll");
gridElt.classList.add("disable-scroll");
} else {
gridElt.classList.remove("disable-scroll");
gridElt.classList.add("enable-scroll");
}
where the associated CSS classes were just
.disable-scroll {
overflow-x: hidden;
}
.enable-scroll {
overflow-x: scroll;
}
Can someone please help me figure this out? How do I disable scrolling in the MUI Grid depending on whether or not something is being dragged?
Thank you.
Fixed this. The #hello-pangea/dnd library automatically scrolls the window while dragging. An option to disable this has now been added to the library in their latest release.

Dynamic height for material ui tab containers

I'm having a problem which at first I thought it was the general configuration of my app and the height I was giving to my page wrapping classes. But I made a simple out of the box material ui tab example and it seems this is natural to material ui Tabs Component.
Material UI tabs component gives their tab container the same height, being that height the largest of all its containers. So if you have one tab content with lots of content in it, it makes the other tab contents just as large, even though they may only have one text field and a button in them.
How can I make it that the height of the container adjusts to the content of its own tab?
Here is a visual
Here is why TAB ONE is so large, TAB TWO is setting the height
Here is a webpackBin for you to see the code working and mess with it.
One hack I've done so far is setting a definite height and overflow, but I don't want to do that because it creates a double scroll bar (one in the tab container, one in the body) besides, it's buggy looking.
I would like it if the tab container (the one with the green border) adjusts to the content as it does in TAB TWO, BUT individually.
Thanks in advance!
If you set the height based on the given element's current visibility you will be able to resolve this issue.
Example
.react-swipeable-view-container > div[aria-hidden="false"] {
height: 100%;
}
.react-swipeable-view-container > div[aria-hidden="true"] {
height: 0;
}
Note: this solution could be improved by using a better selector, something more descriptive like a class name. I suppose it's subjective though, using an attribute selector is not technically wrong and actually more specific than just a class.
Demonstration: https://www.webpackbin.com/bins/-Ky0z8h7PsdTYOddK3LG
animateHeight will animate height on tab change. if all tabs have different height it will show height accordingly.
Example:
<SwipeableViews
animateHeight // it will animate height on tab change
>
<div>{'slide 1'}</div>
<div>{'slide 2'}</div>
<div>{'slide 3'}</div>
</SwipeableViews>
Happy Coding ...!
There's a merge request that have been accepted here on the lib that could be interesting with a new method called updateHeight https://github.com/oliviertassinari/react-swipeable-views/pull/359
<SwipeableViews
action={actions => {
this.swipeableActions = actions;
}}
animateHeight
>
<div>{'slide n°1'}</div>
<div>{'slide n°2'}</div>
<div>{'slide n°3'}</div>
</SwipeableViews>
Then:
componentDidUpdate() {
this.swipeableActions.updateHeight();
}

Materialize Css : select in card

I am trying to use select in a card.
Problem is that when the select list is open and it should overflow outside of card, it doesn't.
The overflowing part is hidden/blocked/gone.
I've tried following and failed:
overflow:visible
increasing z-index
changing position to relative (this would dynamically increase the card to fit the select - not desired outcome)
on a side question, is it not a proper material design to use select (or other inputs) in a card?
This is because the .card class has the style overflow: hidden on it. If you remove this from your card, it will allow the content of the select to flow outside of its boundaries.
Adding overflow: visible to .card works. Here's a codepen. Just make sure you are correctly overriding the .card class styles.
You have to initialize the select manually
something like :
$(document).ready(function(){
$('select').formSelect();
});
Or
M.AutoInit();
If you dont want to initialize manually on pages all just add above one line in your script tag.
follow their documentation https://materializecss.com/select.html navigate to the initialization section
https://materializecss.com/auto-init.html

the new facebook like, that open the comment box...+ overlow:hidden

a quick introduction :
facebook has changed the LIKE (count) button
into something like :
LIKE (count)
[ -------------------- clic = open a Big zone bottom / right --------------------]
problem :
Its nice BUT ....
you forgot that a lot of website are using the like button in "toolbars". Page example
Header
Left column Tooblbar, include fb:like -------------------- Right column
Document content
Footer
and lot of structured pages/ blocs are using "overflow:hidden" !! So it makes the displayed widget randomly truncated everywhere (right, bottom...) depending of its environnement.
Its impossible to remove all the overflow:hidden from the containers blocks, to satisfy a widget update.
What can we do. Some sites where clean, now they look drafts, with all button opening truncated stuff...
any solution ?
If you want to use the Facebook plugin, the only solution seems to be to change the HTML/CSS so overflow:hidden can be removed. Alternatively, you could try to use a service that forwards the user actions to social networks for you and offers different methods of website integration.
If you're not using overflow: hidden for semantic reasons, you could always change it to overflow: visible or just remove it. I'm assuming that the fix isn't that simple...
A quickfix that wouldn't require you to modify your CSS would be to place your FB Like button outside of any containing elements that have overflow: hidden or overflow: auto and use absolute positioning to get it where you want it.

resize a div after setting innerHTML with mootools

I am using mootools 1.2 in a simple page. There's a div that displays a form (call it formdiv) that gets submitted via JS/ajax. The ajax request returns some data "confirmation message".
However, the formdiv div starts out maybe 500px high to accomodate the form elements. When the ajax request returns a variable-length return data ("confirmed for submission!") the div stays 500px high, leaving a lot of extra space.
My question is, is there a way to snap the div back to fit the new content after updating the content using innerHTML?
Thanks
EDITED: to add that the data returned by the Ajax call could be variable length-- so I can't assume it'll be a certain height and then reset the div to that height.
If your div starts off with predefined height using CSS then all you should do is set its height to auto or clearing styles altogether when they were set inline.
Check this JSFiddle (it works with jQuery here, but that doesn't matter when it comes to browser rendering div in question)
Okay I realize that this is like a year late but I came across this question while attempting to find a script to do just this. This was a great starting point but I felt like I should share the method I choose to use:
Get the current actual height of $('element').
h.before = $('element').getSize().y;
Fx.Morph can't handle setting the height to 'auto' so first you must set height: 'auto' on $('element') (in case it hasn't been already) and then set the html to the new content. This will allow you to get the new content's height.
$('element').setStyle('height', 'auto');
$('element').set('html', "Some other content.<br/>Very short.");
h.after = $('element').getSize().y;
Reset the height and then start the Fx.Morph with h.after.
$('element').setStyle('height', h.before);
var myEffect = new Fx.Morph('element', {
onComplete: function() {
$('test').setStyle('height', 'auto');
}
});
myEffect.start({'height': h.after});
You can check out the full code here: http://jsfiddle.net/cd4R9/
Please understand this is method is very basic and a lot would have to be done to make this site-ready. For example if your $('element') has padding, you will have to account for it or use the CSS property box-sizing: border-box;. Hope this helps.

Resources