Html form group inputs

A little trick for grouping fields in an HTML form

Imagine this scenario: You have a group of fields that represent a person. Maybe the form you’re building allows you to create a company, but you also want to be able to add employees of the company.

You don’t know how many employees your users will add, so you add a little JavaScript button that makes it possible to add more.

How do you name your fields?

How we used to do it

You probably know this is the wrong way:

Person 1:    

To pull those out in the backend will require string manipulation—and imagine parsing out the number from that string field name when some numbers have one digit, but then all of a sudden you have 10 employees and now some of the fields have two digits at the end instead. Fail. Don’t do it.

Here’s the more common suggestion: use the field name array syntax:

Person 1:    Person 2:    

This seems like a great idea, and it is—but when you parse the input on the other end, you’re probably expecting something like this:

person1 = ['Jim', 'Barber', 'jim@barber.com']; person2 = ['Amira', 'Sayegh', 'amira@sayegh.com']; 

Sadly, that’s not what you get. Instead, you get this:

first_name = ['Jim', 'Amira']; last_name = ['Barber', 'Sayegh']; email_name = ['jim@barber.com', 'amira@sayegh.com']; 

Parsing that together is not awful, but it can get really clumsy—especially as you add more fields.

What’s this all about then

Fear not! There is a better solution!

If you set your fields to be grouped by «children» of a parent field, and give each «child» a numeric index, they’ll all returned grouped, and then they’ll return the way you’re expecting. So people is our «parent field», people[1] is our first «child», and people[1][first_name] is that child’s first property.

Person 1:    Person 2:    

And take a look at what we get now:

people = [ [ 'first_name' => 'Jim', 'last_name' => 'Barber', 'email' => 'jim@barber.com ], [ 'first_name' => 'Amira', 'last_name' => 'Sayegh', 'email' => 'amira@sayegh.com ] ] 

Bonus

Here’s a quick bit of ES6 JavaScript to show one way you might want to do this:

  

Person 1:




Person 2:



Add new person

Bonus

I remembered that I wanted to write this article as I was listening to a great Full-Stack Radio episode with Jonathan Reinink where they talk about forms for an hour. It’s good stuff. Take a listen.

Also, Adam has written a little about this same problem on his blog—but he chose to solve it on the server side instead. Take a look: Cleaning up form input with transpose

Tags: javascript • html • forms

Subscribe

Quick links to fresh content, and more thoughts that don’t make it to the blog

© 2023 Matt Stauffer • @stauffermatt • Mastodon • LinkedIn • RSS • YouTube • Like what I write? Hire Tighten & we can work together

Источник

Input group

Easily extend form controls by adding text, buttons, or button groups on either side of textual inputs, custom selects, and custom file inputs.

Basic example

Place one add-on or button on either side of an input. You may also place one on both sides of an input. Remember to place s outside the input group.

div class="input-group mb-3">  span class="input-group-text" id="basic-addon1">@span>  input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1"> div>  div class="input-group mb-3">  input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2">  span class="input-group-text" id="basic-addon2">@example.comspan> div>  div class="mb-3">  label for="basic-url" class="form-label">Your vanity URLlabel>  div class="input-group">  span class="input-group-text" id="basic-addon3">https://example.com/users/span>  input type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3 basic-addon4">  div>  div class="form-text" id="basic-addon4">Example help text goes outside the input group.div> div>  div class="input-group mb-3">  span class="input-group-text">$span>  input type="text" class="form-control" aria-label="Amount (to the nearest dollar)">  span class="input-group-text">.00span> div>  div class="input-group mb-3">  input type="text" class="form-control" placeholder="Username" aria-label="Username">  span class="input-group-text">@span>  input type="text" class="form-control" placeholder="Server" aria-label="Server"> div>  div class="input-group">  span class="input-group-text">With textareaspan>  textarea class="form-control" aria-label="With textarea">textarea> div>

Wrapping

Input groups wrap by default via flex-wrap: wrap in order to accommodate custom form field validation within an input group. You may disable this with .flex-nowrap .

div class="input-group flex-nowrap">  span class="input-group-text" id="addon-wrapping">@span>  input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="addon-wrapping"> div>

Sizing

Add the relative form sizing classes to the .input-group itself and contents within will automatically resize—no need for repeating the form control size classes on each element.

Sizing on the individual input group elements isn’t supported.

div class="input-group input-group-sm mb-3">  span class="input-group-text" id="inputGroup-sizing-sm">Smallspan>  input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm"> div>  div class="input-group mb-3">  span class="input-group-text" id="inputGroup-sizing-default">Defaultspan>  input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default"> div>  div class="input-group input-group-lg">  span class="input-group-text" id="inputGroup-sizing-lg">Largespan>  input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-lg"> div>

Checkboxes and radios

Place any checkbox or radio option within an input group’s addon instead of text. We recommend adding .mt-0 to the .form-check-input when there’s no visible text next to the input.

