Incorporate adjustable div heights for dynamically toggling classes on various DOM elements

One of the challenges in developing a chat widget is creating an editable div for users to input text. In order to maintain the design integrity, the box needs to be fixed to the bottom.

An essential requirement is to have javascript detect resizing as users type and apply classes to elements accordingly. While I achieved upward resizing successfully, scaling it back down has been proven quite difficult.

This issue has consumed my time for days now, making any assistance truly valuable at this point.

For those interested, the function and a basic UI version can be found here on JSFiddle: JSFiddle

Despite its apparent simplicity, solving this problem has eluded me thus far.

JSFiddle

var chatBoxSize = {
    oldHeight : 0,
    scrollHeight : 0,
    lastClass : 1,
    minClass : 1,
    maxClass : 5,
    min_height : 0,
    last_size : 0,
    getClass : function (size){
        var sizes = [chatBoxSize.min_height, chatBoxSize.min_height * 2, chatBoxSize.min_height * 3, chatBoxSize.min_height * 4, chatBoxSize.min_height * 5];
        switch (size){ case sizes[0] : return 1; break; case sizes[1] : return 2; break; case sizes[2] : return 3; break; case sizes[3] : return 4; break; case sizes[4] : return 5; break; };
        //is not exact
        var r = null;
        console.log(size);
        for(var x = 0; x < sizes.length; x++){
            if(x < sizes.length){
                if(size >= sizes[x] && size < sizes[(x + 1)]){
                    return (x + 1);
                }
            }
        }
        return chatBoxSize.maxClass;
    }
};
$(function () {
    chatBoxSize.min_height = parseInt($('#msgWriteArea').height());
    chatBoxSize.max_height = chatBoxSize.min_height * 4;
    chatBoxSize.last_size = chatBoxSize.min_height;
});
function updateChatSize() {
    var id = '#msgWriteArea';
    var element = document.querySelector(id);
    var size = $(id)[0].scrollHeight;
    var container = $('.container');
    var toRemove = 'size_' + chatBoxSize.lastClass;
    console.log(chatBoxSize.getClass(size));
        chatBoxSize.lastClass = chatBoxSize.getClass(size);
        console.log('Add new class', chatBoxSize.lastClass);
        chatBoxSize.last_size = size;
        $(id).removeClass(toRemove);
        $(id).addClass('size_' + chatBoxSize.lastClass);
        container.removeClass(toRemove);
        container.addClass('size_' + chatBoxSize.lastClass);
        $('#display').val('Removed ' + toRemove + ' Added ' + chatBoxSize.lastClass);
};
$(function (){
    $('#msgWriteArea').bind('change keydown input', function () {
        if(event.type == 'keydown'){
            updateChatSize();
        }
    });
})

I considered setting the heights to auto, but that would not align with the other ui elements.

Answer №1

Unfortunately, there is No need for JavaScript whatsoever
flex comes to the rescue, along with overflow-y: auto; and max-height for the editable DIV:

Check out this jsBin demo where you can experiment and resize the browser

*{box-sizing:border-box; -webkit-box-sizing:border-box;}
html, body{height:100%; margin:0;font:16px/1 sans-serif; color:#444;}


#chat{
  display: flex;
  flex-direction: column;
  height:100%;
}
#messages{
  flex:1;
  overflow-y: auto;
}
#messages > div{
  padding: 24px;
  background: #eef;
  margin: 4px 0;
}
#ui{
  background: #eee;
}
#msgWriteArea{
  padding: 24px;
  overflow-y: auto;
  height:100%;
  background:#ddd;
  max-height:100px;    /* if max height is exceeded */
  overflow-y: auto;    /* add scrollbars */
}
<div id="chat">
  <div id="messages">
    <div>Message 1</div>
    <div>Message 2</div>
    <div>Message 3</div>
    <div>Message 4</div>
    <div>Message 5</div>
    <div>Message 6</div>      
  </div>
  <div id="ui">
    <div id="msgWriteArea" contenteditable>Some text message</div>
  </div>
</div>

If you still find a compelling reason to determine the height of the message area (for any specific purposes), you could utilize JavaScript to count the number of lines.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a more concise method for accepting a collection of interfaces in TypeScript?

