EmmaO91
EmmaO91

Reputation: 458

Input field with buttons or spans inside

I have a feature in mind for an interface I'm developing but I'm not entirely sure of how to bring it to fruition. I'm basically after an input field with a set of buttons to the side which insert a span/button inside the input to represent the button clicked.

So in a simplified version of my imagined interface, I can type into the field as normal but when I press one of the buttons to the side, they also insert text into the field. Let's say if I press button 1 it inserts the text "Hello" and button 2 inserts the text "Emma". Fairly easy.

The more complex version which I want to create works similarly, but when I click button 1 it inserts a bubble inside the text field. The bubble has its own background colour, contains the word "Hello" and has a small x in the top right to dismiss it. When the bubble is inserted it moves the carat on past the inserted bubble and I can continue to type as normal. If I hit backspace when the carat is to the right of the bubble, it deletes the entire bubble at once. Here's a simple example image:

example image

I feel like I've seen this kind of thing on the internet a lot but I can't work out how it's done. Is there a way to pull this off with an input field? If it's not possible which alternatives should I be looking into?

Upvotes: 1

Views: 489

Answers (3)

Joseph O'Donnell
Joseph O'Donnell

Reputation: 178

You could try using a series of inputs, instead of just one:

<div class="wrapper">
  <input /> <!-- "Is that " -->
  <button>Emma</button>
  <input /> <!-- "? " -->
  <button>Hello</button>
  <input /> <!-- ", " -->
  <button>Emma</button>
  <input /> <!-- "!" -->
</div>

The wrapper is just for styling purposes: you'd give it a border and make the input elements borderless.

You'd need to override a lot of keyboard commands on the input elements. For example, backspacing at the beginning of that last input would cause the preceding button to be deleted, and merge the contents of the two adjacent input elements.

You'd also need to consider the effect of hitting the Home and End keys (and equivalents in other OSes).

Moreover, you'd wanna make sure the input elements will resize as their contents change. It's a little tricky, but doable!

Here's a jumping off point: https://codepen.io/exonj/pen/jxQxGV

Upvotes: 0

Fabio Lolli
Fabio Lolli

Reputation: 889

I don't think you can do this with just an input unless you go change the standard implementation of input for your page :)

I think your best bet would be to have a structure like this:

<div class="wrapper">
  <div class="shownContent">Is that <div class="tag">Emma</div></div>
  <input class="underlyingInput"/>
  <div class="tagsButtons" />
</div>
  • undelyingInput is hidden - available but hidden.
  • Style shownContent to look like an input.
  • You then handle clicks on shownContent: if they click shown content, focus the hidden underlying input, BUT show shownContent as focused.
  • Now if the users start to write after they clicked on shownContent, that text is actually going into the input!
  • When value changes in the input, use the new value to parse it into text and tags, and set the html content of shownContent

Once you got this, removing tags from clicks on the left and adding them from clicks on the right should be straightforward.

Upvotes: 3

Manish Maharjan
Manish Maharjan

Reputation: 19

This is a tagsinput. Checkout this Bootstrap TagsInput. It has the same functionality as you wanted.

Upvotes: -1

Related Questions