React select div height when DOM is loaded - css

I am having issues with react Plotly displaying correctly when a graph loaded in a hidden tab is selected. It seems this is a known issue where every tab but the default tab will not resize appropriately because it doesn't know the hidden graph's dimensions.
To get around this I would like to dynamically update the tab height to be equal to the height of the default tab. Something like this: Change div height when tab is selected.
The issue is, I am unable to select the tab height value on DOM load. I thought I could add a componentDidMount function with an evenlistener for window load like such:
constructor(props) {
super(props)
this.state = {
value: 0
};
this.handleLoad = this.handleLoad.bind(this);
}
componentDidMount() {
window.addEventListener('load', this.handleLoad);
}
handleLoad() {
console.log("firstTab height: " + $('#firstTab').offsetHeight)
}
This issue is, the console log is outputting firstTab height: undefined.
When i inspect the web page and put the command $('#firstTab').offsetHeight into the console I am able to come up with a height of 697 px.
I don't want to hardcode the tab pixel size. Can anyone guide me as to why I am failing to grab the element height on window load?

Try using clientHeight property.
componentDidMount() {
const height = document.getElementById('firstTab').clientHeight;
}

I think instead of using event listener, you can do something like this.
componentDidMount() {
const height = this.firstTab.clientHeight;
console.log(height) // => gives you height
}
render() {
return (
<div
id="firstTab"
ref={ (firsTabElement) => { this.divElement = firstTabElement } }
>
Tab Content
</div>
)
}
After the first render if you are not hiding or putting any condition to remove the firstTab from the DOM. It will be available to you in componentDidMount lifecycle.

Related

Set React Component to Horizonal scroll on mouse wheel

I have a react component that displays a list of images horizontally across the page.
I would like to be able to scroll horizontally through them without having to hold in the SHIFT button.
Is there a way I change the default for just this component using css or react?
Here is my code: https://codesandbox.io/s/team-grid-slicer-2db8d
You can create a ref and bind it to your div which you will scroll. Here is a working codesandbox
Basically you create a ref and assign it to the div
const scrollRef = useRef()
...
<div ref={scrollRef}>
And you listen to the changes on the wheel event within the div:
if(scrollRef.current){
scrollRef.addEventListener('wheel', /* your function */)
}
And you scroll to left, instead of down based on the wheel event's deltaY:
el.scrollTo({
left: el.scrollLeft + e.deltaY * 5,
behavior: "smooth"
});
PS: You can remove * 5 but it looks better imo
just add an id="container to your component and then add
onWheel={(e) => {
e.preventDefault()
var container = document.getElementById('container')
var containerScrollPosition = document.getElementById('container').scrollLeft
container.scrollTo({
top: 0,
left: containerScrollPosition + e.deltaY,
behaviour: 'smooth' //if you want smooth scrolling
})
}}
This will listen to the onWheel and scroll your component.

get height of div angular js

I'm trying to get the height of a div in angularjs, but it only returns the initial value and never updates:
vm.summaryHeight = $(".history-log-container").height();
console.log(vm.summaryHeight);//returns 0 and then never logs again.
How can I get the height of this div as it updates?
I tried this:
link: function ($scope, element, attrs) {
//console.log(element.height());
$scope.$watch(function(){
return element.height();
}, function(oldVal, newVal){
//returns the initial values then nothing else
console.log(arguments);
})
}
As others have said, the value will be taken once unless you specify otherwise. Try something like;
$(document).resize(function(){
// Your code here
});
If your window size changing affects the height of the target element then whenever the document is resized the value will be retaken. This might also work if you were to target the element rather than the document;
$('.history-log-container').resize(function(){
// Your code here
});
But you'd have to check that out- I just usually have all my window responsive sizings within the one document resizing function.

React Component that recursively loads other components

