Input of type "text" similar to the system of tags of the Stack Overflow

4

How to make a input of type text to use in a form that I need to add tags, just as it exists in Stack Overflow ?

  

Note

     

Whoever responds, the answer can be extremely large if it is to quote   the server-side rendering, although welcome, I'm more interested in HTML and JavaScript to do this layout.

    
asked by anonymous 11.01.2016 / 02:32

2 answers

5

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

However the problem seems to me only with the front end itself, so there are plugins ready that can help.

jQuery

For jQuery there are several plugins, but I'll quote the link :

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 $.ready or $(...) this:

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

It supports interaction with the server 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><scriptsrc="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 link :

Add after 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>

No header add:

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

Add application:

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

To use:

<tags-input ng-model="tags"></tags-input>
    
11.01.2016 / 02:52
4

As a complement to Guilherme Nascimento's great response, I leave here a "hand-made" 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><divclass="tags">
  <input type="text" value="html, css, javascript, php">
</div>

JsFiddle

I do not think it's necessary to explain all the functions that I used, because it would be very extensive, but just apply with the standard of the example that will work. If you see a bug, you can let me know.

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

You can manipulate , to your liking, it's commented on.

    
11.01.2016 / 05:35