Arrange dynamic elements in rows to utilize the entire available space, while ensuring that groups remain intact and are not split

My form allows users to dynamically add categories, groups, and individual inputs.

I want to print the completed form so that it looks good on paper. The form can get quite complex, so I created a separate minimal page for printing purposes.

You can view my current progress in this jsFiddle or see the layout https://i.sstatic.net/mrJWt.png

The issues I'm facing are highlighted in red and purple below:

Purple: I want the last input-value field in each row to extend all the way to the right to fill up the remaining space on the row.

Red: I need to prevent the input-label and input-value from breaking across multiple lines. If there isn't enough room on the row, they should move to the next line together.

How can these two problems be resolved? I am open to using JavaScript/jQuery solutions if needed.

Answer №1

I have created a function that performs two distinct tasks:

  1. The function checks if the input-value and input-label are on different rows, and if so, it moves the input-value to a new row with a clear:left property.

  2. After moving the input-value to a new row, the function expands the last input-value in the previous row to utilize the remaining width (row width - input far from the left).

You can view the demonstration on JSFiddle: http://jsfiddle.net/7tnkL9b0/5/

Here's the code snippet for your reference:

$('.category').each(function(){
    $('.input-row').each(function(){
        this_input=$('.input-value',this).offset().top
        this_label=$('.input-label',this).offset().top
        console.log(this_input,this_label)
        if(this_input!=this_label){
            console.log('here')
            $('.input-label',this).css('clear','both')
            $('.input-value',$(this).prev()).width(
                $(this).width()-$('.input-value',$(this).prev()).offset().left
            )
        }

        if($(this).next().length==0){
            $('.input-value',this).width(
               $(this).width()-$('.input-value',this).offset().left
            )
        }
    })
})

You can also refer to the image linked below for visual representation: https://i.sstatic.net/VbrxB.jpg

Answer №2

Here is a snippet of the final code I settled on after working with @Armina's solution. The original answer was good, but it didn't behave consistently across different screen sizes.

If you'd like to see the full code in action, check out this jsFiddle

https://i.sstatic.net/a9dOY.png

$.fn.extend({
    alignRows: function (options) {
        var defaults = {
            container: '#print-container', // the selector for the container element that holds all the groups
            label: '.input-label', // the selector for the elements holding the labels for the inputs
            value: '.input-value', // the selector for the elements holding the values for the inputs
            pair: '.input-pair', // the selector for the wrapper element that holds the label and value
            ignore: 'col-12' // a classname to ignore, these elements will not be evaluated or changed, style these some other way
        };
        options = $.extend(defaults, options);
        this.each(function (g, el) {
            var $group = $(el);
            var $pairs = $group.find(options.pair);
            $pairs.each(function (i, e) {
                var $this = $(e);
                var $label = $this.find(options.label);
                var $value = $this.find(options.value);
                var $nextPair = $pairs.eq(i + 1);
                if ($nextPair.length > 0) {
                    var thisTop = $this.offset().top;
                    var nextTop = $nextPair.offset().top;
                    if (thisTop != nextTop && !$this.hasClass(options.ignore)) {
                        //console.log('break to new row'); 
                        $this.stretch(options);
                    }
                } else {
                    //console.log('last in row'); 
                    $this.stretch(options);
                }
            });
        });
        return this;
    },
    stretch: function (options) {
        this.each(function (g, el) {
            var defaults = {};
            var $this = $(el);
            $this.css('margin-right', '0px').css('margin-right', '0px');
            var $value = $this.find(options.value);
            var elementWidth = $value.outerWidth(true);
            var elementLeft = $value.offset().left;
            var elementRightEdge = elementWidth + elementLeft;
            var containerWidth = $(options.container).outerWidth();
            var containerLeft = $(options.container).offset().left;
            var containerRightEdge = containerWidth + containerLeft;
            var offset = containerRightEdge - elementRightEdge;
            var newWidth = (elementWidth + offset) - 30;
            $value.css('width', newWidth + 'px');
            /*
            console.log('elementRightEdge  is ' + elementRightEdge);
            console.log('containerRightEdge  is ' + containerRightEdge);
            console.log('difference is ' + offset);
            console.log('stretching element to ' + newWidth);
            */
        });
        return this;
    }
});
$('.input-group').alignRows();
html, body {
    font-family: Arial, Helvetica, sans-serif;
}
#print-container {
    width: 210mm;
    /*height: 297mm;*/
    margin-left: auto;
    margin-right: auto;
    display: table;
    height:50px;
    position:relative;
}
.print-header {
    color: #909090 !important;
    font-size: 26px !important;
    line-height: 26px !important;
    font-weight: bold !important;
    padding-bottom:24px !important;
    margin-top: 30px;
}
.print-header-text {
    transform:scale(1.1, 1.3);
    /* W3C */
    -webkit-transform:scale(1.1, 1.3);
    /* Safari and Chrome */
    -moz-transform:scale(1.1, 1.3);
    /* Firefox */
    -ms-transform:scale(1.1, 1.3);
    /* IE 9 */
    -o-transform:scale(1.1, 1.3);
    /* Opera */
    padding-top:22px;
}

...

</script>
<div id="print-container">
    <div class="print-header row">
        <div class="col-3 text-center ">
           <img width="176.5" height="73.15019011406845" src="https://placeholdit.imgix.net/~text?txtsize=33&txt=176%C3%9773&w=176.5&h=73.15019011406845" alt="">
        </div>
        <div class="col-9 text-center vtop print-header-text">SOME FORM TITLE HERE</div>
    </div>

    ...

    </div>
