Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
457 views
in Technique[技术] by (71.8m points)

javascript - Get <input> children of grid to grow and shrink based on content

In a grid, columns can grow and shrink to fill up available space, and do this proportional to the content widths of each column. See the <span> part of the example below.

I would like to make <input> columns grow and shrink too, in exactly the same way the <span>s do.

.grid {
  display: grid;
  grid-template-columns: repeat(2, auto);
  width: 300px;
}

.column {
  border: 1px solid gray;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
<h3>span</h3>
<div class="grid">
  <span class="column" contenteditable></span>
  <span class="column" contenteditable></span>
</div>
<h3>input</h3>
<div class="grid">
  <input class="column" type="text">
  <input class="column" type="text">
</div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

input have a size set by defaut (from the attribute size) but it can be overridden via width.

You can set a small value to size , alike 1 or 2, then use javascript to resize it according to its content.

here is an idea using hidden span where

  • the value of input are mirrored inside (mind font-size and font-family, ...),
  • retrieve the width of the span then apply it back to the input.

// deserves to be rewritten . inspired from https://stackoverflow.com/questions/64092841/react-how-to-make-an-input-only-as-wide-as-the-amount-of-text-provided/64094013#64094013
let val = document.querySelectorAll("#text1, #text2, #text3, #text4");
let tpl = document.querySelectorAll("#sptext1, #sptext2, #sptext3, #sptext4");

function resizeIpt() {
  let text1 = val[0].value;
  let text2 = val[1].value;
  let text3 = val[2].value;
  let text4 = val[3].value;
  tpl[0].textContent = text1;
  tpl[1].textContent = text2;
  tpl[2].textContent = text3;
  tpl[3].textContent = text4;
}
let ipt = document.querySelectorAll('.grid input[type="text"]');
for (let i = 0; i < ipt.length; i++) {
  ipt[i].addEventListener("input", function() {
    // onchange ...
    tpl[i].textContent = val[i].value;
    val[i].style.width = "unset"; /* reset actual width */
    resizeIpt;
  });
}
window.onload = resizeIpt;
* {
  box-sizing: border-box;
}

.grid {
  display: grid;
  grid-template-columns: repeat(2, auto);
  /* justify-content: left; or start will shrink the columns if contents together are  smaller than 300px of width */
  width: 300px;
  background: #bee
}

.column {
  border: 1px solid gray;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: clamp(2em, min-content, 100%);
  padding: 0 0.5em;
  font-size: inherit;
  font-family: inherit;
}

span[id].column {
  height: 0;
  overflow: hidden;
  border: none;
}
<h3>span</h3>
<div class="grid">
  <span class="column" contenteditable>let it be a really much too long text here </span>
  <span class="column" contenteditable>short</span>
</div>

<h3>input</h3>
<div class="grid">
  <span id="sptext1" class="column"></span>
  <span id="sptext2" class="column"></span>
  <input class="column" size="2" id="text1" type="text" value='let it be a really much too long text here'>
  <input class="column" size="2" id="text1" type="text" value="short">
</div>

<h3>input</h3>
<div class="grid" style="font-family:monospace;">
  <span id="sptext3" class="column"></span>
  <span id="sptext4" class="column"></span>
  <input class="column" size="2" id="text3" type="text" value="short">
  <input class="column" size="2" id="text4" type="text" value='let it be longer'>
</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...