"Text" type input similar to the Stack Overflow tag system

Asked

Viewed 384 times

4

How to make a input of the kind text to use in a form I need to add tags, just as in Stack Overflow?

print tags

Observing

To whom to answer, the answer can be extremely large if you quote the server-side processing, although welcome, I’m more interested in HTML and Javascript for making this layout.

  • You need the search system, even if only with javascript, or you just want the functionality of adding tags to the left of the text?

  • Just want the visual part, the logical part of the search would be too complex to ask here without at least having a ready base, so only the visual part of adding the tags to the left and highlighted would already be of good size.

2 answers

5


The element that looks like a <input> is actually a <div>, the <input> this inside it and the tags that appear are Divs inserted with document.createElement. Autocomplete (when typing) is really a matter of using ajax and interacting with the server.

However the problem seems to me only with the front-end even so there are plugins ready that can help you.

jQuery

For jQuery there are several plugins, but I will quote the https://github.com/xoxco/jQuery-Tags-Input:

Add this to the page:

<script src="jquery.tagsinput.js"></script>
<link rel="stylesheet" type="text/css" href="jquery.tagsinput.css" />

Create an element like this:

<input name="tags" id="tags" value="foo,bar,baz" />

Put in the $.ready or $(...) this:

$(function() {
    $('#tags').tagsInput();
})

It supports server interaction like this:

$('#tags').tagsInput({
  autocomplete_url:'http://myserver.com/api/autocomplete'
});

Basic example:

$(function() {
    $('#tag1').tagsInput({});
});
<link href="http://xoxco.com/examples/jquery.tagsinput.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://xoxco.com/examples/jquery.tagsinput.js"></script>

<div id="wrapper">
<p>Exemplo básico: 
    <input id="tag1" value="stack,overflow,portugues,olá,mundo" />
</p>
</div>

Angular.js

For angular there is the http://mbenford.github.io/ngTagsInput/:

Add after the angular.js:

<script type="text/javascript" src="path/to/angular.min.js"></script>
<script type="text/javascript" src="path/to/ng-tags-input.min.js"></script>

In the header add:

<link rel="stylesheet" href="path/to/ng-tags-input.min.css">    

Add the application:

angular.module('myApp', ['ngTagsInput']);

To use:

<tags-input ng-model="tags"></tags-input>
  • Very enlightening, I was interested in the first one, I’m going to run some tests on it, thank you very much. I will not mark as better answer yet so that others can respond with other alternatives, maybe it will be useful for the content of the site.

  • @Renancavalieri the question is not whether or not there will appear better alternatives, it is whether you tested and whether it worked for you. If something better appears then you can uncheck mine and mark the new answer ;) - But the important thing is to test and use first, then you mark the answer.

4

As a complement to Guilherme Nascimento’s great response, I leave here a "handmade" option of this tag system. You can check below:

function tagCreator(par) {
  par.append('<div class="tagInsert"></div>');
  var newTags = par.children('input:text');
  newTags.addClass('newTag');
  newTags.appendTo('.tagInsert');
  $('.tagInsert').add(newTags);

  var tags = newTags.val().split(',');

  function renderTags() {
tags.forEach(function(el, i) {
  if (i != tags.length) {
    newTags.before('<div class="tag"><span class="tagName">' + el + '</span><span class="tagClose">x</span></div>');
  }
})
$('.newTag').val('');
  }
  renderTags()
  var i = 0;
  newTags.bind("keydown", function(e) {

var keyCode = (e.keyCode ? e.keyCode : e.which)

$(this).css('max-width', $(this).closest('div').parent('div').width());
$(this).css('width', (this.value.length + 1) * 6);

$('.tag:last').css('opacity', '1');

if (keyCode == 13 || keyCode == 188) {
  $(this).val(this.value.replace(/[,]/g, ''))
  e.preventDefault();
  if (/\w/g.test(this.value)) {
    $('.tag').remove();
    tags.push(this.value.replace(',', ''))
    renderTags();
  }
}

if (keyCode == 8 && this.value == "") {
  i++;
  if (i == 1) {
    $('.tag:last').css('opacity', '0.6');
  } else if (i == 2) {
    $('.tag:last').remove();
    tags.pop();
    i = 0;
  }
} else {
  i = 0;
}
  })

  $(document).on('click', '.tagClose', function(e) {
tags.splice($(this).index('.tagClose'), 1);
$(this).closest('div.tag').remove();
  })

  par.on('click', function(e) {
newTags.focus();
  })
}
tagCreator($('.tags'));
/* Div que a caixa de texto está inserida */
.tagInsert {
  width: auto;
  display: block;
}

/*Caixa de texto*/
.newTag {
  height: 28px;
  min-width: 80px;
  border: none;
  outline: none;
}

/* Box de cada tag */
.tag {
  display: inline-block;
  line-height: 20px;
  height: auto;
  background: #13d277;
  border: 2px solid #0e9856;
  padding: 3px 5px;
  margin: 1px 3px;
  border-radius: 5px;
  color: #fff;
  max-width: 100%;
  word-break: break-all;  
}

/* Botão de fechar */
.tagClose {
  display: inline-block;
  margin-left: 7px;
  background: #0e9856;
  color: #fff;
  width: 10px;
  height: 10px;
  padding: 2px;
  border-radius: 100%;
  line-height: 110%;
  font-size: 7pt;
  text-align: center;
  cursor: pointer;
  font-family: 'Trebuchet MS', sans-serif;
}

/* Alinhando a caixa de texto e as tags */
.tags div {
  display: inline-block;
}

/* Div geral */
.tags {
  border: 2px solid #666;
  border-radius: 5px;
  background: #fff;
  height: auto;
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tags">
  <input type="text" value="html, css, javascript, php">
</div>

Jsfiddle

I don’t think I need to explain all the functions I used, because it would be too extensive, but just apply with the pattern of the example that will, work. If you see any bugs, you can let me know.

The function tagCreator(), which receives as an argument div that must necessarily have inside a input:text. The default values are entered in the value of input, separated by , comma.

You can manipulate the css to your liking, he is commented.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.