Issue I am facing a simplified version of a problem with my model: Here is how my model currently looks: interface Instrument { name: string; // ...more properties shared by all instruments... } interface Guitar extends Instrument { type: &q ...

Expanding list - Using individual toggles to expand and collapse multiple list items

I stumbled upon an interesting jquery script that allows for a collapsible sub menu within a list. After implementing this code: $('.menu-item-has-children').prepend('<a id="fa-menu" href="#"><i class="fa fa-plus"></i>< ...

Does CSS positioning change depending on the screen size?

I need help fixing the positioning of my logo on the screen. I want it to be 40px from the top and centered horizontally regardless of the screen size. Here is the code that I have: <html> <head> <style type="text/css> body{ back ...

Filter array to only include the most recent items with unique names (javascript)

I'm trying to retrieve the most recent result for each unique name using javascript. Is there a straightforward way to accomplish this in javascript? This question was inspired by a similar SQL post found here: Get Latest Rates For Each Distinct Rate ...

Assign a variable the source of the web subsurface A-frame setting

I want to utilize the websurface A-frame component () to change the URL of the websurface when a button is clicked. I have defined a variable called source and I want the websurface URL to be updated to the value of this variable upon clicking the button. ...

FAQs about utilizing percentage width and margins in CSS with Bootstrap

Currently, I am working on a mobile responsive web design using Twitter Bootstrap 3, and I am facing challenges with margins and resizing. I previously asked about creating a mobile-first responsive web design along with responsive images, which you can f ...

Parsing JSON data to extract values stored in a two-dimensional array

In order to develop a basic version of Tic Tac Toe, I decided to store game data in a JSON file. Here is an example of how the file is structured: [ { "turn": "x", "board": [ [ " ...

Using AngularJS to incorporate ng-include with ng-click functionality

I am trying to figure out a way to insert HTML that is specifically optimized for the controller into an alert div. Unfortunately, I have been unsuccessful so far... <script type="text/ng-include" id="login.html"> <form data-select="exepti ...

The fancybox's excess content is concealed

I've recently integrated fancybox 2 into my project and have encountered an issue when appending HTML content to the modal. I disabled scrolling, but now any overflowing content is being hidden. Could this be related to the max-height of the modal? Ho ...

The span element remains the same width even with the display property set to flex

How can I center a span element within a container div when the span is preceded by another div? Here's my current code: <div id="container"> <div id="a">A</div> <span id="b">B</span> </div> #container { ...

Having difficulties parsing JSON data in JavaScript

So I've got this script embedded in my HTML code $(document).ready(function() { type :'GET', url :'MapleLeafs2011.json', dataType :'json', success :processTeam, error :function() { alert(&apo ...

Using JavaScript to Apply CSS Styles in JSF?

Is it possible to dynamically apply a CSS style to a JSF component or div using Javascript? I have been searching without any success. Below is some pseudo code: <div style="myJSStyleFunction("#{myBean.value}")"> stuff </div> The function wo ...

Tips for utilizing ng-checked and ng-disabled in conjunction with ng-repeat

I encountered a challenge with ng-repeat while incorporating ng-checked and ng-disable alongside it. <div ng-repeat="module in modulelist"> <input id="switch{{$index}}" ng-init="setState($index);" type="checkbox" ng-checked="switch.checked" ng-di ...

Creating subdocuments with input types in MERN stack using Apollo Sandbox and MongoDB mutations

These questions are specific to a Node server application built in JavaScript using express, apollo-server-express, mongoose, and graphql. Below is the content of the package.json file: { "name": "dimond-media-mern-app", "vers ...

Calculator screen filled with numbers overflowing beyond its boundaries

I'm encountering an issue with my calculator created in create-react-app where the numbers are overflowing off the screen. Specifically, when inputting very large numbers like 11111111111111111111111111111111, they exceed the output container. I am lo ...

What is the best way to trigger the code within my useEffect React hook to execute again upon refreshing the page?

I'm encountering an issue where the value of states is becoming 'undefined' after refreshing the page. Within my useEffect hook, I am generating a random number to select a question object from an array. Everything works smoothly on the ini ...

Navigating routes for a module sourced from NPM: Best practices

Looking for guidance on loading Angular routes from an NPM module? Take a look at this snippet from my app.module.ts file: import { HelloWorldModule } from 'hello-world-app-npm/hello-world-app.umd.js'; // Loading module from NPM const routes = ...

output an array based on a specified key/value relationship

Looking to filter results based on a key/value pair in an array? Consider this example array: .factory('dishesFactory', function (){ var factory = { dishes :[ {nameEnglish: 'TAPENADE', nameLocal: 'Tapenade', descript ...

Generate an image instantly from text using ajax when a key is pressed

Currently, I am immersed in a stencil project where my goal is to convert text into an image. In this particular task, there's a textbox that captures the user input on key up event. Once the user enters text, my aim is to display that text as an imag ...

Using MaterialUI to create a GridListTile with two IconButtons

I'm working with a GridListTile and trying to add a second button, but I'm having trouble getting both buttons to display. Even though I've attempted to include two ActionIcons, only one of them is showing up. Here's the code snippet: ...