Search code examples
javascriptcsstwitter-bootstrapbootstrap-tags-input

Bootstrap/TagsInput Applying To All Form Fields/Not Displayed Correctly


I am having issues understanding how to properly apply Bootstrap/TagsInput to a form.

My goal is to have a form with one field using TagsInput and another field not using it.

There are two problems:

  1. TagsInput seems to apply to any form field, not just the one I specify with data-role="tagsinput"
  2. The tags don't stay inside of the form field as the form field is always "just ahead" of the tags.

Here is the code:

        var citynames = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        prefetch: {
            url: 'http://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/assets/citynames.json',
            filter: function(list) {
            return $.map(list, function(cityname) {
                return { name: cityname }; });
            }
        }
        });
        citynames.initialize();

        $('input').tagsinput({
        typeaheadjs: {
            name: 'citynames',
            displayKey: 'name',
            valueKey: 'name',
            source: citynames.ttAdapter()
        }
        });
        .tt-query {
        -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
            -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
                box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
        }

        .tt-hint {
        color: #999
        }

        .tt-menu {    /* used to be tt-dropdown-menu in older versions */
        width: 422px;
        margin-top: 4px;
        padding: 4px 0;
        background-color: #fff;
        border: 1px solid #ccc;
        border: 1px solid rgba(0, 0, 0, 0.2);
        -webkit-border-radius: 4px;
            -moz-border-radius: 4px;
                border-radius: 4px;
        -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
            -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
                box-shadow: 0 5px 10px rgba(0,0,0,.2);
        }

        .tt-suggestion {
        padding: 3px 20px;
        line-height: 24px;
        }

        .tt-suggestion.tt-cursor,.tt-suggestion:hover {
        color: #fff;
        background-color: #0097cf;

        }

        .tt-suggestion p {
        margin: 0;
        }
        
        .bootstrap-tagsinput{
            width: 40%;
            display: block;
        }
        
        .twitter-typeahead {
            width: 40%;
            display: block;            
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap-theme.min.css">    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="http://bootstrap-tagsinput.github.io/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/themes/github.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.js"></script>
<form class="form-inline" role="form" action="/items/create", method="post">
        <div class="form-group">
            <label for="title">Title (should be no tags input):</label>
            <input type="text" class="form-control" id="title" name="title">
        <div class="form-group">
            <label for="tags"> Tags (should have tags input):</label>
            <input type="text" class="form-control" id="tags" name="tags" data-role="tagsinput">
        <button type="submit" class="btn btn-default"> Submit</button>
    </form>

Here is a JSFiddle with my code: https://jsfiddle.net/gg6rwmwa/1/

I am new to JavaScript/CSS, so any guidance would be appreciated on where I doing things wrong.

I found a few similar stackoverflow questions, but none that seemed to hit on these two points exactly (and provided an answer).

Thanks for any help!


Solution

    1. You created two divs inside the "form-inline" class, and they both had action="/items/create" and method="post" attributes. To correct this, just separate the different fields like I show below.

    2. That could be an issue with the CDN's you're using. I found a different one on formvalidation.io that seems to work pretty well. You can change it to suit your needs.

    Edit

    We also need to select the tags input form and do the relevant javascript processing inside of that. Every input field was becoming a tag input field because we forgot to add the $('#TagsInputForm') selector before doing our manipulations.

    HTML:

    <link rel="stylesheet" href="//cdn.jsdelivr.net/bootstrap.tagsinput/0.4.2/bootstrap-tagsinput.css" />
    <script src="//cdn.jsdelivr.net/bootstrap.tagsinput/0.4.2/bootstrap-tagsinput.min.js"></script>
    
    <form>
      <fieldset class="form-group">
        <label for="formGroupExample">No tags</label>
        <input type="text" class="form-control" id="formGroupExample">
      </fieldset>
      <fieldset class="form-group">
        <label for="formGroupExample2">No tags</label>
        <input type="text" class="form-control" id="formGroupExample2">
      </fieldset>
    </form>
    <form id="TagsInputForm" method="post" class="form-horizontal">
        <div class="form-group">
            <label class="control-label col-sm-2">Tag input</label>
            <div class="col-sm-10">
                <input type="text" name="tags" class="form-control"
                       value="Tag" data-role="tagsinput" />
            </div>
        </div>
        </form>
    </form>
    

    JS:

    $(document).ready(function () {
        $('#TagsInputForm') {
            var citynames = new Bloodhound({
            datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
            queryTokenizer: Bloodhound.tokenizers.whitespace,
            prefetch: {
                url: 'https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/assets/citynames.json',
                filter: function(list) {
                return $.map(list, function(cityname) {
                    return { name: cityname }; });
                }
            }
            });
            citynames.initialize();
    
            $('input').tagsinput({
            typeaheadjs: {
                name: 'citynames',
                displayKey: 'name',
                valueKey: 'name',
                source: citynames.ttAdapter()
            }}
            });
            });