div class="input-group mb-3">  div class="input-group-text">  input class="form-check-input mt-0" type="checkbox" value="" aria-label="Checkbox for following text input">  div>  input type="text" class="form-control" aria-label="Text input with checkbox"> div>  div class="input-group">  div class="input-group-text">  input class="form-check-input mt-0" type="radio" value="" aria-label="Radio button for following text input">  div>  input type="text" class="form-control" aria-label="Text input with radio button"> div>

Multiple inputs

While multiple s are supported visually, validation styles are only available for input groups with a single .

div class="input-group">  span class="input-group-text">First and last namespan>  input type="text" aria-label="First name" class="form-control">  input type="text" aria-label="Last name" class="form-control"> div>

Multiple addons

Multiple add-ons are supported and can be mixed with checkbox and radio input versions.

div class="input-group mb-3">  span class="input-group-text">$span>  span class="input-group-text">0.00span>  input type="text" class="form-control" aria-label="Dollar amount (with dot and two decimal places)"> div>  div class="input-group">  input type="text" class="form-control" aria-label="Dollar amount (with dot and two decimal places)">  span class="input-group-text">$span>  span class="input-group-text">0.00span> div>

Button addons

div class="input-group mb-3">  button class="btn btn-outline-secondary" type="button" id="button-addon1">Buttonbutton>  input type="text" class="form-control" placeholder="" aria-label="Example text with button addon" aria-describedby="button-addon1"> div>  div class="input-group mb-3">  input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="button-addon2">  button class="btn btn-outline-secondary" type="button" id="button-addon2">Buttonbutton> div>  div class="input-group mb-3">  button class="btn btn-outline-secondary" type="button">Buttonbutton>  button class="btn btn-outline-secondary" type="button">Buttonbutton>  input type="text" class="form-control" placeholder="" aria-label="Example text with two button addons"> div>  div class="input-group">  input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username with two button addons">  button class="btn btn-outline-secondary" type="button">Buttonbutton>  button class="btn btn-outline-secondary" type="button">Buttonbutton> div>

Buttons with dropdowns

div class="input-group mb-3">  button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Dropdownbutton>  ul class="dropdown-menu">  li>a class="dropdown-item" href="#">Actiona>li>  li>a class="dropdown-item" href="#">Another actiona>li>  li>a class="dropdown-item" href="#">Something else herea>li>  li>hr class="dropdown-divider">li>  li>a class="dropdown-item" href="#">Separated linka>li>  ul>  input type="text" class="form-control" aria-label="Text input with dropdown button"> div>  div class="input-group mb-3">  input type="text" class="form-control" aria-label="Text input with dropdown button">  button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Dropdownbutton>  ul class="dropdown-menu dropdown-menu-end">  li>a class="dropdown-item" href="#">Actiona>li>  li>a class="dropdown-item" href="#">Another actiona>li>  li>a class="dropdown-item" href="#">Something else herea>li>  li>hr class="dropdown-divider">li>  li>a class="dropdown-item" href="#">Separated linka>li>  ul> div>  div class="input-group">  button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Dropdownbutton>  ul class="dropdown-menu">  li>a class="dropdown-item" href="#">Action beforea>li>  li>a class="dropdown-item" href="#">Another action beforea>li>  li>a class="dropdown-item" href="#">Something else herea>li>  li>hr class="dropdown-divider">li>  li>a class="dropdown-item" href="#">Separated linka>li>  ul>  input type="text" class="form-control" aria-label="Text input with 2 dropdown buttons">  button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">Dropdownbutton>  ul class="dropdown-menu dropdown-menu-end">  li>a class="dropdown-item" href="#">Actiona>li>  li>a class="dropdown-item" href="#">Another actiona>li>  li>a class="dropdown-item" href="#">Something else herea>li>  li>hr class="dropdown-divider">li>  li>a class="dropdown-item" href="#">Separated linka>li>  ul> div>

Segmented buttons

div class="input-group mb-3">  button type="button" class="btn btn-outline-secondary">Actionbutton>  button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">  span class="visually-hidden">Toggle Dropdownspan>  button>  ul class="dropdown-menu">  li>a class="dropdown-item" href="#">Actiona>li>  li>a class="dropdown-item" href="#">Another actiona>li>  li>a class="dropdown-item" href="#">Something else herea>li>  li>hr class="dropdown-divider">li>  li>a class="dropdown-item" href="#">Separated linka>li>  ul>  input type="text" class="form-control" aria-label="Text input with segmented dropdown button"> div>  div class="input-group">  input type="text" class="form-control" aria-label="Text input with segmented dropdown button">  button type="button" class="btn btn-outline-secondary">Actionbutton>  button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">  span class="visually-hidden">Toggle Dropdownspan>  button>  ul class="dropdown-menu dropdown-menu-end">  li>a class="dropdown-item" href="#">Actiona>li>  li>a class="dropdown-item" href="#">Another actiona>li>  li>a class="dropdown-item" href="#">Something else herea>li>  li>hr class="dropdown-divider">li>  li>a class="dropdown-item" href="#">Separated linka>li>  ul> div>

Custom forms

Input groups include support for custom selects and custom file inputs. Browser default versions of these are not supported.

Источник

Читайте также:  Java variable initializer is redundant
Оцените статью