3.14159
3.14159

Reputation: 267

dynamically resize div on adding input boxes

I'm trying to expand the height of the box in the demo. When I click the '+' button, a new row with two input boxes is created. I used element.offsetHeight property to increment the current height by a certain quantity. But since this returns a value in pixels and not em the resizing is not working as expected. After a certain number of attempts at clicking it, the '+' sign is no longer contained within the div.

Here's my attempt:

function addItemPrice() {
    toAppendId = document.getElementById("personExtras0");
    var newItemPrice = document.createElement("div");
    newItemPrice.className = "row";
    newItemPrice.innerHTML = "\
        <div class=\"row\">\
            <div class=\"col-sm-4\">"+
                "<input type=\"text\" name=\"item-name0\" class=\"form-control item-name\" id=\"item-name0\" placeholder=\"Item name\" />"
            +"</div>"+
            "<div class=\"col-sm-4\">"
                +"<input type=\"text\" name=\"item-cost0\" class=\"form-control item-cost\" id=\"item-cost0\" placeholder=\"Item Cost\" />"
            +"</div>"
            "<div class=\"col-sm-4\">"+
                "<i class=\"fa fa-minus fa-2x minus\"></i>"+
            +"</div>\
        </div>";
    var element = document.getElementsByClassName("col")[0];
    var height = element.offsetHeight;
    // alert(height);
    var newHeight = height + 40;
    element.style.height = newHeight + "px";
    toAppendId.appendChild(newItemPrice);
}
header {
    text-align: center;
}

.add-users-section {
    text-align: center;
    margin-left: 15em;
}

.add-users-section>.row>.col {
    border: 1px solid black;
    margin-left: 38%;
    margin-top: 2em;
    background-color: rgb(223, 219, 219);
}

#add-users-section-form {
    padding-top: 1em;
    padding-bottom: 2em;
}

#getNumberOfUsers {
    margin-bottom: 1em;
    height: 4em;
    width: 5em;
    margin-top: 1em;
    margin-left: 3em;
    margin-right: 3em;
    text-align: center;
}

#add-users-section-form>button {
    border-radius: 0;
}

#nameOfBill {
    width: 15em;
    height: 2em;
    padding-left: 1em;
    margin-bottom: 2em;
}


/* User items consumed section */

.user-items-consumed-section {
    margin-top: 5em;
    margin-left: 10em;
}

.col {
    border: 1px solid black;
    margin-bottom: 3em;
    height: 20em;
    width: 5em;
}

form>.row {
    margin-bottom: 5em;
}

.form-group {
    border-radius: 0;
    -webkit-appearance: none;
}

.item-name {
    margin-left: 0em;
}

.person-name {
    margin-top: 1em;
}

.plus {
    border: 1px solid black;
    margin-left: 1em;
    margin-top: 0em;
    text-align: center;
    padding: 0.5em;
}

.plus:hover {
    background-color: black;
}

.minus {
    margin-top: 1em;
    border: 1px solid black;
}

.personExtras {
    padding-left: 1em;
}

.personExtras>.row {
    margin-bottom: 2em;
}
<!DOCTYPE html>
<html>
    <head>
        <title>User Input Page</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <link rel="stylesheet" href="home.css">
        <link href="https://fonts.googleapis.com/css?family=Raleway&display=swap" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css?family=Ibarra+Real+Nova&display=swap" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css?family=Comfortaa&display=swap" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css?family=Lato&display=swap" rel="stylesheet">
        <script src="jquery-3.4.1.min.js"></script>
        <script src="https://use.fontawesome.com/8cf2963f4e.js"></script>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
        <script src="users-input-details.js"></script>
    </head>
    <body>
        <header class="page-header">
            <h1>Bill Split</h1>
        </header>
        
        <div class="user-items-consumed-section">
            <div class="container">
                <form>
                    <div class="row">
                        <div class="col-sm-4 col form-group" id="person0">
                            <div class="row">
                                <div class="col-sm-6">
                                    <input type="text" name="person-name" class="form-control person-name border-0" id="person-name0" placeholder="User 1"><br>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-sm-4">
                                    <input type="text" name="item-name0" class="form-control item-name" id="item-name0" placeholder="Item name">
                                </div>
                                <div class="col-sm-4"> 
                                    <input type="text" name="item-cost0" class="form-control item-cost" id="item-cost0" placeholder="Item Cost">
                                </div>
                                <div class="col-sm-4">
                                   <i class="fa fa-minus fa-2x minus"></i>
                                </div>
                            </div>
                            <div id="personExtras0" class="personExtras"></div>
                            <br>
                            <div class="row">
                                <div class="col-sm-10 plus" onclick="addItemPrice()">
                                    <i class="fa fa-plus fa-2x"></i>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-sm-4 col">
                            <p> Hello </p>
                        </div>
                    </div>
                </form>
            </div>
        </div>
        
    </body>