So, I have a media site built with wordpress that is using react js (something I would not suggest, as wordpress has its own way of doing things that doesn't always play nice with react). On this site I want to have a sidebar that dynamically loads elements of the sidebar (ads, recommended articles, social media buttons, etc), based on the height of the article that it is beside. These elements are react components themselves. So the way it all works, in my head that is, is the article component gets loaded onto the page first and when done, componentDidMount, it grabs the height of itself and sends it to the sidebar component. How that part happens is not important to my question, but its given to the sidebar component as a prop this.props.data.sidebarHeight). The sidebar then creates itself based on that height. It does so, or it should does so, recursively: if I have this much space left, well then I'll throw in an ad component, and then subtract the height of the ad component from my height and then check the new height all the way until I have not enough space left to add any more components (see . Bam dynamic sidebar. Here's my jsx code for the sidebar component:
var SidebarComponent = React.createClass({
recursivelyMakeSidebar: function(height, sidebar) {
// base case
if (height < 250 ) {
return sidebar;
}
if (height > 600) {
sidebar = sidebar + <AdvertisementSkyscraper />;
newHeight = height - 600;
} else if (height > 250) {
sidebar = sidebar + <AdvertisementBox />;
newHeight = height - 250;
}
return this.recursivelyMakeSidebar(newHeight, sidebar);
},
render: function() {
sidebarHeight = Math.round(this.props.data.sidebarHeight);
currentSidebar='';
sidebar = this.recursivelyMakeSidebar(sidebarHeight, currentSidebar);
return (
<div>
{sidebar}
</div>
)
}
}
);
// render component
React.render(
<SidebarComponent data={dataStore.sidebar} />,
document.getElementById('mn_sidebar_container')
);
It doesn't work. It returns [object Object] onto the DOM. Perhaps I don't understand react enough, but any thoughts on how to do this, if its actually possible, would be great.
The fundamental problem here is that you're concatenating components together as though they were strings of HTML, but they are actually functions. Pushing them into an array as functions will work. I also tweaked some of your compare operators to '>=' in the following example to make sure you don't get stuck in an endless loop.
var SidebarComponent = React.createClass({
recursivelyMakeSidebar: function(height, sidebar) {
if (height < 250 ) {
return sidebar;
}
if (height >= 600) {
sidebar.push(<p>600</p>)
height-=600
} else if (height >= 250) {
sidebar.push(<p>250</p>)
height-=250
}
return this.recursivelyMakeSidebar(height, sidebar);
},
render:function(){
var sidebarHeight = Math.round(this.props.data.height);
var currentSidebar = [];
var sidebar = this.recursivelyMakeSidebar(sidebarHeight, currentSidebar)
return <div>{sidebar}</div>
}
});
var sidebar = {height:900}
// render component
React.render(<SidebarComponent data={sidebar} />, document.body);

Set div style to avoid control displacement

I have three divs which i set float:left side by side.
In all these three divs, i have one textbox, one checkbox and one button. I have set checkbox set to visible = false initially. On click of button i am setting the checkbox visibility to true. by doing this div position gets adjust to left and causing layout problem. How can i set div style to avoid this layout displacement problem.I want there should not be any control displacement while show and hiding the checkbox I am newbie in css.
Here is my fiddle link Link
How about using the css property visibility? The visibility attribute allows the element to be hidden, but leaves the space where it would have been. For more information about it, read here.
DEMO: http://jsfiddle.net/Lppme028/22/
CSS
#txt
{
visibility: hidden;
}
JavaScript
$(document).ready(function () {
$("#btn").click(function (){
$("#txt").visibilityToggle();
})
});
jQuery.fn.visibilityToggle = function() {
return this.css('visibility', function(i, visibility) {
return (visibility == 'visible') ? 'hidden' : 'visible';
});
};

Infinity.js - Issues with rendering inline-block elements & a grandpa container with defined height

I've been trying to integrate infinity inside a defined scrolled area.
My UI is a bunch of inline-block thumbnails (not floated). Grid Layout.
Infinity works perfect inside my page when it occupy the whole page width & height, and each element is block level, with simple DOM inside.
But when create a little more advanced UI, with grid interface, and an infinity area to scroll inside a container (ListView's height isn't defined. It's container does), then all gets wrong.
Even more than that. If I give 100% to HTML & Body, infinity fails. it calculates wrong listView`s height.
How to solve this? Grid UI is a desired & common one.
JS Fiddle Demos:
All 1300 elements are block-level - #OK
ListItem (CSS) Width & Height defined - #OK
ListItem as inline-block - #Broken
Code Example (Infinity NG Integration)
var demoApp = angular.module("demo", []);
demoApp.controller("demoCtrl", function($scope) {
$scope.items = [];
for(var i = 0; i < 1300; i++) {
$scope.items.push({ title: "Item " + i });
}
});
demoApp.directive("infinityScroll", function() {
'use strict';
return {
restrict: "A",
transclude: true,
link: function(scope, elm, $attrs) {
scope.listView = new infinity.ListView($(elm));
}
};
});
demoApp.directive("infinityItem", function() {
'use strict';
return {
restrict: "A",
link: function(scope, element, attrs) {
scope.listView.append(element);
}
}
});
PostScript: I noticed in the API Reference, that ListItem has width & Height properties. Same as ListView.
I couldn't find how to implement it, Inside the build code itself, i haven't seen how to pass this properties to the object.
Sorry if its obvious thing, and its possible to do that.
Will appreciate any help.
Thanks.
Actually right now I discovered my problem.
2 elements that messed up with my UI where actually - Overflow:Hidden for my Body,HTML, and Height:100% for a page container.
I have removed Overflow:Hidden, and Height from the page container (not ListView!) and all is fine.
'useElementScroll:true' and .scrollable classname did not assisted me, and prevented me from needing do this actions.
Now my UI is impacted, and I need to see how I`ll solve it.
Edit:
I have opened an issue at airbnb git, and I hope they will pay attention to this. Not been able to set a father and relate only to him, is an issue that adds complexity.
https://github.com/airbnb/infinity/issues/46

Resources