Skip to main content
added 361 characters in body
Source Link
morbusg
  • 960
  • 7
  • 10

Put styles in stylesheet, and use semantic markup. It's easier to think about the problem if it is a list of input controls.

You would most probably want to reset the hidden inputs, because in case a previous input value is removed, and then the form is submitted, those hidden input values would still get included.

Short side note: addingAdding a listener on a form propagates it to contained controls so that the event target is the control being manipulated. So in the example below, in case of other controls, the listener would need to check if the target is something that it needs to act upon or not.

In the example below, I have changed the behavior so that on input, the next input label's hidden CSS class is removed, and on removing content from input, all succeeding input labels get that class added, and also resetting their value.

document.addEventListener('DOMContentLoaded', () => {
  const form = document.forms[0] // NOTE: change if multiple forms
  const inputs = Array.from(form.elements)
  // ^NOTE: use a selector or filter if other controls

  const hideAndReset = input => {
    input.parentElement.classList.add('hidden')
    input.value = ''
  }

  const showNext = ({target}) => {
    const nextIndex = inputs.indexOf(target) + 1

    if(nextIndex == inputs.length)
      return false

    if(target.value)
      inputs[nextIndex].parentElement.classList.remove('hidden')
    else
      inputs.slice(nextIndex).forEach(hideAndReset)
  }

  form.addEventListener('input', showNext)
})
label { display: block }
.hidden { display: none }
<form>
  <label>
    <span>Quantity 1</span>
    <input id="qty1" type="number" required>
  </label>

  <label class="hidden">
    <span>Quantity 2</span>
    <input id="qty2" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 3</span>
    <input id="qty3" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 4</span>
    <input id="qty4" type="number">
  </label>
</form>

Put styles in stylesheet, and use semantic markup. It's easier to think about the problem if it is a list of input controls.

You would most probably want to reset the hidden inputs.

Short side note: adding a listener on a form propagates it to contained controls so that the event target is the control being manipulated. So in the example below, in case of other controls, the listener would need to check if the target is something that it needs to act upon or not.

document.addEventListener('DOMContentLoaded', () => {
  const form = document.forms[0] // NOTE: change if multiple forms
  const inputs = Array.from(form.elements)
  // ^NOTE: use a selector or filter if other controls

  const hideAndReset = input => {
    input.parentElement.classList.add('hidden')
    input.value = ''
  }

  const showNext = ({target}) => {
    const nextIndex = inputs.indexOf(target) + 1

    if(nextIndex == inputs.length)
      return false

    if(target.value)
      inputs[nextIndex].parentElement.classList.remove('hidden')
    else
      inputs.slice(nextIndex).forEach(hideAndReset)
  }

  form.addEventListener('input', showNext)
})
label { display: block }
.hidden { display: none }
<form>
  <label>
    <span>Quantity 1</span>
    <input id="qty1" type="number" required>
  </label>

  <label class="hidden">
    <span>Quantity 2</span>
    <input id="qty2" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 3</span>
    <input id="qty3" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 4</span>
    <input id="qty4" type="number">
  </label>
</form>

Put styles in stylesheet, and use semantic markup. It's easier to think about the problem if it is a list of input controls.

You would most probably want to reset the hidden inputs, because in case a previous input value is removed, and then the form is submitted, those hidden input values would still get included.

Adding a listener on a form propagates it to contained controls so that the event target is the control being manipulated. So in the example below, in case of other controls, the listener would need to check if the target is something that it needs to act upon or not.

In the example below, I have changed the behavior so that on input, the next input label's hidden CSS class is removed, and on removing content from input, all succeeding input labels get that class added, and also resetting their value.

document.addEventListener('DOMContentLoaded', () => {
  const form = document.forms[0] // NOTE: change if multiple forms
  const inputs = Array.from(form.elements)
  // ^NOTE: use a selector or filter if other controls

  const hideAndReset = input => {
    input.parentElement.classList.add('hidden')
    input.value = ''
  }

  const showNext = ({target}) => {
    const nextIndex = inputs.indexOf(target) + 1

    if(nextIndex == inputs.length)
      return false

    if(target.value)
      inputs[nextIndex].parentElement.classList.remove('hidden')
    else
      inputs.slice(nextIndex).forEach(hideAndReset)
  }

  form.addEventListener('input', showNext)
})
label { display: block }
.hidden { display: none }
<form>
  <label>
    <span>Quantity 1</span>
    <input id="qty1" type="number" required>
  </label>

  <label class="hidden">
    <span>Quantity 2</span>
    <input id="qty2" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 3</span>
    <input id="qty3" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 4</span>
    <input id="qty4" type="number">
  </label>
</form>

added 289 characters in body
Source Link
morbusg
  • 960
  • 7
  • 10

Put styles in stylesheet, and use semantic markup. It's easier to think about the problem if it is a list of input controls.

You would most probably want to reset the hidden inputs.