</div>

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

Toggle between fading in and out by clicking the button using a div

I'm having trouble getting my fade menu div to work properly. I want it to fade in when the menu button is clicked and fade out when the menu button is clicked again. Despite following various tutorials and researching other questions, I can't se ...

Ways to trigger a modal programmatically in the backend code?

My goal is to trigger the display of a modal when a button is clicked. The modal should be shown by clicking this button: <asp:Button ID="Button4" runat="server" class="btn btn-info" data-toggle="modal" OnClientClick="return false;" data-target="#View1 ...

Transmitting an image encoded in base64 using Ajax and form data

My client has a requirement to collect form data and capture a signature using the SignaturePad library. I have managed to create a solution using Ajax, but I am facing difficulty in making both functionalities work together. When I send image data like t ...

What is the best way to insert HTML elements in front of other HTML elements using a form and jQuery?

I am looking to insert new HTML elements before existing ones using a form and jQuery: Here is the initial HTML Code: <div class="main-content"> <h2 class="main-content-header">Projekte</h2> <div class="project-content"> ...

Is there a way I can showcase my tags such as "vegan, pasta, etc." using the map feature from Firestore?

Is there a way to display all of my labels like "vegan, pasta, etc." from Firestore using the map function? Currently, I am only able to map out the first object [0]. How can I map out all options instead of just one? Here is an example of what works righ ...

Unique element is bound with jQuery's ajaxStart function

Below is the JS code I am working with: <script type="text/javascript"> $(document).ready(function () { $("#innerDiv1").ajaxStart(function () { alert($(this).attr("id") + " ajaxStart"); }); $("#innerDiv2").aj ...

Move your cursor over the toggle menu to reveal the concealed image

Is it feasible to have a hidden image (with ID 10) display when hovering over a toggle menu (with ID 9) in Wordpress? The current setup can be seen here: . I would like the ability to hover over the left toggle menu and reveal an image that is currently ...

Unable to establish the characteristic of 'undefined' to null while using React

For my application, I require the following functionality: If a question's value is null, then the checkbox should appear as indeterminate. Otherwise, it should be checked or not-checked accordingly. The issue arises when I try to update the questio ...

Improving a lengthy TypeScript function through refactoring

Currently, I have this function that I am refactoring with the goal of making it more concise. For instance, by using a generic function. setSelectedSearchOptions(optionLabel: string) { //this.filterSection.reset(); this.selectedOption = optionLa ...

Unable to remove Css class through code behind

I'm currently working on a Gridview code snippet: <SelectedRowStyle CssClass="SelectedRowStyle" /> This changes the color of the selected row to yellow. However, when I click a button, I want to remove the css class. I attempted to do this in ...

The issue of AngularJS failing to bind object properties to the template or HTML element

Just dipping my toes into angularJS, following Todd Motto's tutorials, and I'm having trouble displaying object properties on the page. function AddCurrentJobs($scope){ $scope.jobinfo = [{ title: 'Building Shed', description: ...

Is it possible to access the serial port using HTML5?

Can a HTML5 page access the serial port of a device solely on the client-side? I am aware that this is possible with Java applet, but I am curious to know if it can be achieved using HTML5. ...

What are the steps to fix the eslint error related to "Generic Object Injection Sink"?

I'm attempting to access a JSON array, but every time I try to read the array/value by passing the JSON object key like this- json[key] An Eslint error occurs- [eslint] Generic Object Injection Sink (security/detect-object-injection) I understand ...

In Javascript, you can enhance your axes on a graph by adding labels at both the

Is there a way to add labels at the beginning and end of the axes to indicate the importance level, such as "not very important" and "very important"? I am currently utilizing a slider program from here. Since I am new to JavaScript, I would greatly appre ...

Creating dynamic input forms in PHP

New to PHP and seeking guidance! I'm in the process of creating a photography website and encountering an issue with a specific page. Essentially, I need this page to display a form with a varying number of inputs. The goal is to have a dynamic visua ...

Parsing through an extensive JSON array to locate a particular item

I have a massive JSON file with the top-level structure being an array, filled with numerous subarrays like: [ [], [], [], ... [] ] Each subarray is small enough to load into memory individually; the file's size mainly comes from the number of suba ...

Using webkitRelativePath feature in Angular

I am facing an issue with my Angular application where I need to access the webkitRelativePath for the backend. The code provided below is not functioning properly because you cannot utilize .webkitRelativePath on a FileList. This poses a challenge as I ...

I am attempting to implement an Express static middleware as demonstrated in this book, but I am having trouble understanding the intended purpose of the example

I'm currently studying a chapter in this book that talks about Express, specifically concerning the use of express.static to serve files. However, I'm encountering an issue where the code catches an error when no file is found. I've created ...

Tips for waiting on image loading in canvas

My challenge involves interacting with the image loaded on a canvas. However, I am uncertain about how to handle waiting for the image to load before starting interactions with it in canvas tests. Using driver.sleep() is not a reliable solution. Here is ...

Visualizing Data with Recharts: Creating a Continuous Line or Area Graph in JavaScript to Display Average Values in 15-Minute Intervals

I'm currently working on plotting a month's worth of data that appears as follows, 0: {created: 1601820360, magic: -0.1, magnitude: 0.1, createdDay: "2020-10-05"} 1: {created: 1601820365, magic: -0.8, magnitude: 0.8, createdDay: "2 ...