</html>

The demo works properly only on a full-screen desktop. Apologies. Any help is appreciated.

Upvotes: 4

Views: 80

Answers (1)

Emiel Zuurbier
Emiel Zuurbier

Reputation: 20954

There should be no need to set the height manually as the box should stretch the size of it's children, if your CSS is set properly. I've tried to fix what was causing your issue, but I'm sorry, it is too much work.

So I've tried to recreate a simplified version which demonstrates that you don't need to set the height but should let the document flow and CSS do it's work.

Also I've noticed that you use a lot of id's in your HTML, also when adding new elements. id's have to be unique, otherwise they have no purpose and are practically useless. Consider using class instead if you have reoccuring elements with the same styles.

If you have multiple input elements with the same name attribute in your form, make sure to append [] after the value of the name. For example: name="firstname" should be name="firstname[]". This enables your form to create groups of values. Otherwise the firstname value would be overwritten for each input with that name in your form.

Beware of your Bootstrap layout. col classes should be placed directly into a row and a row should only have col classes as direct children. If you use col-sm-6 and within that col another col-sm-6, you'll get the width of a col-sm-3 as result. This will make your layout difficult to work with. Try to use the classes only when necessary of creating columns.

Prevent overwriting CSS of Bootstrap or modifying classes of Bootstrap directly. This will create unexpected behavior in your project, like columns that don't size properly. Instead use modifier classes that enhance the CSS on an element but do not overwrite the default CSS of Bootstrap. Or make a new div or whatever you need and write your own CSS for it without affecting existing styles.

I understand that you are still learning and I mean everything here above in a constructive sense. Keep it up and keep practicing. You'll do great!

I hope that any of this makes sense and is of any help. Please let me know, if I've been unclear or didn't properly help you in any way.

Cheers!

const form = document.querySelector('form');
const items = form.querySelector('.items');

const createGroup = () => `
  <div class="group">
    <label>
      <span>Item</span>
      <input type="text" name="item[]">
    </label>
    <label>
      <span>Price</span>
      <input type="text" name="price[]">
    </label>
  </div>
`;

form.addEventListener('click', function(event) {
  const button = event.target.closest('.add');
  if (button !== null) {
    const group = createGroup();
    items.insertAdjacentHTML('beforeend', group);
  }
});
*, *::before, *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

label {
  font-family: sans-serif;
}

body {
  width: 100%;
  padding: 1em;
}

.form {
  display: block;
  width: 100%;
  margin: 0 auto;
  background: #f7f7f7;
  border: 1px solid #ccc;
  border-radius: 5px;
  padding: 0 1em 1em;
}

.items {
  counter-reset: groupCount;
}

.group {
  counter-increment: groupCount;
  background-color: #fff;
  padding: 1em;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin: 1em 0;
}

label span::after {
  content: " " counter(groupCount);
}

input {
  display: block;
  width: 100%;
  height: 34px;
  padding: 6px 12px;
  font-size: 14px;
  line-height: 1.42857143;
  color: #555;
  background-color: #fff;
  background-image: none;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  margin: 1em 0;
}

button {
  display: block;
  appearance: none;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 6px 12px;
  font-size: 14px;
  background-color: #fff;
  margin-top: 1em;
}
<form class="form">
  <div class="items">
    <div class="group">
      <label>
        <span>Item</span>
        <input type="text" name="item[]">
      </label>
      <label>
        <span>Price</span>
        <input type="text" name="price[]">
      </label>
    </div>
  </div>
  <div class="controls">
    <button class="add" type="button" name="add">Add group</button>
  </div>
</form>

Upvotes: 3

Related Questions