Short side note: adding a listener on a form propagates it to contained controls so that the event target is the control being manipulated. So in the example below, in case of other controls, the listener would need to check if the target is something that it needs to act upon or not.

document.addEventListener('DOMContentLoaded', () => {
  const form = document.forms[0] // NOTE: change if multiple forms
  const inputs = Array.from(form.elements)
  // ^NOTE: use a selector or filter if other controls

  const hideAndReset = input => {
    input.parentElement.classList.add('hidden')
    input.value = ''
  }

  const showNext = ({target}) => {
    const nextIndex = inputs.indexOf(target) + 1

    if(nextIndex == inputs.length)
      return false

    if(target.value)
      inputs[nextIndex].parentElement.classList.remove('hidden')
    else
      inputs.slice(nextIndex).forEach(hideAndReset)
  }

  form.addEventListener('input', showNext)
})
label { display: block }
.hidden { display: none }
<form>
  <label>
    <span>Quantity 1</span>
    <input id="qty1" type="number" required>
  </label>

  <label class="hidden">
    <span>Quantity 2</span>
    <input id="qty2" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 3</span>
    <input id="qty3" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 4</span>
    <input id="qty4" type="number">
  </label>
</form>

Put styles in stylesheet, and use semantic markup. It's easier to think about the problem if it is a list of input controls.

You would most probably want to reset the hidden inputs.

document.addEventListener('DOMContentLoaded', () => {
  const form = document.forms[0] // NOTE: change if multiple forms
  const inputs = Array.from(form.elements)
  // ^NOTE: use a selector or filter if other controls

  const hideAndReset = input => {
    input.parentElement.classList.add('hidden')
    input.value = ''
  }

  const showNext = ({target}) => {
    const nextIndex = inputs.indexOf(target) + 1

    if(nextIndex == inputs.length)
      return false

    if(target.value)
      inputs[nextIndex].parentElement.classList.remove('hidden')
    else
      inputs.slice(nextIndex).forEach(hideAndReset)
  }

  form.addEventListener('input', showNext)
})
label { display: block }
.hidden { display: none }
<form>
  <label>
    <span>Quantity 1</span>
    <input id="qty1" type="number" required>
  </label>

  <label class="hidden">
    <span>Quantity 2</span>
    <input id="qty2" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 3</span>
    <input id="qty3" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 4</span>
    <input id="qty4" type="number">
  </label>
</form>

Put styles in stylesheet, and use semantic markup. It's easier to think about the problem if it is a list of input controls.

You would most probably want to reset the hidden inputs.

Short side note: adding a listener on a form propagates it to contained controls so that the event target is the control being manipulated. So in the example below, in case of other controls, the listener would need to check if the target is something that it needs to act upon or not.

document.addEventListener('DOMContentLoaded', () => {
  const form = document.forms[0] // NOTE: change if multiple forms
  const inputs = Array.from(form.elements)
  // ^NOTE: use a selector or filter if other controls

  const hideAndReset = input => {
    input.parentElement.classList.add('hidden')
    input.value = ''
  }

  const showNext = ({target}) => {
    const nextIndex = inputs.indexOf(target) + 1

    if(nextIndex == inputs.length)
      return false

    if(target.value)
      inputs[nextIndex].parentElement.classList.remove('hidden')
    else
      inputs.slice(nextIndex).forEach(hideAndReset)
  }

  form.addEventListener('input', showNext)
})
label { display: block }
.hidden { display: none }
<form>
  <label>
    <span>Quantity 1</span>
    <input id="qty1" type="number" required>
  </label>

  <label class="hidden">
    <span>Quantity 2</span>
    <input id="qty2" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 3</span>
    <input id="qty3" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 4</span>
    <input id="qty4" type="number">
  </label>
</form>

Source Link
morbusg
  • 960
  • 7
  • 10

Put styles in stylesheet, and use semantic markup. It's easier to think about the problem if it is a list of input controls.

You would most probably want to reset the hidden inputs.

document.addEventListener('DOMContentLoaded', () => {
  const form = document.forms[0] // NOTE: change if multiple forms
  const inputs = Array.from(form.elements)
  // ^NOTE: use a selector or filter if other controls

  const hideAndReset = input => {
    input.parentElement.classList.add('hidden')
    input.value = ''
  }

  const showNext = ({target}) => {
    const nextIndex = inputs.indexOf(target) + 1

    if(nextIndex == inputs.length)
      return false

    if(target.value)
      inputs[nextIndex].parentElement.classList.remove('hidden')
    else
      inputs.slice(nextIndex).forEach(hideAndReset)
  }

  form.addEventListener('input', showNext)
})
label { display: block }
.hidden { display: none }
<form>
  <label>
    <span>Quantity 1</span>
    <input id="qty1" type="number" required>
  </label>

  <label class="hidden">
    <span>Quantity 2</span>
    <input id="qty2" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 3</span>
    <input id="qty3" type="number">
  </label>

  <label class="hidden">
    <span>Quantity 4</span>
    <input id="qty4" type="number">
  </label>
</form>