How is this React element's height getting updated? - javascript

So I saw this JSfiddle that produces a div element with "textarea textarea--ghost" (non-ghost textarea) as a class. I see the following code snippet:
setFilledTextareaHeight() {
if (this.mounted) {
const element = this.ghost;
this.setState({
height: element.clientHeight,
});
}
}
But that seems to update only the height of the actual textarea box with class ".textarea". How does the height of the "ghost" element with class "textarea textarea--ghost" get updated? Is there something about the React lifecycle I'm not understanding?

No React magic here. As the jsfiddle mentions:
Uses a ghost div to measure height. So the ghost height is measured not set. The height is implicitly specified by the height of the content.
The procedure works by:
Leaving the height of the ghost textarea free
Setting the value of the ghost textarea to the value of the main textarea
Allow the browser to figure out how high to make the ghost textarea to fill the value by rendering it
Measure ghost textarea height in JS/React
Set height of main textarea
This complicated procedure is mainly needed for the height CSS transition as CSS transitions on height don't work for 100% old height to 100% new height, so explicit pixel units must be given for the transition to work.

It's happening like this...
The ghost div has a ref defined -
Line 67: ref={(c) => this.ghost = c}
The ghost div is updated with the value of the textarea during its render.
Line 70: {this.state.value}
This changes the ghost's height.
At the same time, during the onKeyUp event, the setFilledTextareaHeight method uses the reference this.ghost which is the DOM element of the ghost div to get the height of the ghost div and set's it as height in state.
Re-render and presto!
So in a nutshell, the ghost div changes per the value entered in the main text area and its height is then applied to the text area.

Related

React Grid Layout - Update Tinymce Editor height after first Init

I have a React Component that renders an instance of tinymce editor.The goal is to resize the editor's height dynamically after it has been initialized. I am using "React Grid Layout" package to resize the component.
2 Questions:
1. Where can I look up for the change in height of the editor's parent within the react component.In which lifecycle?
2. Where should Update the editor configuration for its height? Within the init method?
render(){
<div id="wrapper">
<textArea id="tinymceSelector"></textArea>
</div>
}
Part of my solution is to determine the parent's height like this:
let parentHeight = document.getElementById('wrapper').clientHeight
If there is any difference before and after resizing with React Grid Layout this parent Height will show the difference in size.
After I have found the height and determine the height change (but where? that is my question 1). I would update the tinymce configuration with:
editorinstance.theme.resizeTo (width, height);
Thank you!!
The implemented solution was:
On first render, I initialize the tinymce editor as follows:
I calculate the initial height at which the editor should be rendered based on #wrapper height.
I set the for the #wrapper's height in a variable called this._wrapperHeight.
Instead of setting the editor's height to the same height as the #wrapper, I adjust it to be only 70% of the total value. This prevents scrollbars. (I must say, I would like a different implementation to this because when I resize it to be too small the scrollbars are persistent)
this._editorHeight = this._wrapperHeight * 0.7;
During init, the I also had to include the plugin autoresize in the editor's configuration and also set the autoresize_min_height=this._editorHeight
After initialization has been accomplished, updating the height dynamically was achieved as follows:
In componentWillReceiveProps I calculate the #wrapper's height again.
Evaluate the old wrapper's height vs the new one
If they are different then: set the new height tinymce.get(this.props.renderId).theme.resizeTo(this._editorWidth, this._editorHeight);

JS, React - calculate height of dynamically created area with div blocks

I'm looking for a JS / React solution to count height or lines number of draggable div blocks (having different width). Height is needed to calculate the content height inside dashed border which is equal to (viewport - draggable_blocks_height).
As you can imagine, calculation should work dynamically during the window sizing / changing resolution and during dragging the blocks / removing or adding to the draggable_blocks_container.
Any ideas, concepts or similar examples?
Thank you
https://www.npmjs.com/package/react-height
Or go npm shopping for any number of variations.
I would assign a ref to a wrapper div. Then write a function that gets the height of the ref and run that func on window resize. Something like...
<dif ref={(div) => this.Wrapper = div}>
{/* blocks */}
</div>
function calcHeight() {
const rect = this.Wrapper.getBoundingClientRect();
return rect.height;
}
componentDidMount() {
window.addEventListener('resize', this.calcHeight());
}
A bit confused on what you want to do, but if you want to mirror the height in another div, set the calculated height to state and then use a style prop to control the height of the 2nd div.

How to obtain clientWidth & clientHeight before DIV is visible

I want to obtain the dimensions of a DIV element (used to display a popup menu at the cursor position) while it's style.display='none;', however the dimensions of the DIV always return 0. The only way I seem to be able to get the dimensions is to make the DIV style.display='block;' at 0,0 and then move it to the required position, but that looks jumpy.
I've tried making the DIV visible outside of the visible screen area but that doesn't work. Is there a way to get the clientWidth and clientHeight values whilst the DIV is hidden?
If your DIV is not visible, you won't be able to get its dimensions.
However, there is a workaround. Your div has to be "visible", but that doesn't mean it's opacity and position have to be 1 and relative.
Set the opacity to 0 and the position to "absolute" and you'll be able to get the DIV dimensions.
EDIT
Since I think more people will have a similar problem, I feel I should explain my answer a little more.
If you try to get the size of a hidden element with JavaScript, you will always get 0.
So there are techniques to get the real size without displaying the element to the user. My favourite is the one I already wrote about above. Here are the more detailed steps:
you set the elements opacity to 0. This way it won't be displayed to the end user while you are getting the dimensions.
you set the element position to "absolute". This way it won't take up any space.
now it's safe to set the display to "inline-block".
you read the elements dimensions. This time you'll get the real values.
You set the display back to "hidden" and set the opacity and position back to its original values.
And now you have the size of a hidden element.
If you'd like to know the size of an element onscreen without it being visible you need it to be painted to the screen but not shown.
In order to get clientHeight and clientWidth you need it to be rendered so the calculations can be performed based on the screens current state (unless you have pre-programmed width and height, which I'm guessing you don't)
you can find out more information at MDN here
So you have options:
create your div offscreen using positioning (fixed or absolute) combined with z-index or opacity
use width: 0 and height: 0 and overflow: hidden then use scrollHeight and scrollWidth to find the overflow size
choose which option is best for your site, considering things like responsiveness and screen reflows and repaints

JavaScript - Need a way to set OuterHeight of the Element

I have an container element which is sort of a layout container for its children and based on some attributes I have to arrange children.
I need simple way to set outerHeight of an element, something like,
$(e).setOuterHeight(200);
jQuery's outerHeight does not set the height at all, indeed its a readonly method.
$(e).height(200); // this clips my element
In above method, I loose borders of input of type text.
My element's children are docked based on available space and some other criteria based on data that it holds, simple layouts like float,clear etc will not work because padding etc change dynamically based on sizes. I will finally end up using Table, even if I dont want to but have no choice, but anyway thanks for the help.
Now when element is sized to more then children then there is no problem, but sometimes container element may have lesser height then the children and that time, I need to increase the size.
function calculateSize(e){
var s = {
width: $(e).innerWidth(),
height: 0
};
var ae = new Enumerator(e.children);
while(ae.next()){
var child = ae.current();
// I have tried all alternatives
// for following lines
// child.clientHeight || child.offsetHeight
// $(child).outerHeight()
// $(child).innerHeight()
s.height += $(child).outerHeight();
}
if(s.height > $(e).height()){
$(e).height(s.height);
}
}
function layoutChildren(e){
....
/// for every child c
/// some steps before
var heightForChildren =
calculatedWithPadMarginBorder(availableHeight,c);
/// tried combinations
$(c).height(heightForChildren);
/// last statement fails for button
/// as button's padding cuts itself
/// removing padding in calculation
/// cuts other input elements !!
/// some steps after
....
}
I need some explanation of how to calculate runtime height/width including/excluding padding/margin/border etc and how to set it correctly so that I dont run into problems. I cant keep on trying all permutations combinations as I dont see a correct documentation even on jQuery website.
Fixed height calculations are fine, but this is kind of a dynamic element which resizes itself and arranges children in specific order.
Problem is there is no way to set outerHeight, when we set height/width of an element, the height/width is actually inner height/width without taking margin into consideration, while when we want to resize parent, we need outerHeight, but we cannot set back the outerHeight that easily.
My calculateSize and layoutChildren are two separate methods and two separate algorithms because parent will be resized to sum of all children's height. And then height is simply divided by no. of children stacked one above other. My calculation is perfect, but in my layoutChildren method I have "outerHeight" and "outerWidth" of element and have no idea on how to set it correctly by using jQuery or any other way.
.outerHeight( value )
version added: 1.8.0
you can use jQuery.outerHeight(value) to set the value of an element's outer height. Ex: $foo.outerHeight( 200 )
If you don't have a special requirement, a standard element by default sizes its height to match its children. If you style the to float:left or float:right its default width will then also be that to contain all its children.
Ok, this is strange but this is the Answer.
There are weird controls,
SELECT
BUTTON (INPUT[type=submit|reset|button])
WebKit Browsers
Padding and Border are considered as part of OuterWidth for all controls
Padding and Border must be added to Width as OuterWidth for all controls
Padding and Border are considered as part of InnerWidth for "weird controls"
Padding and Border must be subtracted from Width before setting the Width for all "non weird controls"
Non WebKit Browsers
Padding and Border are considered as part of OuterWidth for all non "weird controls"
Padding and Border must be added to Width as OuterWidth for all non "weird controls"
Padding and Border are considered as part of InnerWidth for all non "weird controls"
Padding and Border must be subtracted from Width before setting the Width for all "non weird controls"
I would be happy to help, but I simply do not understand your question.
In regards to the documentation of the dimensions methods of jQuery I found that http://api.jquery.com/category/css/ holds documentation on both innerWidth(), innerHeight(), outerWidth() and outerHeight().
I hope this helps, otherwise, try reading through your question, making it more obvious what you need the answer for.

Temporarily adjust height of element on hovering

I have a <h3> tag with limited height (100 px for example, position: absolute) and the text overflows it.
What I would like to do is slide it down over to the height that is needed when the mouse is over it and back to original height (100px).
I hope you understood what I mean
I don't think it uses slidedown() function for that and I am very weak in animate function. Any help please?
You can nest a div inside the h3 that contains the content and then use the h3 as a masking container (use overflow:hidden). When the user mouses over, fire a function that get's the height of the interior div (make sure to include any margins or padding). Then execute you height adjust animate function (In jquery, something like $('h3').animate({height: heightVar}); )The mouseout fires a function that restores the height of the h3 back to 100px.
Here's a sample: http://jsfiddle.net/XR9fb/
You can get the real height of the element with the scrollHeight property. Now, I don't really know much of jQuery, but I imagine you could just call animate to set the height CSS property to the scrollHeight of the element when the mouse hovers it, and return to the original height when the mouse moves out of it.
If the height of the element isn't fixed, you can salve the current height somewhere before displaying the full element, and when the mouse leaves the element you just restores this state.

Categories

Resources